]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/gcc/config/i386/i386.md
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / 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, 2006
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    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156   ])
157
158 (define_constants
159   [(UNSPECV_BLOCKAGE            0)
160    (UNSPECV_STACK_PROBE         1)
161    (UNSPECV_EMMS                2)
162    (UNSPECV_LDMXCSR             3)
163    (UNSPECV_STMXCSR             4)
164    (UNSPECV_FEMMS               5)
165    (UNSPECV_CLFLUSH             6)
166    (UNSPECV_ALIGN               7)
167    (UNSPECV_MONITOR             8)
168    (UNSPECV_MWAIT               9)
169    (UNSPECV_CMPXCHG_1           10)
170    (UNSPECV_CMPXCHG_2           11)
171    (UNSPECV_XCHG                12)
172    (UNSPECV_LOCK                13)
173   ])
174
175 ;; Registers by name.
176 (define_constants
177   [(BP_REG                       6)
178    (SP_REG                       7)
179    (FLAGS_REG                   17)
180    (FPSR_REG                    18)
181    (DIRFLAG_REG                 19)
182   ])
183
184 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
185 ;; from i386.c.
186
187 ;; In C guard expressions, put expressions which may be compile-time
188 ;; constants first.  This allows for better optimization.  For
189 ;; example, write "TARGET_64BIT && reload_completed", not
190 ;; "reload_completed && TARGET_64BIT".
191
192 \f
193 ;; Processor type.  This attribute must exactly match the processor_type
194 ;; enumeration in i386.h.
195 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
196   (const (symbol_ref "ix86_tune")))
197
198 ;; A basic instruction type.  Refinements due to arguments to be
199 ;; provided in other attributes.
200 (define_attr "type"
201   "other,multi,
202    alu,alu1,negnot,imov,imovx,lea,
203    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204    icmp,test,ibr,setcc,icmov,
205    push,pop,call,callv,leave,
206    str,cld,
207    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208    sselog,sselog1,sseiadd,sseishft,sseimul,
209    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
210    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211   (const_string "other"))
212
213 ;; Main data type used by the insn
214 (define_attr "mode"
215   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216   (const_string "unknown"))
217
218 ;; The CPU unit operations uses.
219 (define_attr "unit" "integer,i387,sse,mmx,unknown"
220   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221            (const_string "i387")
222          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
224            (const_string "sse")
225          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
226            (const_string "mmx")
227          (eq_attr "type" "other")
228            (const_string "unknown")]
229          (const_string "integer")))
230
231 ;; The (bounding maximum) length of an instruction immediate.
232 (define_attr "length_immediate" ""
233   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
234            (const_int 0)
235          (eq_attr "unit" "i387,sse,mmx")
236            (const_int 0)
237          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
238                           imul,icmp,push,pop")
239            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240          (eq_attr "type" "imov,test")
241            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242          (eq_attr "type" "call")
243            (if_then_else (match_operand 0 "constant_call_address_operand" "")
244              (const_int 4)
245              (const_int 0))
246          (eq_attr "type" "callv")
247            (if_then_else (match_operand 1 "constant_call_address_operand" "")
248              (const_int 4)
249              (const_int 0))
250          ;; We don't know the size before shorten_branches.  Expect
251          ;; the instruction to fit for better scheduling.
252          (eq_attr "type" "ibr")
253            (const_int 1)
254          ]
255          (symbol_ref "/* Update immediate_length and other attributes! */
256                       gcc_unreachable (),1")))
257
258 ;; The (bounding maximum) length of an instruction address.
259 (define_attr "length_address" ""
260   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
261            (const_int 0)
262          (and (eq_attr "type" "call")
263               (match_operand 0 "constant_call_address_operand" ""))
264              (const_int 0)
265          (and (eq_attr "type" "callv")
266               (match_operand 1 "constant_call_address_operand" ""))
267              (const_int 0)
268          ]
269          (symbol_ref "ix86_attr_length_address_default (insn)")))
270
271 ;; Set when length prefix is used.
272 (define_attr "prefix_data16" ""
273   (if_then_else (ior (eq_attr "mode" "HI")
274                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
275     (const_int 1)
276     (const_int 0)))
277
278 ;; Set when string REP prefix is used.
279 (define_attr "prefix_rep" "" 
280   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
281     (const_int 1)
282     (const_int 0)))
283
284 ;; Set when 0f opcode prefix is used.
285 (define_attr "prefix_0f" ""
286   (if_then_else 
287     (ior (eq_attr "type" "imovx,setcc,icmov")
288          (eq_attr "unit" "sse,mmx"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when REX opcode prefix is used.
293 (define_attr "prefix_rex" ""
294   (cond [(and (eq_attr "mode" "DI")
295               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
296            (const_int 1)
297          (and (eq_attr "mode" "QI")
298               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
299                   (const_int 0)))
300            (const_int 1)
301          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302              (const_int 0))
303            (const_int 1)
304         ]
305         (const_int 0)))
306
307 ;; Set when modrm byte is used.
308 (define_attr "modrm" ""
309   (cond [(eq_attr "type" "str,cld,leave")
310            (const_int 0)
311          (eq_attr "unit" "i387")
312            (const_int 0)
313          (and (eq_attr "type" "incdec")
314               (ior (match_operand:SI 1 "register_operand" "")
315                    (match_operand:HI 1 "register_operand" "")))
316            (const_int 0)
317          (and (eq_attr "type" "push")
318               (not (match_operand 1 "memory_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "pop")
321               (not (match_operand 0 "memory_operand" "")))
322            (const_int 0)
323          (and (eq_attr "type" "imov")
324               (ior (and (match_operand 0 "register_operand" "")
325                         (match_operand 1 "immediate_operand" ""))
326                    (ior (and (match_operand 0 "ax_reg_operand" "")
327                              (match_operand 1 "memory_displacement_only_operand" ""))
328                         (and (match_operand 0 "memory_displacement_only_operand" "")
329                              (match_operand 1 "ax_reg_operand" "")))))
330            (const_int 0)
331          (and (eq_attr "type" "call")
332               (match_operand 0 "constant_call_address_operand" ""))
333              (const_int 0)
334          (and (eq_attr "type" "callv")
335               (match_operand 1 "constant_call_address_operand" ""))
336              (const_int 0)
337          ]
338          (const_int 1)))
339
340 ;; The (bounding maximum) length of an instruction in bytes.
341 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342 ;; Later we may want to split them and compute proper length as for
343 ;; other insns.
344 (define_attr "length" ""
345   (cond [(eq_attr "type" "other,multi,fistp,frndint")
346            (const_int 16)
347          (eq_attr "type" "fcmp")
348            (const_int 4)
349          (eq_attr "unit" "i387")
350            (plus (const_int 2)
351                  (plus (attr "prefix_data16")
352                        (attr "length_address")))]
353          (plus (plus (attr "modrm")
354                      (plus (attr "prefix_0f")
355                            (plus (attr "prefix_rex")
356                                  (const_int 1))))
357                (plus (attr "prefix_rep")
358                      (plus (attr "prefix_data16")
359                            (plus (attr "length_immediate")
360                                  (attr "length_address")))))))
361
362 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
363 ;; `store' if there is a simple memory reference therein, or `unknown'
364 ;; if the instruction is complex.
365
366 (define_attr "memory" "none,load,store,both,unknown"
367   (cond [(eq_attr "type" "other,multi,str")
368            (const_string "unknown")
369          (eq_attr "type" "lea,fcmov,fpspc,cld")
370            (const_string "none")
371          (eq_attr "type" "fistp,leave")
372            (const_string "both")
373          (eq_attr "type" "frndint")
374            (const_string "load")
375          (eq_attr "type" "push")
376            (if_then_else (match_operand 1 "memory_operand" "")
377              (const_string "both")
378              (const_string "store"))
379          (eq_attr "type" "pop")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "both")
382              (const_string "load"))
383          (eq_attr "type" "setcc")
384            (if_then_else (match_operand 0 "memory_operand" "")
385              (const_string "store")
386              (const_string "none"))
387          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388            (if_then_else (ior (match_operand 0 "memory_operand" "")
389                               (match_operand 1 "memory_operand" ""))
390              (const_string "load")
391              (const_string "none"))
392          (eq_attr "type" "ibr")
393            (if_then_else (match_operand 0 "memory_operand" "")
394              (const_string "load")
395              (const_string "none"))
396          (eq_attr "type" "call")
397            (if_then_else (match_operand 0 "constant_call_address_operand" "")
398              (const_string "none")
399              (const_string "load"))
400          (eq_attr "type" "callv")
401            (if_then_else (match_operand 1 "constant_call_address_operand" "")
402              (const_string "none")
403              (const_string "load"))
404          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405               (match_operand 1 "memory_operand" ""))
406            (const_string "both")
407          (and (match_operand 0 "memory_operand" "")
408               (match_operand 1 "memory_operand" ""))
409            (const_string "both")
410          (match_operand 0 "memory_operand" "")
411            (const_string "store")
412          (match_operand 1 "memory_operand" "")
413            (const_string "load")
414          (and (eq_attr "type"
415                  "!alu1,negnot,ishift1,
416                    imov,imovx,icmp,test,
417                    fmov,fcmp,fsgn,
418                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419                    mmx,mmxmov,mmxcmp,mmxcvt")
420               (match_operand 2 "memory_operand" ""))
421            (const_string "load")
422          (and (eq_attr "type" "icmov")
423               (match_operand 3 "memory_operand" ""))
424            (const_string "load")
425         ]
426         (const_string "none")))
427
428 ;; Indicates if an instruction has both an immediate and a displacement.
429
430 (define_attr "imm_disp" "false,true,unknown"
431   (cond [(eq_attr "type" "other,multi")
432            (const_string "unknown")
433          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434               (and (match_operand 0 "memory_displacement_operand" "")
435                    (match_operand 1 "immediate_operand" "")))
436            (const_string "true")
437          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438               (and (match_operand 0 "memory_displacement_operand" "")
439                    (match_operand 2 "immediate_operand" "")))
440            (const_string "true")
441         ]
442         (const_string "false")))
443
444 ;; Indicates if an FP operation has an integer source.
445
446 (define_attr "fp_int_src" "false,true"
447   (const_string "false"))
448
449 ;; Defines rounding mode of an FP operation.
450
451 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452   (const_string "any"))
453
454 ;; Describe a user's asm statement.
455 (define_asm_attributes
456   [(set_attr "length" "128")
457    (set_attr "type" "multi")])
458
459 ;; All x87 floating point modes
460 (define_mode_macro X87MODEF [SF DF XF])
461  
462 ;; All integer modes handled by x87 fisttp operator.
463 (define_mode_macro X87MODEI [HI SI DI])
464
465 ;; All integer modes handled by integer x87 operators.
466 (define_mode_macro X87MODEI12 [HI SI])
467
468 ;; All SSE floating point modes
469 (define_mode_macro SSEMODEF [SF DF])
470  
471 ;; All integer modes handled by SSE cvtts?2si* operators.
472 (define_mode_macro SSEMODEI24 [SI DI])
473
474 \f
475 ;; Scheduling descriptions
476
477 (include "pentium.md")
478 (include "ppro.md")
479 (include "k6.md")
480 (include "athlon.md")
481 (include "geode.md")
482
483 \f
484 ;; Operand and operator predicates and constraints
485
486 (include "predicates.md")
487 (include "constraints.md")
488
489 \f
490 ;; Compare instructions.
491
492 ;; All compare insns have expanders that save the operands away without
493 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
494 ;; after the cmp) will actually emit the cmpM.
495
496 (define_expand "cmpti"
497   [(set (reg:CC FLAGS_REG)
498         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
499                     (match_operand:TI 1 "x86_64_general_operand" "")))]
500   "TARGET_64BIT"
501 {
502   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503     operands[0] = force_reg (TImode, operands[0]);
504   ix86_compare_op0 = operands[0];
505   ix86_compare_op1 = operands[1];
506   DONE;
507 })
508
509 (define_expand "cmpdi"
510   [(set (reg:CC FLAGS_REG)
511         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
512                     (match_operand:DI 1 "x86_64_general_operand" "")))]
513   ""
514 {
515   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516     operands[0] = force_reg (DImode, operands[0]);
517   ix86_compare_op0 = operands[0];
518   ix86_compare_op1 = operands[1];
519   DONE;
520 })
521
522 (define_expand "cmpsi"
523   [(set (reg:CC FLAGS_REG)
524         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
525                     (match_operand:SI 1 "general_operand" "")))]
526   ""
527 {
528   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529     operands[0] = force_reg (SImode, operands[0]);
530   ix86_compare_op0 = operands[0];
531   ix86_compare_op1 = operands[1];
532   DONE;
533 })
534
535 (define_expand "cmphi"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
538                     (match_operand:HI 1 "general_operand" "")))]
539   ""
540 {
541   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542     operands[0] = force_reg (HImode, operands[0]);
543   ix86_compare_op0 = operands[0];
544   ix86_compare_op1 = operands[1];
545   DONE;
546 })
547
548 (define_expand "cmpqi"
549   [(set (reg:CC FLAGS_REG)
550         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
551                     (match_operand:QI 1 "general_operand" "")))]
552   "TARGET_QIMODE_MATH"
553 {
554   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
555     operands[0] = force_reg (QImode, operands[0]);
556   ix86_compare_op0 = operands[0];
557   ix86_compare_op1 = operands[1];
558   DONE;
559 })
560
561 (define_insn "cmpdi_ccno_1_rex64"
562   [(set (reg FLAGS_REG)
563         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
564                  (match_operand:DI 1 "const0_operand" "n,n")))]
565   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
566   "@
567    test{q}\t{%0, %0|%0, %0}
568    cmp{q}\t{%1, %0|%0, %1}"
569   [(set_attr "type" "test,icmp")
570    (set_attr "length_immediate" "0,1")
571    (set_attr "mode" "DI")])
572
573 (define_insn "*cmpdi_minus_1_rex64"
574   [(set (reg FLAGS_REG)
575         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
576                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
577                  (const_int 0)))]
578   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
579   "cmp{q}\t{%1, %0|%0, %1}"
580   [(set_attr "type" "icmp")
581    (set_attr "mode" "DI")])
582
583 (define_expand "cmpdi_1_rex64"
584   [(set (reg:CC FLAGS_REG)
585         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
586                     (match_operand:DI 1 "general_operand" "")))]
587   "TARGET_64BIT"
588   "")
589
590 (define_insn "cmpdi_1_insn_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
593                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
594   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
595   "cmp{q}\t{%1, %0|%0, %1}"
596   [(set_attr "type" "icmp")
597    (set_attr "mode" "DI")])
598
599
600 (define_insn "*cmpsi_ccno_1"
601   [(set (reg FLAGS_REG)
602         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
603                  (match_operand:SI 1 "const0_operand" "n,n")))]
604   "ix86_match_ccmode (insn, CCNOmode)"
605   "@
606    test{l}\t{%0, %0|%0, %0}
607    cmp{l}\t{%1, %0|%0, %1}"
608   [(set_attr "type" "test,icmp")
609    (set_attr "length_immediate" "0,1")
610    (set_attr "mode" "SI")])
611
612 (define_insn "*cmpsi_minus_1"
613   [(set (reg FLAGS_REG)
614         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
615                            (match_operand:SI 1 "general_operand" "ri,mr"))
616                  (const_int 0)))]
617   "ix86_match_ccmode (insn, CCGOCmode)"
618   "cmp{l}\t{%1, %0|%0, %1}"
619   [(set_attr "type" "icmp")
620    (set_attr "mode" "SI")])
621
622 (define_expand "cmpsi_1"
623   [(set (reg:CC FLAGS_REG)
624         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                     (match_operand:SI 1 "general_operand" "ri,mr")))]
626   ""
627   "")
628
629 (define_insn "*cmpsi_1_insn"
630   [(set (reg FLAGS_REG)
631         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                  (match_operand:SI 1 "general_operand" "ri,mr")))]
633   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
634     && ix86_match_ccmode (insn, CCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_insn "*cmphi_ccno_1"
640   [(set (reg FLAGS_REG)
641         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
642                  (match_operand:HI 1 "const0_operand" "n,n")))]
643   "ix86_match_ccmode (insn, CCNOmode)"
644   "@
645    test{w}\t{%0, %0|%0, %0}
646    cmp{w}\t{%1, %0|%0, %1}"
647   [(set_attr "type" "test,icmp")
648    (set_attr "length_immediate" "0,1")
649    (set_attr "mode" "HI")])
650
651 (define_insn "*cmphi_minus_1"
652   [(set (reg FLAGS_REG)
653         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
654                            (match_operand:HI 1 "general_operand" "ri,mr"))
655                  (const_int 0)))]
656   "ix86_match_ccmode (insn, CCGOCmode)"
657   "cmp{w}\t{%1, %0|%0, %1}"
658   [(set_attr "type" "icmp")
659    (set_attr "mode" "HI")])
660
661 (define_insn "*cmphi_1"
662   [(set (reg FLAGS_REG)
663         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664                  (match_operand:HI 1 "general_operand" "ri,mr")))]
665   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
666    && ix86_match_ccmode (insn, CCmode)"
667   "cmp{w}\t{%1, %0|%0, %1}"
668   [(set_attr "type" "icmp")
669    (set_attr "mode" "HI")])
670
671 (define_insn "*cmpqi_ccno_1"
672   [(set (reg FLAGS_REG)
673         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
674                  (match_operand:QI 1 "const0_operand" "n,n")))]
675   "ix86_match_ccmode (insn, CCNOmode)"
676   "@
677    test{b}\t{%0, %0|%0, %0}
678    cmp{b}\t{$0, %0|%0, 0}"
679   [(set_attr "type" "test,icmp")
680    (set_attr "length_immediate" "0,1")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_1"
684   [(set (reg FLAGS_REG)
685         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
686                  (match_operand:QI 1 "general_operand" "qi,mq")))]
687   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
688     && ix86_match_ccmode (insn, CCmode)"
689   "cmp{b}\t{%1, %0|%0, %1}"
690   [(set_attr "type" "icmp")
691    (set_attr "mode" "QI")])
692
693 (define_insn "*cmpqi_minus_1"
694   [(set (reg FLAGS_REG)
695         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696                            (match_operand:QI 1 "general_operand" "qi,mq"))
697                  (const_int 0)))]
698   "ix86_match_ccmode (insn, CCGOCmode)"
699   "cmp{b}\t{%1, %0|%0, %1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
702
703 (define_insn "*cmpqi_ext_1"
704   [(set (reg FLAGS_REG)
705         (compare
706           (match_operand:QI 0 "general_operand" "Qm")
707           (subreg:QI
708             (zero_extract:SI
709               (match_operand 1 "ext_register_operand" "Q")
710               (const_int 8)
711               (const_int 8)) 0)))]
712   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713   "cmp{b}\t{%h1, %0|%0, %h1}"
714   [(set_attr "type" "icmp")
715    (set_attr "mode" "QI")])
716
717 (define_insn "*cmpqi_ext_1_rex64"
718   [(set (reg FLAGS_REG)
719         (compare
720           (match_operand:QI 0 "register_operand" "Q")
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 1 "ext_register_operand" "Q")
724               (const_int 8)
725               (const_int 8)) 0)))]
726   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
727   "cmp{b}\t{%h1, %0|%0, %h1}"
728   [(set_attr "type" "icmp")
729    (set_attr "mode" "QI")])
730
731 (define_insn "*cmpqi_ext_2"
732   [(set (reg FLAGS_REG)
733         (compare
734           (subreg:QI
735             (zero_extract:SI
736               (match_operand 0 "ext_register_operand" "Q")
737               (const_int 8)
738               (const_int 8)) 0)
739           (match_operand:QI 1 "const0_operand" "n")))]
740   "ix86_match_ccmode (insn, CCNOmode)"
741   "test{b}\t%h0, %h0"
742   [(set_attr "type" "test")
743    (set_attr "length_immediate" "0")
744    (set_attr "mode" "QI")])
745
746 (define_expand "cmpqi_ext_3"
747   [(set (reg:CC FLAGS_REG)
748         (compare:CC
749           (subreg:QI
750             (zero_extract:SI
751               (match_operand 0 "ext_register_operand" "")
752               (const_int 8)
753               (const_int 8)) 0)
754           (match_operand:QI 1 "general_operand" "")))]
755   ""
756   "")
757
758 (define_insn "cmpqi_ext_3_insn"
759   [(set (reg FLAGS_REG)
760         (compare
761           (subreg:QI
762             (zero_extract:SI
763               (match_operand 0 "ext_register_operand" "Q")
764               (const_int 8)
765               (const_int 8)) 0)
766           (match_operand:QI 1 "general_operand" "Qmn")))]
767   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768   "cmp{b}\t{%1, %h0|%h0, %1}"
769   [(set_attr "type" "icmp")
770    (set_attr "mode" "QI")])
771
772 (define_insn "cmpqi_ext_3_insn_rex64"
773   [(set (reg FLAGS_REG)
774         (compare
775           (subreg:QI
776             (zero_extract:SI
777               (match_operand 0 "ext_register_operand" "Q")
778               (const_int 8)
779               (const_int 8)) 0)
780           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
781   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
782   "cmp{b}\t{%1, %h0|%h0, %1}"
783   [(set_attr "type" "icmp")
784    (set_attr "mode" "QI")])
785
786 (define_insn "*cmpqi_ext_4"
787   [(set (reg FLAGS_REG)
788         (compare
789           (subreg:QI
790             (zero_extract:SI
791               (match_operand 0 "ext_register_operand" "Q")
792               (const_int 8)
793               (const_int 8)) 0)
794           (subreg:QI
795             (zero_extract:SI
796               (match_operand 1 "ext_register_operand" "Q")
797               (const_int 8)
798               (const_int 8)) 0)))]
799   "ix86_match_ccmode (insn, CCmode)"
800   "cmp{b}\t{%h1, %h0|%h0, %h1}"
801   [(set_attr "type" "icmp")
802    (set_attr "mode" "QI")])
803
804 ;; These implement float point compares.
805 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
806 ;; which would allow mix and match FP modes on the compares.  Which is what
807 ;; the old patterns did, but with many more of them.
808
809 (define_expand "cmpxf"
810   [(set (reg:CC FLAGS_REG)
811         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
812                     (match_operand:XF 1 "nonmemory_operand" "")))]
813   "TARGET_80387"
814 {
815   ix86_compare_op0 = operands[0];
816   ix86_compare_op1 = operands[1];
817   DONE;
818 })
819
820 (define_expand "cmpdf"
821   [(set (reg:CC FLAGS_REG)
822         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
823                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
824   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
825 {
826   ix86_compare_op0 = operands[0];
827   ix86_compare_op1 = operands[1];
828   DONE;
829 })
830
831 (define_expand "cmpsf"
832   [(set (reg:CC FLAGS_REG)
833         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
834                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
835   "TARGET_80387 || TARGET_SSE_MATH"
836 {
837   ix86_compare_op0 = operands[0];
838   ix86_compare_op1 = operands[1];
839   DONE;
840 })
841
842 ;; FP compares, step 1:
843 ;; Set the FP condition codes.
844 ;;
845 ;; CCFPmode     compare with exceptions
846 ;; CCFPUmode    compare with no exceptions
847
848 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
849 ;; used to manage the reg stack popping would not be preserved.
850
851 (define_insn "*cmpfp_0"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand 1 "register_operand" "f")
856              (match_operand 2 "const0_operand" "X"))]
857         UNSPEC_FNSTSW))]
858   "TARGET_80387
859    && FLOAT_MODE_P (GET_MODE (operands[1]))
860    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
861   "* return output_fp_compare (insn, operands, 0, 0);"
862   [(set_attr "type" "multi")
863    (set_attr "unit" "i387")
864    (set (attr "mode")
865      (cond [(match_operand:SF 1 "" "")
866               (const_string "SF")
867             (match_operand:DF 1 "" "")
868               (const_string "DF")
869            ]
870            (const_string "XF")))])
871
872 (define_insn "*cmpfp_sf"
873   [(set (match_operand:HI 0 "register_operand" "=a")
874         (unspec:HI
875           [(compare:CCFP
876              (match_operand:SF 1 "register_operand" "f")
877              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
878           UNSPEC_FNSTSW))]
879   "TARGET_80387"
880   "* return output_fp_compare (insn, operands, 0, 0);"
881   [(set_attr "type" "multi")
882    (set_attr "unit" "i387")
883    (set_attr "mode" "SF")])
884
885 (define_insn "*cmpfp_df"
886   [(set (match_operand:HI 0 "register_operand" "=a")
887         (unspec:HI
888           [(compare:CCFP
889              (match_operand:DF 1 "register_operand" "f")
890              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
891           UNSPEC_FNSTSW))]
892   "TARGET_80387"
893   "* return output_fp_compare (insn, operands, 0, 0);"
894   [(set_attr "type" "multi")
895    (set_attr "unit" "i387")
896    (set_attr "mode" "DF")])
897
898 (define_insn "*cmpfp_xf"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFP
902              (match_operand:XF 1 "register_operand" "f")
903              (match_operand:XF 2 "register_operand" "f"))]
904           UNSPEC_FNSTSW))]
905   "TARGET_80387"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "unit" "i387")
909    (set_attr "mode" "XF")])
910
911 (define_insn "*cmpfp_u"
912   [(set (match_operand:HI 0 "register_operand" "=a")
913         (unspec:HI
914           [(compare:CCFPU
915              (match_operand 1 "register_operand" "f")
916              (match_operand 2 "register_operand" "f"))]
917           UNSPEC_FNSTSW))]
918   "TARGET_80387
919    && FLOAT_MODE_P (GET_MODE (operands[1]))
920    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
921   "* return output_fp_compare (insn, operands, 0, 1);"
922   [(set_attr "type" "multi")
923    (set_attr "unit" "i387")
924    (set (attr "mode")
925      (cond [(match_operand:SF 1 "" "")
926               (const_string "SF")
927             (match_operand:DF 1 "" "")
928               (const_string "DF")
929            ]
930            (const_string "XF")))])
931
932 (define_insn "*cmpfp_<mode>"
933   [(set (match_operand:HI 0 "register_operand" "=a")
934         (unspec:HI
935           [(compare:CCFP
936              (match_operand 1 "register_operand" "f")
937              (match_operator 3 "float_operator"
938                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
939           UNSPEC_FNSTSW))]
940   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
941    && FLOAT_MODE_P (GET_MODE (operands[1]))
942    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
943   "* return output_fp_compare (insn, operands, 0, 0);"
944   [(set_attr "type" "multi")
945    (set_attr "unit" "i387")
946    (set_attr "fp_int_src" "true")
947    (set_attr "mode" "<MODE>")])
948
949 ;; FP compares, step 2
950 ;; Move the fpsw to ax.
951
952 (define_insn "x86_fnstsw_1"
953   [(set (match_operand:HI 0 "register_operand" "=a")
954         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
955   "TARGET_80387"
956   "fnstsw\t%0"
957   [(set_attr "length" "2")
958    (set_attr "mode" "SI")
959    (set_attr "unit" "i387")])
960
961 ;; FP compares, step 3
962 ;; Get ax into flags, general case.
963
964 (define_insn "x86_sahf_1"
965   [(set (reg:CC FLAGS_REG)
966         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
967   "!TARGET_64BIT"
968   "sahf"
969   [(set_attr "length" "1")
970    (set_attr "athlon_decode" "vector")
971    (set_attr "mode" "SI")])
972
973 ;; Pentium Pro can do steps 1 through 3 in one go.
974
975 (define_insn "*cmpfp_i_mixed"
976   [(set (reg:CCFP FLAGS_REG)
977         (compare:CCFP (match_operand 0 "register_operand" "f,x")
978                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
979   "TARGET_MIX_SSE_I387
980    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982   "* return output_fp_compare (insn, operands, 1, 0);"
983   [(set_attr "type" "fcmp,ssecomi")
984    (set (attr "mode")
985      (if_then_else (match_operand:SF 1 "" "")
986         (const_string "SF")
987         (const_string "DF")))
988    (set_attr "athlon_decode" "vector")])
989
990 (define_insn "*cmpfp_i_sse"
991   [(set (reg:CCFP FLAGS_REG)
992         (compare:CCFP (match_operand 0 "register_operand" "x")
993                       (match_operand 1 "nonimmediate_operand" "xm")))]
994   "TARGET_SSE_MATH
995    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997   "* return output_fp_compare (insn, operands, 1, 0);"
998   [(set_attr "type" "ssecomi")
999    (set (attr "mode")
1000      (if_then_else (match_operand:SF 1 "" "")
1001         (const_string "SF")
1002         (const_string "DF")))
1003    (set_attr "athlon_decode" "vector")])
1004
1005 (define_insn "*cmpfp_i_i387"
1006   [(set (reg:CCFP FLAGS_REG)
1007         (compare:CCFP (match_operand 0 "register_operand" "f")
1008                       (match_operand 1 "register_operand" "f")))]
1009   "TARGET_80387 && TARGET_CMOVE
1010    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1011    && FLOAT_MODE_P (GET_MODE (operands[0]))
1012    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1013   "* return output_fp_compare (insn, operands, 1, 0);"
1014   [(set_attr "type" "fcmp")
1015    (set (attr "mode")
1016      (cond [(match_operand:SF 1 "" "")
1017               (const_string "SF")
1018             (match_operand:DF 1 "" "")
1019               (const_string "DF")
1020            ]
1021            (const_string "XF")))
1022    (set_attr "athlon_decode" "vector")])
1023
1024 (define_insn "*cmpfp_iu_mixed"
1025   [(set (reg:CCFPU FLAGS_REG)
1026         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1027                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1028   "TARGET_MIX_SSE_I387
1029    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031   "* return output_fp_compare (insn, operands, 1, 1);"
1032   [(set_attr "type" "fcmp,ssecomi")
1033    (set (attr "mode")
1034      (if_then_else (match_operand:SF 1 "" "")
1035         (const_string "SF")
1036         (const_string "DF")))
1037    (set_attr "athlon_decode" "vector")])
1038
1039 (define_insn "*cmpfp_iu_sse"
1040   [(set (reg:CCFPU FLAGS_REG)
1041         (compare:CCFPU (match_operand 0 "register_operand" "x")
1042                        (match_operand 1 "nonimmediate_operand" "xm")))]
1043   "TARGET_SSE_MATH
1044    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1045    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046   "* return output_fp_compare (insn, operands, 1, 1);"
1047   [(set_attr "type" "ssecomi")
1048    (set (attr "mode")
1049      (if_then_else (match_operand:SF 1 "" "")
1050         (const_string "SF")
1051         (const_string "DF")))
1052    (set_attr "athlon_decode" "vector")])
1053
1054 (define_insn "*cmpfp_iu_387"
1055   [(set (reg:CCFPU FLAGS_REG)
1056         (compare:CCFPU (match_operand 0 "register_operand" "f")
1057                        (match_operand 1 "register_operand" "f")))]
1058   "TARGET_80387 && TARGET_CMOVE
1059    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1060    && FLOAT_MODE_P (GET_MODE (operands[0]))
1061    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1062   "* return output_fp_compare (insn, operands, 1, 1);"
1063   [(set_attr "type" "fcmp")
1064    (set (attr "mode")
1065      (cond [(match_operand:SF 1 "" "")
1066               (const_string "SF")
1067             (match_operand:DF 1 "" "")
1068               (const_string "DF")
1069            ]
1070            (const_string "XF")))
1071    (set_attr "athlon_decode" "vector")])
1072 \f
1073 ;; Move instructions.
1074
1075 ;; General case of fullword move.
1076
1077 (define_expand "movsi"
1078   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079         (match_operand:SI 1 "general_operand" ""))]
1080   ""
1081   "ix86_expand_move (SImode, operands); DONE;")
1082
1083 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1084 ;; general_operand.
1085 ;;
1086 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1087 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089 ;; targets without our curiosities, and it is just as easy to represent
1090 ;; this differently.
1091
1092 (define_insn "*pushsi2"
1093   [(set (match_operand:SI 0 "push_operand" "=<")
1094         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1095   "!TARGET_64BIT"
1096   "push{l}\t%1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1099
1100 ;; For 64BIT abi we always round up to 8 bytes.
1101 (define_insn "*pushsi2_rex64"
1102   [(set (match_operand:SI 0 "push_operand" "=X")
1103         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1104   "TARGET_64BIT"
1105   "push{q}\t%q1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 (define_insn "*pushsi2_prologue"
1110   [(set (match_operand:SI 0 "push_operand" "=<")
1111         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112    (clobber (mem:BLK (scratch)))]
1113   "!TARGET_64BIT"
1114   "push{l}\t%1"
1115   [(set_attr "type" "push")
1116    (set_attr "mode" "SI")])
1117
1118 (define_insn "*popsi1_epilogue"
1119   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120         (mem:SI (reg:SI SP_REG)))
1121    (set (reg:SI SP_REG)
1122         (plus:SI (reg:SI SP_REG) (const_int 4)))
1123    (clobber (mem:BLK (scratch)))]
1124   "!TARGET_64BIT"
1125   "pop{l}\t%0"
1126   [(set_attr "type" "pop")
1127    (set_attr "mode" "SI")])
1128
1129 (define_insn "popsi1"
1130   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131         (mem:SI (reg:SI SP_REG)))
1132    (set (reg:SI SP_REG)
1133         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1134   "!TARGET_64BIT"
1135   "pop{l}\t%0"
1136   [(set_attr "type" "pop")
1137    (set_attr "mode" "SI")])
1138
1139 (define_insn "*movsi_xor"
1140   [(set (match_operand:SI 0 "register_operand" "=r")
1141         (match_operand:SI 1 "const0_operand" "i"))
1142    (clobber (reg:CC FLAGS_REG))]
1143   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144   "xor{l}\t{%0, %0|%0, %0}"
1145   [(set_attr "type" "alu1")
1146    (set_attr "mode" "SI")
1147    (set_attr "length_immediate" "0")])
1148  
1149 (define_insn "*movsi_or"
1150   [(set (match_operand:SI 0 "register_operand" "=r")
1151         (match_operand:SI 1 "immediate_operand" "i"))
1152    (clobber (reg:CC FLAGS_REG))]
1153   "reload_completed
1154    && operands[1] == constm1_rtx
1155    && (TARGET_PENTIUM || optimize_size)"
1156 {
1157   operands[1] = constm1_rtx;
1158   return "or{l}\t{%1, %0|%0, %1}";
1159 }
1160   [(set_attr "type" "alu1")
1161    (set_attr "mode" "SI")
1162    (set_attr "length_immediate" "1")])
1163
1164 (define_insn "*movsi_1"
1165   [(set (match_operand:SI 0 "nonimmediate_operand"
1166                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1167         (match_operand:SI 1 "general_operand"
1168                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1169   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1170 {
1171   switch (get_attr_type (insn))
1172     {
1173     case TYPE_SSELOG1:
1174       if (get_attr_mode (insn) == MODE_TI)
1175         return "pxor\t%0, %0";
1176       return "xorps\t%0, %0";
1177
1178     case TYPE_SSEMOV:
1179       switch (get_attr_mode (insn))
1180         {
1181         case MODE_TI:
1182           return "movdqa\t{%1, %0|%0, %1}";
1183         case MODE_V4SF:
1184           return "movaps\t{%1, %0|%0, %1}";
1185         case MODE_SI:
1186           return "movd\t{%1, %0|%0, %1}";
1187         case MODE_SF:
1188           return "movss\t{%1, %0|%0, %1}";
1189         default:
1190           gcc_unreachable ();
1191         }
1192
1193     case TYPE_MMXADD:
1194       return "pxor\t%0, %0";
1195
1196     case TYPE_MMXMOV:
1197       if (get_attr_mode (insn) == MODE_DI)
1198         return "movq\t{%1, %0|%0, %1}";
1199       return "movd\t{%1, %0|%0, %1}";
1200
1201     case TYPE_LEA:
1202       return "lea{l}\t{%1, %0|%0, %1}";
1203
1204     default:
1205       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1206       return "mov{l}\t{%1, %0|%0, %1}";
1207     }
1208 }
1209   [(set (attr "type")
1210      (cond [(eq_attr "alternative" "2")
1211               (const_string "mmxadd")
1212             (eq_attr "alternative" "3,4,5")
1213               (const_string "mmxmov")
1214             (eq_attr "alternative" "6")
1215               (const_string "sselog1")
1216             (eq_attr "alternative" "7,8,9,10,11")
1217               (const_string "ssemov")
1218             (match_operand:DI 1 "pic_32bit_operand" "")
1219               (const_string "lea")
1220            ]
1221            (const_string "imov")))
1222    (set (attr "mode")
1223      (cond [(eq_attr "alternative" "2,3")
1224               (const_string "DI")
1225             (eq_attr "alternative" "6,7")
1226               (if_then_else
1227                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1228                 (const_string "V4SF")
1229                 (const_string "TI"))
1230             (and (eq_attr "alternative" "8,9,10,11")
1231                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1232               (const_string "SF")
1233            ]
1234            (const_string "SI")))])
1235
1236 ;; Stores and loads of ax to arbitrary constant address.
1237 ;; We fake an second form of instruction to force reload to load address
1238 ;; into register when rax is not available
1239 (define_insn "*movabssi_1_rex64"
1240   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1241         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1242   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1243   "@
1244    movabs{l}\t{%1, %P0|%P0, %1}
1245    mov{l}\t{%1, %a0|%a0, %1}"
1246   [(set_attr "type" "imov")
1247    (set_attr "modrm" "0,*")
1248    (set_attr "length_address" "8,0")
1249    (set_attr "length_immediate" "0,*")
1250    (set_attr "memory" "store")
1251    (set_attr "mode" "SI")])
1252
1253 (define_insn "*movabssi_2_rex64"
1254   [(set (match_operand:SI 0 "register_operand" "=a,r")
1255         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1256   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1257   "@
1258    movabs{l}\t{%P1, %0|%0, %P1}
1259    mov{l}\t{%a1, %0|%0, %a1}"
1260   [(set_attr "type" "imov")
1261    (set_attr "modrm" "0,*")
1262    (set_attr "length_address" "8,0")
1263    (set_attr "length_immediate" "0")
1264    (set_attr "memory" "load")
1265    (set_attr "mode" "SI")])
1266
1267 (define_insn "*swapsi"
1268   [(set (match_operand:SI 0 "register_operand" "+r")
1269         (match_operand:SI 1 "register_operand" "+r"))
1270    (set (match_dup 1)
1271         (match_dup 0))]
1272   ""
1273   "xchg{l}\t%1, %0"
1274   [(set_attr "type" "imov")
1275    (set_attr "mode" "SI")
1276    (set_attr "pent_pair" "np")
1277    (set_attr "athlon_decode" "vector")])
1278
1279 (define_expand "movhi"
1280   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1281         (match_operand:HI 1 "general_operand" ""))]
1282   ""
1283   "ix86_expand_move (HImode, operands); DONE;")
1284
1285 (define_insn "*pushhi2"
1286   [(set (match_operand:HI 0 "push_operand" "=X")
1287         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1288   "!TARGET_64BIT"
1289   "push{l}\t%k1"
1290   [(set_attr "type" "push")
1291    (set_attr "mode" "SI")])
1292
1293 ;; For 64BIT abi we always round up to 8 bytes.
1294 (define_insn "*pushhi2_rex64"
1295   [(set (match_operand:HI 0 "push_operand" "=X")
1296         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1297   "TARGET_64BIT"
1298   "push{q}\t%q1"
1299   [(set_attr "type" "push")
1300    (set_attr "mode" "DI")])
1301
1302 (define_insn "*movhi_1"
1303   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1304         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1305   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1306 {
1307   switch (get_attr_type (insn))
1308     {
1309     case TYPE_IMOVX:
1310       /* movzwl is faster than movw on p2 due to partial word stalls,
1311          though not as fast as an aligned movl.  */
1312       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1313     default:
1314       if (get_attr_mode (insn) == MODE_SI)
1315         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1316       else
1317         return "mov{w}\t{%1, %0|%0, %1}";
1318     }
1319 }
1320   [(set (attr "type")
1321      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1322               (const_string "imov")
1323             (and (eq_attr "alternative" "0")
1324                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1325                           (const_int 0))
1326                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1327                           (const_int 0))))
1328               (const_string "imov")
1329             (and (eq_attr "alternative" "1,2")
1330                  (match_operand:HI 1 "aligned_operand" ""))
1331               (const_string "imov")
1332             (and (ne (symbol_ref "TARGET_MOVX")
1333                      (const_int 0))
1334                  (eq_attr "alternative" "0,2"))
1335               (const_string "imovx")
1336            ]
1337            (const_string "imov")))
1338     (set (attr "mode")
1339       (cond [(eq_attr "type" "imovx")
1340                (const_string "SI")
1341              (and (eq_attr "alternative" "1,2")
1342                   (match_operand:HI 1 "aligned_operand" ""))
1343                (const_string "SI")
1344              (and (eq_attr "alternative" "0")
1345                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1346                            (const_int 0))
1347                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1348                            (const_int 0))))
1349                (const_string "SI")
1350             ]
1351             (const_string "HI")))])
1352
1353 ;; Stores and loads of ax to arbitrary constant address.
1354 ;; We fake an second form of instruction to force reload to load address
1355 ;; into register when rax is not available
1356 (define_insn "*movabshi_1_rex64"
1357   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1358         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1359   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1360   "@
1361    movabs{w}\t{%1, %P0|%P0, %1}
1362    mov{w}\t{%1, %a0|%a0, %1}"
1363   [(set_attr "type" "imov")
1364    (set_attr "modrm" "0,*")
1365    (set_attr "length_address" "8,0")
1366    (set_attr "length_immediate" "0,*")
1367    (set_attr "memory" "store")
1368    (set_attr "mode" "HI")])
1369
1370 (define_insn "*movabshi_2_rex64"
1371   [(set (match_operand:HI 0 "register_operand" "=a,r")
1372         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1373   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1374   "@
1375    movabs{w}\t{%P1, %0|%0, %P1}
1376    mov{w}\t{%a1, %0|%0, %a1}"
1377   [(set_attr "type" "imov")
1378    (set_attr "modrm" "0,*")
1379    (set_attr "length_address" "8,0")
1380    (set_attr "length_immediate" "0")
1381    (set_attr "memory" "load")
1382    (set_attr "mode" "HI")])
1383
1384 (define_insn "*swaphi_1"
1385   [(set (match_operand:HI 0 "register_operand" "+r")
1386         (match_operand:HI 1 "register_operand" "+r"))
1387    (set (match_dup 1)
1388         (match_dup 0))]
1389   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1390   "xchg{l}\t%k1, %k0"
1391   [(set_attr "type" "imov")
1392    (set_attr "mode" "SI")
1393    (set_attr "pent_pair" "np")
1394    (set_attr "athlon_decode" "vector")])
1395
1396 (define_insn "*swaphi_2"
1397   [(set (match_operand:HI 0 "register_operand" "+r")
1398         (match_operand:HI 1 "register_operand" "+r"))
1399    (set (match_dup 1)
1400         (match_dup 0))]
1401   "TARGET_PARTIAL_REG_STALL"
1402   "xchg{w}\t%1, %0"
1403   [(set_attr "type" "imov")
1404    (set_attr "mode" "HI")
1405    (set_attr "pent_pair" "np")
1406    (set_attr "athlon_decode" "vector")])
1407
1408 (define_expand "movstricthi"
1409   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1410         (match_operand:HI 1 "general_operand" ""))]
1411   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1412 {
1413   /* Don't generate memory->memory moves, go through a register */
1414   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1415     operands[1] = force_reg (HImode, operands[1]);
1416 })
1417
1418 (define_insn "*movstricthi_1"
1419   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1420         (match_operand:HI 1 "general_operand" "rn,m"))]
1421   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1422    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1423   "mov{w}\t{%1, %0|%0, %1}"
1424   [(set_attr "type" "imov")
1425    (set_attr "mode" "HI")])
1426
1427 (define_insn "*movstricthi_xor"
1428   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1429         (match_operand:HI 1 "const0_operand" "i"))
1430    (clobber (reg:CC FLAGS_REG))]
1431   "reload_completed
1432    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1433   "xor{w}\t{%0, %0|%0, %0}"
1434   [(set_attr "type" "alu1")
1435    (set_attr "mode" "HI")
1436    (set_attr "length_immediate" "0")])
1437
1438 (define_expand "movqi"
1439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1440         (match_operand:QI 1 "general_operand" ""))]
1441   ""
1442   "ix86_expand_move (QImode, operands); DONE;")
1443
1444 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1445 ;; "push a byte".  But actually we use pushl, which has the effect
1446 ;; of rounding the amount pushed up to a word.
1447
1448 (define_insn "*pushqi2"
1449   [(set (match_operand:QI 0 "push_operand" "=X")
1450         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1451   "!TARGET_64BIT"
1452   "push{l}\t%k1"
1453   [(set_attr "type" "push")
1454    (set_attr "mode" "SI")])
1455
1456 ;; For 64BIT abi we always round up to 8 bytes.
1457 (define_insn "*pushqi2_rex64"
1458   [(set (match_operand:QI 0 "push_operand" "=X")
1459         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1460   "TARGET_64BIT"
1461   "push{q}\t%q1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "DI")])
1464
1465 ;; Situation is quite tricky about when to choose full sized (SImode) move
1466 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1467 ;; partial register dependency machines (such as AMD Athlon), where QImode
1468 ;; moves issue extra dependency and for partial register stalls machines
1469 ;; that don't use QImode patterns (and QImode move cause stall on the next
1470 ;; instruction).
1471 ;;
1472 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1473 ;; register stall machines with, where we use QImode instructions, since
1474 ;; partial register stall can be caused there.  Then we use movzx.
1475 (define_insn "*movqi_1"
1476   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1477         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1478   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1479 {
1480   switch (get_attr_type (insn))
1481     {
1482     case TYPE_IMOVX:
1483       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1484       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1485     default:
1486       if (get_attr_mode (insn) == MODE_SI)
1487         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1488       else
1489         return "mov{b}\t{%1, %0|%0, %1}";
1490     }
1491 }
1492   [(set (attr "type")
1493      (cond [(and (eq_attr "alternative" "5")
1494                  (not (match_operand:QI 1 "aligned_operand" "")))
1495               (const_string "imovx")
1496             (ne (symbol_ref "optimize_size") (const_int 0))
1497               (const_string "imov")
1498             (and (eq_attr "alternative" "3")
1499                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                           (const_int 0))
1501                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                           (const_int 0))))
1503               (const_string "imov")
1504             (eq_attr "alternative" "3,5")
1505               (const_string "imovx")
1506             (and (ne (symbol_ref "TARGET_MOVX")
1507                      (const_int 0))
1508                  (eq_attr "alternative" "2"))
1509               (const_string "imovx")
1510            ]
1511            (const_string "imov")))
1512    (set (attr "mode")
1513       (cond [(eq_attr "alternative" "3,4,5")
1514                (const_string "SI")
1515              (eq_attr "alternative" "6")
1516                (const_string "QI")
1517              (eq_attr "type" "imovx")
1518                (const_string "SI")
1519              (and (eq_attr "type" "imov")
1520                   (and (eq_attr "alternative" "0,1")
1521                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1522                                 (const_int 0))
1523                             (and (eq (symbol_ref "optimize_size")
1524                                      (const_int 0))
1525                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                                      (const_int 0))))))
1527                (const_string "SI")
1528              ;; Avoid partial register stalls when not using QImode arithmetic
1529              (and (eq_attr "type" "imov")
1530                   (and (eq_attr "alternative" "0,1")
1531                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532                                 (const_int 0))
1533                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1534                                 (const_int 0)))))
1535                (const_string "SI")
1536            ]
1537            (const_string "QI")))])
1538
1539 (define_expand "reload_outqi"
1540   [(parallel [(match_operand:QI 0 "" "=m")
1541               (match_operand:QI 1 "register_operand" "r")
1542               (match_operand:QI 2 "register_operand" "=&q")])]
1543   ""
1544 {
1545   rtx op0, op1, op2;
1546   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1547
1548   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1549   if (! q_regs_operand (op1, QImode))
1550     {
1551       emit_insn (gen_movqi (op2, op1));
1552       op1 = op2;
1553     }
1554   emit_insn (gen_movqi (op0, op1));
1555   DONE;
1556 })
1557
1558 (define_insn "*swapqi_1"
1559   [(set (match_operand:QI 0 "register_operand" "+r")
1560         (match_operand:QI 1 "register_operand" "+r"))
1561    (set (match_dup 1)
1562         (match_dup 0))]
1563   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1564   "xchg{l}\t%k1, %k0"
1565   [(set_attr "type" "imov")
1566    (set_attr "mode" "SI")
1567    (set_attr "pent_pair" "np")
1568    (set_attr "athlon_decode" "vector")])
1569
1570 (define_insn "*swapqi_2"
1571   [(set (match_operand:QI 0 "register_operand" "+q")
1572         (match_operand:QI 1 "register_operand" "+q"))
1573    (set (match_dup 1)
1574         (match_dup 0))]
1575   "TARGET_PARTIAL_REG_STALL"
1576   "xchg{b}\t%1, %0"
1577   [(set_attr "type" "imov")
1578    (set_attr "mode" "QI")
1579    (set_attr "pent_pair" "np")
1580    (set_attr "athlon_decode" "vector")])
1581
1582 (define_expand "movstrictqi"
1583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584         (match_operand:QI 1 "general_operand" ""))]
1585   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1586 {
1587   /* Don't generate memory->memory moves, go through a register.  */
1588   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589     operands[1] = force_reg (QImode, operands[1]);
1590 })
1591
1592 (define_insn "*movstrictqi_1"
1593   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594         (match_operand:QI 1 "general_operand" "*qn,m"))]
1595   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597   "mov{b}\t{%1, %0|%0, %1}"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "QI")])
1600
1601 (define_insn "*movstrictqi_xor"
1602   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603         (match_operand:QI 1 "const0_operand" "i"))
1604    (clobber (reg:CC FLAGS_REG))]
1605   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606   "xor{b}\t{%0, %0|%0, %0}"
1607   [(set_attr "type" "alu1")
1608    (set_attr "mode" "QI")
1609    (set_attr "length_immediate" "0")])
1610
1611 (define_insn "*movsi_extv_1"
1612   [(set (match_operand:SI 0 "register_operand" "=R")
1613         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1614                          (const_int 8)
1615                          (const_int 8)))]
1616   ""
1617   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618   [(set_attr "type" "imovx")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "*movhi_extv_1"
1622   [(set (match_operand:HI 0 "register_operand" "=R")
1623         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   ""
1627   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628   [(set_attr "type" "imovx")
1629    (set_attr "mode" "SI")])
1630
1631 (define_insn "*movqi_extv_1"
1632   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   "!TARGET_64BIT"
1637 {
1638   switch (get_attr_type (insn))
1639     {
1640     case TYPE_IMOVX:
1641       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642     default:
1643       return "mov{b}\t{%h1, %0|%0, %h1}";
1644     }
1645 }
1646   [(set (attr "type")
1647      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649                              (ne (symbol_ref "TARGET_MOVX")
1650                                  (const_int 0))))
1651         (const_string "imovx")
1652         (const_string "imov")))
1653    (set (attr "mode")
1654      (if_then_else (eq_attr "type" "imovx")
1655         (const_string "SI")
1656         (const_string "QI")))])
1657
1658 (define_insn "*movqi_extv_1_rex64"
1659   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1661                          (const_int 8)
1662                          (const_int 8)))]
1663   "TARGET_64BIT"
1664 {
1665   switch (get_attr_type (insn))
1666     {
1667     case TYPE_IMOVX:
1668       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1669     default:
1670       return "mov{b}\t{%h1, %0|%0, %h1}";
1671     }
1672 }
1673   [(set (attr "type")
1674      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676                              (ne (symbol_ref "TARGET_MOVX")
1677                                  (const_int 0))))
1678         (const_string "imovx")
1679         (const_string "imov")))
1680    (set (attr "mode")
1681      (if_then_else (eq_attr "type" "imovx")
1682         (const_string "SI")
1683         (const_string "QI")))])
1684
1685 ;; Stores and loads of ax to arbitrary constant address.
1686 ;; We fake an second form of instruction to force reload to load address
1687 ;; into register when rax is not available
1688 (define_insn "*movabsqi_1_rex64"
1689   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1692   "@
1693    movabs{b}\t{%1, %P0|%P0, %1}
1694    mov{b}\t{%1, %a0|%a0, %1}"
1695   [(set_attr "type" "imov")
1696    (set_attr "modrm" "0,*")
1697    (set_attr "length_address" "8,0")
1698    (set_attr "length_immediate" "0,*")
1699    (set_attr "memory" "store")
1700    (set_attr "mode" "QI")])
1701
1702 (define_insn "*movabsqi_2_rex64"
1703   [(set (match_operand:QI 0 "register_operand" "=a,r")
1704         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1706   "@
1707    movabs{b}\t{%P1, %0|%0, %P1}
1708    mov{b}\t{%a1, %0|%0, %a1}"
1709   [(set_attr "type" "imov")
1710    (set_attr "modrm" "0,*")
1711    (set_attr "length_address" "8,0")
1712    (set_attr "length_immediate" "0")
1713    (set_attr "memory" "load")
1714    (set_attr "mode" "QI")])
1715
1716 (define_insn "*movdi_extzv_1"
1717   [(set (match_operand:DI 0 "register_operand" "=R")
1718         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1719                          (const_int 8)
1720                          (const_int 8)))]
1721   "TARGET_64BIT"
1722   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1723   [(set_attr "type" "imovx")
1724    (set_attr "mode" "DI")])
1725
1726 (define_insn "*movsi_extzv_1"
1727   [(set (match_operand:SI 0 "register_operand" "=R")
1728         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1729                          (const_int 8)
1730                          (const_int 8)))]
1731   ""
1732   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733   [(set_attr "type" "imovx")
1734    (set_attr "mode" "SI")])
1735
1736 (define_insn "*movqi_extzv_2"
1737   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739                                     (const_int 8)
1740                                     (const_int 8)) 0))]
1741   "!TARGET_64BIT"
1742 {
1743   switch (get_attr_type (insn))
1744     {
1745     case TYPE_IMOVX:
1746       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747     default:
1748       return "mov{b}\t{%h1, %0|%0, %h1}";
1749     }
1750 }
1751   [(set (attr "type")
1752      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754                              (ne (symbol_ref "TARGET_MOVX")
1755                                  (const_int 0))))
1756         (const_string "imovx")
1757         (const_string "imov")))
1758    (set (attr "mode")
1759      (if_then_else (eq_attr "type" "imovx")
1760         (const_string "SI")
1761         (const_string "QI")))])
1762
1763 (define_insn "*movqi_extzv_2_rex64"
1764   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1766                                     (const_int 8)
1767                                     (const_int 8)) 0))]
1768   "TARGET_64BIT"
1769 {
1770   switch (get_attr_type (insn))
1771     {
1772     case TYPE_IMOVX:
1773       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1774     default:
1775       return "mov{b}\t{%h1, %0|%0, %h1}";
1776     }
1777 }
1778   [(set (attr "type")
1779      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780                         (ne (symbol_ref "TARGET_MOVX")
1781                             (const_int 0)))
1782         (const_string "imovx")
1783         (const_string "imov")))
1784    (set (attr "mode")
1785      (if_then_else (eq_attr "type" "imovx")
1786         (const_string "SI")
1787         (const_string "QI")))])
1788
1789 (define_insn "movsi_insv_1"
1790   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1791                          (const_int 8)
1792                          (const_int 8))
1793         (match_operand:SI 1 "general_operand" "Qmn"))]
1794   "!TARGET_64BIT"
1795   "mov{b}\t{%b1, %h0|%h0, %b1}"
1796   [(set_attr "type" "imov")
1797    (set_attr "mode" "QI")])
1798
1799 (define_insn "movdi_insv_1_rex64"
1800   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1804   "TARGET_64BIT"
1805   "mov{b}\t{%b1, %h0|%h0, %b1}"
1806   [(set_attr "type" "imov")
1807    (set_attr "mode" "QI")])
1808
1809 (define_insn "*movqi_insv_2"
1810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811                          (const_int 8)
1812                          (const_int 8))
1813         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1814                      (const_int 8)))]
1815   ""
1816   "mov{b}\t{%h1, %h0|%h0, %h1}"
1817   [(set_attr "type" "imov")
1818    (set_attr "mode" "QI")])
1819
1820 (define_expand "movdi"
1821   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1822         (match_operand:DI 1 "general_operand" ""))]
1823   ""
1824   "ix86_expand_move (DImode, operands); DONE;")
1825
1826 (define_insn "*pushdi"
1827   [(set (match_operand:DI 0 "push_operand" "=<")
1828         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1829   "!TARGET_64BIT"
1830   "#")
1831
1832 (define_insn "*pushdi2_rex64"
1833   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1834         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1835   "TARGET_64BIT"
1836   "@
1837    push{q}\t%1
1838    #"
1839   [(set_attr "type" "push,multi")
1840    (set_attr "mode" "DI")])
1841
1842 ;; Convert impossible pushes of immediate to existing instructions.
1843 ;; First try to get scratch register and go through it.  In case this
1844 ;; fails, push sign extended lower part first and then overwrite
1845 ;; upper part by 32bit move.
1846 (define_peephole2
1847   [(match_scratch:DI 2 "r")
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)"
1852   [(set (match_dup 2) (match_dup 1))
1853    (set (match_dup 0) (match_dup 2))]
1854   "")
1855
1856 ;; We need to define this as both peepholer and splitter for case
1857 ;; peephole2 pass is not run.
1858 ;; "&& 1" is needed to keep it from matching the previous pattern.
1859 (define_peephole2
1860   [(set (match_operand:DI 0 "push_operand" "")
1861         (match_operand:DI 1 "immediate_operand" ""))]
1862   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864   [(set (match_dup 0) (match_dup 1))
1865    (set (match_dup 2) (match_dup 3))]
1866   "split_di (operands + 1, 1, operands + 2, operands + 3);
1867    operands[1] = gen_lowpart (DImode, operands[2]);
1868    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1869                                                     GEN_INT (4)));
1870   ")
1871
1872 (define_split
1873   [(set (match_operand:DI 0 "push_operand" "")
1874         (match_operand:DI 1 "immediate_operand" ""))]
1875   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1876                     ? flow2_completed : reload_completed)
1877    && !symbolic_operand (operands[1], DImode)
1878    && !x86_64_immediate_operand (operands[1], DImode)"
1879   [(set (match_dup 0) (match_dup 1))
1880    (set (match_dup 2) (match_dup 3))]
1881   "split_di (operands + 1, 1, operands + 2, operands + 3);
1882    operands[1] = gen_lowpart (DImode, operands[2]);
1883    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1884                                                     GEN_INT (4)));
1885   ")
1886
1887 (define_insn "*pushdi2_prologue_rex64"
1888   [(set (match_operand:DI 0 "push_operand" "=<")
1889         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1890    (clobber (mem:BLK (scratch)))]
1891   "TARGET_64BIT"
1892   "push{q}\t%1"
1893   [(set_attr "type" "push")
1894    (set_attr "mode" "DI")])
1895
1896 (define_insn "*popdi1_epilogue_rex64"
1897   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1898         (mem:DI (reg:DI SP_REG)))
1899    (set (reg:DI SP_REG)
1900         (plus:DI (reg:DI SP_REG) (const_int 8)))
1901    (clobber (mem:BLK (scratch)))]
1902   "TARGET_64BIT"
1903   "pop{q}\t%0"
1904   [(set_attr "type" "pop")
1905    (set_attr "mode" "DI")])
1906
1907 (define_insn "popdi1"
1908   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1909         (mem:DI (reg:DI SP_REG)))
1910    (set (reg:DI SP_REG)
1911         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1912   "TARGET_64BIT"
1913   "pop{q}\t%0"
1914   [(set_attr "type" "pop")
1915    (set_attr "mode" "DI")])
1916
1917 (define_insn "*movdi_xor_rex64"
1918   [(set (match_operand:DI 0 "register_operand" "=r")
1919         (match_operand:DI 1 "const0_operand" "i"))
1920    (clobber (reg:CC FLAGS_REG))]
1921   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1922    && reload_completed"
1923   "xor{l}\t{%k0, %k0|%k0, %k0}"
1924   [(set_attr "type" "alu1")
1925    (set_attr "mode" "SI")
1926    (set_attr "length_immediate" "0")])
1927
1928 (define_insn "*movdi_or_rex64"
1929   [(set (match_operand:DI 0 "register_operand" "=r")
1930         (match_operand:DI 1 "const_int_operand" "i"))
1931    (clobber (reg:CC FLAGS_REG))]
1932   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1933    && reload_completed
1934    && operands[1] == constm1_rtx"
1935 {
1936   operands[1] = constm1_rtx;
1937   return "or{q}\t{%1, %0|%0, %1}";
1938 }
1939   [(set_attr "type" "alu1")
1940    (set_attr "mode" "DI")
1941    (set_attr "length_immediate" "1")])
1942
1943 (define_insn "*movdi_2"
1944   [(set (match_operand:DI 0 "nonimmediate_operand"
1945                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1946         (match_operand:DI 1 "general_operand"
1947                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1948   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949   "@
1950    #
1951    #
1952    pxor\t%0, %0
1953    movq\t{%1, %0|%0, %1}
1954    movq\t{%1, %0|%0, %1}
1955    pxor\t%0, %0
1956    movq\t{%1, %0|%0, %1}
1957    movdqa\t{%1, %0|%0, %1}
1958    movq\t{%1, %0|%0, %1}
1959    xorps\t%0, %0
1960    movlps\t{%1, %0|%0, %1}
1961    movaps\t{%1, %0|%0, %1}
1962    movlps\t{%1, %0|%0, %1}"
1963   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1964    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1965
1966 (define_split
1967   [(set (match_operand:DI 0 "push_operand" "")
1968         (match_operand:DI 1 "general_operand" ""))]
1969   "!TARGET_64BIT && reload_completed
1970    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971   [(const_int 0)]
1972   "ix86_split_long_move (operands); DONE;")
1973
1974 ;; %%% This multiword shite has got to go.
1975 (define_split
1976   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1977         (match_operand:DI 1 "general_operand" ""))]
1978   "!TARGET_64BIT && reload_completed
1979    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1980    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1981   [(const_int 0)]
1982   "ix86_split_long_move (operands); DONE;")
1983
1984 (define_insn "*movdi_1_rex64"
1985   [(set (match_operand:DI 0 "nonimmediate_operand"
1986                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1987         (match_operand:DI 1 "general_operand"
1988                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1989   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990 {
1991   switch (get_attr_type (insn))
1992     {
1993     case TYPE_SSECVT:
1994       if (which_alternative == 13)
1995         return "movq2dq\t{%1, %0|%0, %1}";
1996       else
1997         return "movdq2q\t{%1, %0|%0, %1}";
1998     case TYPE_SSEMOV:
1999       if (get_attr_mode (insn) == MODE_TI)
2000           return "movdqa\t{%1, %0|%0, %1}";
2001       /* FALLTHRU */
2002     case TYPE_MMXMOV:
2003       /* Moves from and into integer register is done using movd opcode with
2004          REX prefix.  */
2005       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006           return "movd\t{%1, %0|%0, %1}";
2007       return "movq\t{%1, %0|%0, %1}";
2008     case TYPE_SSELOG1:
2009     case TYPE_MMXADD:
2010       return "pxor\t%0, %0";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2017       if (get_attr_mode (insn) == MODE_SI)
2018         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019       else if (which_alternative == 2)
2020         return "movabs{q}\t{%1, %0|%0, %1}";
2021       else
2022         return "mov{q}\t{%1, %0|%0, %1}";
2023     }
2024 }
2025   [(set (attr "type")
2026      (cond [(eq_attr "alternative" "5")
2027               (const_string "mmxadd")
2028             (eq_attr "alternative" "6,7,8")
2029               (const_string "mmxmov")
2030             (eq_attr "alternative" "9")
2031               (const_string "sselog1")
2032             (eq_attr "alternative" "10,11,12")
2033               (const_string "ssemov")
2034             (eq_attr "alternative" "13,14")
2035               (const_string "ssecvt")
2036             (eq_attr "alternative" "4")
2037               (const_string "multi")
2038             (match_operand:DI 1 "pic_32bit_operand" "")
2039               (const_string "lea")
2040            ]
2041            (const_string "imov")))
2042    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2043    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2044    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2045
2046 ;; Stores and loads of ax to arbitrary constant address.
2047 ;; We fake an second form of instruction to force reload to load address
2048 ;; into register when rax is not available
2049 (define_insn "*movabsdi_1_rex64"
2050   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2051         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2052   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2053   "@
2054    movabs{q}\t{%1, %P0|%P0, %1}
2055    mov{q}\t{%1, %a0|%a0, %1}"
2056   [(set_attr "type" "imov")
2057    (set_attr "modrm" "0,*")
2058    (set_attr "length_address" "8,0")
2059    (set_attr "length_immediate" "0,*")
2060    (set_attr "memory" "store")
2061    (set_attr "mode" "DI")])
2062
2063 (define_insn "*movabsdi_2_rex64"
2064   [(set (match_operand:DI 0 "register_operand" "=a,r")
2065         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2066   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2067   "@
2068    movabs{q}\t{%P1, %0|%0, %P1}
2069    mov{q}\t{%a1, %0|%0, %a1}"
2070   [(set_attr "type" "imov")
2071    (set_attr "modrm" "0,*")
2072    (set_attr "length_address" "8,0")
2073    (set_attr "length_immediate" "0")
2074    (set_attr "memory" "load")
2075    (set_attr "mode" "DI")])
2076
2077 ;; Convert impossible stores of immediate to existing instructions.
2078 ;; First try to get scratch register and go through it.  In case this
2079 ;; fails, move by 32bit parts.
2080 (define_peephole2
2081   [(match_scratch:DI 2 "r")
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)"
2086   [(set (match_dup 2) (match_dup 1))
2087    (set (match_dup 0) (match_dup 2))]
2088   "")
2089
2090 ;; We need to define this as both peepholer and splitter for case
2091 ;; peephole2 pass is not run.
2092 ;; "&& 1" is needed to keep it from matching the previous pattern.
2093 (define_peephole2
2094   [(set (match_operand:DI 0 "memory_operand" "")
2095         (match_operand:DI 1 "immediate_operand" ""))]
2096   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2098   [(set (match_dup 2) (match_dup 3))
2099    (set (match_dup 4) (match_dup 5))]
2100   "split_di (operands, 2, operands + 2, operands + 4);")
2101
2102 (define_split
2103   [(set (match_operand:DI 0 "memory_operand" "")
2104         (match_operand:DI 1 "immediate_operand" ""))]
2105   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2106                     ? flow2_completed : reload_completed)
2107    && !symbolic_operand (operands[1], DImode)
2108    && !x86_64_immediate_operand (operands[1], DImode)"
2109   [(set (match_dup 2) (match_dup 3))
2110    (set (match_dup 4) (match_dup 5))]
2111   "split_di (operands, 2, operands + 2, operands + 4);")
2112
2113 (define_insn "*swapdi_rex64"
2114   [(set (match_operand:DI 0 "register_operand" "+r")
2115         (match_operand:DI 1 "register_operand" "+r"))
2116    (set (match_dup 1)
2117         (match_dup 0))]
2118   "TARGET_64BIT"
2119   "xchg{q}\t%1, %0"
2120   [(set_attr "type" "imov")
2121    (set_attr "mode" "DI")
2122    (set_attr "pent_pair" "np")
2123    (set_attr "athlon_decode" "vector")])
2124
2125 (define_expand "movti"
2126   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2127         (match_operand:TI 1 "nonimmediate_operand" ""))]
2128   "TARGET_SSE || TARGET_64BIT"
2129 {
2130   if (TARGET_64BIT)
2131     ix86_expand_move (TImode, operands);
2132   else
2133     ix86_expand_vector_move (TImode, operands);
2134   DONE;
2135 })
2136
2137 (define_insn "*movti_internal"
2138   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2139         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2140   "TARGET_SSE && !TARGET_64BIT
2141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2142 {
2143   switch (which_alternative)
2144     {
2145     case 0:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "xorps\t%0, %0";
2148       else
2149         return "pxor\t%0, %0";
2150     case 1:
2151     case 2:
2152       if (get_attr_mode (insn) == MODE_V4SF)
2153         return "movaps\t{%1, %0|%0, %1}";
2154       else
2155         return "movdqa\t{%1, %0|%0, %1}";
2156     default:
2157       gcc_unreachable ();
2158     }
2159 }
2160   [(set_attr "type" "sselog1,ssemov,ssemov")
2161    (set (attr "mode")
2162         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2163                     (ne (symbol_ref "optimize_size") (const_int 0)))
2164                  (const_string "V4SF")
2165                (and (eq_attr "alternative" "2")
2166                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2167                         (const_int 0)))
2168                  (const_string "V4SF")]
2169               (const_string "TI")))])
2170
2171 (define_insn "*movti_rex64"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2173         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2174   "TARGET_64BIT
2175    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2176 {
2177   switch (which_alternative)
2178     {
2179     case 0:
2180     case 1:
2181       return "#";
2182     case 2:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "xorps\t%0, %0";
2185       else
2186         return "pxor\t%0, %0";
2187     case 3:
2188     case 4:
2189       if (get_attr_mode (insn) == MODE_V4SF)
2190         return "movaps\t{%1, %0|%0, %1}";
2191       else
2192         return "movdqa\t{%1, %0|%0, %1}";
2193     default:
2194       gcc_unreachable ();
2195     }
2196 }
2197   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2198    (set (attr "mode")
2199         (cond [(eq_attr "alternative" "2,3")
2200                  (if_then_else
2201                    (ne (symbol_ref "optimize_size")
2202                        (const_int 0))
2203                    (const_string "V4SF")
2204                    (const_string "TI"))
2205                (eq_attr "alternative" "4")
2206                  (if_then_else
2207                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2208                             (const_int 0))
2209                         (ne (symbol_ref "optimize_size")
2210                             (const_int 0)))
2211                    (const_string "V4SF")
2212                    (const_string "TI"))]
2213                (const_string "DI")))])
2214
2215 (define_split
2216   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2217         (match_operand:TI 1 "general_operand" ""))]
2218   "reload_completed && !SSE_REG_P (operands[0])
2219    && !SSE_REG_P (operands[1])"
2220   [(const_int 0)]
2221   "ix86_split_long_move (operands); DONE;")
2222
2223 (define_expand "movsf"
2224   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2225         (match_operand:SF 1 "general_operand" ""))]
2226   ""
2227   "ix86_expand_move (SFmode, operands); DONE;")
2228
2229 (define_insn "*pushsf"
2230   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2231         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2232   "!TARGET_64BIT"
2233 {
2234   /* Anything else should be already split before reg-stack.  */
2235   gcc_assert (which_alternative == 1);
2236   return "push{l}\t%1";
2237 }
2238   [(set_attr "type" "multi,push,multi")
2239    (set_attr "unit" "i387,*,*")
2240    (set_attr "mode" "SF,SI,SF")])
2241
2242 (define_insn "*pushsf_rex64"
2243   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2244         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2245   "TARGET_64BIT"
2246 {
2247   /* Anything else should be already split before reg-stack.  */
2248   gcc_assert (which_alternative == 1);
2249   return "push{q}\t%q1";
2250 }
2251   [(set_attr "type" "multi,push,multi")
2252    (set_attr "unit" "i387,*,*")
2253    (set_attr "mode" "SF,DI,SF")])
2254
2255 (define_split
2256   [(set (match_operand:SF 0 "push_operand" "")
2257         (match_operand:SF 1 "memory_operand" ""))]
2258   "reload_completed
2259    && GET_CODE (operands[1]) == MEM
2260    && constant_pool_reference_p (operands[1])"
2261   [(set (match_dup 0)
2262         (match_dup 1))]
2263   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2264
2265
2266 ;; %%% Kill this when call knows how to work this out.
2267 (define_split
2268   [(set (match_operand:SF 0 "push_operand" "")
2269         (match_operand:SF 1 "any_fp_register_operand" ""))]
2270   "!TARGET_64BIT"
2271   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2272    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2273
2274 (define_split
2275   [(set (match_operand:SF 0 "push_operand" "")
2276         (match_operand:SF 1 "any_fp_register_operand" ""))]
2277   "TARGET_64BIT"
2278   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2279    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2280
2281 (define_insn "*movsf_1"
2282   [(set (match_operand:SF 0 "nonimmediate_operand"
2283           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2284         (match_operand:SF 1 "general_operand"
2285           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2286   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2287    && (reload_in_progress || reload_completed
2288        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289        || GET_CODE (operands[1]) != CONST_DOUBLE
2290        || memory_operand (operands[0], SFmode))" 
2291 {
2292   switch (which_alternative)
2293     {
2294     case 0:
2295       return output_387_reg_move (insn, operands);
2296
2297     case 1:
2298       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2299         return "fstp%z0\t%y0";
2300       else
2301         return "fst%z0\t%y0";
2302
2303     case 2:
2304       return standard_80387_constant_opcode (operands[1]);
2305
2306     case 3:
2307     case 4:
2308       return "mov{l}\t{%1, %0|%0, %1}";
2309     case 5:
2310       if (get_attr_mode (insn) == MODE_TI)
2311         return "pxor\t%0, %0";
2312       else
2313         return "xorps\t%0, %0";
2314     case 6:
2315       if (get_attr_mode (insn) == MODE_V4SF)
2316         return "movaps\t{%1, %0|%0, %1}";
2317       else
2318         return "movss\t{%1, %0|%0, %1}";
2319     case 7:
2320     case 8:
2321       return "movss\t{%1, %0|%0, %1}";
2322
2323     case 9:
2324     case 10:
2325       return "movd\t{%1, %0|%0, %1}";
2326
2327     case 11:
2328       return "movq\t{%1, %0|%0, %1}";
2329
2330     default:
2331       gcc_unreachable ();
2332     }
2333 }
2334   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2335    (set (attr "mode")
2336         (cond [(eq_attr "alternative" "3,4,9,10")
2337                  (const_string "SI")
2338                (eq_attr "alternative" "5")
2339                  (if_then_else
2340                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2341                                  (const_int 0))
2342                              (ne (symbol_ref "TARGET_SSE2")
2343                                  (const_int 0)))
2344                         (eq (symbol_ref "optimize_size")
2345                             (const_int 0)))
2346                    (const_string "TI")
2347                    (const_string "V4SF"))
2348                /* For architectures resolving dependencies on
2349                   whole SSE registers use APS move to break dependency
2350                   chains, otherwise use short move to avoid extra work. 
2351
2352                   Do the same for architectures resolving dependencies on
2353                   the parts.  While in DF mode it is better to always handle
2354                   just register parts, the SF mode is different due to lack
2355                   of instructions to load just part of the register.  It is
2356                   better to maintain the whole registers in single format
2357                   to avoid problems on using packed logical operations.  */
2358                (eq_attr "alternative" "6")
2359                  (if_then_else
2360                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2361                             (const_int 0))
2362                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2363                             (const_int 0)))
2364                    (const_string "V4SF")
2365                    (const_string "SF"))
2366                (eq_attr "alternative" "11")
2367                  (const_string "DI")]
2368                (const_string "SF")))])
2369
2370 (define_insn "*swapsf"
2371   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2372         (match_operand:SF 1 "fp_register_operand" "+f"))
2373    (set (match_dup 1)
2374         (match_dup 0))]
2375   "reload_completed || TARGET_80387"
2376 {
2377   if (STACK_TOP_P (operands[0]))
2378     return "fxch\t%1";
2379   else
2380     return "fxch\t%0";
2381 }
2382   [(set_attr "type" "fxch")
2383    (set_attr "mode" "SF")])
2384
2385 (define_expand "movdf"
2386   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2387         (match_operand:DF 1 "general_operand" ""))]
2388   ""
2389   "ix86_expand_move (DFmode, operands); DONE;")
2390
2391 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2392 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2393 ;; On the average, pushdf using integers can be still shorter.  Allow this
2394 ;; pattern for optimize_size too.
2395
2396 (define_insn "*pushdf_nointeger"
2397   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2398         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
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,SI,DF")])
2407
2408 (define_insn "*pushdf_integer"
2409   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2410         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2411   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2412 {
2413   /* This insn should be already split before reg-stack.  */
2414   gcc_unreachable ();
2415 }
2416   [(set_attr "type" "multi")
2417    (set_attr "unit" "i387,*,*")
2418    (set_attr "mode" "DF,SI,DF")])
2419
2420 ;; %%% Kill this when call knows how to work this out.
2421 (define_split
2422   [(set (match_operand:DF 0 "push_operand" "")
2423         (match_operand:DF 1 "any_fp_register_operand" ""))]
2424   "!TARGET_64BIT && reload_completed"
2425   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2426    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2427   "")
2428
2429 (define_split
2430   [(set (match_operand:DF 0 "push_operand" "")
2431         (match_operand:DF 1 "any_fp_register_operand" ""))]
2432   "TARGET_64BIT && reload_completed"
2433   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2434    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2435   "")
2436
2437 (define_split
2438   [(set (match_operand:DF 0 "push_operand" "")
2439         (match_operand:DF 1 "general_operand" ""))]
2440   "reload_completed"
2441   [(const_int 0)]
2442   "ix86_split_long_move (operands); DONE;")
2443
2444 ;; Moving is usually shorter when only FP registers are used. This separate
2445 ;; movdf pattern avoids the use of integer registers for FP operations
2446 ;; when optimizing for size.
2447
2448 (define_insn "*movdf_nointeger"
2449   [(set (match_operand:DF 0 "nonimmediate_operand"
2450                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2451         (match_operand:DF 1 "general_operand"
2452                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2453   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2454    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2455    && (reload_in_progress || reload_completed
2456        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2457        || GET_CODE (operands[1]) != CONST_DOUBLE
2458        || memory_operand (operands[0], DFmode))" 
2459 {
2460   switch (which_alternative)
2461     {
2462     case 0:
2463       return output_387_reg_move (insn, operands);
2464
2465     case 1:
2466       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467         return "fstp%z0\t%y0";
2468       else
2469         return "fst%z0\t%y0";
2470
2471     case 2:
2472       return standard_80387_constant_opcode (operands[1]);
2473
2474     case 3:
2475     case 4:
2476       return "#";
2477     case 5:
2478       switch (get_attr_mode (insn))
2479         {
2480         case MODE_V4SF:
2481           return "xorps\t%0, %0";
2482         case MODE_V2DF:
2483           return "xorpd\t%0, %0";
2484         case MODE_TI:
2485           return "pxor\t%0, %0";
2486         default:
2487           gcc_unreachable ();
2488         }
2489     case 6:
2490     case 7:
2491     case 8:
2492       switch (get_attr_mode (insn))
2493         {
2494         case MODE_V4SF:
2495           return "movaps\t{%1, %0|%0, %1}";
2496         case MODE_V2DF:
2497           return "movapd\t{%1, %0|%0, %1}";
2498         case MODE_TI:
2499           return "movdqa\t{%1, %0|%0, %1}";
2500         case MODE_DI:
2501           return "movq\t{%1, %0|%0, %1}";
2502         case MODE_DF:
2503           return "movsd\t{%1, %0|%0, %1}";
2504         case MODE_V1DF:
2505           return "movlpd\t{%1, %0|%0, %1}";
2506         case MODE_V2SF:
2507           return "movlps\t{%1, %0|%0, %1}";
2508         default:
2509           gcc_unreachable ();
2510         }
2511
2512     default:
2513       gcc_unreachable ();
2514     }
2515 }
2516   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2517    (set (attr "mode")
2518         (cond [(eq_attr "alternative" "0,1,2")
2519                  (const_string "DF")
2520                (eq_attr "alternative" "3,4")
2521                  (const_string "SI")
2522
2523                /* For SSE1, we have many fewer alternatives.  */
2524                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2525                  (cond [(eq_attr "alternative" "5,6")
2526                           (const_string "V4SF")
2527                        ]
2528                    (const_string "V2SF"))
2529
2530                /* xorps is one byte shorter.  */
2531                (eq_attr "alternative" "5")
2532                  (cond [(ne (symbol_ref "optimize_size")
2533                             (const_int 0))
2534                           (const_string "V4SF")
2535                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2536                             (const_int 0))
2537                           (const_string "TI")
2538                        ]
2539                        (const_string "V2DF"))
2540
2541                /* For architectures resolving dependencies on
2542                   whole SSE registers use APD move to break dependency
2543                   chains, otherwise use short move to avoid extra work.
2544
2545                   movaps encodes one byte shorter.  */
2546                (eq_attr "alternative" "6")
2547                  (cond
2548                    [(ne (symbol_ref "optimize_size")
2549                         (const_int 0))
2550                       (const_string "V4SF")
2551                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2552                         (const_int 0))
2553                       (const_string "V2DF")
2554                    ]
2555                    (const_string "DF"))
2556                /* For architectures resolving dependencies on register
2557                   parts we may avoid extra work to zero out upper part
2558                   of register.  */
2559                (eq_attr "alternative" "7")
2560                  (if_then_else
2561                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2562                        (const_int 0))
2563                    (const_string "V1DF")
2564                    (const_string "DF"))
2565               ]
2566               (const_string "DF")))])
2567
2568 (define_insn "*movdf_integer"
2569   [(set (match_operand:DF 0 "nonimmediate_operand"
2570                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2571         (match_operand:DF 1 "general_operand"
2572                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2573   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2574    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2575    && (reload_in_progress || reload_completed
2576        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2577        || GET_CODE (operands[1]) != CONST_DOUBLE
2578        || memory_operand (operands[0], DFmode))" 
2579 {
2580   switch (which_alternative)
2581     {
2582     case 0:
2583       return output_387_reg_move (insn, operands);
2584
2585     case 1:
2586       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587         return "fstp%z0\t%y0";
2588       else
2589         return "fst%z0\t%y0";
2590
2591     case 2:
2592       return standard_80387_constant_opcode (operands[1]);
2593
2594     case 3:
2595     case 4:
2596       return "#";
2597
2598     case 5:
2599       switch (get_attr_mode (insn))
2600         {
2601         case MODE_V4SF:
2602           return "xorps\t%0, %0";
2603         case MODE_V2DF:
2604           return "xorpd\t%0, %0";
2605         case MODE_TI:
2606           return "pxor\t%0, %0";
2607         default:
2608           gcc_unreachable ();
2609         }
2610     case 6:
2611     case 7:
2612     case 8:
2613       switch (get_attr_mode (insn))
2614         {
2615         case MODE_V4SF:
2616           return "movaps\t{%1, %0|%0, %1}";
2617         case MODE_V2DF:
2618           return "movapd\t{%1, %0|%0, %1}";
2619         case MODE_TI:
2620           return "movdqa\t{%1, %0|%0, %1}";
2621         case MODE_DI:
2622           return "movq\t{%1, %0|%0, %1}";
2623         case MODE_DF:
2624           return "movsd\t{%1, %0|%0, %1}";
2625         case MODE_V1DF:
2626           return "movlpd\t{%1, %0|%0, %1}";
2627         case MODE_V2SF:
2628           return "movlps\t{%1, %0|%0, %1}";
2629         default:
2630           gcc_unreachable ();
2631         }
2632
2633     default:
2634       gcc_unreachable();
2635     }
2636 }
2637   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2638    (set (attr "mode")
2639         (cond [(eq_attr "alternative" "0,1,2")
2640                  (const_string "DF")
2641                (eq_attr "alternative" "3,4")
2642                  (const_string "SI")
2643
2644                /* For SSE1, we have many fewer alternatives.  */
2645                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2646                  (cond [(eq_attr "alternative" "5,6")
2647                           (const_string "V4SF")
2648                        ]
2649                    (const_string "V2SF"))
2650
2651                /* xorps is one byte shorter.  */
2652                (eq_attr "alternative" "5")
2653                  (cond [(ne (symbol_ref "optimize_size")
2654                             (const_int 0))
2655                           (const_string "V4SF")
2656                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2657                             (const_int 0))
2658                           (const_string "TI")
2659                        ]
2660                        (const_string "V2DF"))
2661
2662                /* For architectures resolving dependencies on
2663                   whole SSE registers use APD move to break dependency
2664                   chains, otherwise use short move to avoid extra work.
2665
2666                   movaps encodes one byte shorter.  */
2667                (eq_attr "alternative" "6")
2668                  (cond
2669                    [(ne (symbol_ref "optimize_size")
2670                         (const_int 0))
2671                       (const_string "V4SF")
2672                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2673                         (const_int 0))
2674                       (const_string "V2DF")
2675                    ]
2676                    (const_string "DF"))
2677                /* For architectures resolving dependencies on register
2678                   parts we may avoid extra work to zero out upper part
2679                   of register.  */
2680                (eq_attr "alternative" "7")
2681                  (if_then_else
2682                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683                        (const_int 0))
2684                    (const_string "V1DF")
2685                    (const_string "DF"))
2686               ]
2687               (const_string "DF")))])
2688
2689 (define_split
2690   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2691         (match_operand:DF 1 "general_operand" ""))]
2692   "reload_completed
2693    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2694    && ! (ANY_FP_REG_P (operands[0]) || 
2695          (GET_CODE (operands[0]) == SUBREG
2696           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2697    && ! (ANY_FP_REG_P (operands[1]) || 
2698          (GET_CODE (operands[1]) == SUBREG
2699           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2700   [(const_int 0)]
2701   "ix86_split_long_move (operands); DONE;")
2702
2703 (define_insn "*swapdf"
2704   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2705         (match_operand:DF 1 "fp_register_operand" "+f"))
2706    (set (match_dup 1)
2707         (match_dup 0))]
2708   "reload_completed || TARGET_80387"
2709 {
2710   if (STACK_TOP_P (operands[0]))
2711     return "fxch\t%1";
2712   else
2713     return "fxch\t%0";
2714 }
2715   [(set_attr "type" "fxch")
2716    (set_attr "mode" "DF")])
2717
2718 (define_expand "movxf"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2720         (match_operand:XF 1 "general_operand" ""))]
2721   ""
2722   "ix86_expand_move (XFmode, operands); DONE;")
2723
2724 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2725 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2726 ;; Pushing using integer instructions is longer except for constants
2727 ;; and direct memory references.
2728 ;; (assuming that any given constant is pushed only once, but this ought to be
2729 ;;  handled elsewhere).
2730
2731 (define_insn "*pushxf_nointeger"
2732   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2733         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
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,SI")])
2742
2743 (define_insn "*pushxf_integer"
2744   [(set (match_operand:XF 0 "push_operand" "=<,<")
2745         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2746   "!optimize_size"
2747 {
2748   /* This insn should be already split before reg-stack.  */
2749   gcc_unreachable ();
2750 }
2751   [(set_attr "type" "multi")
2752    (set_attr "unit" "i387,*")
2753    (set_attr "mode" "XF,SI")])
2754
2755 (define_split
2756   [(set (match_operand 0 "push_operand" "")
2757         (match_operand 1 "general_operand" ""))]
2758   "reload_completed
2759    && (GET_MODE (operands[0]) == XFmode
2760        || GET_MODE (operands[0]) == DFmode)
2761    && !ANY_FP_REG_P (operands[1])"
2762   [(const_int 0)]
2763   "ix86_split_long_move (operands); DONE;")
2764
2765 (define_split
2766   [(set (match_operand:XF 0 "push_operand" "")
2767         (match_operand:XF 1 "any_fp_register_operand" ""))]
2768   "!TARGET_64BIT"
2769   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773 (define_split
2774   [(set (match_operand:XF 0 "push_operand" "")
2775         (match_operand:XF 1 "any_fp_register_operand" ""))]
2776   "TARGET_64BIT"
2777   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781 ;; Do not use integer registers when optimizing for size
2782 (define_insn "*movxf_nointeger"
2783   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785   "optimize_size
2786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787    && (reload_in_progress || reload_completed
2788        || GET_CODE (operands[1]) != CONST_DOUBLE
2789        || memory_operand (operands[0], XFmode))" 
2790 {
2791   switch (which_alternative)
2792     {
2793     case 0:
2794       return output_387_reg_move (insn, operands);
2795
2796     case 1:
2797       /* There is no non-popping store to memory for XFmode.  So if
2798          we need one, follow the store with a load.  */
2799       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800         return "fstp%z0\t%y0\;fld%z0\t%y0";
2801       else
2802         return "fstp%z0\t%y0";
2803
2804     case 2:
2805       return standard_80387_constant_opcode (operands[1]);
2806
2807     case 3: case 4:
2808       return "#";
2809     default:
2810       gcc_unreachable ();
2811     }
2812 }
2813   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814    (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816 (define_insn "*movxf_integer"
2817   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2819   "!optimize_size
2820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821    && (reload_in_progress || reload_completed
2822        || GET_CODE (operands[1]) != CONST_DOUBLE
2823        || memory_operand (operands[0], XFmode))" 
2824 {
2825   switch (which_alternative)
2826     {
2827     case 0:
2828       return output_387_reg_move (insn, operands);
2829
2830     case 1:
2831       /* There is no non-popping store to memory for XFmode.  So if
2832          we need one, follow the store with a load.  */
2833       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834         return "fstp%z0\t%y0\;fld%z0\t%y0";
2835       else
2836         return "fstp%z0\t%y0";
2837
2838     case 2:
2839       return standard_80387_constant_opcode (operands[1]);
2840
2841     case 3: case 4:
2842       return "#";
2843
2844     default:
2845       gcc_unreachable ();
2846     }
2847 }
2848   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2849    (set_attr "mode" "XF,XF,XF,SI,SI")])
2850
2851 (define_split
2852   [(set (match_operand 0 "nonimmediate_operand" "")
2853         (match_operand 1 "general_operand" ""))]
2854   "reload_completed
2855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2856    && GET_MODE (operands[0]) == XFmode
2857    && ! (ANY_FP_REG_P (operands[0]) || 
2858          (GET_CODE (operands[0]) == SUBREG
2859           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2860    && ! (ANY_FP_REG_P (operands[1]) || 
2861          (GET_CODE (operands[1]) == SUBREG
2862           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2863   [(const_int 0)]
2864   "ix86_split_long_move (operands); DONE;")
2865
2866 (define_split
2867   [(set (match_operand 0 "register_operand" "")
2868         (match_operand 1 "memory_operand" ""))]
2869   "reload_completed
2870    && GET_CODE (operands[1]) == MEM
2871    && (GET_MODE (operands[0]) == XFmode
2872        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2873    && constant_pool_reference_p (operands[1])"
2874   [(set (match_dup 0) (match_dup 1))]
2875 {
2876   rtx c = avoid_constant_pool_reference (operands[1]);
2877   rtx r = operands[0];
2878
2879   if (GET_CODE (r) == SUBREG)
2880     r = SUBREG_REG (r);
2881
2882   if (SSE_REG_P (r))
2883     {
2884       if (!standard_sse_constant_p (c))
2885         FAIL;
2886     }
2887   else if (FP_REG_P (r))
2888     {
2889       if (!standard_80387_constant_p (c))
2890         FAIL;
2891     }
2892   else if (MMX_REG_P (r))
2893     FAIL;
2894
2895   operands[1] = c;
2896 })
2897
2898 (define_insn "swapxf"
2899   [(set (match_operand:XF 0 "register_operand" "+f")
2900         (match_operand:XF 1 "register_operand" "+f"))
2901    (set (match_dup 1)
2902         (match_dup 0))]
2903   "TARGET_80387"
2904 {
2905   if (STACK_TOP_P (operands[0]))
2906     return "fxch\t%1";
2907   else
2908     return "fxch\t%0";
2909 }
2910   [(set_attr "type" "fxch")
2911    (set_attr "mode" "XF")])
2912
2913 (define_expand "movtf"
2914   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2915         (match_operand:TF 1 "nonimmediate_operand" ""))]
2916   "TARGET_64BIT"
2917 {
2918   ix86_expand_move (TFmode, operands);
2919   DONE;
2920 })
2921
2922 (define_insn "*movtf_internal"
2923   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2924         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2925   "TARGET_64BIT
2926    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2927 {
2928   switch (which_alternative)
2929     {
2930     case 0:
2931     case 1:
2932       return "#";
2933     case 2:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "xorps\t%0, %0";
2936       else
2937         return "pxor\t%0, %0";
2938     case 3:
2939     case 4:
2940       if (get_attr_mode (insn) == MODE_V4SF)
2941         return "movaps\t{%1, %0|%0, %1}";
2942       else
2943         return "movdqa\t{%1, %0|%0, %1}";
2944     default:
2945       gcc_unreachable ();
2946     }
2947 }
2948   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2949    (set (attr "mode")
2950         (cond [(eq_attr "alternative" "2,3")
2951                  (if_then_else
2952                    (ne (symbol_ref "optimize_size")
2953                        (const_int 0))
2954                    (const_string "V4SF")
2955                    (const_string "TI"))
2956                (eq_attr "alternative" "4")
2957                  (if_then_else
2958                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2959                             (const_int 0))
2960                         (ne (symbol_ref "optimize_size")
2961                             (const_int 0)))
2962                    (const_string "V4SF")
2963                    (const_string "TI"))]
2964                (const_string "DI")))])
2965
2966 (define_split
2967   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2968         (match_operand:TF 1 "general_operand" ""))]
2969   "reload_completed && !SSE_REG_P (operands[0])
2970    && !SSE_REG_P (operands[1])"
2971   [(const_int 0)]
2972   "ix86_split_long_move (operands); DONE;")
2973 \f
2974 ;; Zero extension instructions
2975
2976 (define_expand "zero_extendhisi2"
2977   [(set (match_operand:SI 0 "register_operand" "")
2978      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2979   ""
2980 {
2981   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2982     {
2983       operands[1] = force_reg (HImode, operands[1]);
2984       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2985       DONE;
2986     }
2987 })
2988
2989 (define_insn "zero_extendhisi2_and"
2990   [(set (match_operand:SI 0 "register_operand" "=r")
2991      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2992    (clobber (reg:CC FLAGS_REG))]
2993   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994   "#"
2995   [(set_attr "type" "alu1")
2996    (set_attr "mode" "SI")])
2997
2998 (define_split
2999   [(set (match_operand:SI 0 "register_operand" "")
3000         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3001    (clobber (reg:CC FLAGS_REG))]
3002   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3003   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3004               (clobber (reg:CC FLAGS_REG))])]
3005   "")
3006
3007 (define_insn "*zero_extendhisi2_movzwl"
3008   [(set (match_operand:SI 0 "register_operand" "=r")
3009      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3010   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3011   "movz{wl|x}\t{%1, %0|%0, %1}"
3012   [(set_attr "type" "imovx")
3013    (set_attr "mode" "SI")])
3014
3015 (define_expand "zero_extendqihi2"
3016   [(parallel
3017     [(set (match_operand:HI 0 "register_operand" "")
3018        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3022
3023 (define_insn "*zero_extendqihi2_and"
3024   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3025      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "HI")])
3031
3032 (define_insn "*zero_extendqihi2_movzbw_and"
3033   [(set (match_operand:HI 0 "register_operand" "=r,r")
3034      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "HI")])
3040
3041 ; zero extend to SImode here to avoid partial register stalls
3042 (define_insn "*zero_extendqihi2_movzbl"
3043   [(set (match_operand:HI 0 "register_operand" "=r")
3044      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3045   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3046   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3047   [(set_attr "type" "imovx")
3048    (set_attr "mode" "SI")])
3049
3050 ;; For the movzbw case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3057    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3058   [(set (match_operand:HI 0 "register_operand" "")
3059         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3060
3061 ;; When source and destination does not overlap, clear destination
3062 ;; first and then do the movb
3063 (define_split
3064   [(set (match_operand:HI 0 "register_operand" "")
3065         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "reload_completed
3068    && ANY_QI_REG_P (operands[0])
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:HI 0 "register_operand" "")
3078         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 (define_expand "zero_extendqisi2"
3087   [(parallel
3088     [(set (match_operand:SI 0 "register_operand" "")
3089        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090      (clobber (reg:CC FLAGS_REG))])]
3091   ""
3092   "")
3093
3094 (define_insn "*zero_extendqisi2_and"
3095   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3096      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3097    (clobber (reg:CC FLAGS_REG))]
3098   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3099   "#"
3100   [(set_attr "type" "alu1")
3101    (set_attr "mode" "SI")])
3102
3103 (define_insn "*zero_extendqisi2_movzbw_and"
3104   [(set (match_operand:SI 0 "register_operand" "=r,r")
3105      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3108   "#"
3109   [(set_attr "type" "imovx,alu1")
3110    (set_attr "mode" "SI")])
3111
3112 (define_insn "*zero_extendqisi2_movzbw"
3113   [(set (match_operand:SI 0 "register_operand" "=r")
3114      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3115   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3116   "movz{bl|x}\t{%1, %0|%0, %1}"
3117   [(set_attr "type" "imovx")
3118    (set_attr "mode" "SI")])
3119
3120 ;; For the movzbl case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3127    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3128   [(set (match_dup 0)
3129         (zero_extend:SI (match_dup 1)))])
3130
3131 ;; When source and destination does not overlap, clear destination
3132 ;; first and then do the movb
3133 (define_split
3134   [(set (match_operand:SI 0 "register_operand" "")
3135         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3136    (clobber (reg:CC FLAGS_REG))]
3137   "reload_completed
3138    && ANY_QI_REG_P (operands[0])
3139    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3140    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3141    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3142   [(set (match_dup 0) (const_int 0))
3143    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3144   "operands[2] = gen_lowpart (QImode, operands[0]);")
3145
3146 ;; Rest is handled by single and.
3147 (define_split
3148   [(set (match_operand:SI 0 "register_operand" "")
3149         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3150    (clobber (reg:CC FLAGS_REG))]
3151   "reload_completed
3152    && true_regnum (operands[0]) == true_regnum (operands[1])"
3153   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3154               (clobber (reg:CC FLAGS_REG))])]
3155   "")
3156
3157 ;; %%% Kill me once multi-word ops are sane.
3158 (define_expand "zero_extendsidi2"
3159   [(set (match_operand:DI 0 "register_operand" "=r")
3160      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3161   ""
3162   "if (!TARGET_64BIT)
3163      {
3164        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3165        DONE;
3166      }
3167   ")
3168
3169 (define_insn "zero_extendsidi2_32"
3170   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3171         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3172    (clobber (reg:CC FLAGS_REG))]
3173   "!TARGET_64BIT"
3174   "@
3175    #
3176    #
3177    #
3178    movd\t{%1, %0|%0, %1}
3179    movd\t{%1, %0|%0, %1}"
3180   [(set_attr "mode" "SI,SI,SI,DI,TI")
3181    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3182
3183 (define_insn "zero_extendsidi2_rex64"
3184   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3185      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3186   "TARGET_64BIT"
3187   "@
3188    mov\t{%k1, %k0|%k0, %k1}
3189    #
3190    movd\t{%1, %0|%0, %1}
3191    movd\t{%1, %0|%0, %1}"
3192   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3193    (set_attr "mode" "SI,DI,SI,SI")])
3194
3195 (define_split
3196   [(set (match_operand:DI 0 "memory_operand" "")
3197      (zero_extend:DI (match_dup 0)))]
3198   "TARGET_64BIT"
3199   [(set (match_dup 4) (const_int 0))]
3200   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3201
3202 (define_split 
3203   [(set (match_operand:DI 0 "register_operand" "")
3204         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3205    (clobber (reg:CC FLAGS_REG))]
3206   "!TARGET_64BIT && reload_completed
3207    && true_regnum (operands[0]) == true_regnum (operands[1])"
3208   [(set (match_dup 4) (const_int 0))]
3209   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210
3211 (define_split 
3212   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3213         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3214    (clobber (reg:CC FLAGS_REG))]
3215   "!TARGET_64BIT && reload_completed
3216    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3217   [(set (match_dup 3) (match_dup 1))
3218    (set (match_dup 4) (const_int 0))]
3219   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3220
3221 (define_insn "zero_extendhidi2"
3222   [(set (match_operand:DI 0 "register_operand" "=r")
3223      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3224   "TARGET_64BIT"
3225   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3226   [(set_attr "type" "imovx")
3227    (set_attr "mode" "DI")])
3228
3229 (define_insn "zero_extendqidi2"
3230   [(set (match_operand:DI 0 "register_operand" "=r")
3231      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3232   "TARGET_64BIT"
3233   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3234   [(set_attr "type" "imovx")
3235    (set_attr "mode" "DI")])
3236 \f
3237 ;; Sign extension instructions
3238
3239 (define_expand "extendsidi2"
3240   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3241                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3242               (clobber (reg:CC FLAGS_REG))
3243               (clobber (match_scratch:SI 2 ""))])]
3244   ""
3245 {
3246   if (TARGET_64BIT)
3247     {
3248       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3249       DONE;
3250     }
3251 })
3252
3253 (define_insn "*extendsidi2_1"
3254   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3255         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3256    (clobber (reg:CC FLAGS_REG))
3257    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3258   "!TARGET_64BIT"
3259   "#")
3260
3261 (define_insn "extendsidi2_rex64"
3262   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3263         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3264   "TARGET_64BIT"
3265   "@
3266    {cltq|cdqe}
3267    movs{lq|x}\t{%1,%0|%0, %1}"
3268   [(set_attr "type" "imovx")
3269    (set_attr "mode" "DI")
3270    (set_attr "prefix_0f" "0")
3271    (set_attr "modrm" "0,1")])
3272
3273 (define_insn "extendhidi2"
3274   [(set (match_operand:DI 0 "register_operand" "=r")
3275         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3276   "TARGET_64BIT"
3277   "movs{wq|x}\t{%1,%0|%0, %1}"
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "DI")])
3280
3281 (define_insn "extendqidi2"
3282   [(set (match_operand:DI 0 "register_operand" "=r")
3283         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3284   "TARGET_64BIT"
3285   "movs{bq|x}\t{%1,%0|%0, %1}"
3286    [(set_attr "type" "imovx")
3287     (set_attr "mode" "DI")])
3288
3289 ;; Extend to memory case when source register does die.
3290 (define_split 
3291   [(set (match_operand:DI 0 "memory_operand" "")
3292         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3293    (clobber (reg:CC FLAGS_REG))
3294    (clobber (match_operand:SI 2 "register_operand" ""))]
3295   "(reload_completed
3296     && dead_or_set_p (insn, operands[1])
3297     && !reg_mentioned_p (operands[1], operands[0]))"
3298   [(set (match_dup 3) (match_dup 1))
3299    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3300               (clobber (reg:CC FLAGS_REG))])
3301    (set (match_dup 4) (match_dup 1))]
3302   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303
3304 ;; Extend to memory case when source register does not die.
3305 (define_split 
3306   [(set (match_operand:DI 0 "memory_operand" "")
3307         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308    (clobber (reg:CC FLAGS_REG))
3309    (clobber (match_operand:SI 2 "register_operand" ""))]
3310   "reload_completed"
3311   [(const_int 0)]
3312 {
3313   split_di (&operands[0], 1, &operands[3], &operands[4]);
3314
3315   emit_move_insn (operands[3], operands[1]);
3316
3317   /* Generate a cltd if possible and doing so it profitable.  */
3318   if (true_regnum (operands[1]) == 0
3319       && true_regnum (operands[2]) == 1
3320       && (optimize_size || TARGET_USE_CLTD))
3321     {
3322       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3323     }
3324   else
3325     {
3326       emit_move_insn (operands[2], operands[1]);
3327       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3328     }
3329   emit_move_insn (operands[4], operands[2]);
3330   DONE;
3331 })
3332
3333 ;; Extend to register case.  Optimize case where source and destination
3334 ;; registers match and cases where we can use cltd.
3335 (define_split 
3336   [(set (match_operand:DI 0 "register_operand" "")
3337         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3338    (clobber (reg:CC FLAGS_REG))
3339    (clobber (match_scratch:SI 2 ""))]
3340   "reload_completed"
3341   [(const_int 0)]
3342 {
3343   split_di (&operands[0], 1, &operands[3], &operands[4]);
3344
3345   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[3], operands[1]);
3347
3348   /* Generate a cltd if possible and doing so it profitable.  */
3349   if (true_regnum (operands[3]) == 0
3350       && (optimize_size || TARGET_USE_CLTD))
3351     {
3352       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3353       DONE;
3354     }
3355
3356   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3357     emit_move_insn (operands[4], operands[1]);
3358
3359   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3360   DONE;
3361 })
3362
3363 (define_insn "extendhisi2"
3364   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3365         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3366   ""
3367 {
3368   switch (get_attr_prefix_0f (insn))
3369     {
3370     case 0:
3371       return "{cwtl|cwde}";
3372     default:
3373       return "movs{wl|x}\t{%1,%0|%0, %1}";
3374     }
3375 }
3376   [(set_attr "type" "imovx")
3377    (set_attr "mode" "SI")
3378    (set (attr "prefix_0f")
3379      ;; movsx is short decodable while cwtl is vector decoded.
3380      (if_then_else (and (eq_attr "cpu" "!k6")
3381                         (eq_attr "alternative" "0"))
3382         (const_string "0")
3383         (const_string "1")))
3384    (set (attr "modrm")
3385      (if_then_else (eq_attr "prefix_0f" "0")
3386         (const_string "0")
3387         (const_string "1")))])
3388
3389 (define_insn "*extendhisi2_zext"
3390   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3391         (zero_extend:DI
3392           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3393   "TARGET_64BIT"
3394 {
3395   switch (get_attr_prefix_0f (insn))
3396     {
3397     case 0:
3398       return "{cwtl|cwde}";
3399     default:
3400       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3401     }
3402 }
3403   [(set_attr "type" "imovx")
3404    (set_attr "mode" "SI")
3405    (set (attr "prefix_0f")
3406      ;; movsx is short decodable while cwtl is vector decoded.
3407      (if_then_else (and (eq_attr "cpu" "!k6")
3408                         (eq_attr "alternative" "0"))
3409         (const_string "0")
3410         (const_string "1")))
3411    (set (attr "modrm")
3412      (if_then_else (eq_attr "prefix_0f" "0")
3413         (const_string "0")
3414         (const_string "1")))])
3415
3416 (define_insn "extendqihi2"
3417   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3418         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3419   ""
3420 {
3421   switch (get_attr_prefix_0f (insn))
3422     {
3423     case 0:
3424       return "{cbtw|cbw}";
3425     default:
3426       return "movs{bw|x}\t{%1,%0|%0, %1}";
3427     }
3428 }
3429   [(set_attr "type" "imovx")
3430    (set_attr "mode" "HI")
3431    (set (attr "prefix_0f")
3432      ;; movsx is short decodable while cwtl is vector decoded.
3433      (if_then_else (and (eq_attr "cpu" "!k6")
3434                         (eq_attr "alternative" "0"))
3435         (const_string "0")
3436         (const_string "1")))
3437    (set (attr "modrm")
3438      (if_then_else (eq_attr "prefix_0f" "0")
3439         (const_string "0")
3440         (const_string "1")))])
3441
3442 (define_insn "extendqisi2"
3443   [(set (match_operand:SI 0 "register_operand" "=r")
3444         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445   ""
3446   "movs{bl|x}\t{%1,%0|%0, %1}"
3447    [(set_attr "type" "imovx")
3448     (set_attr "mode" "SI")])
3449
3450 (define_insn "*extendqisi2_zext"
3451   [(set (match_operand:DI 0 "register_operand" "=r")
3452         (zero_extend:DI
3453           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3454   "TARGET_64BIT"
3455   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3456    [(set_attr "type" "imovx")
3457     (set_attr "mode" "SI")])
3458 \f
3459 ;; Conversions between float and double.
3460
3461 ;; These are all no-ops in the model used for the 80387.  So just
3462 ;; emit moves.
3463
3464 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3465 (define_insn "*dummy_extendsfdf2"
3466   [(set (match_operand:DF 0 "push_operand" "=<")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3468   "0"
3469   "#")
3470
3471 (define_split
3472   [(set (match_operand:DF 0 "push_operand" "")
3473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "!TARGET_64BIT"
3475   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3476    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_split
3479   [(set (match_operand:DF 0 "push_operand" "")
3480         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3481   "TARGET_64BIT"
3482   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3483    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3484
3485 (define_insn "*dummy_extendsfxf2"
3486   [(set (match_operand:XF 0 "push_operand" "=<")
3487         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3488   "0"
3489   "#")
3490
3491 (define_split
3492   [(set (match_operand:XF 0 "push_operand" "")
3493         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494   ""
3495   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3496    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3497   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3498
3499 (define_split
3500   [(set (match_operand:XF 0 "push_operand" "")
3501         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3502   "TARGET_64BIT"
3503   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3504    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3505   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3506
3507 (define_split
3508   [(set (match_operand:XF 0 "push_operand" "")
3509         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510   ""
3511   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3512    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3513   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3514
3515 (define_split
3516   [(set (match_operand:XF 0 "push_operand" "")
3517         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3518   "TARGET_64BIT"
3519   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3520    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3521   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522
3523 (define_expand "extendsfdf2"
3524   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3525         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3526   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3527 {
3528   /* ??? Needed for compress_float_constant since all fp constants
3529      are LEGITIMATE_CONSTANT_P.  */
3530   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3531     {
3532       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3533           && standard_80387_constant_p (operands[1]) > 0)
3534         {
3535           operands[1] = simplify_const_unary_operation
3536             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3537           emit_move_insn_1 (operands[0], operands[1]);
3538           DONE;
3539         }
3540       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3541     }
3542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3543     operands[1] = force_reg (SFmode, operands[1]);
3544 })
3545
3546 (define_insn "*extendsfdf2_mixed"
3547   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3551 {
3552   switch (which_alternative)
3553     {
3554     case 0:
3555       return output_387_reg_move (insn, operands);
3556
3557     case 1:
3558       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559         return "fstp%z0\t%y0";
3560       else
3561         return "fst%z0\t%y0";
3562
3563     case 2:
3564       return "cvtss2sd\t{%1, %0|%0, %1}";
3565
3566     default:
3567       gcc_unreachable ();
3568     }
3569 }
3570   [(set_attr "type" "fmov,fmov,ssecvt")
3571    (set_attr "mode" "SF,XF,DF")])
3572
3573 (define_insn "*extendsfdf2_sse"
3574   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3575         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3576   "TARGET_SSE2 && TARGET_SSE_MATH
3577    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578   "cvtss2sd\t{%1, %0|%0, %1}"
3579   [(set_attr "type" "ssecvt")
3580    (set_attr "mode" "DF")])
3581
3582 (define_insn "*extendsfdf2_i387"
3583   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3584         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3585   "TARGET_80387
3586    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3587 {
3588   switch (which_alternative)
3589     {
3590     case 0:
3591       return output_387_reg_move (insn, operands);
3592
3593     case 1:
3594       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3595         return "fstp%z0\t%y0";
3596       else
3597         return "fst%z0\t%y0";
3598
3599     default:
3600       gcc_unreachable ();
3601     }
3602 }
3603   [(set_attr "type" "fmov")
3604    (set_attr "mode" "SF,XF")])
3605
3606 (define_expand "extendsfxf2"
3607   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3608         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3609   "TARGET_80387"
3610 {
3611   /* ??? Needed for compress_float_constant since all fp constants
3612      are LEGITIMATE_CONSTANT_P.  */
3613   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3614     {
3615       if (standard_80387_constant_p (operands[1]) > 0)
3616         {
3617           operands[1] = simplify_const_unary_operation
3618             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3619           emit_move_insn_1 (operands[0], operands[1]);
3620           DONE;
3621         }
3622       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3623     }
3624   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625     operands[1] = force_reg (SFmode, operands[1]);
3626 })
3627
3628 (define_insn "*extendsfxf2_i387"
3629   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3631   "TARGET_80387
3632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633 {
3634   switch (which_alternative)
3635     {
3636     case 0:
3637       return output_387_reg_move (insn, operands);
3638
3639     case 1:
3640       /* There is no non-popping store to memory for XFmode.  So if
3641          we need one, follow the store with a load.  */
3642       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643         return "fstp%z0\t%y0";
3644       else
3645         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646
3647     default:
3648       gcc_unreachable ();
3649     }
3650 }
3651   [(set_attr "type" "fmov")
3652    (set_attr "mode" "SF,XF")])
3653
3654 (define_expand "extenddfxf2"
3655   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3656         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3657   "TARGET_80387"
3658 {
3659   /* ??? Needed for compress_float_constant since all fp constants
3660      are LEGITIMATE_CONSTANT_P.  */
3661   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3662     {
3663       if (standard_80387_constant_p (operands[1]) > 0)
3664         {
3665           operands[1] = simplify_const_unary_operation
3666             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3667           emit_move_insn_1 (operands[0], operands[1]);
3668           DONE;
3669         }
3670       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3671     }
3672   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3673     operands[1] = force_reg (DFmode, operands[1]);
3674 })
3675
3676 (define_insn "*extenddfxf2_i387"
3677   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3679   "TARGET_80387
3680    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3681 {
3682   switch (which_alternative)
3683     {
3684     case 0:
3685       return output_387_reg_move (insn, operands);
3686
3687     case 1:
3688       /* There is no non-popping store to memory for XFmode.  So if
3689          we need one, follow the store with a load.  */
3690       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3692       else
3693         return "fstp%z0\t%y0";
3694
3695     default:
3696       gcc_unreachable ();
3697     }
3698 }
3699   [(set_attr "type" "fmov")
3700    (set_attr "mode" "DF,XF")])
3701
3702 ;; %%% This seems bad bad news.
3703 ;; This cannot output into an f-reg because there is no way to be sure
3704 ;; of truncating in that case.  Otherwise this is just like a simple move
3705 ;; insn.  So we pretend we can output to a reg in order to get better
3706 ;; register preferencing, but we really use a stack slot.
3707
3708 ;; Conversion from DFmode to SFmode.
3709
3710 (define_expand "truncdfsf2"
3711   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3712         (float_truncate:SF
3713           (match_operand:DF 1 "nonimmediate_operand" "")))]
3714   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3715 {
3716   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3717     operands[1] = force_reg (DFmode, operands[1]);
3718
3719   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3720     ;
3721   else if (flag_unsafe_math_optimizations)
3722     ;
3723   else
3724     {
3725       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3726       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3727       DONE;
3728     }
3729 })
3730
3731 (define_expand "truncdfsf2_with_temp"
3732   [(parallel [(set (match_operand:SF 0 "" "")
3733                    (float_truncate:SF (match_operand:DF 1 "" "")))
3734               (clobber (match_operand:SF 2 "" ""))])]
3735   "")
3736
3737 (define_insn "*truncdfsf_fast_mixed"
3738   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3741   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3742 {
3743   switch (which_alternative)
3744     {
3745     case 0:
3746       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3747         return "fstp%z0\t%y0";
3748       else
3749         return "fst%z0\t%y0";
3750     case 1:
3751       return output_387_reg_move (insn, operands);
3752     case 2:
3753       return "cvtsd2ss\t{%1, %0|%0, %1}";
3754     default:
3755       gcc_unreachable ();
3756     }
3757 }
3758   [(set_attr "type" "fmov,fmov,ssecvt")
3759    (set_attr "mode" "SF")])
3760
3761 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3762 ;; because nothing we do here is unsafe.
3763 (define_insn "*truncdfsf_fast_sse"
3764   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3765         (float_truncate:SF
3766           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3767   "TARGET_SSE2 && TARGET_SSE_MATH"
3768   "cvtsd2ss\t{%1, %0|%0, %1}"
3769   [(set_attr "type" "ssecvt")
3770    (set_attr "mode" "SF")])
3771
3772 (define_insn "*truncdfsf_fast_i387"
3773   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3774         (float_truncate:SF
3775           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3776   "TARGET_80387 && flag_unsafe_math_optimizations"
3777   "* return output_387_reg_move (insn, operands);"
3778   [(set_attr "type" "fmov")
3779    (set_attr "mode" "SF")])
3780
3781 (define_insn "*truncdfsf_mixed"
3782   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3783         (float_truncate:SF
3784           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3785    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3786   "TARGET_MIX_SSE_I387"
3787 {
3788   switch (which_alternative)
3789     {
3790     case 0:
3791       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792         return "fstp%z0\t%y0";
3793       else
3794         return "fst%z0\t%y0";
3795     case 1:
3796       return "#";
3797     case 2:
3798       return "cvtsd2ss\t{%1, %0|%0, %1}";
3799     default:
3800       gcc_unreachable ();
3801     }
3802 }
3803   [(set_attr "type" "fmov,multi,ssecvt")
3804    (set_attr "unit" "*,i387,*")
3805    (set_attr "mode" "SF")])
3806
3807 (define_insn "*truncdfsf_i387"
3808   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3809         (float_truncate:SF
3810           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3811    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3812   "TARGET_80387"
3813 {
3814   switch (which_alternative)
3815     {
3816     case 0:
3817       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3818         return "fstp%z0\t%y0";
3819       else
3820         return "fst%z0\t%y0";
3821     case 1:
3822       return "#";
3823     default:
3824       gcc_unreachable ();
3825     }
3826 }
3827   [(set_attr "type" "fmov,multi")
3828    (set_attr "unit" "*,i387")
3829    (set_attr "mode" "SF")])
3830
3831 (define_insn "*truncdfsf2_i387_1"
3832   [(set (match_operand:SF 0 "memory_operand" "=m")
3833         (float_truncate:SF
3834           (match_operand:DF 1 "register_operand" "f")))]
3835   "TARGET_80387
3836    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3837    && !TARGET_MIX_SSE_I387"
3838 {
3839   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840     return "fstp%z0\t%y0";
3841   else
3842     return "fst%z0\t%y0";
3843 }
3844   [(set_attr "type" "fmov")
3845    (set_attr "mode" "SF")])
3846
3847 (define_split
3848   [(set (match_operand:SF 0 "register_operand" "")
3849         (float_truncate:SF
3850          (match_operand:DF 1 "fp_register_operand" "")))
3851    (clobber (match_operand 2 "" ""))]
3852   "reload_completed"
3853   [(set (match_dup 2) (match_dup 1))
3854    (set (match_dup 0) (match_dup 2))]
3855 {
3856   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3857 })
3858
3859 ;; Conversion from XFmode to SFmode.
3860
3861 (define_expand "truncxfsf2"
3862   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3863                    (float_truncate:SF
3864                     (match_operand:XF 1 "register_operand" "")))
3865               (clobber (match_dup 2))])]
3866   "TARGET_80387"
3867 {
3868   if (flag_unsafe_math_optimizations)
3869     {
3870       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3871       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3872       if (reg != operands[0])
3873         emit_move_insn (operands[0], reg);
3874       DONE;
3875     }
3876   else
3877     operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3878 })
3879
3880 (define_insn "*truncxfsf2_mixed"
3881   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3882         (float_truncate:SF
3883          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3884    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3885   "TARGET_MIX_SSE_I387"
3886 {
3887   gcc_assert (!which_alternative);
3888   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889     return "fstp%z0\t%y0";
3890   else
3891     return "fst%z0\t%y0";
3892 }
3893   [(set_attr "type" "fmov,multi,multi,multi")
3894    (set_attr "unit" "*,i387,i387,i387")
3895    (set_attr "mode" "SF")])
3896
3897 (define_insn "truncxfsf2_i387_noop"
3898   [(set (match_operand:SF 0 "register_operand" "=f")
3899         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3900   "TARGET_80387 && flag_unsafe_math_optimizations"
3901 {
3902   return output_387_reg_move (insn, operands);
3903 }
3904   [(set_attr "type" "fmov")
3905    (set_attr "mode" "SF")])
3906
3907 (define_insn "*truncxfsf2_i387"
3908   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3909         (float_truncate:SF
3910          (match_operand:XF 1 "register_operand" "f,f,f")))
3911    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3912   "TARGET_80387"
3913 {
3914   gcc_assert (!which_alternative);
3915   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916     return "fstp%z0\t%y0";
3917    else
3918      return "fst%z0\t%y0";
3919 }
3920   [(set_attr "type" "fmov,multi,multi")
3921    (set_attr "unit" "*,i387,i387")
3922    (set_attr "mode" "SF")])
3923
3924 (define_insn "*truncxfsf2_i387_1"
3925   [(set (match_operand:SF 0 "memory_operand" "=m")
3926         (float_truncate:SF
3927          (match_operand:XF 1 "register_operand" "f")))]
3928   "TARGET_80387"
3929 {
3930   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931     return "fstp%z0\t%y0";
3932   else
3933     return "fst%z0\t%y0";
3934 }
3935   [(set_attr "type" "fmov")
3936    (set_attr "mode" "SF")])
3937
3938 (define_split
3939   [(set (match_operand:SF 0 "register_operand" "")
3940         (float_truncate:SF
3941          (match_operand:XF 1 "register_operand" "")))
3942    (clobber (match_operand:SF 2 "memory_operand" ""))]
3943   "TARGET_80387 && reload_completed"
3944   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945    (set (match_dup 0) (match_dup 2))]
3946   "")
3947
3948 (define_split
3949   [(set (match_operand:SF 0 "memory_operand" "")
3950         (float_truncate:SF
3951          (match_operand:XF 1 "register_operand" "")))
3952    (clobber (match_operand:SF 2 "memory_operand" ""))]
3953   "TARGET_80387"
3954   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3955   "")
3956
3957 ;; Conversion from XFmode to DFmode.
3958
3959 (define_expand "truncxfdf2"
3960   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3961                    (float_truncate:DF
3962                     (match_operand:XF 1 "register_operand" "")))
3963               (clobber (match_dup 2))])]
3964   "TARGET_80387"
3965 {
3966   if (flag_unsafe_math_optimizations)
3967     {
3968       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3969       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3970       if (reg != operands[0])
3971         emit_move_insn (operands[0], reg);
3972       DONE;
3973     }
3974   else
3975     operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3976 })
3977
3978 (define_insn "*truncxfdf2_mixed"
3979   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3980         (float_truncate:DF
3981          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3982    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3983   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3984 {
3985   gcc_assert (!which_alternative);
3986   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3987     return "fstp%z0\t%y0";
3988   else
3989     return "fst%z0\t%y0";
3990 }
3991   [(set_attr "type" "fmov,multi,multi,multi")
3992    (set_attr "unit" "*,i387,i387,i387")
3993    (set_attr "mode" "DF")])
3994
3995 (define_insn "truncxfdf2_i387_noop"
3996   [(set (match_operand:DF 0 "register_operand" "=f")
3997         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3998   "TARGET_80387 && flag_unsafe_math_optimizations"
3999 {
4000   return output_387_reg_move (insn, operands);
4001 }
4002   [(set_attr "type" "fmov")
4003    (set_attr "mode" "DF")])
4004
4005 (define_insn "*truncxfdf2_i387"
4006   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "f,f,f")))
4009    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4010   "TARGET_80387"
4011 {
4012   gcc_assert (!which_alternative);
4013   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014     return "fstp%z0\t%y0";
4015   else
4016     return "fst%z0\t%y0";
4017 }
4018   [(set_attr "type" "fmov,multi,multi")
4019    (set_attr "unit" "*,i387,i387")
4020    (set_attr "mode" "DF")])
4021
4022 (define_insn "*truncxfdf2_i387_1"
4023   [(set (match_operand:DF 0 "memory_operand" "=m")
4024         (float_truncate:DF
4025           (match_operand:XF 1 "register_operand" "f")))]
4026   "TARGET_80387"
4027 {
4028   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029     return "fstp%z0\t%y0";
4030   else
4031     return "fst%z0\t%y0";
4032 }
4033   [(set_attr "type" "fmov")
4034    (set_attr "mode" "DF")])
4035
4036 (define_split
4037   [(set (match_operand:DF 0 "register_operand" "")
4038         (float_truncate:DF
4039          (match_operand:XF 1 "register_operand" "")))
4040    (clobber (match_operand:DF 2 "memory_operand" ""))]
4041   "TARGET_80387 && reload_completed"
4042   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4043    (set (match_dup 0) (match_dup 2))]
4044   "")
4045
4046 (define_split
4047   [(set (match_operand:DF 0 "memory_operand" "")
4048         (float_truncate:DF
4049          (match_operand:XF 1 "register_operand" "")))
4050    (clobber (match_operand:DF 2 "memory_operand" ""))]
4051   "TARGET_80387"
4052   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4053   "")
4054 \f
4055 ;; Signed conversion to DImode.
4056
4057 (define_expand "fix_truncxfdi2"
4058   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4059                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4060               (clobber (reg:CC FLAGS_REG))])]
4061   "TARGET_80387"
4062 {
4063   if (TARGET_FISTTP)
4064    {
4065      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4066      DONE;
4067    }
4068 })
4069
4070 (define_expand "fix_trunc<mode>di2"
4071   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])]
4074   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4075 {
4076   if (TARGET_FISTTP
4077       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4078    {
4079      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4080      DONE;
4081    }
4082   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4083    {
4084      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4085      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4086      if (out != operands[0])
4087         emit_move_insn (operands[0], out);
4088      DONE;
4089    }
4090 })
4091
4092 ;; Signed conversion to SImode.
4093
4094 (define_expand "fix_truncxfsi2"
4095   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4096                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4097               (clobber (reg:CC FLAGS_REG))])]
4098   "TARGET_80387"
4099 {
4100   if (TARGET_FISTTP)
4101    {
4102      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4103      DONE;
4104    }
4105 })
4106
4107 (define_expand "fix_trunc<mode>si2"
4108   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4110               (clobber (reg:CC FLAGS_REG))])]
4111   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4112 {
4113   if (TARGET_FISTTP
4114       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4115    {
4116      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4117      DONE;
4118    }
4119   if (SSE_FLOAT_MODE_P (<MODE>mode))
4120    {
4121      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4122      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4123      if (out != operands[0])
4124         emit_move_insn (operands[0], out);
4125      DONE;
4126    }
4127 })
4128
4129 ;; Signed conversion to HImode.
4130
4131 (define_expand "fix_trunc<mode>hi2"
4132   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4133                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4134               (clobber (reg:CC FLAGS_REG))])]
4135   "TARGET_80387
4136    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4137 {
4138   if (TARGET_FISTTP)
4139    {
4140      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4141      DONE;
4142    }
4143 })
4144
4145 ;; When SSE is available, it is always faster to use it!
4146 (define_insn "fix_truncsfdi_sse"
4147   [(set (match_operand:DI 0 "register_operand" "=r,r")
4148         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4149   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4150   "cvttss2si{q}\t{%1, %0|%0, %1}"
4151   [(set_attr "type" "sseicvt")
4152    (set_attr "mode" "SF")
4153    (set_attr "athlon_decode" "double,vector")])
4154
4155 (define_insn "fix_truncdfdi_sse"
4156   [(set (match_operand:DI 0 "register_operand" "=r,r")
4157         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4158   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4159   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4160   [(set_attr "type" "sseicvt")
4161    (set_attr "mode" "DF")
4162    (set_attr "athlon_decode" "double,vector")])
4163
4164 (define_insn "fix_truncsfsi_sse"
4165   [(set (match_operand:SI 0 "register_operand" "=r,r")
4166         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4167   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4168   "cvttss2si\t{%1, %0|%0, %1}"
4169   [(set_attr "type" "sseicvt")
4170    (set_attr "mode" "DF")
4171    (set_attr "athlon_decode" "double,vector")])
4172
4173 (define_insn "fix_truncdfsi_sse"
4174   [(set (match_operand:SI 0 "register_operand" "=r,r")
4175         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4176   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177   "cvttsd2si\t{%1, %0|%0, %1}"
4178   [(set_attr "type" "sseicvt")
4179    (set_attr "mode" "DF")
4180    (set_attr "athlon_decode" "double,vector")])
4181
4182 ;; Avoid vector decoded forms of the instruction.
4183 (define_peephole2
4184   [(match_scratch:DF 2 "Y")
4185    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4186         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4187   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4188   [(set (match_dup 2) (match_dup 1))
4189    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4190   "")
4191
4192 (define_peephole2
4193   [(match_scratch:SF 2 "x")
4194    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4196   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197   [(set (match_dup 2) (match_dup 1))
4198    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199   "")
4200
4201 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4202   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4203         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4204   "TARGET_FISTTP
4205    && FLOAT_MODE_P (GET_MODE (operands[1]))
4206    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4207          && (TARGET_64BIT || <MODE>mode != DImode))
4208         && TARGET_SSE_MATH)
4209    && !(reload_completed || reload_in_progress)"
4210   "#"
4211   "&& 1"
4212   [(const_int 0)]
4213 {
4214   if (memory_operand (operands[0], VOIDmode))
4215     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4216   else
4217     {
4218       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4219       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4220                                                             operands[1],
4221                                                             operands[2]));
4222     }
4223   DONE;
4224 }
4225   [(set_attr "type" "fisttp")
4226    (set_attr "mode" "<MODE>")])
4227
4228 (define_insn "fix_trunc<mode>_i387_fisttp"
4229   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4230         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4231    (clobber (match_scratch:XF 2 "=&1f"))]
4232   "TARGET_FISTTP
4233    && FLOAT_MODE_P (GET_MODE (operands[1]))
4234    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4235          && (TARGET_64BIT || <MODE>mode != DImode))
4236         && TARGET_SSE_MATH)"
4237   "* return output_fix_trunc (insn, operands, 1);"
4238   [(set_attr "type" "fisttp")
4239    (set_attr "mode" "<MODE>")])
4240
4241 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4242   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4243         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4244    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4245    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4246   "TARGET_FISTTP
4247    && FLOAT_MODE_P (GET_MODE (operands[1]))
4248    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249         && (TARGET_64BIT || <MODE>mode != DImode))
4250         && TARGET_SSE_MATH)"
4251   "#"
4252   [(set_attr "type" "fisttp")
4253    (set_attr "mode" "<MODE>")])
4254
4255 (define_split
4256   [(set (match_operand:X87MODEI 0 "register_operand" "")
4257         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4258    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4259    (clobber (match_scratch 3 ""))]
4260   "reload_completed"
4261   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4262               (clobber (match_dup 3))])
4263    (set (match_dup 0) (match_dup 2))]
4264   "")
4265
4266 (define_split
4267   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4268         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4269    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4270    (clobber (match_scratch 3 ""))]
4271   "reload_completed"
4272   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4273               (clobber (match_dup 3))])]
4274   "")
4275
4276 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4277 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4278 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4279 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4280 ;; function in i386.c.
4281 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4282   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4283         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4284    (clobber (reg:CC FLAGS_REG))]
4285   "TARGET_80387 && !TARGET_FISTTP
4286    && FLOAT_MODE_P (GET_MODE (operands[1]))
4287    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4288          && (TARGET_64BIT || <MODE>mode != DImode))
4289    && !(reload_completed || reload_in_progress)"
4290   "#"
4291   "&& 1"
4292   [(const_int 0)]
4293 {
4294   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4295
4296   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4297   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4298   if (memory_operand (operands[0], VOIDmode))
4299     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4300                                          operands[2], operands[3]));
4301   else
4302     {
4303       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4304       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4305                                                      operands[2], operands[3],
4306                                                      operands[4]));
4307     }
4308   DONE;
4309 }
4310   [(set_attr "type" "fistp")
4311    (set_attr "i387_cw" "trunc")
4312    (set_attr "mode" "<MODE>")])
4313
4314 (define_insn "fix_truncdi_i387"
4315   [(set (match_operand:DI 0 "memory_operand" "=m")
4316         (fix:DI (match_operand 1 "register_operand" "f")))
4317    (use (match_operand:HI 2 "memory_operand" "m"))
4318    (use (match_operand:HI 3 "memory_operand" "m"))
4319    (clobber (match_scratch:XF 4 "=&1f"))]
4320   "TARGET_80387 && !TARGET_FISTTP
4321    && FLOAT_MODE_P (GET_MODE (operands[1]))
4322    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4323   "* return output_fix_trunc (insn, operands, 0);"
4324   [(set_attr "type" "fistp")
4325    (set_attr "i387_cw" "trunc")
4326    (set_attr "mode" "DI")])
4327
4328 (define_insn "fix_truncdi_i387_with_temp"
4329   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4330         (fix:DI (match_operand 1 "register_operand" "f,f")))
4331    (use (match_operand:HI 2 "memory_operand" "m,m"))
4332    (use (match_operand:HI 3 "memory_operand" "m,m"))
4333    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4334    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4335   "TARGET_80387 && !TARGET_FISTTP
4336    && FLOAT_MODE_P (GET_MODE (operands[1]))
4337    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4338   "#"
4339   [(set_attr "type" "fistp")
4340    (set_attr "i387_cw" "trunc")
4341    (set_attr "mode" "DI")])
4342
4343 (define_split 
4344   [(set (match_operand:DI 0 "register_operand" "")
4345         (fix:DI (match_operand 1 "register_operand" "")))
4346    (use (match_operand:HI 2 "memory_operand" ""))
4347    (use (match_operand:HI 3 "memory_operand" ""))
4348    (clobber (match_operand:DI 4 "memory_operand" ""))
4349    (clobber (match_scratch 5 ""))]
4350   "reload_completed"
4351   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4352               (use (match_dup 2))
4353               (use (match_dup 3))
4354               (clobber (match_dup 5))])
4355    (set (match_dup 0) (match_dup 4))]
4356   "")
4357
4358 (define_split 
4359   [(set (match_operand:DI 0 "memory_operand" "")
4360         (fix:DI (match_operand 1 "register_operand" "")))
4361    (use (match_operand:HI 2 "memory_operand" ""))
4362    (use (match_operand:HI 3 "memory_operand" ""))
4363    (clobber (match_operand:DI 4 "memory_operand" ""))
4364    (clobber (match_scratch 5 ""))]
4365   "reload_completed"
4366   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4367               (use (match_dup 2))
4368               (use (match_dup 3))
4369               (clobber (match_dup 5))])]
4370   "")
4371
4372 (define_insn "fix_trunc<mode>_i387"
4373   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4374         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4375    (use (match_operand:HI 2 "memory_operand" "m"))
4376    (use (match_operand:HI 3 "memory_operand" "m"))]
4377   "TARGET_80387 && !TARGET_FISTTP
4378    && FLOAT_MODE_P (GET_MODE (operands[1]))
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "* return output_fix_trunc (insn, operands, 0);"
4381   [(set_attr "type" "fistp")
4382    (set_attr "i387_cw" "trunc")
4383    (set_attr "mode" "<MODE>")])
4384
4385 (define_insn "fix_trunc<mode>_i387_with_temp"
4386   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4387         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4388    (use (match_operand:HI 2 "memory_operand" "m,m"))
4389    (use (match_operand:HI 3 "memory_operand" "m,m"))
4390    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4391   "TARGET_80387 && !TARGET_FISTTP
4392    && FLOAT_MODE_P (GET_MODE (operands[1]))
4393    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4394   "#"
4395   [(set_attr "type" "fistp")
4396    (set_attr "i387_cw" "trunc")
4397    (set_attr "mode" "<MODE>")])
4398
4399 (define_split 
4400   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4401         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4402    (use (match_operand:HI 2 "memory_operand" ""))
4403    (use (match_operand:HI 3 "memory_operand" ""))
4404    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4405   "reload_completed"
4406   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4407               (use (match_dup 2))
4408               (use (match_dup 3))])
4409    (set (match_dup 0) (match_dup 4))]
4410   "")
4411
4412 (define_split 
4413   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4414         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4415    (use (match_operand:HI 2 "memory_operand" ""))
4416    (use (match_operand:HI 3 "memory_operand" ""))
4417    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4418   "reload_completed"
4419   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4420               (use (match_dup 2))
4421               (use (match_dup 3))])]
4422   "")
4423
4424 (define_insn "x86_fnstcw_1"
4425   [(set (match_operand:HI 0 "memory_operand" "=m")
4426         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4427   "TARGET_80387"
4428   "fnstcw\t%0"
4429   [(set_attr "length" "2")
4430    (set_attr "mode" "HI")
4431    (set_attr "unit" "i387")])
4432
4433 (define_insn "x86_fldcw_1"
4434   [(set (reg:HI FPSR_REG)
4435         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4436   "TARGET_80387"
4437   "fldcw\t%0"
4438   [(set_attr "length" "2")
4439    (set_attr "mode" "HI")
4440    (set_attr "unit" "i387")
4441    (set_attr "athlon_decode" "vector")])
4442 \f
4443 ;; Conversion between fixed point and floating point.
4444
4445 ;; Even though we only accept memory inputs, the backend _really_
4446 ;; wants to be able to do this between registers.
4447
4448 (define_expand "floathisf2"
4449   [(set (match_operand:SF 0 "register_operand" "")
4450         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4451   "TARGET_80387 || TARGET_SSE_MATH"
4452 {
4453   if (TARGET_SSE_MATH)
4454     {
4455       emit_insn (gen_floatsisf2 (operands[0],
4456                                  convert_to_mode (SImode, operands[1], 0)));
4457       DONE;
4458     }
4459 })
4460
4461 (define_insn "*floathisf2_i387"
4462   [(set (match_operand:SF 0 "register_operand" "=f,f")
4463         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4464   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4465   "@
4466    fild%z1\t%1
4467    #"
4468   [(set_attr "type" "fmov,multi")
4469    (set_attr "mode" "SF")
4470    (set_attr "unit" "*,i387")
4471    (set_attr "fp_int_src" "true")])
4472
4473 (define_expand "floatsisf2"
4474   [(set (match_operand:SF 0 "register_operand" "")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4476   "TARGET_80387 || TARGET_SSE_MATH"
4477   "")
4478
4479 (define_insn "*floatsisf2_mixed"
4480   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4481         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4482   "TARGET_MIX_SSE_I387"
4483   "@
4484    fild%z1\t%1
4485    #
4486    cvtsi2ss\t{%1, %0|%0, %1}
4487    cvtsi2ss\t{%1, %0|%0, %1}"
4488   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4489    (set_attr "mode" "SF")
4490    (set_attr "unit" "*,i387,*,*")
4491    (set_attr "athlon_decode" "*,*,vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 (define_insn "*floatsisf2_sse"
4495   [(set (match_operand:SF 0 "register_operand" "=x,x")
4496         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4497   "TARGET_SSE_MATH"
4498   "cvtsi2ss\t{%1, %0|%0, %1}"
4499   [(set_attr "type" "sseicvt")
4500    (set_attr "mode" "SF")
4501    (set_attr "athlon_decode" "vector,double")
4502    (set_attr "fp_int_src" "true")])
4503
4504 (define_insn "*floatsisf2_i387"
4505   [(set (match_operand:SF 0 "register_operand" "=f,f")
4506         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4507   "TARGET_80387"
4508   "@
4509    fild%z1\t%1
4510    #"
4511   [(set_attr "type" "fmov,multi")
4512    (set_attr "mode" "SF")
4513    (set_attr "unit" "*,i387")
4514    (set_attr "fp_int_src" "true")])
4515
4516 (define_expand "floatdisf2"
4517   [(set (match_operand:SF 0 "register_operand" "")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4519   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4520   "")
4521
4522 (define_insn "*floatdisf2_mixed"
4523   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4524         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4525   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4526   "@
4527    fild%z1\t%1
4528    #
4529    cvtsi2ss{q}\t{%1, %0|%0, %1}
4530    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4531   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4532    (set_attr "mode" "SF")
4533    (set_attr "unit" "*,i387,*,*")
4534    (set_attr "athlon_decode" "*,*,vector,double")
4535    (set_attr "fp_int_src" "true")])
4536
4537 (define_insn "*floatdisf2_sse"
4538   [(set (match_operand:SF 0 "register_operand" "=x,x")
4539         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4540   "TARGET_64BIT && TARGET_SSE_MATH"
4541   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4542   [(set_attr "type" "sseicvt")
4543    (set_attr "mode" "SF")
4544    (set_attr "athlon_decode" "vector,double")
4545    (set_attr "fp_int_src" "true")])
4546
4547 (define_insn "*floatdisf2_i387"
4548   [(set (match_operand:SF 0 "register_operand" "=f,f")
4549         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4550   "TARGET_80387"
4551   "@
4552    fild%z1\t%1
4553    #"
4554   [(set_attr "type" "fmov,multi")
4555    (set_attr "mode" "SF")
4556    (set_attr "unit" "*,i387")
4557    (set_attr "fp_int_src" "true")])
4558
4559 (define_expand "floathidf2"
4560   [(set (match_operand:DF 0 "register_operand" "")
4561         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4562   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4563 {
4564   if (TARGET_SSE2 && TARGET_SSE_MATH)
4565     {
4566       emit_insn (gen_floatsidf2 (operands[0],
4567                                  convert_to_mode (SImode, operands[1], 0)));
4568       DONE;
4569     }
4570 })
4571
4572 (define_insn "*floathidf2_i387"
4573   [(set (match_operand:DF 0 "register_operand" "=f,f")
4574         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4575   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4576   "@
4577    fild%z1\t%1
4578    #"
4579   [(set_attr "type" "fmov,multi")
4580    (set_attr "mode" "DF")
4581    (set_attr "unit" "*,i387")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_expand "floatsidf2"
4585   [(set (match_operand:DF 0 "register_operand" "")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588   "")
4589
4590 (define_insn "*floatsidf2_mixed"
4591   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4592         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594   "@
4595    fild%z1\t%1
4596    #
4597    cvtsi2sd\t{%1, %0|%0, %1}
4598    cvtsi2sd\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "unit" "*,i387,*,*")
4602    (set_attr "athlon_decode" "*,*,double,direct")
4603    (set_attr "fp_int_src" "true")])
4604
4605 (define_insn "*floatsidf2_sse"
4606   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4607         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4608   "TARGET_SSE2 && TARGET_SSE_MATH"
4609   "cvtsi2sd\t{%1, %0|%0, %1}"
4610   [(set_attr "type" "sseicvt")
4611    (set_attr "mode" "DF")
4612    (set_attr "athlon_decode" "double,direct")
4613    (set_attr "fp_int_src" "true")])
4614
4615 (define_insn "*floatsidf2_i387"
4616   [(set (match_operand:DF 0 "register_operand" "=f,f")
4617         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4618   "TARGET_80387"
4619   "@
4620    fild%z1\t%1
4621    #"
4622   [(set_attr "type" "fmov,multi")
4623    (set_attr "mode" "DF")
4624    (set_attr "unit" "*,i387")
4625    (set_attr "fp_int_src" "true")])
4626
4627 (define_expand "floatdidf2"
4628   [(set (match_operand:DF 0 "register_operand" "")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4630   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4631   "")
4632
4633 (define_insn "*floatdidf2_mixed"
4634   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4635         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4637   "@
4638    fild%z1\t%1
4639    #
4640    cvtsi2sd{q}\t{%1, %0|%0, %1}
4641    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4642   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643    (set_attr "mode" "DF")
4644    (set_attr "unit" "*,i387,*,*")
4645    (set_attr "athlon_decode" "*,*,double,direct")
4646    (set_attr "fp_int_src" "true")])
4647
4648 (define_insn "*floatdidf2_sse"
4649   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4650         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4651   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4652   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4653   [(set_attr "type" "sseicvt")
4654    (set_attr "mode" "DF")
4655    (set_attr "athlon_decode" "double,direct")
4656    (set_attr "fp_int_src" "true")])
4657
4658 (define_insn "*floatdidf2_i387"
4659   [(set (match_operand:DF 0 "register_operand" "=f,f")
4660         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4661   "TARGET_80387"
4662   "@
4663    fild%z1\t%1
4664    #"
4665   [(set_attr "type" "fmov,multi")
4666    (set_attr "mode" "DF")
4667    (set_attr "unit" "*,i387")
4668    (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "floathixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "unit" "*,i387")
4680    (set_attr "fp_int_src" "true")])
4681
4682 (define_insn "floatsixf2"
4683   [(set (match_operand:XF 0 "register_operand" "=f,f")
4684         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4685   "TARGET_80387"
4686   "@
4687    fild%z1\t%1
4688    #"
4689   [(set_attr "type" "fmov,multi")
4690    (set_attr "mode" "XF")
4691    (set_attr "unit" "*,i387")
4692    (set_attr "fp_int_src" "true")])
4693
4694 (define_insn "floatdixf2"
4695   [(set (match_operand:XF 0 "register_operand" "=f,f")
4696         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4697   "TARGET_80387"
4698   "@
4699    fild%z1\t%1
4700    #"
4701   [(set_attr "type" "fmov,multi")
4702    (set_attr "mode" "XF")
4703    (set_attr "unit" "*,i387")
4704    (set_attr "fp_int_src" "true")])
4705
4706 ;; %%% Kill these when reload knows how to do it.
4707 (define_split
4708   [(set (match_operand 0 "fp_register_operand" "")
4709         (float (match_operand 1 "register_operand" "")))]
4710   "reload_completed
4711    && TARGET_80387
4712    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4713   [(const_int 0)]
4714 {
4715   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718   ix86_free_from_memory (GET_MODE (operands[1]));
4719   DONE;
4720 })
4721
4722 (define_expand "floatunssisf2"
4723   [(use (match_operand:SF 0 "register_operand" ""))
4724    (use (match_operand:SI 1 "register_operand" ""))]
4725   "!TARGET_64BIT && TARGET_SSE_MATH"
4726   "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdisf2"
4729   [(use (match_operand:SF 0 "register_operand" ""))
4730    (use (match_operand:DI 1 "register_operand" ""))]
4731   "TARGET_64BIT && TARGET_SSE_MATH"
4732   "x86_emit_floatuns (operands); DONE;")
4733
4734 (define_expand "floatunsdidf2"
4735   [(use (match_operand:DF 0 "register_operand" ""))
4736    (use (match_operand:DI 1 "register_operand" ""))]
4737   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4738   "x86_emit_floatuns (operands); DONE;")
4739 \f
4740 ;; SSE extract/set expanders
4741
4742 \f
4743 ;; Add instructions
4744
4745 ;; %%% splits for addditi3
4746
4747 (define_expand "addti3"
4748   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4749         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4750                  (match_operand:TI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   "TARGET_64BIT"
4753   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4754
4755 (define_insn "*addti3_1"
4756   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4757         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4761   "#")
4762
4763 (define_split
4764   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4765         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4766                  (match_operand:TI 2 "x86_64_general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_ti (operands+0, 1, operands+0, operands+3);
4778    split_ti (operands+1, 1, operands+1, operands+4);
4779    split_ti (operands+2, 1, operands+2, operands+5);")
4780
4781 ;; %%% splits for addsidi3
4782 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4784 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4785
4786 (define_expand "adddi3"
4787   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4788         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4789                  (match_operand:DI 2 "x86_64_general_operand" "")))
4790    (clobber (reg:CC FLAGS_REG))]
4791   ""
4792   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4793
4794 (define_insn "*adddi3_1"
4795   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4796         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4798    (clobber (reg:CC FLAGS_REG))]
4799   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4800   "#")
4801
4802 (define_split
4803   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4804         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4805                  (match_operand:DI 2 "general_operand" "")))
4806    (clobber (reg:CC FLAGS_REG))]
4807   "!TARGET_64BIT && reload_completed"
4808   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4809                                           UNSPEC_ADD_CARRY))
4810               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4811    (parallel [(set (match_dup 3)
4812                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4813                                      (match_dup 4))
4814                             (match_dup 5)))
4815               (clobber (reg:CC FLAGS_REG))])]
4816   "split_di (operands+0, 1, operands+0, operands+3);
4817    split_di (operands+1, 1, operands+1, operands+4);
4818    split_di (operands+2, 1, operands+2, operands+5);")
4819
4820 (define_insn "adddi3_carry_rex64"
4821   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4822           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4823                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4824                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4825    (clobber (reg:CC FLAGS_REG))]
4826   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4827   "adc{q}\t{%2, %0|%0, %2}"
4828   [(set_attr "type" "alu")
4829    (set_attr "pent_pair" "pu")
4830    (set_attr "mode" "DI")])
4831
4832 (define_insn "*adddi3_cc_rex64"
4833   [(set (reg:CC FLAGS_REG)
4834         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4835                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4836                    UNSPEC_ADD_CARRY))
4837    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4838         (plus:DI (match_dup 1) (match_dup 2)))]
4839   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840   "add{q}\t{%2, %0|%0, %2}"
4841   [(set_attr "type" "alu")
4842    (set_attr "mode" "DI")])
4843
4844 (define_insn "addqi3_carry"
4845   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4846           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4847                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4848                    (match_operand:QI 2 "general_operand" "qi,qm")))
4849    (clobber (reg:CC FLAGS_REG))]
4850   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4851   "adc{b}\t{%2, %0|%0, %2}"
4852   [(set_attr "type" "alu")
4853    (set_attr "pent_pair" "pu")
4854    (set_attr "mode" "QI")])
4855
4856 (define_insn "addhi3_carry"
4857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4858           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4859                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4860                    (match_operand:HI 2 "general_operand" "ri,rm")))
4861    (clobber (reg:CC FLAGS_REG))]
4862   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4863   "adc{w}\t{%2, %0|%0, %2}"
4864   [(set_attr "type" "alu")
4865    (set_attr "pent_pair" "pu")
4866    (set_attr "mode" "HI")])
4867
4868 (define_insn "addsi3_carry"
4869   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4870           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4871                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4872                    (match_operand:SI 2 "general_operand" "ri,rm")))
4873    (clobber (reg:CC FLAGS_REG))]
4874   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4875   "adc{l}\t{%2, %0|%0, %2}"
4876   [(set_attr "type" "alu")
4877    (set_attr "pent_pair" "pu")
4878    (set_attr "mode" "SI")])
4879
4880 (define_insn "*addsi3_carry_zext"
4881   [(set (match_operand:DI 0 "register_operand" "=r")
4882           (zero_extend:DI 
4883             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4885                      (match_operand:SI 2 "general_operand" "rim"))))
4886    (clobber (reg:CC FLAGS_REG))]
4887   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4888   "adc{l}\t{%2, %k0|%k0, %2}"
4889   [(set_attr "type" "alu")
4890    (set_attr "pent_pair" "pu")
4891    (set_attr "mode" "SI")])
4892
4893 (define_insn "*addsi3_cc"
4894   [(set (reg:CC FLAGS_REG)
4895         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4896                     (match_operand:SI 2 "general_operand" "ri,rm")]
4897                    UNSPEC_ADD_CARRY))
4898    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4899         (plus:SI (match_dup 1) (match_dup 2)))]
4900   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4901   "add{l}\t{%2, %0|%0, %2}"
4902   [(set_attr "type" "alu")
4903    (set_attr "mode" "SI")])
4904
4905 (define_insn "addqi3_cc"
4906   [(set (reg:CC FLAGS_REG)
4907         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4908                     (match_operand:QI 2 "general_operand" "qi,qm")]
4909                    UNSPEC_ADD_CARRY))
4910    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4911         (plus:QI (match_dup 1) (match_dup 2)))]
4912   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4913   "add{b}\t{%2, %0|%0, %2}"
4914   [(set_attr "type" "alu")
4915    (set_attr "mode" "QI")])
4916
4917 (define_expand "addsi3"
4918   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4919                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4920                             (match_operand:SI 2 "general_operand" "")))
4921               (clobber (reg:CC FLAGS_REG))])]
4922   ""
4923   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4924
4925 (define_insn "*lea_1"
4926   [(set (match_operand:SI 0 "register_operand" "=r")
4927         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4928   "!TARGET_64BIT"
4929   "lea{l}\t{%a1, %0|%0, %a1}"
4930   [(set_attr "type" "lea")
4931    (set_attr "mode" "SI")])
4932
4933 (define_insn "*lea_1_rex64"
4934   [(set (match_operand:SI 0 "register_operand" "=r")
4935         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4936   "TARGET_64BIT"
4937   "lea{l}\t{%a1, %0|%0, %a1}"
4938   [(set_attr "type" "lea")
4939    (set_attr "mode" "SI")])
4940
4941 (define_insn "*lea_1_zext"
4942   [(set (match_operand:DI 0 "register_operand" "=r")
4943         (zero_extend:DI
4944          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4945   "TARGET_64BIT"
4946   "lea{l}\t{%a1, %k0|%k0, %a1}"
4947   [(set_attr "type" "lea")
4948    (set_attr "mode" "SI")])
4949
4950 (define_insn "*lea_2_rex64"
4951   [(set (match_operand:DI 0 "register_operand" "=r")
4952         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4953   "TARGET_64BIT"
4954   "lea{q}\t{%a1, %0|%0, %a1}"
4955   [(set_attr "type" "lea")
4956    (set_attr "mode" "DI")])
4957
4958 ;; The lea patterns for non-Pmodes needs to be matched by several
4959 ;; insns converted to real lea by splitters.
4960
4961 (define_insn_and_split "*lea_general_1"
4962   [(set (match_operand 0 "register_operand" "=r")
4963         (plus (plus (match_operand 1 "index_register_operand" "l")
4964                     (match_operand 2 "register_operand" "r"))
4965               (match_operand 3 "immediate_operand" "i")))]
4966   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4967     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4968    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4969    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4970    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4971    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4972        || GET_MODE (operands[3]) == VOIDmode)"
4973   "#"
4974   "&& reload_completed"
4975   [(const_int 0)]
4976 {
4977   rtx pat;
4978   operands[0] = gen_lowpart (SImode, operands[0]);
4979   operands[1] = gen_lowpart (Pmode, operands[1]);
4980   operands[2] = gen_lowpart (Pmode, operands[2]);
4981   operands[3] = gen_lowpart (Pmode, operands[3]);
4982   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4983                       operands[3]);
4984   if (Pmode != SImode)
4985     pat = gen_rtx_SUBREG (SImode, pat, 0);
4986   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4987   DONE;
4988 }
4989   [(set_attr "type" "lea")
4990    (set_attr "mode" "SI")])
4991
4992 (define_insn_and_split "*lea_general_1_zext"
4993   [(set (match_operand:DI 0 "register_operand" "=r")
4994         (zero_extend:DI
4995           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4996                             (match_operand:SI 2 "register_operand" "r"))
4997                    (match_operand:SI 3 "immediate_operand" "i"))))]
4998   "TARGET_64BIT"
4999   "#"
5000   "&& reload_completed"
5001   [(set (match_dup 0)
5002         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5003                                                      (match_dup 2))
5004                                             (match_dup 3)) 0)))]
5005 {
5006   operands[1] = gen_lowpart (Pmode, operands[1]);
5007   operands[2] = gen_lowpart (Pmode, operands[2]);
5008   operands[3] = gen_lowpart (Pmode, operands[3]);
5009 }
5010   [(set_attr "type" "lea")
5011    (set_attr "mode" "SI")])
5012
5013 (define_insn_and_split "*lea_general_2"
5014   [(set (match_operand 0 "register_operand" "=r")
5015         (plus (mult (match_operand 1 "index_register_operand" "l")
5016                     (match_operand 2 "const248_operand" "i"))
5017               (match_operand 3 "nonmemory_operand" "ri")))]
5018   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5019     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5020    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5021    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5022    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5023        || GET_MODE (operands[3]) == VOIDmode)"
5024   "#"
5025   "&& reload_completed"
5026   [(const_int 0)]
5027 {
5028   rtx pat;
5029   operands[0] = gen_lowpart (SImode, operands[0]);
5030   operands[1] = gen_lowpart (Pmode, operands[1]);
5031   operands[3] = gen_lowpart (Pmode, operands[3]);
5032   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5033                       operands[3]);
5034   if (Pmode != SImode)
5035     pat = gen_rtx_SUBREG (SImode, pat, 0);
5036   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5037   DONE;
5038 }
5039   [(set_attr "type" "lea")
5040    (set_attr "mode" "SI")])
5041
5042 (define_insn_and_split "*lea_general_2_zext"
5043   [(set (match_operand:DI 0 "register_operand" "=r")
5044         (zero_extend:DI
5045           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5046                             (match_operand:SI 2 "const248_operand" "n"))
5047                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5048   "TARGET_64BIT"
5049   "#"
5050   "&& reload_completed"
5051   [(set (match_dup 0)
5052         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5053                                                      (match_dup 2))
5054                                             (match_dup 3)) 0)))]
5055 {
5056   operands[1] = gen_lowpart (Pmode, operands[1]);
5057   operands[3] = gen_lowpart (Pmode, operands[3]);
5058 }
5059   [(set_attr "type" "lea")
5060    (set_attr "mode" "SI")])
5061
5062 (define_insn_and_split "*lea_general_3"
5063   [(set (match_operand 0 "register_operand" "=r")
5064         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5065                           (match_operand 2 "const248_operand" "i"))
5066                     (match_operand 3 "register_operand" "r"))
5067               (match_operand 4 "immediate_operand" "i")))]
5068   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5073   "#"
5074   "&& reload_completed"
5075   [(const_int 0)]
5076 {
5077   rtx pat;
5078   operands[0] = gen_lowpart (SImode, operands[0]);
5079   operands[1] = gen_lowpart (Pmode, operands[1]);
5080   operands[3] = gen_lowpart (Pmode, operands[3]);
5081   operands[4] = gen_lowpart (Pmode, operands[4]);
5082   pat = gen_rtx_PLUS (Pmode,
5083                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5084                                                          operands[2]),
5085                                     operands[3]),
5086                       operands[4]);
5087   if (Pmode != SImode)
5088     pat = gen_rtx_SUBREG (SImode, pat, 0);
5089   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5090   DONE;
5091 }
5092   [(set_attr "type" "lea")
5093    (set_attr "mode" "SI")])
5094
5095 (define_insn_and_split "*lea_general_3_zext"
5096   [(set (match_operand:DI 0 "register_operand" "=r")
5097         (zero_extend:DI
5098           (plus:SI (plus:SI (mult:SI
5099                               (match_operand:SI 1 "index_register_operand" "l")
5100                               (match_operand:SI 2 "const248_operand" "n"))
5101                             (match_operand:SI 3 "register_operand" "r"))
5102                    (match_operand:SI 4 "immediate_operand" "i"))))]
5103   "TARGET_64BIT"
5104   "#"
5105   "&& reload_completed"
5106   [(set (match_dup 0)
5107         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5108                                                               (match_dup 2))
5109                                                      (match_dup 3))
5110                                             (match_dup 4)) 0)))]
5111 {
5112   operands[1] = gen_lowpart (Pmode, operands[1]);
5113   operands[3] = gen_lowpart (Pmode, operands[3]);
5114   operands[4] = gen_lowpart (Pmode, operands[4]);
5115 }
5116   [(set_attr "type" "lea")
5117    (set_attr "mode" "SI")])
5118
5119 (define_insn "*adddi_1_rex64"
5120   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5121         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5122                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5123    (clobber (reg:CC FLAGS_REG))]
5124   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5125 {
5126   switch (get_attr_type (insn))
5127     {
5128     case TYPE_LEA:
5129       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5130       return "lea{q}\t{%a2, %0|%0, %a2}";
5131
5132     case TYPE_INCDEC:
5133       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5134       if (operands[2] == const1_rtx)
5135         return "inc{q}\t%0";
5136       else
5137         {
5138           gcc_assert (operands[2] == constm1_rtx);
5139           return "dec{q}\t%0";
5140         }
5141
5142     default:
5143       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5144
5145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5146          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5147       if (GET_CODE (operands[2]) == CONST_INT
5148           /* Avoid overflows.  */
5149           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5150           && (INTVAL (operands[2]) == 128
5151               || (INTVAL (operands[2]) < 0
5152                   && INTVAL (operands[2]) != -128)))
5153         {
5154           operands[2] = GEN_INT (-INTVAL (operands[2]));
5155           return "sub{q}\t{%2, %0|%0, %2}";
5156         }
5157       return "add{q}\t{%2, %0|%0, %2}";
5158     }
5159 }
5160   [(set (attr "type")
5161      (cond [(eq_attr "alternative" "2")
5162               (const_string "lea")
5163             ; Current assemblers are broken and do not allow @GOTOFF in
5164             ; ought but a memory context.
5165             (match_operand:DI 2 "pic_symbolic_operand" "")
5166               (const_string "lea")
5167             (match_operand:DI 2 "incdec_operand" "")
5168               (const_string "incdec")
5169            ]
5170            (const_string "alu")))
5171    (set_attr "mode" "DI")])
5172
5173 ;; Convert lea to the lea pattern to avoid flags dependency.
5174 (define_split
5175   [(set (match_operand:DI 0 "register_operand" "")
5176         (plus:DI (match_operand:DI 1 "register_operand" "")
5177                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5178    (clobber (reg:CC FLAGS_REG))]
5179   "TARGET_64BIT && reload_completed
5180    && true_regnum (operands[0]) != true_regnum (operands[1])"
5181   [(set (match_dup 0)
5182         (plus:DI (match_dup 1)
5183                  (match_dup 2)))]
5184   "")
5185
5186 (define_insn "*adddi_2_rex64"
5187   [(set (reg FLAGS_REG)
5188         (compare
5189           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5190                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5191           (const_int 0)))                       
5192    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5193         (plus:DI (match_dup 1) (match_dup 2)))]
5194   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5195    && ix86_binary_operator_ok (PLUS, DImode, operands)
5196    /* Current assemblers are broken and do not allow @GOTOFF in
5197       ought but a memory context.  */
5198    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5199 {
5200   switch (get_attr_type (insn))
5201     {
5202     case TYPE_INCDEC:
5203       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5204       if (operands[2] == const1_rtx)
5205         return "inc{q}\t%0";
5206       else
5207         {
5208           gcc_assert (operands[2] == constm1_rtx);
5209           return "dec{q}\t%0";
5210         }
5211
5212     default:
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       /* ???? We ought to handle there the 32bit case too
5215          - do we need new constraint?  */
5216       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5217          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5218       if (GET_CODE (operands[2]) == CONST_INT
5219           /* Avoid overflows.  */
5220           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5221           && (INTVAL (operands[2]) == 128
5222               || (INTVAL (operands[2]) < 0
5223                   && INTVAL (operands[2]) != -128)))
5224         {
5225           operands[2] = GEN_INT (-INTVAL (operands[2]));
5226           return "sub{q}\t{%2, %0|%0, %2}";
5227         }
5228       return "add{q}\t{%2, %0|%0, %2}";
5229     }
5230 }
5231   [(set (attr "type")
5232      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233         (const_string "incdec")
5234         (const_string "alu")))
5235    (set_attr "mode" "DI")])
5236
5237 (define_insn "*adddi_3_rex64"
5238   [(set (reg FLAGS_REG)
5239         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5240                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5241    (clobber (match_scratch:DI 0 "=r"))]
5242   "TARGET_64BIT
5243    && ix86_match_ccmode (insn, CCZmode)
5244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5245    /* Current assemblers are broken and do not allow @GOTOFF in
5246       ought but a memory context.  */
5247    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248 {
5249   switch (get_attr_type (insn))
5250     {
5251     case TYPE_INCDEC:
5252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253       if (operands[2] == const1_rtx)
5254         return "inc{q}\t%0";
5255       else
5256         {
5257           gcc_assert (operands[2] == constm1_rtx);
5258           return "dec{q}\t%0";
5259         }
5260
5261     default:
5262       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263       /* ???? We ought to handle there the 32bit case too
5264          - do we need new constraint?  */
5265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5267       if (GET_CODE (operands[2]) == CONST_INT
5268           /* Avoid overflows.  */
5269           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270           && (INTVAL (operands[2]) == 128
5271               || (INTVAL (operands[2]) < 0
5272                   && INTVAL (operands[2]) != -128)))
5273         {
5274           operands[2] = GEN_INT (-INTVAL (operands[2]));
5275           return "sub{q}\t{%2, %0|%0, %2}";
5276         }
5277       return "add{q}\t{%2, %0|%0, %2}";
5278     }
5279 }
5280   [(set (attr "type")
5281      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282         (const_string "incdec")
5283         (const_string "alu")))
5284    (set_attr "mode" "DI")])
5285
5286 ; For comparisons against 1, -1 and 128, we may generate better code
5287 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5288 ; is matched then.  We can't accept general immediate, because for
5289 ; case of overflows,  the result is messed up.
5290 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5291 ; when negated.
5292 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5293 ; only for comparisons not depending on it.
5294 (define_insn "*adddi_4_rex64"
5295   [(set (reg FLAGS_REG)
5296         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5297                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5298    (clobber (match_scratch:DI 0 "=rm"))]
5299   "TARGET_64BIT
5300    &&  ix86_match_ccmode (insn, CCGCmode)"
5301 {
5302   switch (get_attr_type (insn))
5303     {
5304     case TYPE_INCDEC:
5305       if (operands[2] == constm1_rtx)
5306         return "inc{q}\t%0";
5307       else
5308         {
5309           gcc_assert (operands[2] == const1_rtx);
5310           return "dec{q}\t%0";
5311         }
5312
5313     default:
5314       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5315       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5317       if ((INTVAL (operands[2]) == -128
5318            || (INTVAL (operands[2]) > 0
5319                && INTVAL (operands[2]) != 128))
5320           /* Avoid overflows.  */
5321           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5322         return "sub{q}\t{%2, %0|%0, %2}";
5323       operands[2] = GEN_INT (-INTVAL (operands[2]));
5324       return "add{q}\t{%2, %0|%0, %2}";
5325     }
5326 }
5327   [(set (attr "type")
5328      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329         (const_string "incdec")
5330         (const_string "alu")))
5331    (set_attr "mode" "DI")])
5332
5333 (define_insn "*adddi_5_rex64"
5334   [(set (reg FLAGS_REG)
5335         (compare
5336           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5337                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5338           (const_int 0)))                       
5339    (clobber (match_scratch:DI 0 "=r"))]
5340   "TARGET_64BIT
5341    && ix86_match_ccmode (insn, CCGOCmode)
5342    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5343    /* Current assemblers are broken and do not allow @GOTOFF in
5344       ought but a memory context.  */
5345    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5346 {
5347   switch (get_attr_type (insn))
5348     {
5349     case TYPE_INCDEC:
5350       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5351       if (operands[2] == const1_rtx)
5352         return "inc{q}\t%0";
5353       else
5354         {
5355           gcc_assert (operands[2] == constm1_rtx);
5356           return "dec{q}\t%0";
5357         }
5358
5359     default:
5360       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5361       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363       if (GET_CODE (operands[2]) == CONST_INT
5364           /* Avoid overflows.  */
5365           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366           && (INTVAL (operands[2]) == 128
5367               || (INTVAL (operands[2]) < 0
5368                   && INTVAL (operands[2]) != -128)))
5369         {
5370           operands[2] = GEN_INT (-INTVAL (operands[2]));
5371           return "sub{q}\t{%2, %0|%0, %2}";
5372         }
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5375 }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5381
5382
5383 (define_insn "*addsi_1"
5384   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5385         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5386                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5387    (clobber (reg:CC FLAGS_REG))]
5388   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5389 {
5390   switch (get_attr_type (insn))
5391     {
5392     case TYPE_LEA:
5393       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394       return "lea{l}\t{%a2, %0|%0, %a2}";
5395
5396     case TYPE_INCDEC:
5397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398       if (operands[2] == const1_rtx)
5399         return "inc{l}\t%0";
5400       else
5401         {
5402           gcc_assert (operands[2] == constm1_rtx);
5403           return "dec{l}\t%0";
5404         }
5405
5406     default:
5407       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5408
5409       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5411       if (GET_CODE (operands[2]) == CONST_INT
5412           && (INTVAL (operands[2]) == 128
5413               || (INTVAL (operands[2]) < 0
5414                   && INTVAL (operands[2]) != -128)))
5415         {
5416           operands[2] = GEN_INT (-INTVAL (operands[2]));
5417           return "sub{l}\t{%2, %0|%0, %2}";
5418         }
5419       return "add{l}\t{%2, %0|%0, %2}";
5420     }
5421 }
5422   [(set (attr "type")
5423      (cond [(eq_attr "alternative" "2")
5424               (const_string "lea")
5425             ; Current assemblers are broken and do not allow @GOTOFF in
5426             ; ought but a memory context.
5427             (match_operand:SI 2 "pic_symbolic_operand" "")
5428               (const_string "lea")
5429             (match_operand:SI 2 "incdec_operand" "")
5430               (const_string "incdec")
5431            ]
5432            (const_string "alu")))
5433    (set_attr "mode" "SI")])
5434
5435 ;; Convert lea to the lea pattern to avoid flags dependency.
5436 (define_split
5437   [(set (match_operand 0 "register_operand" "")
5438         (plus (match_operand 1 "register_operand" "")
5439               (match_operand 2 "nonmemory_operand" "")))
5440    (clobber (reg:CC FLAGS_REG))]
5441   "reload_completed
5442    && true_regnum (operands[0]) != true_regnum (operands[1])"
5443   [(const_int 0)]
5444 {
5445   rtx pat;
5446   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5447      may confuse gen_lowpart.  */
5448   if (GET_MODE (operands[0]) != Pmode)
5449     {
5450       operands[1] = gen_lowpart (Pmode, operands[1]);
5451       operands[2] = gen_lowpart (Pmode, operands[2]);
5452     }
5453   operands[0] = gen_lowpart (SImode, operands[0]);
5454   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5455   if (Pmode != SImode)
5456     pat = gen_rtx_SUBREG (SImode, pat, 0);
5457   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5458   DONE;
5459 })
5460
5461 ;; It may seem that nonimmediate operand is proper one for operand 1.
5462 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5463 ;; we take care in ix86_binary_operator_ok to not allow two memory
5464 ;; operands so proper swapping will be done in reload.  This allow
5465 ;; patterns constructed from addsi_1 to match.
5466 (define_insn "addsi_1_zext"
5467   [(set (match_operand:DI 0 "register_operand" "=r,r")
5468         (zero_extend:DI
5469           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5470                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5473 {
5474   switch (get_attr_type (insn))
5475     {
5476     case TYPE_LEA:
5477       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5479
5480     case TYPE_INCDEC:
5481       if (operands[2] == const1_rtx)
5482         return "inc{l}\t%k0";
5483       else
5484         {
5485           gcc_assert (operands[2] == constm1_rtx);
5486           return "dec{l}\t%k0";
5487         }
5488
5489     default:
5490       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5492       if (GET_CODE (operands[2]) == CONST_INT
5493           && (INTVAL (operands[2]) == 128
5494               || (INTVAL (operands[2]) < 0
5495                   && INTVAL (operands[2]) != -128)))
5496         {
5497           operands[2] = GEN_INT (-INTVAL (operands[2]));
5498           return "sub{l}\t{%2, %k0|%k0, %2}";
5499         }
5500       return "add{l}\t{%2, %k0|%k0, %2}";
5501     }
5502 }
5503   [(set (attr "type")
5504      (cond [(eq_attr "alternative" "1")
5505               (const_string "lea")
5506             ; Current assemblers are broken and do not allow @GOTOFF in
5507             ; ought but a memory context.
5508             (match_operand:SI 2 "pic_symbolic_operand" "")
5509               (const_string "lea")
5510             (match_operand:SI 2 "incdec_operand" "")
5511               (const_string "incdec")
5512            ]
5513            (const_string "alu")))
5514    (set_attr "mode" "SI")])
5515
5516 ;; Convert lea to the lea pattern to avoid flags dependency.
5517 (define_split
5518   [(set (match_operand:DI 0 "register_operand" "")
5519         (zero_extend:DI
5520           (plus:SI (match_operand:SI 1 "register_operand" "")
5521                    (match_operand:SI 2 "nonmemory_operand" ""))))
5522    (clobber (reg:CC FLAGS_REG))]
5523   "TARGET_64BIT && reload_completed
5524    && true_regnum (operands[0]) != true_regnum (operands[1])"
5525   [(set (match_dup 0)
5526         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5527 {
5528   operands[1] = gen_lowpart (Pmode, operands[1]);
5529   operands[2] = gen_lowpart (Pmode, operands[2]);
5530 })
5531
5532 (define_insn "*addsi_2"
5533   [(set (reg FLAGS_REG)
5534         (compare
5535           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5536                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5537           (const_int 0)))                       
5538    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5539         (plus:SI (match_dup 1) (match_dup 2)))]
5540   "ix86_match_ccmode (insn, CCGOCmode)
5541    && ix86_binary_operator_ok (PLUS, SImode, operands)
5542    /* Current assemblers are broken and do not allow @GOTOFF in
5543       ought but a memory context.  */
5544    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5545 {
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_INCDEC:
5549       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550       if (operands[2] == const1_rtx)
5551         return "inc{l}\t%0";
5552       else
5553         {
5554           gcc_assert (operands[2] == constm1_rtx);
5555           return "dec{l}\t%0";
5556         }
5557
5558     default:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5562       if (GET_CODE (operands[2]) == CONST_INT
5563           && (INTVAL (operands[2]) == 128
5564               || (INTVAL (operands[2]) < 0
5565                   && INTVAL (operands[2]) != -128)))
5566         {
5567           operands[2] = GEN_INT (-INTVAL (operands[2]));
5568           return "sub{l}\t{%2, %0|%0, %2}";
5569         }
5570       return "add{l}\t{%2, %0|%0, %2}";
5571     }
5572 }
5573   [(set (attr "type")
5574      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575         (const_string "incdec")
5576         (const_string "alu")))
5577    (set_attr "mode" "SI")])
5578
5579 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580 (define_insn "*addsi_2_zext"
5581   [(set (reg FLAGS_REG)
5582         (compare
5583           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5584                    (match_operand:SI 2 "general_operand" "rmni"))
5585           (const_int 0)))                       
5586    (set (match_operand:DI 0 "register_operand" "=r")
5587         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5588   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5589    && ix86_binary_operator_ok (PLUS, SImode, operands)
5590    /* Current assemblers are broken and do not allow @GOTOFF in
5591       ought but a memory context.  */
5592    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5593 {
5594   switch (get_attr_type (insn))
5595     {
5596     case TYPE_INCDEC:
5597       if (operands[2] == const1_rtx)
5598         return "inc{l}\t%k0";
5599       else
5600         {
5601           gcc_assert (operands[2] == constm1_rtx);
5602           return "dec{l}\t%k0";
5603         }
5604
5605     default:
5606       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5607          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5608       if (GET_CODE (operands[2]) == CONST_INT
5609           && (INTVAL (operands[2]) == 128
5610               || (INTVAL (operands[2]) < 0
5611                   && INTVAL (operands[2]) != -128)))
5612         {
5613           operands[2] = GEN_INT (-INTVAL (operands[2]));
5614           return "sub{l}\t{%2, %k0|%k0, %2}";
5615         }
5616       return "add{l}\t{%2, %k0|%k0, %2}";
5617     }
5618 }
5619   [(set (attr "type")
5620      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5621         (const_string "incdec")
5622         (const_string "alu")))
5623    (set_attr "mode" "SI")])
5624
5625 (define_insn "*addsi_3"
5626   [(set (reg FLAGS_REG)
5627         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5628                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5629    (clobber (match_scratch:SI 0 "=r"))]
5630   "ix86_match_ccmode (insn, CCZmode)
5631    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5632    /* Current assemblers are broken and do not allow @GOTOFF in
5633       ought but a memory context.  */
5634    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5635 {
5636   switch (get_attr_type (insn))
5637     {
5638     case TYPE_INCDEC:
5639       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640       if (operands[2] == const1_rtx)
5641         return "inc{l}\t%0";
5642       else
5643         {
5644           gcc_assert (operands[2] == constm1_rtx);
5645           return "dec{l}\t%0";
5646         }
5647
5648     default:
5649       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5650       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5651          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5652       if (GET_CODE (operands[2]) == CONST_INT
5653           && (INTVAL (operands[2]) == 128
5654               || (INTVAL (operands[2]) < 0
5655                   && INTVAL (operands[2]) != -128)))
5656         {
5657           operands[2] = GEN_INT (-INTVAL (operands[2]));
5658           return "sub{l}\t{%2, %0|%0, %2}";
5659         }
5660       return "add{l}\t{%2, %0|%0, %2}";
5661     }
5662 }
5663   [(set (attr "type")
5664      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5665         (const_string "incdec")
5666         (const_string "alu")))
5667    (set_attr "mode" "SI")])
5668
5669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5670 (define_insn "*addsi_3_zext"
5671   [(set (reg FLAGS_REG)
5672         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5673                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5674    (set (match_operand:DI 0 "register_operand" "=r")
5675         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5676   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5677    && ix86_binary_operator_ok (PLUS, SImode, operands)
5678    /* Current assemblers are broken and do not allow @GOTOFF in
5679       ought but a memory context.  */
5680    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5681 {
5682   switch (get_attr_type (insn))
5683     {
5684     case TYPE_INCDEC:
5685       if (operands[2] == const1_rtx)
5686         return "inc{l}\t%k0";
5687       else
5688         {
5689           gcc_assert (operands[2] == constm1_rtx);
5690           return "dec{l}\t%k0";
5691         }
5692
5693     default:
5694       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5695          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5696       if (GET_CODE (operands[2]) == CONST_INT
5697           && (INTVAL (operands[2]) == 128
5698               || (INTVAL (operands[2]) < 0
5699                   && INTVAL (operands[2]) != -128)))
5700         {
5701           operands[2] = GEN_INT (-INTVAL (operands[2]));
5702           return "sub{l}\t{%2, %k0|%k0, %2}";
5703         }
5704       return "add{l}\t{%2, %k0|%k0, %2}";
5705     }
5706 }
5707   [(set (attr "type")
5708      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5709         (const_string "incdec")
5710         (const_string "alu")))
5711    (set_attr "mode" "SI")])
5712
5713 ; For comparisons against 1, -1 and 128, we may generate better code
5714 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5715 ; is matched then.  We can't accept general immediate, because for
5716 ; case of overflows,  the result is messed up.
5717 ; This pattern also don't hold of 0x80000000, since the value overflows
5718 ; when negated.
5719 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5720 ; only for comparisons not depending on it.
5721 (define_insn "*addsi_4"
5722   [(set (reg FLAGS_REG)
5723         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5724                  (match_operand:SI 2 "const_int_operand" "n")))
5725    (clobber (match_scratch:SI 0 "=rm"))]
5726   "ix86_match_ccmode (insn, CCGCmode)
5727    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5728 {
5729   switch (get_attr_type (insn))
5730     {
5731     case TYPE_INCDEC:
5732       if (operands[2] == constm1_rtx)
5733         return "inc{l}\t%0";
5734       else
5735         {
5736           gcc_assert (operands[2] == const1_rtx);
5737           return "dec{l}\t%0";
5738         }
5739
5740     default:
5741       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5742       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5744       if ((INTVAL (operands[2]) == -128
5745            || (INTVAL (operands[2]) > 0
5746                && INTVAL (operands[2]) != 128)))
5747         return "sub{l}\t{%2, %0|%0, %2}";
5748       operands[2] = GEN_INT (-INTVAL (operands[2]));
5749       return "add{l}\t{%2, %0|%0, %2}";
5750     }
5751 }
5752   [(set (attr "type")
5753      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5754         (const_string "incdec")
5755         (const_string "alu")))
5756    (set_attr "mode" "SI")])
5757
5758 (define_insn "*addsi_5"
5759   [(set (reg FLAGS_REG)
5760         (compare
5761           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5762                    (match_operand:SI 2 "general_operand" "rmni"))
5763           (const_int 0)))                       
5764    (clobber (match_scratch:SI 0 "=r"))]
5765   "ix86_match_ccmode (insn, CCGOCmode)
5766    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5767    /* Current assemblers are broken and do not allow @GOTOFF in
5768       ought but a memory context.  */
5769    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5770 {
5771   switch (get_attr_type (insn))
5772     {
5773     case TYPE_INCDEC:
5774       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775       if (operands[2] == const1_rtx)
5776         return "inc{l}\t%0";
5777       else
5778         {
5779           gcc_assert (operands[2] == constm1_rtx);
5780           return "dec{l}\t%0";
5781         }
5782
5783     default:
5784       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5786          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5787       if (GET_CODE (operands[2]) == CONST_INT
5788           && (INTVAL (operands[2]) == 128
5789               || (INTVAL (operands[2]) < 0
5790                   && INTVAL (operands[2]) != -128)))
5791         {
5792           operands[2] = GEN_INT (-INTVAL (operands[2]));
5793           return "sub{l}\t{%2, %0|%0, %2}";
5794         }
5795       return "add{l}\t{%2, %0|%0, %2}";
5796     }
5797 }
5798   [(set (attr "type")
5799      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5800         (const_string "incdec")
5801         (const_string "alu")))
5802    (set_attr "mode" "SI")])
5803
5804 (define_expand "addhi3"
5805   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5806                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5807                             (match_operand:HI 2 "general_operand" "")))
5808               (clobber (reg:CC FLAGS_REG))])]
5809   "TARGET_HIMODE_MATH"
5810   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5811
5812 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5813 ;; type optimizations enabled by define-splits.  This is not important
5814 ;; for PII, and in fact harmful because of partial register stalls.
5815
5816 (define_insn "*addhi_1_lea"
5817   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5818         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5819                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5820    (clobber (reg:CC FLAGS_REG))]
5821   "!TARGET_PARTIAL_REG_STALL
5822    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5823 {
5824   switch (get_attr_type (insn))
5825     {
5826     case TYPE_LEA:
5827       return "#";
5828     case TYPE_INCDEC:
5829       if (operands[2] == const1_rtx)
5830         return "inc{w}\t%0";
5831       else
5832         {
5833           gcc_assert (operands[2] == constm1_rtx);
5834           return "dec{w}\t%0";
5835         }
5836
5837     default:
5838       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5840       if (GET_CODE (operands[2]) == CONST_INT
5841           && (INTVAL (operands[2]) == 128
5842               || (INTVAL (operands[2]) < 0
5843                   && INTVAL (operands[2]) != -128)))
5844         {
5845           operands[2] = GEN_INT (-INTVAL (operands[2]));
5846           return "sub{w}\t{%2, %0|%0, %2}";
5847         }
5848       return "add{w}\t{%2, %0|%0, %2}";
5849     }
5850 }
5851   [(set (attr "type")
5852      (if_then_else (eq_attr "alternative" "2")
5853         (const_string "lea")
5854         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855            (const_string "incdec")
5856            (const_string "alu"))))
5857    (set_attr "mode" "HI,HI,SI")])
5858
5859 (define_insn "*addhi_1"
5860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5861         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5862                  (match_operand:HI 2 "general_operand" "ri,rm")))
5863    (clobber (reg:CC FLAGS_REG))]
5864   "TARGET_PARTIAL_REG_STALL
5865    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5866 {
5867   switch (get_attr_type (insn))
5868     {
5869     case TYPE_INCDEC:
5870       if (operands[2] == const1_rtx)
5871         return "inc{w}\t%0";
5872       else
5873         {
5874           gcc_assert (operands[2] == constm1_rtx);
5875           return "dec{w}\t%0";
5876         }
5877
5878     default:
5879       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881       if (GET_CODE (operands[2]) == CONST_INT
5882           && (INTVAL (operands[2]) == 128
5883               || (INTVAL (operands[2]) < 0
5884                   && INTVAL (operands[2]) != -128)))
5885         {
5886           operands[2] = GEN_INT (-INTVAL (operands[2]));
5887           return "sub{w}\t{%2, %0|%0, %2}";
5888         }
5889       return "add{w}\t{%2, %0|%0, %2}";
5890     }
5891 }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set_attr "mode" "HI")])
5897
5898 (define_insn "*addhi_2"
5899   [(set (reg FLAGS_REG)
5900         (compare
5901           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5902                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5903           (const_int 0)))                       
5904    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5905         (plus:HI (match_dup 1) (match_dup 2)))]
5906   "ix86_match_ccmode (insn, CCGOCmode)
5907    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5908 {
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{w}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{w}\t%0";
5918         }
5919
5920     default:
5921       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923       if (GET_CODE (operands[2]) == CONST_INT
5924           && (INTVAL (operands[2]) == 128
5925               || (INTVAL (operands[2]) < 0
5926                   && INTVAL (operands[2]) != -128)))
5927         {
5928           operands[2] = GEN_INT (-INTVAL (operands[2]));
5929           return "sub{w}\t{%2, %0|%0, %2}";
5930         }
5931       return "add{w}\t{%2, %0|%0, %2}";
5932     }
5933 }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936         (const_string "incdec")
5937         (const_string "alu")))
5938    (set_attr "mode" "HI")])
5939
5940 (define_insn "*addhi_3"
5941   [(set (reg FLAGS_REG)
5942         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5943                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5944    (clobber (match_scratch:HI 0 "=r"))]
5945   "ix86_match_ccmode (insn, CCZmode)
5946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5947 {
5948   switch (get_attr_type (insn))
5949     {
5950     case TYPE_INCDEC:
5951       if (operands[2] == const1_rtx)
5952         return "inc{w}\t%0";
5953       else
5954         {
5955           gcc_assert (operands[2] == constm1_rtx);
5956           return "dec{w}\t%0";
5957         }
5958
5959     default:
5960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962       if (GET_CODE (operands[2]) == CONST_INT
5963           && (INTVAL (operands[2]) == 128
5964               || (INTVAL (operands[2]) < 0
5965                   && INTVAL (operands[2]) != -128)))
5966         {
5967           operands[2] = GEN_INT (-INTVAL (operands[2]));
5968           return "sub{w}\t{%2, %0|%0, %2}";
5969         }
5970       return "add{w}\t{%2, %0|%0, %2}";
5971     }
5972 }
5973   [(set (attr "type")
5974      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975         (const_string "incdec")
5976         (const_string "alu")))
5977    (set_attr "mode" "HI")])
5978
5979 ; See comments above addsi_4 for details.
5980 (define_insn "*addhi_4"
5981   [(set (reg FLAGS_REG)
5982         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5983                  (match_operand:HI 2 "const_int_operand" "n")))
5984    (clobber (match_scratch:HI 0 "=rm"))]
5985   "ix86_match_ccmode (insn, CCGCmode)
5986    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5987 {
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_INCDEC:
5991       if (operands[2] == constm1_rtx)
5992         return "inc{w}\t%0";
5993       else
5994         {
5995           gcc_assert (operands[2] == const1_rtx);
5996           return "dec{w}\t%0";
5997         }
5998
5999     default:
6000       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if ((INTVAL (operands[2]) == -128
6004            || (INTVAL (operands[2]) > 0
6005                && INTVAL (operands[2]) != 128)))
6006         return "sub{w}\t{%2, %0|%0, %2}";
6007       operands[2] = GEN_INT (-INTVAL (operands[2]));
6008       return "add{w}\t{%2, %0|%0, %2}";
6009     }
6010 }
6011   [(set (attr "type")
6012      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6013         (const_string "incdec")
6014         (const_string "alu")))
6015    (set_attr "mode" "SI")])
6016
6017
6018 (define_insn "*addhi_5"
6019   [(set (reg FLAGS_REG)
6020         (compare
6021           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6022                    (match_operand:HI 2 "general_operand" "rmni"))
6023           (const_int 0)))                       
6024    (clobber (match_scratch:HI 0 "=r"))]
6025   "ix86_match_ccmode (insn, CCGOCmode)
6026    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6027 {
6028   switch (get_attr_type (insn))
6029     {
6030     case TYPE_INCDEC:
6031       if (operands[2] == const1_rtx)
6032         return "inc{w}\t%0";
6033       else
6034         {
6035           gcc_assert (operands[2] == constm1_rtx);
6036           return "dec{w}\t%0";
6037         }
6038
6039     default:
6040       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6041          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6042       if (GET_CODE (operands[2]) == CONST_INT
6043           && (INTVAL (operands[2]) == 128
6044               || (INTVAL (operands[2]) < 0
6045                   && INTVAL (operands[2]) != -128)))
6046         {
6047           operands[2] = GEN_INT (-INTVAL (operands[2]));
6048           return "sub{w}\t{%2, %0|%0, %2}";
6049         }
6050       return "add{w}\t{%2, %0|%0, %2}";
6051     }
6052 }
6053   [(set (attr "type")
6054      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6055         (const_string "incdec")
6056         (const_string "alu")))
6057    (set_attr "mode" "HI")])
6058
6059 (define_expand "addqi3"
6060   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6061                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6062                             (match_operand:QI 2 "general_operand" "")))
6063               (clobber (reg:CC FLAGS_REG))])]
6064   "TARGET_QIMODE_MATH"
6065   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6066
6067 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6068 (define_insn "*addqi_1_lea"
6069   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6070         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6071                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6072    (clobber (reg:CC FLAGS_REG))]
6073   "!TARGET_PARTIAL_REG_STALL
6074    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6075 {
6076   int widen = (which_alternative == 2);
6077   switch (get_attr_type (insn))
6078     {
6079     case TYPE_LEA:
6080       return "#";
6081     case TYPE_INCDEC:
6082       if (operands[2] == const1_rtx)
6083         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6084       else
6085         {
6086           gcc_assert (operands[2] == constm1_rtx);
6087           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6088         }
6089
6090     default:
6091       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6093       if (GET_CODE (operands[2]) == CONST_INT
6094           && (INTVAL (operands[2]) == 128
6095               || (INTVAL (operands[2]) < 0
6096                   && INTVAL (operands[2]) != -128)))
6097         {
6098           operands[2] = GEN_INT (-INTVAL (operands[2]));
6099           if (widen)
6100             return "sub{l}\t{%2, %k0|%k0, %2}";
6101           else
6102             return "sub{b}\t{%2, %0|%0, %2}";
6103         }
6104       if (widen)
6105         return "add{l}\t{%k2, %k0|%k0, %k2}";
6106       else
6107         return "add{b}\t{%2, %0|%0, %2}";
6108     }
6109 }
6110   [(set (attr "type")
6111      (if_then_else (eq_attr "alternative" "3")
6112         (const_string "lea")
6113         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114            (const_string "incdec")
6115            (const_string "alu"))))
6116    (set_attr "mode" "QI,QI,SI,SI")])
6117
6118 (define_insn "*addqi_1"
6119   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6120         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6121                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6122    (clobber (reg:CC FLAGS_REG))]
6123   "TARGET_PARTIAL_REG_STALL
6124    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125 {
6126   int widen = (which_alternative == 2);
6127   switch (get_attr_type (insn))
6128     {
6129     case TYPE_INCDEC:
6130       if (operands[2] == const1_rtx)
6131         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6132       else
6133         {
6134           gcc_assert (operands[2] == constm1_rtx);
6135           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6136         }
6137
6138     default:
6139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6141       if (GET_CODE (operands[2]) == CONST_INT
6142           && (INTVAL (operands[2]) == 128
6143               || (INTVAL (operands[2]) < 0
6144                   && INTVAL (operands[2]) != -128)))
6145         {
6146           operands[2] = GEN_INT (-INTVAL (operands[2]));
6147           if (widen)
6148             return "sub{l}\t{%2, %k0|%k0, %2}";
6149           else
6150             return "sub{b}\t{%2, %0|%0, %2}";
6151         }
6152       if (widen)
6153         return "add{l}\t{%k2, %k0|%k0, %k2}";
6154       else
6155         return "add{b}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6160         (const_string "incdec")
6161         (const_string "alu")))
6162    (set_attr "mode" "QI,QI,SI")])
6163
6164 (define_insn "*addqi_1_slp"
6165   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6166         (plus:QI (match_dup 0)
6167                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6168    (clobber (reg:CC FLAGS_REG))]
6169   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6170    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6171 {
6172   switch (get_attr_type (insn))
6173     {
6174     case TYPE_INCDEC:
6175       if (operands[1] == const1_rtx)
6176         return "inc{b}\t%0";
6177       else
6178         {
6179           gcc_assert (operands[1] == constm1_rtx);
6180           return "dec{b}\t%0";
6181         }
6182
6183     default:
6184       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6185       if (GET_CODE (operands[1]) == CONST_INT
6186           && INTVAL (operands[1]) < 0)
6187         {
6188           operands[1] = GEN_INT (-INTVAL (operands[1]));
6189           return "sub{b}\t{%1, %0|%0, %1}";
6190         }
6191       return "add{b}\t{%1, %0|%0, %1}";
6192     }
6193 }
6194   [(set (attr "type")
6195      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6196         (const_string "incdec")
6197         (const_string "alu1")))
6198    (set (attr "memory")
6199      (if_then_else (match_operand 1 "memory_operand" "")
6200         (const_string "load")
6201         (const_string "none")))
6202    (set_attr "mode" "QI")])
6203
6204 (define_insn "*addqi_2"
6205   [(set (reg FLAGS_REG)
6206         (compare
6207           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6208                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6209           (const_int 0)))
6210    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6211         (plus:QI (match_dup 1) (match_dup 2)))]
6212   "ix86_match_ccmode (insn, CCGOCmode)
6213    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6214 {
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_INCDEC:
6218       if (operands[2] == const1_rtx)
6219         return "inc{b}\t%0";
6220       else
6221         {
6222           gcc_assert (operands[2] == constm1_rtx
6223                       || (GET_CODE (operands[2]) == CONST_INT
6224                           && INTVAL (operands[2]) == 255));
6225           return "dec{b}\t%0";
6226         }
6227
6228     default:
6229       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6230       if (GET_CODE (operands[2]) == CONST_INT
6231           && INTVAL (operands[2]) < 0)
6232         {
6233           operands[2] = GEN_INT (-INTVAL (operands[2]));
6234           return "sub{b}\t{%2, %0|%0, %2}";
6235         }
6236       return "add{b}\t{%2, %0|%0, %2}";
6237     }
6238 }
6239   [(set (attr "type")
6240      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241         (const_string "incdec")
6242         (const_string "alu")))
6243    (set_attr "mode" "QI")])
6244
6245 (define_insn "*addqi_3"
6246   [(set (reg FLAGS_REG)
6247         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6248                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6249    (clobber (match_scratch:QI 0 "=q"))]
6250   "ix86_match_ccmode (insn, CCZmode)
6251    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == const1_rtx)
6257         return "inc{b}\t%0";
6258       else
6259         {
6260           gcc_assert (operands[2] == constm1_rtx
6261                       || (GET_CODE (operands[2]) == CONST_INT
6262                           && INTVAL (operands[2]) == 255));
6263           return "dec{b}\t%0";
6264         }
6265
6266     default:
6267       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6268       if (GET_CODE (operands[2]) == CONST_INT
6269           && INTVAL (operands[2]) < 0)
6270         {
6271           operands[2] = GEN_INT (-INTVAL (operands[2]));
6272           return "sub{b}\t{%2, %0|%0, %2}";
6273         }
6274       return "add{b}\t{%2, %0|%0, %2}";
6275     }
6276 }
6277   [(set (attr "type")
6278      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279         (const_string "incdec")
6280         (const_string "alu")))
6281    (set_attr "mode" "QI")])
6282
6283 ; See comments above addsi_4 for details.
6284 (define_insn "*addqi_4"
6285   [(set (reg FLAGS_REG)
6286         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6287                  (match_operand:QI 2 "const_int_operand" "n")))
6288    (clobber (match_scratch:QI 0 "=qm"))]
6289   "ix86_match_ccmode (insn, CCGCmode)
6290    && (INTVAL (operands[2]) & 0xff) != 0x80"
6291 {
6292   switch (get_attr_type (insn))
6293     {
6294     case TYPE_INCDEC:
6295       if (operands[2] == constm1_rtx
6296           || (GET_CODE (operands[2]) == CONST_INT
6297               && INTVAL (operands[2]) == 255))
6298         return "inc{b}\t%0";
6299       else
6300         {
6301           gcc_assert (operands[2] == const1_rtx);
6302           return "dec{b}\t%0";
6303         }
6304
6305     default:
6306       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6307       if (INTVAL (operands[2]) < 0)
6308         {
6309           operands[2] = GEN_INT (-INTVAL (operands[2]));
6310           return "add{b}\t{%2, %0|%0, %2}";
6311         }
6312       return "sub{b}\t{%2, %0|%0, %2}";
6313     }
6314 }
6315   [(set (attr "type")
6316      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6317         (const_string "incdec")
6318         (const_string "alu")))
6319    (set_attr "mode" "QI")])
6320
6321
6322 (define_insn "*addqi_5"
6323   [(set (reg FLAGS_REG)
6324         (compare
6325           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6326                    (match_operand:QI 2 "general_operand" "qmni"))
6327           (const_int 0)))
6328    (clobber (match_scratch:QI 0 "=q"))]
6329   "ix86_match_ccmode (insn, CCGOCmode)
6330    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6331 {
6332   switch (get_attr_type (insn))
6333     {
6334     case TYPE_INCDEC:
6335       if (operands[2] == const1_rtx)
6336         return "inc{b}\t%0";
6337       else
6338         {
6339           gcc_assert (operands[2] == constm1_rtx
6340                       || (GET_CODE (operands[2]) == CONST_INT
6341                           && INTVAL (operands[2]) == 255));
6342           return "dec{b}\t%0";
6343         }
6344
6345     default:
6346       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6347       if (GET_CODE (operands[2]) == CONST_INT
6348           && INTVAL (operands[2]) < 0)
6349         {
6350           operands[2] = GEN_INT (-INTVAL (operands[2]));
6351           return "sub{b}\t{%2, %0|%0, %2}";
6352         }
6353       return "add{b}\t{%2, %0|%0, %2}";
6354     }
6355 }
6356   [(set (attr "type")
6357      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6358         (const_string "incdec")
6359         (const_string "alu")))
6360    (set_attr "mode" "QI")])
6361
6362
6363 (define_insn "addqi_ext_1"
6364   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6365                          (const_int 8)
6366                          (const_int 8))
6367         (plus:SI
6368           (zero_extract:SI
6369             (match_operand 1 "ext_register_operand" "0")
6370             (const_int 8)
6371             (const_int 8))
6372           (match_operand:QI 2 "general_operand" "Qmn")))
6373    (clobber (reg:CC FLAGS_REG))]
6374   "!TARGET_64BIT"
6375 {
6376   switch (get_attr_type (insn))
6377     {
6378     case TYPE_INCDEC:
6379       if (operands[2] == const1_rtx)
6380         return "inc{b}\t%h0";
6381       else
6382         {
6383           gcc_assert (operands[2] == constm1_rtx
6384                       || (GET_CODE (operands[2]) == CONST_INT
6385                           && INTVAL (operands[2]) == 255));
6386           return "dec{b}\t%h0";
6387         }
6388
6389     default:
6390       return "add{b}\t{%2, %h0|%h0, %2}";
6391     }
6392 }
6393   [(set (attr "type")
6394      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6395         (const_string "incdec")
6396         (const_string "alu")))
6397    (set_attr "mode" "QI")])
6398
6399 (define_insn "*addqi_ext_1_rex64"
6400   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401                          (const_int 8)
6402                          (const_int 8))
6403         (plus:SI
6404           (zero_extract:SI
6405             (match_operand 1 "ext_register_operand" "0")
6406             (const_int 8)
6407             (const_int 8))
6408           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6409    (clobber (reg:CC FLAGS_REG))]
6410   "TARGET_64BIT"
6411 {
6412   switch (get_attr_type (insn))
6413     {
6414     case TYPE_INCDEC:
6415       if (operands[2] == const1_rtx)
6416         return "inc{b}\t%h0";
6417       else
6418         {
6419           gcc_assert (operands[2] == constm1_rtx
6420                       || (GET_CODE (operands[2]) == CONST_INT
6421                           && INTVAL (operands[2]) == 255));
6422           return "dec{b}\t%h0";
6423         }
6424
6425     default:
6426       return "add{b}\t{%2, %h0|%h0, %2}";
6427     }
6428 }
6429   [(set (attr "type")
6430      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6431         (const_string "incdec")
6432         (const_string "alu")))
6433    (set_attr "mode" "QI")])
6434
6435 (define_insn "*addqi_ext_2"
6436   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437                          (const_int 8)
6438                          (const_int 8))
6439         (plus:SI
6440           (zero_extract:SI
6441             (match_operand 1 "ext_register_operand" "%0")
6442             (const_int 8)
6443             (const_int 8))
6444           (zero_extract:SI
6445             (match_operand 2 "ext_register_operand" "Q")
6446             (const_int 8)
6447             (const_int 8))))
6448    (clobber (reg:CC FLAGS_REG))]
6449   ""
6450   "add{b}\t{%h2, %h0|%h0, %h2}"
6451   [(set_attr "type" "alu")
6452    (set_attr "mode" "QI")])
6453
6454 ;; The patterns that match these are at the end of this file.
6455
6456 (define_expand "addxf3"
6457   [(set (match_operand:XF 0 "register_operand" "")
6458         (plus:XF (match_operand:XF 1 "register_operand" "")
6459                  (match_operand:XF 2 "register_operand" "")))]
6460   "TARGET_80387"
6461   "")
6462
6463 (define_expand "adddf3"
6464   [(set (match_operand:DF 0 "register_operand" "")
6465         (plus:DF (match_operand:DF 1 "register_operand" "")
6466                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6467   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6468   "")
6469
6470 (define_expand "addsf3"
6471   [(set (match_operand:SF 0 "register_operand" "")
6472         (plus:SF (match_operand:SF 1 "register_operand" "")
6473                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6474   "TARGET_80387 || TARGET_SSE_MATH"
6475   "")
6476 \f
6477 ;; Subtract instructions
6478
6479 ;; %%% splits for subditi3
6480
6481 (define_expand "subti3"
6482   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6483                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6484                              (match_operand:TI 2 "x86_64_general_operand" "")))
6485               (clobber (reg:CC FLAGS_REG))])]
6486   "TARGET_64BIT"
6487   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6488
6489 (define_insn "*subti3_1"
6490   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6491         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6492                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6495   "#")
6496
6497 (define_split
6498   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6499         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6500                   (match_operand:TI 2 "x86_64_general_operand" "")))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "TARGET_64BIT && reload_completed"
6503   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6505    (parallel [(set (match_dup 3)
6506                    (minus:DI (match_dup 4)
6507                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6508                                       (match_dup 5))))
6509               (clobber (reg:CC FLAGS_REG))])]
6510   "split_ti (operands+0, 1, operands+0, operands+3);
6511    split_ti (operands+1, 1, operands+1, operands+4);
6512    split_ti (operands+2, 1, operands+2, operands+5);")
6513
6514 ;; %%% splits for subsidi3
6515
6516 (define_expand "subdi3"
6517   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6518                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6519                              (match_operand:DI 2 "x86_64_general_operand" "")))
6520               (clobber (reg:CC FLAGS_REG))])]
6521   ""
6522   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6523
6524 (define_insn "*subdi3_1"
6525   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6526         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6527                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6528    (clobber (reg:CC FLAGS_REG))]
6529   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6530   "#")
6531
6532 (define_split
6533   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6534         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6535                   (match_operand:DI 2 "general_operand" "")))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "!TARGET_64BIT && reload_completed"
6538   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6539               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6540    (parallel [(set (match_dup 3)
6541                    (minus:SI (match_dup 4)
6542                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6543                                       (match_dup 5))))
6544               (clobber (reg:CC FLAGS_REG))])]
6545   "split_di (operands+0, 1, operands+0, operands+3);
6546    split_di (operands+1, 1, operands+1, operands+4);
6547    split_di (operands+2, 1, operands+2, operands+5);")
6548
6549 (define_insn "subdi3_carry_rex64"
6550   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6552             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6553                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6554    (clobber (reg:CC FLAGS_REG))]
6555   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6556   "sbb{q}\t{%2, %0|%0, %2}"
6557   [(set_attr "type" "alu")
6558    (set_attr "pent_pair" "pu")
6559    (set_attr "mode" "DI")])
6560
6561 (define_insn "*subdi_1_rex64"
6562   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6563         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6564                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6565    (clobber (reg:CC FLAGS_REG))]
6566   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567   "sub{q}\t{%2, %0|%0, %2}"
6568   [(set_attr "type" "alu")
6569    (set_attr "mode" "DI")])
6570
6571 (define_insn "*subdi_2_rex64"
6572   [(set (reg FLAGS_REG)
6573         (compare
6574           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6576           (const_int 0)))
6577    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6578         (minus:DI (match_dup 1) (match_dup 2)))]
6579   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6580    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6581   "sub{q}\t{%2, %0|%0, %2}"
6582   [(set_attr "type" "alu")
6583    (set_attr "mode" "DI")])
6584
6585 (define_insn "*subdi_3_rex63"
6586   [(set (reg FLAGS_REG)
6587         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6589    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6590         (minus:DI (match_dup 1) (match_dup 2)))]
6591   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6592    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6593   "sub{q}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "alu")
6595    (set_attr "mode" "DI")])
6596
6597 (define_insn "subqi3_carry"
6598   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6599           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6600             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6601                (match_operand:QI 2 "general_operand" "qi,qm"))))
6602    (clobber (reg:CC FLAGS_REG))]
6603   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6604   "sbb{b}\t{%2, %0|%0, %2}"
6605   [(set_attr "type" "alu")
6606    (set_attr "pent_pair" "pu")
6607    (set_attr "mode" "QI")])
6608
6609 (define_insn "subhi3_carry"
6610   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6611           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6612             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6613                (match_operand:HI 2 "general_operand" "ri,rm"))))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6616   "sbb{w}\t{%2, %0|%0, %2}"
6617   [(set_attr "type" "alu")
6618    (set_attr "pent_pair" "pu")
6619    (set_attr "mode" "HI")])
6620
6621 (define_insn "subsi3_carry"
6622   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6623           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6624             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6625                (match_operand:SI 2 "general_operand" "ri,rm"))))
6626    (clobber (reg:CC FLAGS_REG))]
6627   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6628   "sbb{l}\t{%2, %0|%0, %2}"
6629   [(set_attr "type" "alu")
6630    (set_attr "pent_pair" "pu")
6631    (set_attr "mode" "SI")])
6632
6633 (define_insn "subsi3_carry_zext"
6634   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6635           (zero_extend:DI
6636             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6637               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6639    (clobber (reg:CC FLAGS_REG))]
6640   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641   "sbb{l}\t{%2, %k0|%k0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "pent_pair" "pu")
6644    (set_attr "mode" "SI")])
6645
6646 (define_expand "subsi3"
6647   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649                              (match_operand:SI 2 "general_operand" "")))
6650               (clobber (reg:CC FLAGS_REG))])]
6651   ""
6652   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6653
6654 (define_insn "*subsi_1"
6655   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6656         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6657                   (match_operand:SI 2 "general_operand" "ri,rm")))
6658    (clobber (reg:CC FLAGS_REG))]
6659   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6660   "sub{l}\t{%2, %0|%0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "mode" "SI")])
6663
6664 (define_insn "*subsi_1_zext"
6665   [(set (match_operand:DI 0 "register_operand" "=r")
6666         (zero_extend:DI
6667           (minus:SI (match_operand:SI 1 "register_operand" "0")
6668                     (match_operand:SI 2 "general_operand" "rim"))))
6669    (clobber (reg:CC FLAGS_REG))]
6670   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6671   "sub{l}\t{%2, %k0|%k0, %2}"
6672   [(set_attr "type" "alu")
6673    (set_attr "mode" "SI")])
6674
6675 (define_insn "*subsi_2"
6676   [(set (reg FLAGS_REG)
6677         (compare
6678           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6679                     (match_operand:SI 2 "general_operand" "ri,rm"))
6680           (const_int 0)))
6681    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6682         (minus:SI (match_dup 1) (match_dup 2)))]
6683   "ix86_match_ccmode (insn, CCGOCmode)
6684    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sub{l}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "SI")])
6688
6689 (define_insn "*subsi_2_zext"
6690   [(set (reg FLAGS_REG)
6691         (compare
6692           (minus:SI (match_operand:SI 1 "register_operand" "0")
6693                     (match_operand:SI 2 "general_operand" "rim"))
6694           (const_int 0)))
6695    (set (match_operand:DI 0 "register_operand" "=r")
6696         (zero_extend:DI
6697           (minus:SI (match_dup 1)
6698                     (match_dup 2))))]
6699   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6700    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6701   "sub{l}\t{%2, %k0|%k0, %2}"
6702   [(set_attr "type" "alu")
6703    (set_attr "mode" "SI")])
6704
6705 (define_insn "*subsi_3"
6706   [(set (reg FLAGS_REG)
6707         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708                  (match_operand:SI 2 "general_operand" "ri,rm")))
6709    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6710         (minus:SI (match_dup 1) (match_dup 2)))]
6711   "ix86_match_ccmode (insn, CCmode)
6712    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6713   "sub{l}\t{%2, %0|%0, %2}"
6714   [(set_attr "type" "alu")
6715    (set_attr "mode" "SI")])
6716
6717 (define_insn "*subsi_3_zext"
6718   [(set (reg FLAGS_REG)
6719         (compare (match_operand:SI 1 "register_operand" "0")
6720                  (match_operand:SI 2 "general_operand" "rim")))
6721    (set (match_operand:DI 0 "register_operand" "=r")
6722         (zero_extend:DI
6723           (minus:SI (match_dup 1)
6724                     (match_dup 2))))]
6725   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6726    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727   "sub{l}\t{%2, %1|%1, %2}"
6728   [(set_attr "type" "alu")
6729    (set_attr "mode" "DI")])
6730
6731 (define_expand "subhi3"
6732   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6733                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6734                              (match_operand:HI 2 "general_operand" "")))
6735               (clobber (reg:CC FLAGS_REG))])]
6736   "TARGET_HIMODE_MATH"
6737   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6738
6739 (define_insn "*subhi_1"
6740   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6741         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6742                   (match_operand:HI 2 "general_operand" "ri,rm")))
6743    (clobber (reg:CC FLAGS_REG))]
6744   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6745   "sub{w}\t{%2, %0|%0, %2}"
6746   [(set_attr "type" "alu")
6747    (set_attr "mode" "HI")])
6748
6749 (define_insn "*subhi_2"
6750   [(set (reg FLAGS_REG)
6751         (compare
6752           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6753                     (match_operand:HI 2 "general_operand" "ri,rm"))
6754           (const_int 0)))
6755    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756         (minus:HI (match_dup 1) (match_dup 2)))]
6757   "ix86_match_ccmode (insn, CCGOCmode)
6758    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6759   "sub{w}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "HI")])
6762
6763 (define_insn "*subhi_3"
6764   [(set (reg FLAGS_REG)
6765         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766                  (match_operand:HI 2 "general_operand" "ri,rm")))
6767    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6768         (minus:HI (match_dup 1) (match_dup 2)))]
6769   "ix86_match_ccmode (insn, CCmode)
6770    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6771   "sub{w}\t{%2, %0|%0, %2}"
6772   [(set_attr "type" "alu")
6773    (set_attr "mode" "HI")])
6774
6775 (define_expand "subqi3"
6776   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6777                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6778                              (match_operand:QI 2 "general_operand" "")))
6779               (clobber (reg:CC FLAGS_REG))])]
6780   "TARGET_QIMODE_MATH"
6781   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6782
6783 (define_insn "*subqi_1"
6784   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6785         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6787    (clobber (reg:CC FLAGS_REG))]
6788   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6789   "sub{b}\t{%2, %0|%0, %2}"
6790   [(set_attr "type" "alu")
6791    (set_attr "mode" "QI")])
6792
6793 (define_insn "*subqi_1_slp"
6794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6795         (minus:QI (match_dup 0)
6796                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6797    (clobber (reg:CC FLAGS_REG))]
6798   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6799    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6800   "sub{b}\t{%1, %0|%0, %1}"
6801   [(set_attr "type" "alu1")
6802    (set_attr "mode" "QI")])
6803
6804 (define_insn "*subqi_2"
6805   [(set (reg FLAGS_REG)
6806         (compare
6807           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6808                     (match_operand:QI 2 "general_operand" "qi,qm"))
6809           (const_int 0)))
6810    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6811         (minus:HI (match_dup 1) (match_dup 2)))]
6812   "ix86_match_ccmode (insn, CCGOCmode)
6813    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6814   "sub{b}\t{%2, %0|%0, %2}"
6815   [(set_attr "type" "alu")
6816    (set_attr "mode" "QI")])
6817
6818 (define_insn "*subqi_3"
6819   [(set (reg FLAGS_REG)
6820         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821                  (match_operand:QI 2 "general_operand" "qi,qm")))
6822    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6823         (minus:HI (match_dup 1) (match_dup 2)))]
6824   "ix86_match_ccmode (insn, CCmode)
6825    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6826   "sub{b}\t{%2, %0|%0, %2}"
6827   [(set_attr "type" "alu")
6828    (set_attr "mode" "QI")])
6829
6830 ;; The patterns that match these are at the end of this file.
6831
6832 (define_expand "subxf3"
6833   [(set (match_operand:XF 0 "register_operand" "")
6834         (minus:XF (match_operand:XF 1 "register_operand" "")
6835                   (match_operand:XF 2 "register_operand" "")))]
6836   "TARGET_80387"
6837   "")
6838
6839 (define_expand "subdf3"
6840   [(set (match_operand:DF 0 "register_operand" "")
6841         (minus:DF (match_operand:DF 1 "register_operand" "")
6842                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6843   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6844   "")
6845
6846 (define_expand "subsf3"
6847   [(set (match_operand:SF 0 "register_operand" "")
6848         (minus:SF (match_operand:SF 1 "register_operand" "")
6849                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6850   "TARGET_80387 || TARGET_SSE_MATH"
6851   "")
6852 \f
6853 ;; Multiply instructions
6854
6855 (define_expand "muldi3"
6856   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6857                    (mult:DI (match_operand:DI 1 "register_operand" "")
6858                             (match_operand:DI 2 "x86_64_general_operand" "")))
6859               (clobber (reg:CC FLAGS_REG))])]
6860   "TARGET_64BIT"
6861   "")
6862
6863 (define_insn "*muldi3_1_rex64"
6864   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6865         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6866                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6867    (clobber (reg:CC FLAGS_REG))]
6868   "TARGET_64BIT
6869    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6870   "@
6871    imul{q}\t{%2, %1, %0|%0, %1, %2}
6872    imul{q}\t{%2, %1, %0|%0, %1, %2}
6873    imul{q}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "imul")
6875    (set_attr "prefix_0f" "0,0,1")
6876    (set (attr "athlon_decode")
6877         (cond [(eq_attr "cpu" "athlon")
6878                   (const_string "vector")
6879                (eq_attr "alternative" "1")
6880                   (const_string "vector")
6881                (and (eq_attr "alternative" "2")
6882                     (match_operand 1 "memory_operand" ""))
6883                   (const_string "vector")]
6884               (const_string "direct")))
6885    (set_attr "mode" "DI")])
6886
6887 (define_expand "mulsi3"
6888   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6889                    (mult:SI (match_operand:SI 1 "register_operand" "")
6890                             (match_operand:SI 2 "general_operand" "")))
6891               (clobber (reg:CC FLAGS_REG))])]
6892   ""
6893   "")
6894
6895 (define_insn "*mulsi3_1"
6896   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6897         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6899    (clobber (reg:CC FLAGS_REG))]
6900   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6901   "@
6902    imul{l}\t{%2, %1, %0|%0, %1, %2}
6903    imul{l}\t{%2, %1, %0|%0, %1, %2}
6904    imul{l}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "imul")
6906    (set_attr "prefix_0f" "0,0,1")
6907    (set (attr "athlon_decode")
6908         (cond [(eq_attr "cpu" "athlon")
6909                   (const_string "vector")
6910                (eq_attr "alternative" "1")
6911                   (const_string "vector")
6912                (and (eq_attr "alternative" "2")
6913                     (match_operand 1 "memory_operand" ""))
6914                   (const_string "vector")]
6915               (const_string "direct")))
6916    (set_attr "mode" "SI")])
6917
6918 (define_insn "*mulsi3_1_zext"
6919   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6920         (zero_extend:DI
6921           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6922                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6923    (clobber (reg:CC FLAGS_REG))]
6924   "TARGET_64BIT
6925    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6926   "@
6927    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6928    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929    imul{l}\t{%2, %k0|%k0, %2}"
6930   [(set_attr "type" "imul")
6931    (set_attr "prefix_0f" "0,0,1")
6932    (set (attr "athlon_decode")
6933         (cond [(eq_attr "cpu" "athlon")
6934                   (const_string "vector")
6935                (eq_attr "alternative" "1")
6936                   (const_string "vector")
6937                (and (eq_attr "alternative" "2")
6938                     (match_operand 1 "memory_operand" ""))
6939                   (const_string "vector")]
6940               (const_string "direct")))
6941    (set_attr "mode" "SI")])
6942
6943 (define_expand "mulhi3"
6944   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6945                    (mult:HI (match_operand:HI 1 "register_operand" "")
6946                             (match_operand:HI 2 "general_operand" "")))
6947               (clobber (reg:CC FLAGS_REG))])]
6948   "TARGET_HIMODE_MATH"
6949   "")
6950
6951 (define_insn "*mulhi3_1"
6952   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6953         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6954                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957   "@
6958    imul{w}\t{%2, %1, %0|%0, %1, %2}
6959    imul{w}\t{%2, %1, %0|%0, %1, %2}
6960    imul{w}\t{%2, %0|%0, %2}"
6961   [(set_attr "type" "imul")
6962    (set_attr "prefix_0f" "0,0,1")
6963    (set (attr "athlon_decode")
6964         (cond [(eq_attr "cpu" "athlon")
6965                   (const_string "vector")
6966                (eq_attr "alternative" "1,2")
6967                   (const_string "vector")]
6968               (const_string "direct")))
6969    (set_attr "mode" "HI")])
6970
6971 (define_expand "mulqi3"
6972   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6973                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6974                             (match_operand:QI 2 "register_operand" "")))
6975               (clobber (reg:CC FLAGS_REG))])]
6976   "TARGET_QIMODE_MATH"
6977   "")
6978
6979 (define_insn "*mulqi3_1"
6980   [(set (match_operand:QI 0 "register_operand" "=a")
6981         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6982                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6983    (clobber (reg:CC FLAGS_REG))]
6984   "TARGET_QIMODE_MATH
6985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986   "mul{b}\t%2"
6987   [(set_attr "type" "imul")
6988    (set_attr "length_immediate" "0")
6989    (set (attr "athlon_decode")
6990      (if_then_else (eq_attr "cpu" "athlon")
6991         (const_string "vector")
6992         (const_string "direct")))
6993    (set_attr "mode" "QI")])
6994
6995 (define_expand "umulqihi3"
6996   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6997                    (mult:HI (zero_extend:HI
6998                               (match_operand:QI 1 "nonimmediate_operand" ""))
6999                             (zero_extend:HI
7000                               (match_operand:QI 2 "register_operand" ""))))
7001               (clobber (reg:CC FLAGS_REG))])]
7002   "TARGET_QIMODE_MATH"
7003   "")
7004
7005 (define_insn "*umulqihi3_1"
7006   [(set (match_operand:HI 0 "register_operand" "=a")
7007         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7009    (clobber (reg:CC FLAGS_REG))]
7010   "TARGET_QIMODE_MATH
7011    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7012   "mul{b}\t%2"
7013   [(set_attr "type" "imul")
7014    (set_attr "length_immediate" "0")
7015    (set (attr "athlon_decode")
7016      (if_then_else (eq_attr "cpu" "athlon")
7017         (const_string "vector")
7018         (const_string "direct")))
7019    (set_attr "mode" "QI")])
7020
7021 (define_expand "mulqihi3"
7022   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7024                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7025               (clobber (reg:CC FLAGS_REG))])]
7026   "TARGET_QIMODE_MATH"
7027   "")
7028
7029 (define_insn "*mulqihi3_insn"
7030   [(set (match_operand:HI 0 "register_operand" "=a")
7031         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7032                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7033    (clobber (reg:CC FLAGS_REG))]
7034   "TARGET_QIMODE_MATH
7035    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7036   "imul{b}\t%2"
7037   [(set_attr "type" "imul")
7038    (set_attr "length_immediate" "0")
7039    (set (attr "athlon_decode")
7040      (if_then_else (eq_attr "cpu" "athlon")
7041         (const_string "vector")
7042         (const_string "direct")))
7043    (set_attr "mode" "QI")])
7044
7045 (define_expand "umulditi3"
7046   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7047                    (mult:TI (zero_extend:TI
7048                               (match_operand:DI 1 "nonimmediate_operand" ""))
7049                             (zero_extend:TI
7050                               (match_operand:DI 2 "register_operand" ""))))
7051               (clobber (reg:CC FLAGS_REG))])]
7052   "TARGET_64BIT"
7053   "")
7054
7055 (define_insn "*umulditi3_insn"
7056   [(set (match_operand:TI 0 "register_operand" "=A")
7057         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7058                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7059    (clobber (reg:CC FLAGS_REG))]
7060   "TARGET_64BIT
7061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7062   "mul{q}\t%2"
7063   [(set_attr "type" "imul")
7064    (set_attr "length_immediate" "0")
7065    (set (attr "athlon_decode")
7066      (if_then_else (eq_attr "cpu" "athlon")
7067         (const_string "vector")
7068         (const_string "double")))
7069    (set_attr "mode" "DI")])
7070
7071 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7072 (define_expand "umulsidi3"
7073   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7074                    (mult:DI (zero_extend:DI
7075                               (match_operand:SI 1 "nonimmediate_operand" ""))
7076                             (zero_extend:DI
7077                               (match_operand:SI 2 "register_operand" ""))))
7078               (clobber (reg:CC FLAGS_REG))])]
7079   "!TARGET_64BIT"
7080   "")
7081
7082 (define_insn "*umulsidi3_insn"
7083   [(set (match_operand:DI 0 "register_operand" "=A")
7084         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7085                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7086    (clobber (reg:CC FLAGS_REG))]
7087   "!TARGET_64BIT
7088    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7089   "mul{l}\t%2"
7090   [(set_attr "type" "imul")
7091    (set_attr "length_immediate" "0")
7092    (set (attr "athlon_decode")
7093      (if_then_else (eq_attr "cpu" "athlon")
7094         (const_string "vector")
7095         (const_string "double")))
7096    (set_attr "mode" "SI")])
7097
7098 (define_expand "mulditi3"
7099   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7100                    (mult:TI (sign_extend:TI
7101                               (match_operand:DI 1 "nonimmediate_operand" ""))
7102                             (sign_extend:TI
7103                               (match_operand:DI 2 "register_operand" ""))))
7104               (clobber (reg:CC FLAGS_REG))])]
7105   "TARGET_64BIT"
7106   "")
7107
7108 (define_insn "*mulditi3_insn"
7109   [(set (match_operand:TI 0 "register_operand" "=A")
7110         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7111                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7112    (clobber (reg:CC FLAGS_REG))]
7113   "TARGET_64BIT
7114    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7115   "imul{q}\t%2"
7116   [(set_attr "type" "imul")
7117    (set_attr "length_immediate" "0")
7118    (set (attr "athlon_decode")
7119      (if_then_else (eq_attr "cpu" "athlon")
7120         (const_string "vector")
7121         (const_string "double")))
7122    (set_attr "mode" "DI")])
7123
7124 (define_expand "mulsidi3"
7125   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7126                    (mult:DI (sign_extend:DI
7127                               (match_operand:SI 1 "nonimmediate_operand" ""))
7128                             (sign_extend:DI
7129                               (match_operand:SI 2 "register_operand" ""))))
7130               (clobber (reg:CC FLAGS_REG))])]
7131   "!TARGET_64BIT"
7132   "")
7133
7134 (define_insn "*mulsidi3_insn"
7135   [(set (match_operand:DI 0 "register_operand" "=A")
7136         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7137                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7138    (clobber (reg:CC FLAGS_REG))]
7139   "!TARGET_64BIT
7140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7141   "imul{l}\t%2"
7142   [(set_attr "type" "imul")
7143    (set_attr "length_immediate" "0")
7144    (set (attr "athlon_decode")
7145      (if_then_else (eq_attr "cpu" "athlon")
7146         (const_string "vector")
7147         (const_string "double")))
7148    (set_attr "mode" "SI")])
7149
7150 (define_expand "umuldi3_highpart"
7151   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7152                    (truncate:DI
7153                      (lshiftrt:TI
7154                        (mult:TI (zero_extend:TI
7155                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7156                                 (zero_extend:TI
7157                                   (match_operand:DI 2 "register_operand" "")))
7158                        (const_int 64))))
7159               (clobber (match_scratch:DI 3 ""))
7160               (clobber (reg:CC FLAGS_REG))])]
7161   "TARGET_64BIT"
7162   "")
7163
7164 (define_insn "*umuldi3_highpart_rex64"
7165   [(set (match_operand:DI 0 "register_operand" "=d")
7166         (truncate:DI
7167           (lshiftrt:TI
7168             (mult:TI (zero_extend:TI
7169                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170                      (zero_extend:TI
7171                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172             (const_int 64))))
7173    (clobber (match_scratch:DI 3 "=1"))
7174    (clobber (reg:CC FLAGS_REG))]
7175   "TARGET_64BIT
7176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177   "mul{q}\t%2"
7178   [(set_attr "type" "imul")
7179    (set_attr "length_immediate" "0")
7180    (set (attr "athlon_decode")
7181      (if_then_else (eq_attr "cpu" "athlon")
7182         (const_string "vector")
7183         (const_string "double")))
7184    (set_attr "mode" "DI")])
7185
7186 (define_expand "umulsi3_highpart"
7187   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7188                    (truncate:SI
7189                      (lshiftrt:DI
7190                        (mult:DI (zero_extend:DI
7191                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7192                                 (zero_extend:DI
7193                                   (match_operand:SI 2 "register_operand" "")))
7194                        (const_int 32))))
7195               (clobber (match_scratch:SI 3 ""))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   ""
7198   "")
7199
7200 (define_insn "*umulsi3_highpart_insn"
7201   [(set (match_operand:SI 0 "register_operand" "=d")
7202         (truncate:SI
7203           (lshiftrt:DI
7204             (mult:DI (zero_extend:DI
7205                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7206                      (zero_extend:DI
7207                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7208             (const_int 32))))
7209    (clobber (match_scratch:SI 3 "=1"))
7210    (clobber (reg:CC FLAGS_REG))]
7211   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7212   "mul{l}\t%2"
7213   [(set_attr "type" "imul")
7214    (set_attr "length_immediate" "0")
7215    (set (attr "athlon_decode")
7216      (if_then_else (eq_attr "cpu" "athlon")
7217         (const_string "vector")
7218         (const_string "double")))
7219    (set_attr "mode" "SI")])
7220
7221 (define_insn "*umulsi3_highpart_zext"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (zero_extend:DI (truncate:SI
7224           (lshiftrt:DI
7225             (mult:DI (zero_extend:DI
7226                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7227                      (zero_extend:DI
7228                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7229             (const_int 32)))))
7230    (clobber (match_scratch:SI 3 "=1"))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{l}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "SI")])
7242
7243 (define_expand "smuldi3_highpart"
7244   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7245                    (truncate:DI
7246                      (lshiftrt:TI
7247                        (mult:TI (sign_extend:TI
7248                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7249                                 (sign_extend:TI
7250                                   (match_operand:DI 2 "register_operand" "")))
7251                        (const_int 64))))
7252               (clobber (match_scratch:DI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   "TARGET_64BIT"
7255   "")
7256
7257 (define_insn "*smuldi3_highpart_rex64"
7258   [(set (match_operand:DI 0 "register_operand" "=d")
7259         (truncate:DI
7260           (lshiftrt:TI
7261             (mult:TI (sign_extend:TI
7262                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7263                      (sign_extend:TI
7264                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7265             (const_int 64))))
7266    (clobber (match_scratch:DI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "TARGET_64BIT
7269    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7270   "imul{q}\t%2"
7271   [(set_attr "type" "imul")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "DI")])
7277
7278 (define_expand "smulsi3_highpart"
7279   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280                    (truncate:SI
7281                      (lshiftrt:DI
7282                        (mult:DI (sign_extend:DI
7283                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7284                                 (sign_extend:DI
7285                                   (match_operand:SI 2 "register_operand" "")))
7286                        (const_int 32))))
7287               (clobber (match_scratch:SI 3 ""))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   ""
7290   "")
7291
7292 (define_insn "*smulsi3_highpart_insn"
7293   [(set (match_operand:SI 0 "register_operand" "=d")
7294         (truncate:SI
7295           (lshiftrt:DI
7296             (mult:DI (sign_extend:DI
7297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298                      (sign_extend:DI
7299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300             (const_int 32))))
7301    (clobber (match_scratch:SI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304   "imul{l}\t%2"
7305   [(set_attr "type" "imul")
7306    (set (attr "athlon_decode")
7307      (if_then_else (eq_attr "cpu" "athlon")
7308         (const_string "vector")
7309         (const_string "double")))
7310    (set_attr "mode" "SI")])
7311
7312 (define_insn "*smulsi3_highpart_zext"
7313   [(set (match_operand:DI 0 "register_operand" "=d")
7314         (zero_extend:DI (truncate:SI
7315           (lshiftrt:DI
7316             (mult:DI (sign_extend:DI
7317                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7318                      (sign_extend:DI
7319                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7320             (const_int 32)))))
7321    (clobber (match_scratch:SI 3 "=1"))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_64BIT
7324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7325   "imul{l}\t%2"
7326   [(set_attr "type" "imul")
7327    (set (attr "athlon_decode")
7328      (if_then_else (eq_attr "cpu" "athlon")
7329         (const_string "vector")
7330         (const_string "double")))
7331    (set_attr "mode" "SI")])
7332
7333 ;; The patterns that match these are at the end of this file.
7334
7335 (define_expand "mulxf3"
7336   [(set (match_operand:XF 0 "register_operand" "")
7337         (mult:XF (match_operand:XF 1 "register_operand" "")
7338                  (match_operand:XF 2 "register_operand" "")))]
7339   "TARGET_80387"
7340   "")
7341
7342 (define_expand "muldf3"
7343   [(set (match_operand:DF 0 "register_operand" "")
7344         (mult:DF (match_operand:DF 1 "register_operand" "")
7345                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7346   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7347   "")
7348
7349 (define_expand "mulsf3"
7350   [(set (match_operand:SF 0 "register_operand" "")
7351         (mult:SF (match_operand:SF 1 "register_operand" "")
7352                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7353   "TARGET_80387 || TARGET_SSE_MATH"
7354   "")
7355 \f
7356 ;; Divide instructions
7357
7358 (define_insn "divqi3"
7359   [(set (match_operand:QI 0 "register_operand" "=a")
7360         (div:QI (match_operand:HI 1 "register_operand" "0")
7361                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "TARGET_QIMODE_MATH"
7364   "idiv{b}\t%2"
7365   [(set_attr "type" "idiv")
7366    (set_attr "mode" "QI")])
7367
7368 (define_insn "udivqi3"
7369   [(set (match_operand:QI 0 "register_operand" "=a")
7370         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7371                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7372    (clobber (reg:CC FLAGS_REG))]
7373   "TARGET_QIMODE_MATH"
7374   "div{b}\t%2"
7375   [(set_attr "type" "idiv")
7376    (set_attr "mode" "QI")])
7377
7378 ;; The patterns that match these are at the end of this file.
7379
7380 (define_expand "divxf3"
7381   [(set (match_operand:XF 0 "register_operand" "")
7382         (div:XF (match_operand:XF 1 "register_operand" "")
7383                 (match_operand:XF 2 "register_operand" "")))]
7384   "TARGET_80387"
7385   "")
7386
7387 (define_expand "divdf3"
7388   [(set (match_operand:DF 0 "register_operand" "")
7389         (div:DF (match_operand:DF 1 "register_operand" "")
7390                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7391    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7392    "")
7393  
7394 (define_expand "divsf3"
7395   [(set (match_operand:SF 0 "register_operand" "")
7396         (div:SF (match_operand:SF 1 "register_operand" "")
7397                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7398   "TARGET_80387 || TARGET_SSE_MATH"
7399   "")
7400 \f
7401 ;; Remainder instructions.
7402
7403 (define_expand "divmoddi4"
7404   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7405                    (div:DI (match_operand:DI 1 "register_operand" "")
7406                            (match_operand:DI 2 "nonimmediate_operand" "")))
7407               (set (match_operand:DI 3 "register_operand" "")
7408                    (mod:DI (match_dup 1) (match_dup 2)))
7409               (clobber (reg:CC FLAGS_REG))])]
7410   "TARGET_64BIT"
7411   "")
7412
7413 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7414 ;; Penalize eax case slightly because it results in worse scheduling
7415 ;; of code.
7416 (define_insn "*divmoddi4_nocltd_rex64"
7417   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7418         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7419                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7420    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7421         (mod:DI (match_dup 2) (match_dup 3)))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7424   "#"
7425   [(set_attr "type" "multi")])
7426
7427 (define_insn "*divmoddi4_cltd_rex64"
7428   [(set (match_operand:DI 0 "register_operand" "=a")
7429         (div:DI (match_operand:DI 2 "register_operand" "a")
7430                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7431    (set (match_operand:DI 1 "register_operand" "=&d")
7432         (mod:DI (match_dup 2) (match_dup 3)))
7433    (clobber (reg:CC FLAGS_REG))]
7434   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7435   "#"
7436   [(set_attr "type" "multi")])
7437
7438 (define_insn "*divmoddi_noext_rex64"
7439   [(set (match_operand:DI 0 "register_operand" "=a")
7440         (div:DI (match_operand:DI 1 "register_operand" "0")
7441                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7442    (set (match_operand:DI 3 "register_operand" "=d")
7443         (mod:DI (match_dup 1) (match_dup 2)))
7444    (use (match_operand:DI 4 "register_operand" "3"))
7445    (clobber (reg:CC FLAGS_REG))]
7446   "TARGET_64BIT"
7447   "idiv{q}\t%2"
7448   [(set_attr "type" "idiv")
7449    (set_attr "mode" "DI")])
7450
7451 (define_split
7452   [(set (match_operand:DI 0 "register_operand" "")
7453         (div:DI (match_operand:DI 1 "register_operand" "")
7454                 (match_operand:DI 2 "nonimmediate_operand" "")))
7455    (set (match_operand:DI 3 "register_operand" "")
7456         (mod:DI (match_dup 1) (match_dup 2)))
7457    (clobber (reg:CC FLAGS_REG))]
7458   "TARGET_64BIT && reload_completed"
7459   [(parallel [(set (match_dup 3)
7460                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7461               (clobber (reg:CC FLAGS_REG))])
7462    (parallel [(set (match_dup 0)
7463                    (div:DI (reg:DI 0) (match_dup 2)))
7464               (set (match_dup 3)
7465                    (mod:DI (reg:DI 0) (match_dup 2)))
7466               (use (match_dup 3))
7467               (clobber (reg:CC FLAGS_REG))])]
7468 {
7469   /* Avoid use of cltd in favor of a mov+shift.  */
7470   if (!TARGET_USE_CLTD && !optimize_size)
7471     {
7472       if (true_regnum (operands[1]))
7473         emit_move_insn (operands[0], operands[1]);
7474       else
7475         emit_move_insn (operands[3], operands[1]);
7476       operands[4] = operands[3];
7477     }
7478   else
7479     {
7480       gcc_assert (!true_regnum (operands[1]));
7481       operands[4] = operands[1];
7482     }
7483 })
7484
7485
7486 (define_expand "divmodsi4"
7487   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7488                    (div:SI (match_operand:SI 1 "register_operand" "")
7489                            (match_operand:SI 2 "nonimmediate_operand" "")))
7490               (set (match_operand:SI 3 "register_operand" "")
7491                    (mod:SI (match_dup 1) (match_dup 2)))
7492               (clobber (reg:CC FLAGS_REG))])]
7493   ""
7494   "")
7495
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7498 ;; of code.
7499 (define_insn "*divmodsi4_nocltd"
7500   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7501         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7502                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7503    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7504         (mod:SI (match_dup 2) (match_dup 3)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "!optimize_size && !TARGET_USE_CLTD"
7507   "#"
7508   [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmodsi4_cltd"
7511   [(set (match_operand:SI 0 "register_operand" "=a")
7512         (div:SI (match_operand:SI 2 "register_operand" "a")
7513                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7514    (set (match_operand:SI 1 "register_operand" "=&d")
7515         (mod:SI (match_dup 2) (match_dup 3)))
7516    (clobber (reg:CC FLAGS_REG))]
7517   "optimize_size || TARGET_USE_CLTD"
7518   "#"
7519   [(set_attr "type" "multi")])
7520
7521 (define_insn "*divmodsi_noext"
7522   [(set (match_operand:SI 0 "register_operand" "=a")
7523         (div:SI (match_operand:SI 1 "register_operand" "0")
7524                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7525    (set (match_operand:SI 3 "register_operand" "=d")
7526         (mod:SI (match_dup 1) (match_dup 2)))
7527    (use (match_operand:SI 4 "register_operand" "3"))
7528    (clobber (reg:CC FLAGS_REG))]
7529   ""
7530   "idiv{l}\t%2"
7531   [(set_attr "type" "idiv")
7532    (set_attr "mode" "SI")])
7533
7534 (define_split
7535   [(set (match_operand:SI 0 "register_operand" "")
7536         (div:SI (match_operand:SI 1 "register_operand" "")
7537                 (match_operand:SI 2 "nonimmediate_operand" "")))
7538    (set (match_operand:SI 3 "register_operand" "")
7539         (mod:SI (match_dup 1) (match_dup 2)))
7540    (clobber (reg:CC FLAGS_REG))]
7541   "reload_completed"
7542   [(parallel [(set (match_dup 3)
7543                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7544               (clobber (reg:CC FLAGS_REG))])
7545    (parallel [(set (match_dup 0)
7546                    (div:SI (reg:SI 0) (match_dup 2)))
7547               (set (match_dup 3)
7548                    (mod:SI (reg:SI 0) (match_dup 2)))
7549               (use (match_dup 3))
7550               (clobber (reg:CC FLAGS_REG))])]
7551 {
7552   /* Avoid use of cltd in favor of a mov+shift.  */
7553   if (!TARGET_USE_CLTD && !optimize_size)
7554     {
7555       if (true_regnum (operands[1]))
7556         emit_move_insn (operands[0], operands[1]);
7557       else
7558         emit_move_insn (operands[3], operands[1]);
7559       operands[4] = operands[3];
7560     }
7561   else
7562     {
7563       gcc_assert (!true_regnum (operands[1]));
7564       operands[4] = operands[1];
7565     }
7566 })
7567 ;; %%% Split me.
7568 (define_insn "divmodhi4"
7569   [(set (match_operand:HI 0 "register_operand" "=a")
7570         (div:HI (match_operand:HI 1 "register_operand" "0")
7571                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7572    (set (match_operand:HI 3 "register_operand" "=&d")
7573         (mod:HI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_HIMODE_MATH"
7576   "cwtd\;idiv{w}\t%2"
7577   [(set_attr "type" "multi")
7578    (set_attr "length_immediate" "0")
7579    (set_attr "mode" "SI")])
7580
7581 (define_insn "udivmoddi4"
7582   [(set (match_operand:DI 0 "register_operand" "=a")
7583         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7584                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585    (set (match_operand:DI 3 "register_operand" "=&d")
7586         (umod:DI (match_dup 1) (match_dup 2)))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "TARGET_64BIT"
7589   "xor{q}\t%3, %3\;div{q}\t%2"
7590   [(set_attr "type" "multi")
7591    (set_attr "length_immediate" "0")
7592    (set_attr "mode" "DI")])
7593
7594 (define_insn "*udivmoddi4_noext"
7595   [(set (match_operand:DI 0 "register_operand" "=a")
7596         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7597                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7598    (set (match_operand:DI 3 "register_operand" "=d")
7599         (umod:DI (match_dup 1) (match_dup 2)))
7600    (use (match_dup 3))
7601    (clobber (reg:CC FLAGS_REG))]
7602   "TARGET_64BIT"
7603   "div{q}\t%2"
7604   [(set_attr "type" "idiv")
7605    (set_attr "mode" "DI")])
7606
7607 (define_split
7608   [(set (match_operand:DI 0 "register_operand" "")
7609         (udiv:DI (match_operand:DI 1 "register_operand" "")
7610                  (match_operand:DI 2 "nonimmediate_operand" "")))
7611    (set (match_operand:DI 3 "register_operand" "")
7612         (umod:DI (match_dup 1) (match_dup 2)))
7613    (clobber (reg:CC FLAGS_REG))]
7614   "TARGET_64BIT && reload_completed"
7615   [(set (match_dup 3) (const_int 0))
7616    (parallel [(set (match_dup 0)
7617                    (udiv:DI (match_dup 1) (match_dup 2)))
7618               (set (match_dup 3)
7619                    (umod:DI (match_dup 1) (match_dup 2)))
7620               (use (match_dup 3))
7621               (clobber (reg:CC FLAGS_REG))])]
7622   "")
7623
7624 (define_insn "udivmodsi4"
7625   [(set (match_operand:SI 0 "register_operand" "=a")
7626         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7627                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7628    (set (match_operand:SI 3 "register_operand" "=&d")
7629         (umod:SI (match_dup 1) (match_dup 2)))
7630    (clobber (reg:CC FLAGS_REG))]
7631   ""
7632   "xor{l}\t%3, %3\;div{l}\t%2"
7633   [(set_attr "type" "multi")
7634    (set_attr "length_immediate" "0")
7635    (set_attr "mode" "SI")])
7636
7637 (define_insn "*udivmodsi4_noext"
7638   [(set (match_operand:SI 0 "register_operand" "=a")
7639         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7640                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7641    (set (match_operand:SI 3 "register_operand" "=d")
7642         (umod:SI (match_dup 1) (match_dup 2)))
7643    (use (match_dup 3))
7644    (clobber (reg:CC FLAGS_REG))]
7645   ""
7646   "div{l}\t%2"
7647   [(set_attr "type" "idiv")
7648    (set_attr "mode" "SI")])
7649
7650 (define_split
7651   [(set (match_operand:SI 0 "register_operand" "")
7652         (udiv:SI (match_operand:SI 1 "register_operand" "")
7653                  (match_operand:SI 2 "nonimmediate_operand" "")))
7654    (set (match_operand:SI 3 "register_operand" "")
7655         (umod:SI (match_dup 1) (match_dup 2)))
7656    (clobber (reg:CC FLAGS_REG))]
7657   "reload_completed"
7658   [(set (match_dup 3) (const_int 0))
7659    (parallel [(set (match_dup 0)
7660                    (udiv:SI (match_dup 1) (match_dup 2)))
7661               (set (match_dup 3)
7662                    (umod:SI (match_dup 1) (match_dup 2)))
7663               (use (match_dup 3))
7664               (clobber (reg:CC FLAGS_REG))])]
7665   "")
7666
7667 (define_expand "udivmodhi4"
7668   [(set (match_dup 4) (const_int 0))
7669    (parallel [(set (match_operand:HI 0 "register_operand" "")
7670                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7671                             (match_operand:HI 2 "nonimmediate_operand" "")))
7672               (set (match_operand:HI 3 "register_operand" "")
7673                    (umod:HI (match_dup 1) (match_dup 2)))
7674               (use (match_dup 4))
7675               (clobber (reg:CC FLAGS_REG))])]
7676   "TARGET_HIMODE_MATH"
7677   "operands[4] = gen_reg_rtx (HImode);")
7678
7679 (define_insn "*udivmodhi_noext"
7680   [(set (match_operand:HI 0 "register_operand" "=a")
7681         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7682                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7683    (set (match_operand:HI 3 "register_operand" "=d")
7684         (umod:HI (match_dup 1) (match_dup 2)))
7685    (use (match_operand:HI 4 "register_operand" "3"))
7686    (clobber (reg:CC FLAGS_REG))]
7687   ""
7688   "div{w}\t%2"
7689   [(set_attr "type" "idiv")
7690    (set_attr "mode" "HI")])
7691
7692 ;; We cannot use div/idiv for double division, because it causes
7693 ;; "division by zero" on the overflow and that's not what we expect
7694 ;; from truncate.  Because true (non truncating) double division is
7695 ;; never generated, we can't create this insn anyway.
7696 ;
7697 ;(define_insn ""
7698 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7699 ;       (truncate:SI
7700 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7701 ;                  (zero_extend:DI
7702 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7703 ;   (set (match_operand:SI 3 "register_operand" "=d")
7704 ;       (truncate:SI
7705 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7706 ;   (clobber (reg:CC FLAGS_REG))]
7707 ;  ""
7708 ;  "div{l}\t{%2, %0|%0, %2}"
7709 ;  [(set_attr "type" "idiv")])
7710 \f
7711 ;;- Logical AND instructions
7712
7713 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7714 ;; Note that this excludes ah.
7715
7716 (define_insn "*testdi_1_rex64"
7717   [(set (reg FLAGS_REG)
7718         (compare
7719           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7720                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7721           (const_int 0)))]
7722   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724   "@
7725    test{l}\t{%k1, %k0|%k0, %k1}
7726    test{l}\t{%k1, %k0|%k0, %k1}
7727    test{q}\t{%1, %0|%0, %1}
7728    test{q}\t{%1, %0|%0, %1}
7729    test{q}\t{%1, %0|%0, %1}"
7730   [(set_attr "type" "test")
7731    (set_attr "modrm" "0,1,0,1,1")
7732    (set_attr "mode" "SI,SI,DI,DI,DI")
7733    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7734
7735 (define_insn "testsi_1"
7736   [(set (reg FLAGS_REG)
7737         (compare
7738           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7739                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7740           (const_int 0)))]
7741   "ix86_match_ccmode (insn, CCNOmode)
7742    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743   "test{l}\t{%1, %0|%0, %1}"
7744   [(set_attr "type" "test")
7745    (set_attr "modrm" "0,1,1")
7746    (set_attr "mode" "SI")
7747    (set_attr "pent_pair" "uv,np,uv")])
7748
7749 (define_expand "testsi_ccno_1"
7750   [(set (reg:CCNO FLAGS_REG)
7751         (compare:CCNO
7752           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7753                   (match_operand:SI 1 "nonmemory_operand" ""))
7754           (const_int 0)))]
7755   ""
7756   "")
7757
7758 (define_insn "*testhi_1"
7759   [(set (reg FLAGS_REG)
7760         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7761                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7762                  (const_int 0)))]
7763   "ix86_match_ccmode (insn, CCNOmode)
7764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7765   "test{w}\t{%1, %0|%0, %1}"
7766   [(set_attr "type" "test")
7767    (set_attr "modrm" "0,1,1")
7768    (set_attr "mode" "HI")
7769    (set_attr "pent_pair" "uv,np,uv")])
7770
7771 (define_expand "testqi_ccz_1"
7772   [(set (reg:CCZ FLAGS_REG)
7773         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7774                              (match_operand:QI 1 "nonmemory_operand" ""))
7775                  (const_int 0)))]
7776   ""
7777   "")
7778
7779 (define_insn "*testqi_1_maybe_si"
7780   [(set (reg FLAGS_REG)
7781         (compare
7782           (and:QI
7783             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7784             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7785           (const_int 0)))]
7786    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7787     && ix86_match_ccmode (insn,
7788                          GET_CODE (operands[1]) == CONST_INT
7789                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7790 {
7791   if (which_alternative == 3)
7792     {
7793       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7794         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7795       return "test{l}\t{%1, %k0|%k0, %1}";
7796     }
7797   return "test{b}\t{%1, %0|%0, %1}";
7798 }
7799   [(set_attr "type" "test")
7800    (set_attr "modrm" "0,1,1,1")
7801    (set_attr "mode" "QI,QI,QI,SI")
7802    (set_attr "pent_pair" "uv,np,uv,np")])
7803
7804 (define_insn "*testqi_1"
7805   [(set (reg FLAGS_REG)
7806         (compare
7807           (and:QI
7808             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7809             (match_operand:QI 1 "general_operand" "n,n,qn"))
7810           (const_int 0)))]
7811   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7812    && ix86_match_ccmode (insn, CCNOmode)"
7813   "test{b}\t{%1, %0|%0, %1}"
7814   [(set_attr "type" "test")
7815    (set_attr "modrm" "0,1,1")
7816    (set_attr "mode" "QI")
7817    (set_attr "pent_pair" "uv,np,uv")])
7818
7819 (define_expand "testqi_ext_ccno_0"
7820   [(set (reg:CCNO FLAGS_REG)
7821         (compare:CCNO
7822           (and:SI
7823             (zero_extract:SI
7824               (match_operand 0 "ext_register_operand" "")
7825               (const_int 8)
7826               (const_int 8))
7827             (match_operand 1 "const_int_operand" ""))
7828           (const_int 0)))]
7829   ""
7830   "")
7831
7832 (define_insn "*testqi_ext_0"
7833   [(set (reg FLAGS_REG)
7834         (compare
7835           (and:SI
7836             (zero_extract:SI
7837               (match_operand 0 "ext_register_operand" "Q")
7838               (const_int 8)
7839               (const_int 8))
7840             (match_operand 1 "const_int_operand" "n"))
7841           (const_int 0)))]
7842   "ix86_match_ccmode (insn, CCNOmode)"
7843   "test{b}\t{%1, %h0|%h0, %1}"
7844   [(set_attr "type" "test")
7845    (set_attr "mode" "QI")
7846    (set_attr "length_immediate" "1")
7847    (set_attr "pent_pair" "np")])
7848
7849 (define_insn "*testqi_ext_1"
7850   [(set (reg FLAGS_REG)
7851         (compare
7852           (and:SI
7853             (zero_extract:SI
7854               (match_operand 0 "ext_register_operand" "Q")
7855               (const_int 8)
7856               (const_int 8))
7857             (zero_extend:SI
7858               (match_operand:QI 1 "general_operand" "Qm")))
7859           (const_int 0)))]
7860   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7861    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7862   "test{b}\t{%1, %h0|%h0, %1}"
7863   [(set_attr "type" "test")
7864    (set_attr "mode" "QI")])
7865
7866 (define_insn "*testqi_ext_1_rex64"
7867   [(set (reg FLAGS_REG)
7868         (compare
7869           (and:SI
7870             (zero_extract:SI
7871               (match_operand 0 "ext_register_operand" "Q")
7872               (const_int 8)
7873               (const_int 8))
7874             (zero_extend:SI
7875               (match_operand:QI 1 "register_operand" "Q")))
7876           (const_int 0)))]
7877   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7878   "test{b}\t{%1, %h0|%h0, %1}"
7879   [(set_attr "type" "test")
7880    (set_attr "mode" "QI")])
7881
7882 (define_insn "*testqi_ext_2"
7883   [(set (reg FLAGS_REG)
7884         (compare
7885           (and:SI
7886             (zero_extract:SI
7887               (match_operand 0 "ext_register_operand" "Q")
7888               (const_int 8)
7889               (const_int 8))
7890             (zero_extract:SI
7891               (match_operand 1 "ext_register_operand" "Q")
7892               (const_int 8)
7893               (const_int 8)))
7894           (const_int 0)))]
7895   "ix86_match_ccmode (insn, CCNOmode)"
7896   "test{b}\t{%h1, %h0|%h0, %h1}"
7897   [(set_attr "type" "test")
7898    (set_attr "mode" "QI")])
7899
7900 ;; Combine likes to form bit extractions for some tests.  Humor it.
7901 (define_insn "*testqi_ext_3"
7902   [(set (reg FLAGS_REG)
7903         (compare (zero_extract:SI
7904                    (match_operand 0 "nonimmediate_operand" "rm")
7905                    (match_operand:SI 1 "const_int_operand" "")
7906                    (match_operand:SI 2 "const_int_operand" ""))
7907                  (const_int 0)))]
7908   "ix86_match_ccmode (insn, CCNOmode)
7909    && INTVAL (operands[1]) > 0
7910    && INTVAL (operands[2]) >= 0
7911    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7912    && (GET_MODE (operands[0]) == SImode
7913        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7914        || GET_MODE (operands[0]) == HImode
7915        || GET_MODE (operands[0]) == QImode)"
7916   "#")
7917
7918 (define_insn "*testqi_ext_3_rex64"
7919   [(set (reg FLAGS_REG)
7920         (compare (zero_extract:DI
7921                    (match_operand 0 "nonimmediate_operand" "rm")
7922                    (match_operand:DI 1 "const_int_operand" "")
7923                    (match_operand:DI 2 "const_int_operand" ""))
7924                  (const_int 0)))]
7925   "TARGET_64BIT
7926    && ix86_match_ccmode (insn, CCNOmode)
7927    && INTVAL (operands[1]) > 0
7928    && INTVAL (operands[2]) >= 0
7929    /* Ensure that resulting mask is zero or sign extended operand.  */
7930    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7931        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7932            && INTVAL (operands[1]) > 32))
7933    && (GET_MODE (operands[0]) == SImode
7934        || GET_MODE (operands[0]) == DImode
7935        || GET_MODE (operands[0]) == HImode
7936        || GET_MODE (operands[0]) == QImode)"
7937   "#")
7938
7939 (define_split
7940   [(set (match_operand 0 "flags_reg_operand" "")
7941         (match_operator 1 "compare_operator"
7942           [(zero_extract
7943              (match_operand 2 "nonimmediate_operand" "")
7944              (match_operand 3 "const_int_operand" "")
7945              (match_operand 4 "const_int_operand" ""))
7946            (const_int 0)]))]
7947   "ix86_match_ccmode (insn, CCNOmode)"
7948   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7949 {
7950   rtx val = operands[2];
7951   HOST_WIDE_INT len = INTVAL (operands[3]);
7952   HOST_WIDE_INT pos = INTVAL (operands[4]);
7953   HOST_WIDE_INT mask;
7954   enum machine_mode mode, submode;
7955
7956   mode = GET_MODE (val);
7957   if (GET_CODE (val) == MEM)
7958     {
7959       /* ??? Combine likes to put non-volatile mem extractions in QImode
7960          no matter the size of the test.  So find a mode that works.  */
7961       if (! MEM_VOLATILE_P (val))
7962         {
7963           mode = smallest_mode_for_size (pos + len, MODE_INT);
7964           val = adjust_address (val, mode, 0);
7965         }
7966     }
7967   else if (GET_CODE (val) == SUBREG
7968            && (submode = GET_MODE (SUBREG_REG (val)),
7969                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970            && pos + len <= GET_MODE_BITSIZE (submode))
7971     {
7972       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7973       mode = submode;
7974       val = SUBREG_REG (val);
7975     }
7976   else if (mode == HImode && pos + len <= 8)
7977     {
7978       /* Small HImode tests can be converted to QImode.  */
7979       mode = QImode;
7980       val = gen_lowpart (QImode, val);
7981     }
7982
7983   if (len == HOST_BITS_PER_WIDE_INT)
7984     mask = -1;
7985   else
7986     mask = ((HOST_WIDE_INT)1 << len) - 1;
7987   mask <<= pos;
7988
7989   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7990 })
7991
7992 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7993 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7994 ;; this is relatively important trick.
7995 ;; Do the conversion only post-reload to avoid limiting of the register class
7996 ;; to QI regs.
7997 (define_split
7998   [(set (match_operand 0 "flags_reg_operand" "")
7999         (match_operator 1 "compare_operator"
8000           [(and (match_operand 2 "register_operand" "")
8001                 (match_operand 3 "const_int_operand" ""))
8002            (const_int 0)]))]
8003    "reload_completed
8004     && QI_REG_P (operands[2])
8005     && GET_MODE (operands[2]) != QImode
8006     && ((ix86_match_ccmode (insn, CCZmode)
8007          && !(INTVAL (operands[3]) & ~(255 << 8)))
8008         || (ix86_match_ccmode (insn, CCNOmode)
8009             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8010   [(set (match_dup 0)
8011         (match_op_dup 1
8012           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8013                    (match_dup 3))
8014            (const_int 0)]))]
8015   "operands[2] = gen_lowpart (SImode, operands[2]);
8016    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8017
8018 (define_split
8019   [(set (match_operand 0 "flags_reg_operand" "")
8020         (match_operator 1 "compare_operator"
8021           [(and (match_operand 2 "nonimmediate_operand" "")
8022                 (match_operand 3 "const_int_operand" ""))
8023            (const_int 0)]))]
8024    "reload_completed
8025     && GET_MODE (operands[2]) != QImode
8026     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027     && ((ix86_match_ccmode (insn, CCZmode)
8028          && !(INTVAL (operands[3]) & ~255))
8029         || (ix86_match_ccmode (insn, CCNOmode)
8030             && !(INTVAL (operands[3]) & ~127)))"
8031   [(set (match_dup 0)
8032         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8033                          (const_int 0)]))]
8034   "operands[2] = gen_lowpart (QImode, operands[2]);
8035    operands[3] = gen_lowpart (QImode, operands[3]);")
8036
8037
8038 ;; %%% This used to optimize known byte-wide and operations to memory,
8039 ;; and sometimes to QImode registers.  If this is considered useful,
8040 ;; it should be done with splitters.
8041
8042 (define_expand "anddi3"
8043   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8044         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8045                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8046    (clobber (reg:CC FLAGS_REG))]
8047   "TARGET_64BIT"
8048   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8049
8050 (define_insn "*anddi_1_rex64"
8051   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8052         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8053                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8056 {
8057   switch (get_attr_type (insn))
8058     {
8059     case TYPE_IMOVX:
8060       {
8061         enum machine_mode mode;
8062
8063         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8064         if (INTVAL (operands[2]) == 0xff)
8065           mode = QImode;
8066         else
8067           {
8068             gcc_assert (INTVAL (operands[2]) == 0xffff);
8069             mode = HImode;
8070           }
8071         
8072         operands[1] = gen_lowpart (mode, operands[1]);
8073         if (mode == QImode)
8074           return "movz{bq|x}\t{%1,%0|%0, %1}";
8075         else
8076           return "movz{wq|x}\t{%1,%0|%0, %1}";
8077       }
8078
8079     default:
8080       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8081       if (get_attr_mode (insn) == MODE_SI)
8082         return "and{l}\t{%k2, %k0|%k0, %k2}";
8083       else
8084         return "and{q}\t{%2, %0|%0, %2}";
8085     }
8086 }
8087   [(set_attr "type" "alu,alu,alu,imovx")
8088    (set_attr "length_immediate" "*,*,*,0")
8089    (set_attr "mode" "SI,DI,DI,DI")])
8090
8091 (define_insn "*anddi_2"
8092   [(set (reg FLAGS_REG)
8093         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8094                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8095                  (const_int 0)))
8096    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8097         (and:DI (match_dup 1) (match_dup 2)))]
8098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099    && ix86_binary_operator_ok (AND, DImode, operands)"
8100   "@
8101    and{l}\t{%k2, %k0|%k0, %k2}
8102    and{q}\t{%2, %0|%0, %2}
8103    and{q}\t{%2, %0|%0, %2}"
8104   [(set_attr "type" "alu")
8105    (set_attr "mode" "SI,DI,DI")])
8106
8107 (define_expand "andsi3"
8108   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8109         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8110                 (match_operand:SI 2 "general_operand" "")))
8111    (clobber (reg:CC FLAGS_REG))]
8112   ""
8113   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8114
8115 (define_insn "*andsi_1"
8116   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8117         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8118                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "ix86_binary_operator_ok (AND, SImode, operands)"
8121 {
8122   switch (get_attr_type (insn))
8123     {
8124     case TYPE_IMOVX:
8125       {
8126         enum machine_mode mode;
8127
8128         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8129         if (INTVAL (operands[2]) == 0xff)
8130           mode = QImode;
8131         else
8132           {
8133             gcc_assert (INTVAL (operands[2]) == 0xffff);
8134             mode = HImode;
8135           }
8136         
8137         operands[1] = gen_lowpart (mode, operands[1]);
8138         if (mode == QImode)
8139           return "movz{bl|x}\t{%1,%0|%0, %1}";
8140         else
8141           return "movz{wl|x}\t{%1,%0|%0, %1}";
8142       }
8143
8144     default:
8145       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8146       return "and{l}\t{%2, %0|%0, %2}";
8147     }
8148 }
8149   [(set_attr "type" "alu,alu,imovx")
8150    (set_attr "length_immediate" "*,*,0")
8151    (set_attr "mode" "SI")])
8152
8153 (define_split
8154   [(set (match_operand 0 "register_operand" "")
8155         (and (match_dup 0)
8156              (const_int -65536)))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8159   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8160   "operands[1] = gen_lowpart (HImode, operands[0]);")
8161
8162 (define_split
8163   [(set (match_operand 0 "ext_register_operand" "")
8164         (and (match_dup 0)
8165              (const_int -256)))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8168   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169   "operands[1] = gen_lowpart (QImode, operands[0]);")
8170
8171 (define_split
8172   [(set (match_operand 0 "ext_register_operand" "")
8173         (and (match_dup 0)
8174              (const_int -65281)))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177   [(parallel [(set (zero_extract:SI (match_dup 0)
8178                                     (const_int 8)
8179                                     (const_int 8))
8180                    (xor:SI 
8181                      (zero_extract:SI (match_dup 0)
8182                                       (const_int 8)
8183                                       (const_int 8))
8184                      (zero_extract:SI (match_dup 0)
8185                                       (const_int 8)
8186                                       (const_int 8))))
8187               (clobber (reg:CC FLAGS_REG))])]
8188   "operands[0] = gen_lowpart (SImode, operands[0]);")
8189
8190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191 (define_insn "*andsi_1_zext"
8192   [(set (match_operand:DI 0 "register_operand" "=r")
8193         (zero_extend:DI
8194           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195                   (match_operand:SI 2 "general_operand" "rim"))))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8198   "and{l}\t{%2, %k0|%k0, %2}"
8199   [(set_attr "type" "alu")
8200    (set_attr "mode" "SI")])
8201
8202 (define_insn "*andsi_2"
8203   [(set (reg FLAGS_REG)
8204         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8205                          (match_operand:SI 2 "general_operand" "rim,ri"))
8206                  (const_int 0)))
8207    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8208         (and:SI (match_dup 1) (match_dup 2)))]
8209   "ix86_match_ccmode (insn, CCNOmode)
8210    && ix86_binary_operator_ok (AND, SImode, operands)"
8211   "and{l}\t{%2, %0|%0, %2}"
8212   [(set_attr "type" "alu")
8213    (set_attr "mode" "SI")])
8214
8215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216 (define_insn "*andsi_2_zext"
8217   [(set (reg FLAGS_REG)
8218         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8219                          (match_operand:SI 2 "general_operand" "rim"))
8220                  (const_int 0)))
8221    (set (match_operand:DI 0 "register_operand" "=r")
8222         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8223   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8224    && ix86_binary_operator_ok (AND, SImode, operands)"
8225   "and{l}\t{%2, %k0|%k0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "SI")])
8228
8229 (define_expand "andhi3"
8230   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8231         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8232                 (match_operand:HI 2 "general_operand" "")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_HIMODE_MATH"
8235   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8236
8237 (define_insn "*andhi_1"
8238   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8239         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8240                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8241    (clobber (reg:CC FLAGS_REG))]
8242   "ix86_binary_operator_ok (AND, HImode, operands)"
8243 {
8244   switch (get_attr_type (insn))
8245     {
8246     case TYPE_IMOVX:
8247       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8248       gcc_assert (INTVAL (operands[2]) == 0xff);
8249       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8250
8251     default:
8252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8253
8254       return "and{w}\t{%2, %0|%0, %2}";
8255     }
8256 }
8257   [(set_attr "type" "alu,alu,imovx")
8258    (set_attr "length_immediate" "*,*,0")
8259    (set_attr "mode" "HI,HI,SI")])
8260
8261 (define_insn "*andhi_2"
8262   [(set (reg FLAGS_REG)
8263         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8264                          (match_operand:HI 2 "general_operand" "rim,ri"))
8265                  (const_int 0)))
8266    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8267         (and:HI (match_dup 1) (match_dup 2)))]
8268   "ix86_match_ccmode (insn, CCNOmode)
8269    && ix86_binary_operator_ok (AND, HImode, operands)"
8270   "and{w}\t{%2, %0|%0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "mode" "HI")])
8273
8274 (define_expand "andqi3"
8275   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8276         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8277                 (match_operand:QI 2 "general_operand" "")))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "TARGET_QIMODE_MATH"
8280   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8281
8282 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8283 (define_insn "*andqi_1"
8284   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8285         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8286                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "ix86_binary_operator_ok (AND, QImode, operands)"
8289   "@
8290    and{b}\t{%2, %0|%0, %2}
8291    and{b}\t{%2, %0|%0, %2}
8292    and{l}\t{%k2, %k0|%k0, %k2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "QI,QI,SI")])
8295
8296 (define_insn "*andqi_1_slp"
8297   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8298         (and:QI (match_dup 0)
8299                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8302    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8303   "and{b}\t{%1, %0|%0, %1}"
8304   [(set_attr "type" "alu1")
8305    (set_attr "mode" "QI")])
8306
8307 (define_insn "*andqi_2_maybe_si"
8308   [(set (reg FLAGS_REG)
8309         (compare (and:QI
8310                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8312                  (const_int 0)))
8313    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8314         (and:QI (match_dup 1) (match_dup 2)))]
8315   "ix86_binary_operator_ok (AND, QImode, operands)
8316    && ix86_match_ccmode (insn,
8317                          GET_CODE (operands[2]) == CONST_INT
8318                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8319 {
8320   if (which_alternative == 2)
8321     {
8322       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8323         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8324       return "and{l}\t{%2, %k0|%k0, %2}";
8325     }
8326   return "and{b}\t{%2, %0|%0, %2}";
8327 }
8328   [(set_attr "type" "alu")
8329    (set_attr "mode" "QI,QI,SI")])
8330
8331 (define_insn "*andqi_2"
8332   [(set (reg FLAGS_REG)
8333         (compare (and:QI
8334                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8335                    (match_operand:QI 2 "general_operand" "qim,qi"))
8336                  (const_int 0)))
8337    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8338         (and:QI (match_dup 1) (match_dup 2)))]
8339   "ix86_match_ccmode (insn, CCNOmode)
8340    && ix86_binary_operator_ok (AND, QImode, operands)"
8341   "and{b}\t{%2, %0|%0, %2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "QI")])
8344
8345 (define_insn "*andqi_2_slp"
8346   [(set (reg FLAGS_REG)
8347         (compare (and:QI
8348                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8349                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8350                  (const_int 0)))
8351    (set (strict_low_part (match_dup 0))
8352         (and:QI (match_dup 0) (match_dup 1)))]
8353   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8354    && ix86_match_ccmode (insn, CCNOmode)
8355    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8356   "and{b}\t{%1, %0|%0, %1}"
8357   [(set_attr "type" "alu1")
8358    (set_attr "mode" "QI")])
8359
8360 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8361 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8362 ;; for a QImode operand, which of course failed.
8363
8364 (define_insn "andqi_ext_0"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (and:SI 
8369           (zero_extract:SI
8370             (match_operand 1 "ext_register_operand" "0")
8371             (const_int 8)
8372             (const_int 8))
8373           (match_operand 2 "const_int_operand" "n")))
8374    (clobber (reg:CC FLAGS_REG))]
8375   ""
8376   "and{b}\t{%2, %h0|%h0, %2}"
8377   [(set_attr "type" "alu")
8378    (set_attr "length_immediate" "1")
8379    (set_attr "mode" "QI")])
8380
8381 ;; Generated by peephole translating test to and.  This shows up
8382 ;; often in fp comparisons.
8383
8384 (define_insn "*andqi_ext_0_cc"
8385   [(set (reg FLAGS_REG)
8386         (compare
8387           (and:SI
8388             (zero_extract:SI
8389               (match_operand 1 "ext_register_operand" "0")
8390               (const_int 8)
8391               (const_int 8))
8392             (match_operand 2 "const_int_operand" "n"))
8393           (const_int 0)))
8394    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8395                          (const_int 8)
8396                          (const_int 8))
8397         (and:SI 
8398           (zero_extract:SI
8399             (match_dup 1)
8400             (const_int 8)
8401             (const_int 8))
8402           (match_dup 2)))]
8403   "ix86_match_ccmode (insn, CCNOmode)"
8404   "and{b}\t{%2, %h0|%h0, %2}"
8405   [(set_attr "type" "alu")
8406    (set_attr "length_immediate" "1")
8407    (set_attr "mode" "QI")])
8408
8409 (define_insn "*andqi_ext_1"
8410   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8411                          (const_int 8)
8412                          (const_int 8))
8413         (and:SI 
8414           (zero_extract:SI
8415             (match_operand 1 "ext_register_operand" "0")
8416             (const_int 8)
8417             (const_int 8))
8418           (zero_extend:SI
8419             (match_operand:QI 2 "general_operand" "Qm"))))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "!TARGET_64BIT"
8422   "and{b}\t{%2, %h0|%h0, %2}"
8423   [(set_attr "type" "alu")
8424    (set_attr "length_immediate" "0")
8425    (set_attr "mode" "QI")])
8426
8427 (define_insn "*andqi_ext_1_rex64"
8428   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429                          (const_int 8)
8430                          (const_int 8))
8431         (and:SI 
8432           (zero_extract:SI
8433             (match_operand 1 "ext_register_operand" "0")
8434             (const_int 8)
8435             (const_int 8))
8436           (zero_extend:SI
8437             (match_operand 2 "ext_register_operand" "Q"))))
8438    (clobber (reg:CC FLAGS_REG))]
8439   "TARGET_64BIT"
8440   "and{b}\t{%2, %h0|%h0, %2}"
8441   [(set_attr "type" "alu")
8442    (set_attr "length_immediate" "0")
8443    (set_attr "mode" "QI")])
8444
8445 (define_insn "*andqi_ext_2"
8446   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447                          (const_int 8)
8448                          (const_int 8))
8449         (and:SI
8450           (zero_extract:SI
8451             (match_operand 1 "ext_register_operand" "%0")
8452             (const_int 8)
8453             (const_int 8))
8454           (zero_extract:SI
8455             (match_operand 2 "ext_register_operand" "Q")
8456             (const_int 8)
8457             (const_int 8))))
8458    (clobber (reg:CC FLAGS_REG))]
8459   ""
8460   "and{b}\t{%h2, %h0|%h0, %h2}"
8461   [(set_attr "type" "alu")
8462    (set_attr "length_immediate" "0")
8463    (set_attr "mode" "QI")])
8464
8465 ;; Convert wide AND instructions with immediate operand to shorter QImode
8466 ;; equivalents when possible.
8467 ;; Don't do the splitting with memory operands, since it introduces risk
8468 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8469 ;; for size, but that can (should?) be handled by generic code instead.
8470 (define_split
8471   [(set (match_operand 0 "register_operand" "")
8472         (and (match_operand 1 "register_operand" "")
8473              (match_operand 2 "const_int_operand" "")))
8474    (clobber (reg:CC FLAGS_REG))]
8475    "reload_completed
8476     && QI_REG_P (operands[0])
8477     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8478     && !(~INTVAL (operands[2]) & ~(255 << 8))
8479     && GET_MODE (operands[0]) != QImode"
8480   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8481                    (and:SI (zero_extract:SI (match_dup 1)
8482                                             (const_int 8) (const_int 8))
8483                            (match_dup 2)))
8484               (clobber (reg:CC FLAGS_REG))])]
8485   "operands[0] = gen_lowpart (SImode, operands[0]);
8486    operands[1] = gen_lowpart (SImode, operands[1]);
8487    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8488
8489 ;; Since AND can be encoded with sign extended immediate, this is only
8490 ;; profitable when 7th bit is not set.
8491 (define_split
8492   [(set (match_operand 0 "register_operand" "")
8493         (and (match_operand 1 "general_operand" "")
8494              (match_operand 2 "const_int_operand" "")))
8495    (clobber (reg:CC FLAGS_REG))]
8496    "reload_completed
8497     && ANY_QI_REG_P (operands[0])
8498     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8499     && !(~INTVAL (operands[2]) & ~255)
8500     && !(INTVAL (operands[2]) & 128)
8501     && GET_MODE (operands[0]) != QImode"
8502   [(parallel [(set (strict_low_part (match_dup 0))
8503                    (and:QI (match_dup 1)
8504                            (match_dup 2)))
8505               (clobber (reg:CC FLAGS_REG))])]
8506   "operands[0] = gen_lowpart (QImode, operands[0]);
8507    operands[1] = gen_lowpart (QImode, operands[1]);
8508    operands[2] = gen_lowpart (QImode, operands[2]);")
8509 \f
8510 ;; Logical inclusive OR instructions
8511
8512 ;; %%% This used to optimize known byte-wide and operations to memory.
8513 ;; If this is considered useful, it should be done with splitters.
8514
8515 (define_expand "iordi3"
8516   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8517         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8518                 (match_operand:DI 2 "x86_64_general_operand" "")))
8519    (clobber (reg:CC FLAGS_REG))]
8520   "TARGET_64BIT"
8521   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8522
8523 (define_insn "*iordi_1_rex64"
8524   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8525         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8526                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT
8529    && ix86_binary_operator_ok (IOR, DImode, operands)"
8530   "or{q}\t{%2, %0|%0, %2}"
8531   [(set_attr "type" "alu")
8532    (set_attr "mode" "DI")])
8533
8534 (define_insn "*iordi_2_rex64"
8535   [(set (reg FLAGS_REG)
8536         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8537                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8538                  (const_int 0)))
8539    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8540         (ior:DI (match_dup 1) (match_dup 2)))]
8541   "TARGET_64BIT
8542    && ix86_match_ccmode (insn, CCNOmode)
8543    && ix86_binary_operator_ok (IOR, DImode, operands)"
8544   "or{q}\t{%2, %0|%0, %2}"
8545   [(set_attr "type" "alu")
8546    (set_attr "mode" "DI")])
8547
8548 (define_insn "*iordi_3_rex64"
8549   [(set (reg FLAGS_REG)
8550         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8551                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8552                  (const_int 0)))
8553    (clobber (match_scratch:DI 0 "=r"))]
8554   "TARGET_64BIT
8555    && ix86_match_ccmode (insn, CCNOmode)
8556    && ix86_binary_operator_ok (IOR, DImode, operands)"
8557   "or{q}\t{%2, %0|%0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "DI")])
8560
8561
8562 (define_expand "iorsi3"
8563   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8564         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8565                 (match_operand:SI 2 "general_operand" "")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   ""
8568   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8569
8570 (define_insn "*iorsi_1"
8571   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8572         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "ix86_binary_operator_ok (IOR, SImode, operands)"
8576   "or{l}\t{%2, %0|%0, %2}"
8577   [(set_attr "type" "alu")
8578    (set_attr "mode" "SI")])
8579
8580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581 (define_insn "*iorsi_1_zext"
8582   [(set (match_operand:DI 0 "register_operand" "=rm")
8583         (zero_extend:DI
8584           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585                   (match_operand:SI 2 "general_operand" "rim"))))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8588   "or{l}\t{%2, %k0|%k0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "SI")])
8591
8592 (define_insn "*iorsi_1_zext_imm"
8593   [(set (match_operand:DI 0 "register_operand" "=rm")
8594         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8595                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8596    (clobber (reg:CC FLAGS_REG))]
8597   "TARGET_64BIT"
8598   "or{l}\t{%2, %k0|%k0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "SI")])
8601
8602 (define_insn "*iorsi_2"
8603   [(set (reg FLAGS_REG)
8604         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605                          (match_operand:SI 2 "general_operand" "rim,ri"))
8606                  (const_int 0)))
8607    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608         (ior:SI (match_dup 1) (match_dup 2)))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (IOR, SImode, operands)"
8611   "or{l}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "SI")])
8614
8615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616 ;; ??? Special case for immediate operand is missing - it is tricky.
8617 (define_insn "*iorsi_2_zext"
8618   [(set (reg FLAGS_REG)
8619         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8620                          (match_operand:SI 2 "general_operand" "rim"))
8621                  (const_int 0)))
8622    (set (match_operand:DI 0 "register_operand" "=r")
8623         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8624   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8625    && ix86_binary_operator_ok (IOR, SImode, operands)"
8626   "or{l}\t{%2, %k0|%k0, %2}"
8627   [(set_attr "type" "alu")
8628    (set_attr "mode" "SI")])
8629
8630 (define_insn "*iorsi_2_zext_imm"
8631   [(set (reg FLAGS_REG)
8632         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8634                  (const_int 0)))
8635    (set (match_operand:DI 0 "register_operand" "=r")
8636         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8637   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638    && ix86_binary_operator_ok (IOR, SImode, operands)"
8639   "or{l}\t{%2, %k0|%k0, %2}"
8640   [(set_attr "type" "alu")
8641    (set_attr "mode" "SI")])
8642
8643 (define_insn "*iorsi_3"
8644   [(set (reg FLAGS_REG)
8645         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8646                          (match_operand:SI 2 "general_operand" "rim"))
8647                  (const_int 0)))
8648    (clobber (match_scratch:SI 0 "=r"))]
8649   "ix86_match_ccmode (insn, CCNOmode)
8650    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8651   "or{l}\t{%2, %0|%0, %2}"
8652   [(set_attr "type" "alu")
8653    (set_attr "mode" "SI")])
8654
8655 (define_expand "iorhi3"
8656   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8657         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8658                 (match_operand:HI 2 "general_operand" "")))
8659    (clobber (reg:CC FLAGS_REG))]
8660   "TARGET_HIMODE_MATH"
8661   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8662
8663 (define_insn "*iorhi_1"
8664   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8665         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8666                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "ix86_binary_operator_ok (IOR, HImode, operands)"
8669   "or{w}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "HI")])
8672
8673 (define_insn "*iorhi_2"
8674   [(set (reg FLAGS_REG)
8675         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8676                          (match_operand:HI 2 "general_operand" "rim,ri"))
8677                  (const_int 0)))
8678    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8679         (ior:HI (match_dup 1) (match_dup 2)))]
8680   "ix86_match_ccmode (insn, CCNOmode)
8681    && ix86_binary_operator_ok (IOR, HImode, operands)"
8682   "or{w}\t{%2, %0|%0, %2}"
8683   [(set_attr "type" "alu")
8684    (set_attr "mode" "HI")])
8685
8686 (define_insn "*iorhi_3"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8689                          (match_operand:HI 2 "general_operand" "rim"))
8690                  (const_int 0)))
8691    (clobber (match_scratch:HI 0 "=r"))]
8692   "ix86_match_ccmode (insn, CCNOmode)
8693    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8694   "or{w}\t{%2, %0|%0, %2}"
8695   [(set_attr "type" "alu")
8696    (set_attr "mode" "HI")])
8697
8698 (define_expand "iorqi3"
8699   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8700         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8701                 (match_operand:QI 2 "general_operand" "")))
8702    (clobber (reg:CC FLAGS_REG))]
8703   "TARGET_QIMODE_MATH"
8704   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8705
8706 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8707 (define_insn "*iorqi_1"
8708   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8709         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8710                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "ix86_binary_operator_ok (IOR, QImode, operands)"
8713   "@
8714    or{b}\t{%2, %0|%0, %2}
8715    or{b}\t{%2, %0|%0, %2}
8716    or{l}\t{%k2, %k0|%k0, %k2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "QI,QI,SI")])
8719
8720 (define_insn "*iorqi_1_slp"
8721   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8722         (ior:QI (match_dup 0)
8723                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8724    (clobber (reg:CC FLAGS_REG))]
8725   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8726    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8727   "or{b}\t{%1, %0|%0, %1}"
8728   [(set_attr "type" "alu1")
8729    (set_attr "mode" "QI")])
8730
8731 (define_insn "*iorqi_2"
8732   [(set (reg FLAGS_REG)
8733         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8734                          (match_operand:QI 2 "general_operand" "qim,qi"))
8735                  (const_int 0)))
8736    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8737         (ior:QI (match_dup 1) (match_dup 2)))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && ix86_binary_operator_ok (IOR, QImode, operands)"
8740   "or{b}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "QI")])
8743
8744 (define_insn "*iorqi_2_slp"
8745   [(set (reg FLAGS_REG)
8746         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8747                          (match_operand:QI 1 "general_operand" "qim,qi"))
8748                  (const_int 0)))
8749    (set (strict_low_part (match_dup 0))
8750         (ior:QI (match_dup 0) (match_dup 1)))]
8751   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8752    && ix86_match_ccmode (insn, CCNOmode)
8753    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8754   "or{b}\t{%1, %0|%0, %1}"
8755   [(set_attr "type" "alu1")
8756    (set_attr "mode" "QI")])
8757
8758 (define_insn "*iorqi_3"
8759   [(set (reg FLAGS_REG)
8760         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8761                          (match_operand:QI 2 "general_operand" "qim"))
8762                  (const_int 0)))
8763    (clobber (match_scratch:QI 0 "=q"))]
8764   "ix86_match_ccmode (insn, CCNOmode)
8765    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766   "or{b}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "QI")])
8769
8770 (define_insn "iorqi_ext_0"
8771   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772                          (const_int 8)
8773                          (const_int 8))
8774         (ior:SI 
8775           (zero_extract:SI
8776             (match_operand 1 "ext_register_operand" "0")
8777             (const_int 8)
8778             (const_int 8))
8779           (match_operand 2 "const_int_operand" "n")))
8780    (clobber (reg:CC FLAGS_REG))]
8781   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782   "or{b}\t{%2, %h0|%h0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "length_immediate" "1")
8785    (set_attr "mode" "QI")])
8786
8787 (define_insn "*iorqi_ext_1"
8788   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789                          (const_int 8)
8790                          (const_int 8))
8791         (ior:SI 
8792           (zero_extract:SI
8793             (match_operand 1 "ext_register_operand" "0")
8794             (const_int 8)
8795             (const_int 8))
8796           (zero_extend:SI
8797             (match_operand:QI 2 "general_operand" "Qm"))))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "!TARGET_64BIT
8800    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801   "or{b}\t{%2, %h0|%h0, %2}"
8802   [(set_attr "type" "alu")
8803    (set_attr "length_immediate" "0")
8804    (set_attr "mode" "QI")])
8805
8806 (define_insn "*iorqi_ext_1_rex64"
8807   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8808                          (const_int 8)
8809                          (const_int 8))
8810         (ior:SI 
8811           (zero_extract:SI
8812             (match_operand 1 "ext_register_operand" "0")
8813             (const_int 8)
8814             (const_int 8))
8815           (zero_extend:SI
8816             (match_operand 2 "ext_register_operand" "Q"))))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "TARGET_64BIT
8819    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8820   "or{b}\t{%2, %h0|%h0, %2}"
8821   [(set_attr "type" "alu")
8822    (set_attr "length_immediate" "0")
8823    (set_attr "mode" "QI")])
8824
8825 (define_insn "*iorqi_ext_2"
8826   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8827                          (const_int 8)
8828                          (const_int 8))
8829         (ior:SI 
8830           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8831                            (const_int 8)
8832                            (const_int 8))
8833           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8834                            (const_int 8)
8835                            (const_int 8))))
8836    (clobber (reg:CC FLAGS_REG))]
8837   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8838   "ior{b}\t{%h2, %h0|%h0, %h2}"
8839   [(set_attr "type" "alu")
8840    (set_attr "length_immediate" "0")
8841    (set_attr "mode" "QI")])
8842
8843 (define_split
8844   [(set (match_operand 0 "register_operand" "")
8845         (ior (match_operand 1 "register_operand" "")
8846              (match_operand 2 "const_int_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848    "reload_completed
8849     && QI_REG_P (operands[0])
8850     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851     && !(INTVAL (operands[2]) & ~(255 << 8))
8852     && GET_MODE (operands[0]) != QImode"
8853   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8854                    (ior:SI (zero_extract:SI (match_dup 1)
8855                                             (const_int 8) (const_int 8))
8856                            (match_dup 2)))
8857               (clobber (reg:CC FLAGS_REG))])]
8858   "operands[0] = gen_lowpart (SImode, operands[0]);
8859    operands[1] = gen_lowpart (SImode, operands[1]);
8860    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8861
8862 ;; Since OR can be encoded with sign extended immediate, this is only
8863 ;; profitable when 7th bit is set.
8864 (define_split
8865   [(set (match_operand 0 "register_operand" "")
8866         (ior (match_operand 1 "general_operand" "")
8867              (match_operand 2 "const_int_operand" "")))
8868    (clobber (reg:CC FLAGS_REG))]
8869    "reload_completed
8870     && ANY_QI_REG_P (operands[0])
8871     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8872     && !(INTVAL (operands[2]) & ~255)
8873     && (INTVAL (operands[2]) & 128)
8874     && GET_MODE (operands[0]) != QImode"
8875   [(parallel [(set (strict_low_part (match_dup 0))
8876                    (ior:QI (match_dup 1)
8877                            (match_dup 2)))
8878               (clobber (reg:CC FLAGS_REG))])]
8879   "operands[0] = gen_lowpart (QImode, operands[0]);
8880    operands[1] = gen_lowpart (QImode, operands[1]);
8881    operands[2] = gen_lowpart (QImode, operands[2]);")
8882 \f
8883 ;; Logical XOR instructions
8884
8885 ;; %%% This used to optimize known byte-wide and operations to memory.
8886 ;; If this is considered useful, it should be done with splitters.
8887
8888 (define_expand "xordi3"
8889   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8890         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8891                 (match_operand:DI 2 "x86_64_general_operand" "")))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "TARGET_64BIT"
8894   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8895
8896 (define_insn "*xordi_1_rex64"
8897   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8898         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8899                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8900    (clobber (reg:CC FLAGS_REG))]
8901   "TARGET_64BIT
8902    && ix86_binary_operator_ok (XOR, DImode, operands)"
8903   "@
8904    xor{q}\t{%2, %0|%0, %2}
8905    xor{q}\t{%2, %0|%0, %2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "mode" "DI,DI")])
8908
8909 (define_insn "*xordi_2_rex64"
8910   [(set (reg FLAGS_REG)
8911         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8912                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8913                  (const_int 0)))
8914    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8915         (xor:DI (match_dup 1) (match_dup 2)))]
8916   "TARGET_64BIT
8917    && ix86_match_ccmode (insn, CCNOmode)
8918    && ix86_binary_operator_ok (XOR, DImode, operands)"
8919   "@
8920    xor{q}\t{%2, %0|%0, %2}
8921    xor{q}\t{%2, %0|%0, %2}"
8922   [(set_attr "type" "alu")
8923    (set_attr "mode" "DI,DI")])
8924
8925 (define_insn "*xordi_3_rex64"
8926   [(set (reg FLAGS_REG)
8927         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8928                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8929                  (const_int 0)))
8930    (clobber (match_scratch:DI 0 "=r"))]
8931   "TARGET_64BIT
8932    && ix86_match_ccmode (insn, CCNOmode)
8933    && ix86_binary_operator_ok (XOR, DImode, operands)"
8934   "xor{q}\t{%2, %0|%0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "DI")])
8937
8938 (define_expand "xorsi3"
8939   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8940         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8941                 (match_operand:SI 2 "general_operand" "")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   ""
8944   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8945
8946 (define_insn "*xorsi_1"
8947   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8948         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8949                 (match_operand:SI 2 "general_operand" "ri,rm")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "ix86_binary_operator_ok (XOR, SImode, operands)"
8952   "xor{l}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "SI")])
8955
8956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957 ;; Add speccase for immediates
8958 (define_insn "*xorsi_1_zext"
8959   [(set (match_operand:DI 0 "register_operand" "=r")
8960         (zero_extend:DI
8961           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962                   (match_operand:SI 2 "general_operand" "rim"))))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8965   "xor{l}\t{%2, %k0|%k0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "SI")])
8968
8969 (define_insn "*xorsi_1_zext_imm"
8970   [(set (match_operand:DI 0 "register_operand" "=r")
8971         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8972                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8975   "xor{l}\t{%2, %k0|%k0, %2}"
8976   [(set_attr "type" "alu")
8977    (set_attr "mode" "SI")])
8978
8979 (define_insn "*xorsi_2"
8980   [(set (reg FLAGS_REG)
8981         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982                          (match_operand:SI 2 "general_operand" "rim,ri"))
8983                  (const_int 0)))
8984    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8985         (xor:SI (match_dup 1) (match_dup 2)))]
8986   "ix86_match_ccmode (insn, CCNOmode)
8987    && ix86_binary_operator_ok (XOR, SImode, operands)"
8988   "xor{l}\t{%2, %0|%0, %2}"
8989   [(set_attr "type" "alu")
8990    (set_attr "mode" "SI")])
8991
8992 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8993 ;; ??? Special case for immediate operand is missing - it is tricky.
8994 (define_insn "*xorsi_2_zext"
8995   [(set (reg FLAGS_REG)
8996         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8997                          (match_operand:SI 2 "general_operand" "rim"))
8998                  (const_int 0)))
8999    (set (match_operand:DI 0 "register_operand" "=r")
9000         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9001   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002    && ix86_binary_operator_ok (XOR, SImode, operands)"
9003   "xor{l}\t{%2, %k0|%k0, %2}"
9004   [(set_attr "type" "alu")
9005    (set_attr "mode" "SI")])
9006
9007 (define_insn "*xorsi_2_zext_imm"
9008   [(set (reg FLAGS_REG)
9009         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9011                  (const_int 0)))
9012    (set (match_operand:DI 0 "register_operand" "=r")
9013         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9014   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9015    && ix86_binary_operator_ok (XOR, SImode, operands)"
9016   "xor{l}\t{%2, %k0|%k0, %2}"
9017   [(set_attr "type" "alu")
9018    (set_attr "mode" "SI")])
9019
9020 (define_insn "*xorsi_3"
9021   [(set (reg FLAGS_REG)
9022         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9023                          (match_operand:SI 2 "general_operand" "rim"))
9024                  (const_int 0)))
9025    (clobber (match_scratch:SI 0 "=r"))]
9026   "ix86_match_ccmode (insn, CCNOmode)
9027    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9028   "xor{l}\t{%2, %0|%0, %2}"
9029   [(set_attr "type" "alu")
9030    (set_attr "mode" "SI")])
9031
9032 (define_expand "xorhi3"
9033   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9034         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9035                 (match_operand:HI 2 "general_operand" "")))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "TARGET_HIMODE_MATH"
9038   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9039
9040 (define_insn "*xorhi_1"
9041   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9042         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9043                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9044    (clobber (reg:CC FLAGS_REG))]
9045   "ix86_binary_operator_ok (XOR, HImode, operands)"
9046   "xor{w}\t{%2, %0|%0, %2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "HI")])
9049
9050 (define_insn "*xorhi_2"
9051   [(set (reg FLAGS_REG)
9052         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9053                          (match_operand:HI 2 "general_operand" "rim,ri"))
9054                  (const_int 0)))
9055    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9056         (xor:HI (match_dup 1) (match_dup 2)))]
9057   "ix86_match_ccmode (insn, CCNOmode)
9058    && ix86_binary_operator_ok (XOR, HImode, operands)"
9059   "xor{w}\t{%2, %0|%0, %2}"
9060   [(set_attr "type" "alu")
9061    (set_attr "mode" "HI")])
9062
9063 (define_insn "*xorhi_3"
9064   [(set (reg FLAGS_REG)
9065         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9066                          (match_operand:HI 2 "general_operand" "rim"))
9067                  (const_int 0)))
9068    (clobber (match_scratch:HI 0 "=r"))]
9069   "ix86_match_ccmode (insn, CCNOmode)
9070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9071   "xor{w}\t{%2, %0|%0, %2}"
9072   [(set_attr "type" "alu")
9073    (set_attr "mode" "HI")])
9074
9075 (define_expand "xorqi3"
9076   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9077         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9078                 (match_operand:QI 2 "general_operand" "")))
9079    (clobber (reg:CC FLAGS_REG))]
9080   "TARGET_QIMODE_MATH"
9081   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9082
9083 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9084 (define_insn "*xorqi_1"
9085   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9086         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9087                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9088    (clobber (reg:CC FLAGS_REG))]
9089   "ix86_binary_operator_ok (XOR, QImode, operands)"
9090   "@
9091    xor{b}\t{%2, %0|%0, %2}
9092    xor{b}\t{%2, %0|%0, %2}
9093    xor{l}\t{%k2, %k0|%k0, %k2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "QI,QI,SI")])
9096
9097 (define_insn "*xorqi_1_slp"
9098   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9099         (xor:QI (match_dup 0)
9100                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9103    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9104   "xor{b}\t{%1, %0|%0, %1}"
9105   [(set_attr "type" "alu1")
9106    (set_attr "mode" "QI")])
9107
9108 (define_insn "xorqi_ext_0"
9109   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110                          (const_int 8)
9111                          (const_int 8))
9112         (xor:SI 
9113           (zero_extract:SI
9114             (match_operand 1 "ext_register_operand" "0")
9115             (const_int 8)
9116             (const_int 8))
9117           (match_operand 2 "const_int_operand" "n")))
9118    (clobber (reg:CC FLAGS_REG))]
9119   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120   "xor{b}\t{%2, %h0|%h0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "length_immediate" "1")
9123    (set_attr "mode" "QI")])
9124
9125 (define_insn "*xorqi_ext_1"
9126   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127                          (const_int 8)
9128                          (const_int 8))
9129         (xor:SI 
9130           (zero_extract:SI
9131             (match_operand 1 "ext_register_operand" "0")
9132             (const_int 8)
9133             (const_int 8))
9134           (zero_extend:SI
9135             (match_operand:QI 2 "general_operand" "Qm"))))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "!TARGET_64BIT
9138    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139   "xor{b}\t{%2, %h0|%h0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "length_immediate" "0")
9142    (set_attr "mode" "QI")])
9143
9144 (define_insn "*xorqi_ext_1_rex64"
9145   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9146                          (const_int 8)
9147                          (const_int 8))
9148         (xor:SI 
9149           (zero_extract:SI
9150             (match_operand 1 "ext_register_operand" "0")
9151             (const_int 8)
9152             (const_int 8))
9153           (zero_extend:SI
9154             (match_operand 2 "ext_register_operand" "Q"))))
9155    (clobber (reg:CC FLAGS_REG))]
9156   "TARGET_64BIT
9157    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9158   "xor{b}\t{%2, %h0|%h0, %2}"
9159   [(set_attr "type" "alu")
9160    (set_attr "length_immediate" "0")
9161    (set_attr "mode" "QI")])
9162
9163 (define_insn "*xorqi_ext_2"
9164   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9165                          (const_int 8)
9166                          (const_int 8))
9167         (xor:SI 
9168           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9169                            (const_int 8)
9170                            (const_int 8))
9171           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9172                            (const_int 8)
9173                            (const_int 8))))
9174    (clobber (reg:CC FLAGS_REG))]
9175   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176   "xor{b}\t{%h2, %h0|%h0, %h2}"
9177   [(set_attr "type" "alu")
9178    (set_attr "length_immediate" "0")
9179    (set_attr "mode" "QI")])
9180
9181 (define_insn "*xorqi_cc_1"
9182   [(set (reg FLAGS_REG)
9183         (compare
9184           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9185                   (match_operand:QI 2 "general_operand" "qim,qi"))
9186           (const_int 0)))
9187    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9188         (xor:QI (match_dup 1) (match_dup 2)))]
9189   "ix86_match_ccmode (insn, CCNOmode)
9190    && ix86_binary_operator_ok (XOR, QImode, operands)"
9191   "xor{b}\t{%2, %0|%0, %2}"
9192   [(set_attr "type" "alu")
9193    (set_attr "mode" "QI")])
9194
9195 (define_insn "*xorqi_2_slp"
9196   [(set (reg FLAGS_REG)
9197         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9198                          (match_operand:QI 1 "general_operand" "qim,qi"))
9199                  (const_int 0)))
9200    (set (strict_low_part (match_dup 0))
9201         (xor:QI (match_dup 0) (match_dup 1)))]
9202   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9203    && ix86_match_ccmode (insn, CCNOmode)
9204    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9205   "xor{b}\t{%1, %0|%0, %1}"
9206   [(set_attr "type" "alu1")
9207    (set_attr "mode" "QI")])
9208
9209 (define_insn "*xorqi_cc_2"
9210   [(set (reg FLAGS_REG)
9211         (compare
9212           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9213                   (match_operand:QI 2 "general_operand" "qim"))
9214           (const_int 0)))
9215    (clobber (match_scratch:QI 0 "=q"))]
9216   "ix86_match_ccmode (insn, CCNOmode)
9217    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9218   "xor{b}\t{%2, %0|%0, %2}"
9219   [(set_attr "type" "alu")
9220    (set_attr "mode" "QI")])
9221
9222 (define_insn "*xorqi_cc_ext_1"
9223   [(set (reg FLAGS_REG)
9224         (compare
9225           (xor:SI
9226             (zero_extract:SI
9227               (match_operand 1 "ext_register_operand" "0")
9228               (const_int 8)
9229               (const_int 8))
9230             (match_operand:QI 2 "general_operand" "qmn"))
9231           (const_int 0)))
9232    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9233                          (const_int 8)
9234                          (const_int 8))
9235         (xor:SI 
9236           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9237           (match_dup 2)))]
9238   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9239   "xor{b}\t{%2, %h0|%h0, %2}"
9240   [(set_attr "type" "alu")
9241    (set_attr "mode" "QI")])
9242
9243 (define_insn "*xorqi_cc_ext_1_rex64"
9244   [(set (reg FLAGS_REG)
9245         (compare
9246           (xor:SI
9247             (zero_extract:SI
9248               (match_operand 1 "ext_register_operand" "0")
9249               (const_int 8)
9250               (const_int 8))
9251             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9252           (const_int 0)))
9253    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254                          (const_int 8)
9255                          (const_int 8))
9256         (xor:SI 
9257           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9258           (match_dup 2)))]
9259   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9260   "xor{b}\t{%2, %h0|%h0, %2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "mode" "QI")])
9263
9264 (define_expand "xorqi_cc_ext_1"
9265   [(parallel [
9266      (set (reg:CCNO FLAGS_REG)
9267           (compare:CCNO
9268             (xor:SI
9269               (zero_extract:SI
9270                 (match_operand 1 "ext_register_operand" "")
9271                 (const_int 8)
9272                 (const_int 8))
9273               (match_operand:QI 2 "general_operand" ""))
9274             (const_int 0)))
9275      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9276                            (const_int 8)
9277                            (const_int 8))
9278           (xor:SI 
9279             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9280             (match_dup 2)))])]
9281   ""
9282   "")
9283
9284 (define_split
9285   [(set (match_operand 0 "register_operand" "")
9286         (xor (match_operand 1 "register_operand" "")
9287              (match_operand 2 "const_int_operand" "")))
9288    (clobber (reg:CC FLAGS_REG))]
9289    "reload_completed
9290     && QI_REG_P (operands[0])
9291     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292     && !(INTVAL (operands[2]) & ~(255 << 8))
9293     && GET_MODE (operands[0]) != QImode"
9294   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9295                    (xor:SI (zero_extract:SI (match_dup 1)
9296                                             (const_int 8) (const_int 8))
9297                            (match_dup 2)))
9298               (clobber (reg:CC FLAGS_REG))])]
9299   "operands[0] = gen_lowpart (SImode, operands[0]);
9300    operands[1] = gen_lowpart (SImode, operands[1]);
9301    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9302
9303 ;; Since XOR can be encoded with sign extended immediate, this is only
9304 ;; profitable when 7th bit is set.
9305 (define_split
9306   [(set (match_operand 0 "register_operand" "")
9307         (xor (match_operand 1 "general_operand" "")
9308              (match_operand 2 "const_int_operand" "")))
9309    (clobber (reg:CC FLAGS_REG))]
9310    "reload_completed
9311     && ANY_QI_REG_P (operands[0])
9312     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9313     && !(INTVAL (operands[2]) & ~255)
9314     && (INTVAL (operands[2]) & 128)
9315     && GET_MODE (operands[0]) != QImode"
9316   [(parallel [(set (strict_low_part (match_dup 0))
9317                    (xor:QI (match_dup 1)
9318                            (match_dup 2)))
9319               (clobber (reg:CC FLAGS_REG))])]
9320   "operands[0] = gen_lowpart (QImode, operands[0]);
9321    operands[1] = gen_lowpart (QImode, operands[1]);
9322    operands[2] = gen_lowpart (QImode, operands[2]);")
9323 \f
9324 ;; Negation instructions
9325
9326 (define_expand "negti2"
9327   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9328                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9329               (clobber (reg:CC FLAGS_REG))])]
9330   "TARGET_64BIT"
9331   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9332
9333 (define_insn "*negti2_1"
9334   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9335         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "TARGET_64BIT
9338    && ix86_unary_operator_ok (NEG, TImode, operands)"
9339   "#")
9340
9341 (define_split
9342   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9343         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9344    (clobber (reg:CC FLAGS_REG))]
9345   "TARGET_64BIT && reload_completed"
9346   [(parallel
9347     [(set (reg:CCZ FLAGS_REG)
9348           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9349      (set (match_dup 0) (neg:DI (match_dup 2)))])
9350    (parallel
9351     [(set (match_dup 1)
9352           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9353                             (match_dup 3))
9354                    (const_int 0)))
9355      (clobber (reg:CC FLAGS_REG))])
9356    (parallel
9357     [(set (match_dup 1)
9358           (neg:DI (match_dup 1)))
9359      (clobber (reg:CC FLAGS_REG))])]
9360   "split_ti (operands+1, 1, operands+2, operands+3);
9361    split_ti (operands+0, 1, operands+0, operands+1);")
9362
9363 (define_expand "negdi2"
9364   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9365                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9366               (clobber (reg:CC FLAGS_REG))])]
9367   ""
9368   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9369
9370 (define_insn "*negdi2_1"
9371   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9372         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9373    (clobber (reg:CC FLAGS_REG))]
9374   "!TARGET_64BIT
9375    && ix86_unary_operator_ok (NEG, DImode, operands)"
9376   "#")
9377
9378 (define_split
9379   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9380         (neg:DI (match_operand:DI 1 "general_operand" "")))
9381    (clobber (reg:CC FLAGS_REG))]
9382   "!TARGET_64BIT && reload_completed"
9383   [(parallel
9384     [(set (reg:CCZ FLAGS_REG)
9385           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9386      (set (match_dup 0) (neg:SI (match_dup 2)))])
9387    (parallel
9388     [(set (match_dup 1)
9389           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9390                             (match_dup 3))
9391                    (const_int 0)))
9392      (clobber (reg:CC FLAGS_REG))])
9393    (parallel
9394     [(set (match_dup 1)
9395           (neg:SI (match_dup 1)))
9396      (clobber (reg:CC FLAGS_REG))])]
9397   "split_di (operands+1, 1, operands+2, operands+3);
9398    split_di (operands+0, 1, operands+0, operands+1);")
9399
9400 (define_insn "*negdi2_1_rex64"
9401   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9402         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9405   "neg{q}\t%0"
9406   [(set_attr "type" "negnot")
9407    (set_attr "mode" "DI")])
9408
9409 ;; The problem with neg is that it does not perform (compare x 0),
9410 ;; it really performs (compare 0 x), which leaves us with the zero
9411 ;; flag being the only useful item.
9412
9413 (define_insn "*negdi2_cmpz_rex64"
9414   [(set (reg:CCZ FLAGS_REG)
9415         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9416                      (const_int 0)))
9417    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9418         (neg:DI (match_dup 1)))]
9419   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9420   "neg{q}\t%0"
9421   [(set_attr "type" "negnot")
9422    (set_attr "mode" "DI")])
9423
9424
9425 (define_expand "negsi2"
9426   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9427                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9428               (clobber (reg:CC FLAGS_REG))])]
9429   ""
9430   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9431
9432 (define_insn "*negsi2_1"
9433   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9434         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9435    (clobber (reg:CC FLAGS_REG))]
9436   "ix86_unary_operator_ok (NEG, SImode, operands)"
9437   "neg{l}\t%0"
9438   [(set_attr "type" "negnot")
9439    (set_attr "mode" "SI")])
9440
9441 ;; Combine is quite creative about this pattern.
9442 (define_insn "*negsi2_1_zext"
9443   [(set (match_operand:DI 0 "register_operand" "=r")
9444         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9445                                         (const_int 32)))
9446                      (const_int 32)))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9449   "neg{l}\t%k0"
9450   [(set_attr "type" "negnot")
9451    (set_attr "mode" "SI")])
9452
9453 ;; The problem with neg is that it does not perform (compare x 0),
9454 ;; it really performs (compare 0 x), which leaves us with the zero
9455 ;; flag being the only useful item.
9456
9457 (define_insn "*negsi2_cmpz"
9458   [(set (reg:CCZ FLAGS_REG)
9459         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9460                      (const_int 0)))
9461    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9462         (neg:SI (match_dup 1)))]
9463   "ix86_unary_operator_ok (NEG, SImode, operands)"
9464   "neg{l}\t%0"
9465   [(set_attr "type" "negnot")
9466    (set_attr "mode" "SI")])
9467
9468 (define_insn "*negsi2_cmpz_zext"
9469   [(set (reg:CCZ FLAGS_REG)
9470         (compare:CCZ (lshiftrt:DI
9471                        (neg:DI (ashift:DI
9472                                  (match_operand:DI 1 "register_operand" "0")
9473                                  (const_int 32)))
9474                        (const_int 32))
9475                      (const_int 0)))
9476    (set (match_operand:DI 0 "register_operand" "=r")
9477         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9478                                         (const_int 32)))
9479                      (const_int 32)))]
9480   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9481   "neg{l}\t%k0"
9482   [(set_attr "type" "negnot")
9483    (set_attr "mode" "SI")])
9484
9485 (define_expand "neghi2"
9486   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9487                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9488               (clobber (reg:CC FLAGS_REG))])]
9489   "TARGET_HIMODE_MATH"
9490   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9491
9492 (define_insn "*neghi2_1"
9493   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9494         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9495    (clobber (reg:CC FLAGS_REG))]
9496   "ix86_unary_operator_ok (NEG, HImode, operands)"
9497   "neg{w}\t%0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "HI")])
9500
9501 (define_insn "*neghi2_cmpz"
9502   [(set (reg:CCZ FLAGS_REG)
9503         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9504                      (const_int 0)))
9505    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9506         (neg:HI (match_dup 1)))]
9507   "ix86_unary_operator_ok (NEG, HImode, operands)"
9508   "neg{w}\t%0"
9509   [(set_attr "type" "negnot")
9510    (set_attr "mode" "HI")])
9511
9512 (define_expand "negqi2"
9513   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9514                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9515               (clobber (reg:CC FLAGS_REG))])]
9516   "TARGET_QIMODE_MATH"
9517   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9518
9519 (define_insn "*negqi2_1"
9520   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9521         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "ix86_unary_operator_ok (NEG, QImode, operands)"
9524   "neg{b}\t%0"
9525   [(set_attr "type" "negnot")
9526    (set_attr "mode" "QI")])
9527
9528 (define_insn "*negqi2_cmpz"
9529   [(set (reg:CCZ FLAGS_REG)
9530         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9531                      (const_int 0)))
9532    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9533         (neg:QI (match_dup 1)))]
9534   "ix86_unary_operator_ok (NEG, QImode, operands)"
9535   "neg{b}\t%0"
9536   [(set_attr "type" "negnot")
9537    (set_attr "mode" "QI")])
9538
9539 ;; Changing of sign for FP values is doable using integer unit too.
9540
9541 (define_expand "negsf2"
9542   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544   "TARGET_80387 || TARGET_SSE_MATH"
9545   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9546
9547 (define_expand "abssf2"
9548   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9550   "TARGET_80387 || TARGET_SSE_MATH"
9551   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9552
9553 (define_insn "*absnegsf2_mixed"
9554   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9555         (match_operator:SF 3 "absneg_operator"
9556           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9557    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9560    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9561   "#")
9562
9563 (define_insn "*absnegsf2_sse"
9564   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9565         (match_operator:SF 3 "absneg_operator"
9566           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9567    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9568    (clobber (reg:CC FLAGS_REG))]
9569   "TARGET_SSE_MATH
9570    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9571   "#")
9572
9573 (define_insn "*absnegsf2_i387"
9574   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9575         (match_operator:SF 3 "absneg_operator"
9576           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9577    (use (match_operand 2 "" ""))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_80387 && !TARGET_SSE_MATH
9580    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581   "#")
9582
9583 (define_expand "copysignsf3"
9584   [(match_operand:SF 0 "register_operand" "")
9585    (match_operand:SF 1 "nonmemory_operand" "")
9586    (match_operand:SF 2 "register_operand" "")]
9587   "TARGET_SSE_MATH"
9588 {
9589   ix86_expand_copysign (operands);
9590   DONE;
9591 })
9592
9593 (define_insn_and_split "copysignsf3_const"
9594   [(set (match_operand:SF 0 "register_operand"          "=x")
9595         (unspec:SF
9596           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9597            (match_operand:SF 2 "register_operand"       "0")
9598            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9599           UNSPEC_COPYSIGN))]
9600   "TARGET_SSE_MATH"
9601   "#"
9602   "&& reload_completed"
9603   [(const_int 0)]
9604 {
9605   ix86_split_copysign_const (operands);
9606   DONE;
9607 })
9608
9609 (define_insn "copysignsf3_var"
9610   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9611         (unspec:SF
9612           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9613            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9614            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9615            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9616           UNSPEC_COPYSIGN))
9617    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9618   "TARGET_SSE_MATH"
9619   "#")
9620
9621 (define_split
9622   [(set (match_operand:SF 0 "register_operand" "")
9623         (unspec:SF
9624           [(match_operand:SF 2 "register_operand" "")
9625            (match_operand:SF 3 "register_operand" "")
9626            (match_operand:V4SF 4 "" "")
9627            (match_operand:V4SF 5 "" "")]
9628           UNSPEC_COPYSIGN))
9629    (clobber (match_scratch:V4SF 1 ""))]
9630   "TARGET_SSE_MATH && reload_completed"
9631   [(const_int 0)]
9632 {
9633   ix86_split_copysign_var (operands);
9634   DONE;
9635 })
9636
9637 (define_expand "negdf2"
9638   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9642
9643 (define_expand "absdf2"
9644   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9645         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9646   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9647   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9648
9649 (define_insn "*absnegdf2_mixed"
9650   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9651         (match_operator:DF 3 "absneg_operator"
9652           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9653    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9654    (clobber (reg:CC FLAGS_REG))]
9655   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9656    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9657   "#")
9658
9659 (define_insn "*absnegdf2_sse"
9660   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9661         (match_operator:DF 3 "absneg_operator"
9662           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9663    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9664    (clobber (reg:CC FLAGS_REG))]
9665   "TARGET_SSE2 && TARGET_SSE_MATH
9666    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9667   "#")
9668
9669 (define_insn "*absnegdf2_i387"
9670   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9671         (match_operator:DF 3 "absneg_operator"
9672           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9673    (use (match_operand 2 "" ""))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9676    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9677   "#")
9678
9679 (define_expand "copysigndf3"
9680   [(match_operand:DF 0 "register_operand" "")
9681    (match_operand:DF 1 "nonmemory_operand" "")
9682    (match_operand:DF 2 "register_operand" "")]
9683   "TARGET_SSE2 && TARGET_SSE_MATH"
9684 {
9685   ix86_expand_copysign (operands);
9686   DONE;
9687 })
9688
9689 (define_insn_and_split "copysigndf3_const"
9690   [(set (match_operand:DF 0 "register_operand"          "=x")
9691         (unspec:DF
9692           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9693            (match_operand:DF 2 "register_operand"       "0")
9694            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9695           UNSPEC_COPYSIGN))]
9696   "TARGET_SSE2 && TARGET_SSE_MATH"
9697   "#"
9698   "&& reload_completed"
9699   [(const_int 0)]
9700 {
9701   ix86_split_copysign_const (operands);
9702   DONE;
9703 })
9704
9705 (define_insn "copysigndf3_var"
9706   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9707         (unspec:DF
9708           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9709            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9710            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9711            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9712           UNSPEC_COPYSIGN))
9713    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9714   "TARGET_SSE2 && TARGET_SSE_MATH"
9715   "#")
9716
9717 (define_split
9718   [(set (match_operand:DF 0 "register_operand" "")
9719         (unspec:DF
9720           [(match_operand:DF 2 "register_operand" "")
9721            (match_operand:DF 3 "register_operand" "")
9722            (match_operand:V2DF 4 "" "")
9723            (match_operand:V2DF 5 "" "")]
9724           UNSPEC_COPYSIGN))
9725    (clobber (match_scratch:V2DF 1 ""))]
9726   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9727   [(const_int 0)]
9728 {
9729   ix86_split_copysign_var (operands);
9730   DONE;
9731 })
9732
9733 (define_expand "negxf2"
9734   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736   "TARGET_80387"
9737   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9738
9739 (define_expand "absxf2"
9740   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9741         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9742   "TARGET_80387"
9743   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9744
9745 (define_insn "*absnegxf2_i387"
9746   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9747         (match_operator:XF 3 "absneg_operator"
9748           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9749    (use (match_operand 2 "" ""))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "TARGET_80387
9752    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9753   "#")
9754
9755 ;; Splitters for fp abs and neg.
9756
9757 (define_split
9758   [(set (match_operand 0 "fp_register_operand" "")
9759         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9760    (use (match_operand 2 "" ""))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "reload_completed"
9763   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9764
9765 (define_split
9766   [(set (match_operand 0 "register_operand" "")
9767         (match_operator 3 "absneg_operator"
9768           [(match_operand 1 "register_operand" "")]))
9769    (use (match_operand 2 "nonimmediate_operand" ""))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "reload_completed && SSE_REG_P (operands[0])"
9772   [(set (match_dup 0) (match_dup 3))]
9773 {
9774   enum machine_mode mode = GET_MODE (operands[0]);
9775   enum machine_mode vmode = GET_MODE (operands[2]);
9776   rtx tmp;
9777   
9778   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9779   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9780   if (operands_match_p (operands[0], operands[2]))
9781     {
9782       tmp = operands[1];
9783       operands[1] = operands[2];
9784       operands[2] = tmp;
9785     }
9786   if (GET_CODE (operands[3]) == ABS)
9787     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9788   else
9789     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9790   operands[3] = tmp;
9791 })
9792
9793 (define_split
9794   [(set (match_operand:SF 0 "register_operand" "")
9795         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9796    (use (match_operand:V4SF 2 "" ""))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "reload_completed"
9799   [(parallel [(set (match_dup 0) (match_dup 1))
9800               (clobber (reg:CC FLAGS_REG))])]
9801
9802   rtx tmp;
9803   operands[0] = gen_lowpart (SImode, operands[0]);
9804   if (GET_CODE (operands[1]) == ABS)
9805     {
9806       tmp = gen_int_mode (0x7fffffff, SImode);
9807       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9808     }
9809   else
9810     {
9811       tmp = gen_int_mode (0x80000000, SImode);
9812       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9813     }
9814   operands[1] = tmp;
9815 })
9816
9817 (define_split
9818   [(set (match_operand:DF 0 "register_operand" "")
9819         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9820    (use (match_operand 2 "" ""))
9821    (clobber (reg:CC FLAGS_REG))]
9822   "reload_completed"
9823   [(parallel [(set (match_dup 0) (match_dup 1))
9824               (clobber (reg:CC FLAGS_REG))])]
9825 {
9826   rtx tmp;
9827   if (TARGET_64BIT)
9828     {
9829       tmp = gen_lowpart (DImode, operands[0]);
9830       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9831       operands[0] = tmp;
9832
9833       if (GET_CODE (operands[1]) == ABS)
9834         tmp = const0_rtx;
9835       else
9836         tmp = gen_rtx_NOT (DImode, tmp);
9837     }
9838   else
9839     {
9840       operands[0] = gen_highpart (SImode, operands[0]);
9841       if (GET_CODE (operands[1]) == ABS)
9842         {
9843           tmp = gen_int_mode (0x7fffffff, SImode);
9844           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9845         }
9846       else
9847         {
9848           tmp = gen_int_mode (0x80000000, SImode);
9849           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9850         }
9851     }
9852   operands[1] = tmp;
9853 })
9854
9855 (define_split
9856   [(set (match_operand:XF 0 "register_operand" "")
9857         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9858    (use (match_operand 2 "" ""))
9859    (clobber (reg:CC FLAGS_REG))]
9860   "reload_completed"
9861   [(parallel [(set (match_dup 0) (match_dup 1))
9862               (clobber (reg:CC FLAGS_REG))])]
9863 {
9864   rtx tmp;
9865   operands[0] = gen_rtx_REG (SImode,
9866                              true_regnum (operands[0])
9867                              + (TARGET_64BIT ? 1 : 2));
9868   if (GET_CODE (operands[1]) == ABS)
9869     {
9870       tmp = GEN_INT (0x7fff);
9871       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9872     }
9873   else
9874     {
9875       tmp = GEN_INT (0x8000);
9876       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9877     }
9878   operands[1] = tmp;
9879 })
9880
9881 (define_split
9882   [(set (match_operand 0 "memory_operand" "")
9883         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9884    (use (match_operand 2 "" ""))
9885    (clobber (reg:CC FLAGS_REG))]
9886   "reload_completed"
9887   [(parallel [(set (match_dup 0) (match_dup 1))
9888               (clobber (reg:CC FLAGS_REG))])]
9889 {
9890   enum machine_mode mode = GET_MODE (operands[0]);
9891   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9892   rtx tmp;
9893
9894   operands[0] = adjust_address (operands[0], QImode, size - 1);
9895   if (GET_CODE (operands[1]) == ABS)
9896     {
9897       tmp = gen_int_mode (0x7f, QImode);
9898       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9899     }
9900   else
9901     {
9902       tmp = gen_int_mode (0x80, QImode);
9903       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9904     }
9905   operands[1] = tmp;
9906 })
9907
9908 ;; Conditionalize these after reload. If they match before reload, we 
9909 ;; lose the clobber and ability to use integer instructions.
9910
9911 (define_insn "*negsf2_1"
9912   [(set (match_operand:SF 0 "register_operand" "=f")
9913         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9915   "fchs"
9916   [(set_attr "type" "fsgn")
9917    (set_attr "mode" "SF")])
9918
9919 (define_insn "*negdf2_1"
9920   [(set (match_operand:DF 0 "register_operand" "=f")
9921         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9926
9927 (define_insn "*negxf2_1"
9928   [(set (match_operand:XF 0 "register_operand" "=f")
9929         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9930   "TARGET_80387"
9931   "fchs"
9932   [(set_attr "type" "fsgn")
9933    (set_attr "mode" "XF")])
9934
9935 (define_insn "*abssf2_1"
9936   [(set (match_operand:SF 0 "register_operand" "=f")
9937         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9938   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9939   "fabs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "SF")])
9942
9943 (define_insn "*absdf2_1"
9944   [(set (match_operand:DF 0 "register_operand" "=f")
9945         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9946   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9947   "fabs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "DF")])
9950
9951 (define_insn "*absxf2_1"
9952   [(set (match_operand:XF 0 "register_operand" "=f")
9953         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9954   "TARGET_80387"
9955   "fabs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "DF")])
9958
9959 (define_insn "*negextendsfdf2"
9960   [(set (match_operand:DF 0 "register_operand" "=f")
9961         (neg:DF (float_extend:DF
9962                   (match_operand:SF 1 "register_operand" "0"))))]
9963   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9964   "fchs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "DF")])
9967
9968 (define_insn "*negextenddfxf2"
9969   [(set (match_operand:XF 0 "register_operand" "=f")
9970         (neg:XF (float_extend:XF
9971                   (match_operand:DF 1 "register_operand" "0"))))]
9972   "TARGET_80387"
9973   "fchs"
9974   [(set_attr "type" "fsgn")
9975    (set_attr "mode" "XF")])
9976
9977 (define_insn "*negextendsfxf2"
9978   [(set (match_operand:XF 0 "register_operand" "=f")
9979         (neg:XF (float_extend:XF
9980                   (match_operand:SF 1 "register_operand" "0"))))]
9981   "TARGET_80387"
9982   "fchs"
9983   [(set_attr "type" "fsgn")
9984    (set_attr "mode" "XF")])
9985
9986 (define_insn "*absextendsfdf2"
9987   [(set (match_operand:DF 0 "register_operand" "=f")
9988         (abs:DF (float_extend:DF
9989                   (match_operand:SF 1 "register_operand" "0"))))]
9990   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9991   "fabs"
9992   [(set_attr "type" "fsgn")
9993    (set_attr "mode" "DF")])
9994
9995 (define_insn "*absextenddfxf2"
9996   [(set (match_operand:XF 0 "register_operand" "=f")
9997         (abs:XF (float_extend:XF
9998           (match_operand:DF 1 "register_operand" "0"))))]
9999   "TARGET_80387"
10000   "fabs"
10001   [(set_attr "type" "fsgn")
10002    (set_attr "mode" "XF")])
10003
10004 (define_insn "*absextendsfxf2"
10005   [(set (match_operand:XF 0 "register_operand" "=f")
10006         (abs:XF (float_extend:XF
10007           (match_operand:SF 1 "register_operand" "0"))))]
10008   "TARGET_80387"
10009   "fabs"
10010   [(set_attr "type" "fsgn")
10011    (set_attr "mode" "XF")])
10012 \f
10013 ;; One complement instructions
10014
10015 (define_expand "one_cmpldi2"
10016   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10017         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10018   "TARGET_64BIT"
10019   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10020
10021 (define_insn "*one_cmpldi2_1_rex64"
10022   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10023         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10024   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10025   "not{q}\t%0"
10026   [(set_attr "type" "negnot")
10027    (set_attr "mode" "DI")])
10028
10029 (define_insn "*one_cmpldi2_2_rex64"
10030   [(set (reg FLAGS_REG)
10031         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10032                  (const_int 0)))
10033    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10034         (not:DI (match_dup 1)))]
10035   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10036    && ix86_unary_operator_ok (NOT, DImode, operands)"
10037   "#"
10038   [(set_attr "type" "alu1")
10039    (set_attr "mode" "DI")])
10040
10041 (define_split
10042   [(set (match_operand 0 "flags_reg_operand" "")
10043         (match_operator 2 "compare_operator"
10044           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10045            (const_int 0)]))
10046    (set (match_operand:DI 1 "nonimmediate_operand" "")
10047         (not:DI (match_dup 3)))]
10048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10049   [(parallel [(set (match_dup 0)
10050                    (match_op_dup 2
10051                      [(xor:DI (match_dup 3) (const_int -1))
10052                       (const_int 0)]))
10053               (set (match_dup 1)
10054                    (xor:DI (match_dup 3) (const_int -1)))])]
10055   "")
10056
10057 (define_expand "one_cmplsi2"
10058   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10059         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10060   ""
10061   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10062
10063 (define_insn "*one_cmplsi2_1"
10064   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10066   "ix86_unary_operator_ok (NOT, SImode, operands)"
10067   "not{l}\t%0"
10068   [(set_attr "type" "negnot")
10069    (set_attr "mode" "SI")])
10070
10071 ;; ??? Currently never generated - xor is used instead.
10072 (define_insn "*one_cmplsi2_1_zext"
10073   [(set (match_operand:DI 0 "register_operand" "=r")
10074         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10075   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10076   "not{l}\t%k0"
10077   [(set_attr "type" "negnot")
10078    (set_attr "mode" "SI")])
10079
10080 (define_insn "*one_cmplsi2_2"
10081   [(set (reg FLAGS_REG)
10082         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10083                  (const_int 0)))
10084    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10085         (not:SI (match_dup 1)))]
10086   "ix86_match_ccmode (insn, CCNOmode)
10087    && ix86_unary_operator_ok (NOT, SImode, operands)"
10088   "#"
10089   [(set_attr "type" "alu1")
10090    (set_attr "mode" "SI")])
10091
10092 (define_split
10093   [(set (match_operand 0 "flags_reg_operand" "")
10094         (match_operator 2 "compare_operator"
10095           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10096            (const_int 0)]))
10097    (set (match_operand:SI 1 "nonimmediate_operand" "")
10098         (not:SI (match_dup 3)))]
10099   "ix86_match_ccmode (insn, CCNOmode)"
10100   [(parallel [(set (match_dup 0)
10101                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10102                                     (const_int 0)]))
10103               (set (match_dup 1)
10104                    (xor:SI (match_dup 3) (const_int -1)))])]
10105   "")
10106
10107 ;; ??? Currently never generated - xor is used instead.
10108 (define_insn "*one_cmplsi2_2_zext"
10109   [(set (reg FLAGS_REG)
10110         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10111                  (const_int 0)))
10112    (set (match_operand:DI 0 "register_operand" "=r")
10113         (zero_extend:DI (not:SI (match_dup 1))))]
10114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10115    && ix86_unary_operator_ok (NOT, SImode, operands)"
10116   "#"
10117   [(set_attr "type" "alu1")
10118    (set_attr "mode" "SI")])
10119
10120 (define_split
10121   [(set (match_operand 0 "flags_reg_operand" "")
10122         (match_operator 2 "compare_operator"
10123           [(not:SI (match_operand:SI 3 "register_operand" ""))
10124            (const_int 0)]))
10125    (set (match_operand:DI 1 "register_operand" "")
10126         (zero_extend:DI (not:SI (match_dup 3))))]
10127   "ix86_match_ccmode (insn, CCNOmode)"
10128   [(parallel [(set (match_dup 0)
10129                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10130                                     (const_int 0)]))
10131               (set (match_dup 1)
10132                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10133   "")
10134
10135 (define_expand "one_cmplhi2"
10136   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10137         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10138   "TARGET_HIMODE_MATH"
10139   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10140
10141 (define_insn "*one_cmplhi2_1"
10142   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10143         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10144   "ix86_unary_operator_ok (NOT, HImode, operands)"
10145   "not{w}\t%0"
10146   [(set_attr "type" "negnot")
10147    (set_attr "mode" "HI")])
10148
10149 (define_insn "*one_cmplhi2_2"
10150   [(set (reg FLAGS_REG)
10151         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10152                  (const_int 0)))
10153    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154         (not:HI (match_dup 1)))]
10155   "ix86_match_ccmode (insn, CCNOmode)
10156    && ix86_unary_operator_ok (NEG, HImode, operands)"
10157   "#"
10158   [(set_attr "type" "alu1")
10159    (set_attr "mode" "HI")])
10160
10161 (define_split
10162   [(set (match_operand 0 "flags_reg_operand" "")
10163         (match_operator 2 "compare_operator"
10164           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10165            (const_int 0)]))
10166    (set (match_operand:HI 1 "nonimmediate_operand" "")
10167         (not:HI (match_dup 3)))]
10168   "ix86_match_ccmode (insn, CCNOmode)"
10169   [(parallel [(set (match_dup 0)
10170                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10171                                     (const_int 0)]))
10172               (set (match_dup 1)
10173                    (xor:HI (match_dup 3) (const_int -1)))])]
10174   "")
10175
10176 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10177 (define_expand "one_cmplqi2"
10178   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10179         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10180   "TARGET_QIMODE_MATH"
10181   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10182
10183 (define_insn "*one_cmplqi2_1"
10184   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10185         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10186   "ix86_unary_operator_ok (NOT, QImode, operands)"
10187   "@
10188    not{b}\t%0
10189    not{l}\t%k0"
10190   [(set_attr "type" "negnot")
10191    (set_attr "mode" "QI,SI")])
10192
10193 (define_insn "*one_cmplqi2_2"
10194   [(set (reg FLAGS_REG)
10195         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10196                  (const_int 0)))
10197    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10198         (not:QI (match_dup 1)))]
10199   "ix86_match_ccmode (insn, CCNOmode)
10200    && ix86_unary_operator_ok (NOT, QImode, operands)"
10201   "#"
10202   [(set_attr "type" "alu1")
10203    (set_attr "mode" "QI")])
10204
10205 (define_split
10206   [(set (match_operand 0 "flags_reg_operand" "")
10207         (match_operator 2 "compare_operator"
10208           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10209            (const_int 0)]))
10210    (set (match_operand:QI 1 "nonimmediate_operand" "")
10211         (not:QI (match_dup 3)))]
10212   "ix86_match_ccmode (insn, CCNOmode)"
10213   [(parallel [(set (match_dup 0)
10214                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10215                                     (const_int 0)]))
10216               (set (match_dup 1)
10217                    (xor:QI (match_dup 3) (const_int -1)))])]
10218   "")
10219 \f
10220 ;; Arithmetic shift instructions
10221
10222 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10223 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10224 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10225 ;; from the assembler input.
10226 ;;
10227 ;; This instruction shifts the target reg/mem as usual, but instead of
10228 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10229 ;; is a left shift double, bits are taken from the high order bits of
10230 ;; reg, else if the insn is a shift right double, bits are taken from the
10231 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10232 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10233 ;;
10234 ;; Since sh[lr]d does not change the `reg' operand, that is done
10235 ;; separately, making all shifts emit pairs of shift double and normal
10236 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10237 ;; support a 63 bit shift, each shift where the count is in a reg expands
10238 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10239 ;;
10240 ;; If the shift count is a constant, we need never emit more than one
10241 ;; shift pair, instead using moves and sign extension for counts greater
10242 ;; than 31.
10243
10244 (define_expand "ashlti3"
10245   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10246                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10247                               (match_operand:QI 2 "nonmemory_operand" "")))
10248               (clobber (reg:CC FLAGS_REG))])]
10249   "TARGET_64BIT"
10250 {
10251   if (! immediate_operand (operands[2], QImode))
10252     {
10253       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10254       DONE;
10255     }
10256   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10257   DONE;
10258 })
10259
10260 (define_insn "ashlti3_1"
10261   [(set (match_operand:TI 0 "register_operand" "=r")
10262         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10263                    (match_operand:QI 2 "register_operand" "c")))
10264    (clobber (match_scratch:DI 3 "=&r"))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "TARGET_64BIT"
10267   "#"
10268   [(set_attr "type" "multi")])
10269
10270 (define_insn "*ashlti3_2"
10271   [(set (match_operand:TI 0 "register_operand" "=r")
10272         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10273                    (match_operand:QI 2 "immediate_operand" "O")))
10274    (clobber (reg:CC FLAGS_REG))]
10275   "TARGET_64BIT"
10276   "#"
10277   [(set_attr "type" "multi")])
10278
10279 (define_split
10280   [(set (match_operand:TI 0 "register_operand" "")
10281         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10282                    (match_operand:QI 2 "register_operand" "")))
10283    (clobber (match_scratch:DI 3 ""))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "TARGET_64BIT && reload_completed"
10286   [(const_int 0)]
10287   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10288
10289 (define_split
10290   [(set (match_operand:TI 0 "register_operand" "")
10291         (ashift:TI (match_operand:TI 1 "register_operand" "")
10292                    (match_operand:QI 2 "immediate_operand" "")))
10293    (clobber (reg:CC FLAGS_REG))]
10294   "TARGET_64BIT && reload_completed"
10295   [(const_int 0)]
10296   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10297
10298 (define_insn "x86_64_shld"
10299   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10300         (ior:DI (ashift:DI (match_dup 0)
10301                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10302                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10303                   (minus:QI (const_int 64) (match_dup 2)))))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "TARGET_64BIT"
10306   "@
10307    shld{q}\t{%2, %1, %0|%0, %1, %2}
10308    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10309   [(set_attr "type" "ishift")
10310    (set_attr "prefix_0f" "1")
10311    (set_attr "mode" "DI")
10312    (set_attr "athlon_decode" "vector")])
10313
10314 (define_expand "x86_64_shift_adj"
10315   [(set (reg:CCZ FLAGS_REG)
10316         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10317                              (const_int 64))
10318                      (const_int 0)))
10319    (set (match_operand:DI 0 "register_operand" "")
10320         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10321                          (match_operand:DI 1 "register_operand" "")
10322                          (match_dup 0)))
10323    (set (match_dup 1)
10324         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10325                          (match_operand:DI 3 "register_operand" "r")
10326                          (match_dup 1)))]
10327   "TARGET_64BIT"
10328   "")
10329
10330 (define_expand "ashldi3"
10331   [(set (match_operand:DI 0 "shiftdi_operand" "")
10332         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10333                    (match_operand:QI 2 "nonmemory_operand" "")))]
10334   ""
10335   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10336
10337 (define_insn "*ashldi3_1_rex64"
10338   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10339         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10340                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10343 {
10344   switch (get_attr_type (insn))
10345     {
10346     case TYPE_ALU:
10347       gcc_assert (operands[2] == const1_rtx);
10348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10349       return "add{q}\t{%0, %0|%0, %0}";
10350
10351     case TYPE_LEA:
10352       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10353       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10354       operands[1] = gen_rtx_MULT (DImode, operands[1],
10355                                   GEN_INT (1 << INTVAL (operands[2])));
10356       return "lea{q}\t{%a1, %0|%0, %a1}";
10357
10358     default:
10359       if (REG_P (operands[2]))
10360         return "sal{q}\t{%b2, %0|%0, %b2}";
10361       else if (operands[2] == const1_rtx
10362                && (TARGET_SHIFT1 || optimize_size))
10363         return "sal{q}\t%0";
10364       else
10365         return "sal{q}\t{%2, %0|%0, %2}";
10366     }
10367 }
10368   [(set (attr "type")
10369      (cond [(eq_attr "alternative" "1")
10370               (const_string "lea")
10371             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10372                           (const_int 0))
10373                       (match_operand 0 "register_operand" ""))
10374                  (match_operand 2 "const1_operand" ""))
10375               (const_string "alu")
10376            ]
10377            (const_string "ishift")))
10378    (set_attr "mode" "DI")])
10379
10380 ;; Convert lea to the lea pattern to avoid flags dependency.
10381 (define_split
10382   [(set (match_operand:DI 0 "register_operand" "")
10383         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10384                    (match_operand:QI 2 "immediate_operand" "")))
10385    (clobber (reg:CC FLAGS_REG))]
10386   "TARGET_64BIT && reload_completed
10387    && true_regnum (operands[0]) != true_regnum (operands[1])"
10388   [(set (match_dup 0)
10389         (mult:DI (match_dup 1)
10390                  (match_dup 2)))]
10391   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10392
10393 ;; This pattern can't accept a variable shift count, since shifts by
10394 ;; zero don't affect the flags.  We assume that shifts by constant
10395 ;; zero are optimized away.
10396 (define_insn "*ashldi3_cmp_rex64"
10397   [(set (reg FLAGS_REG)
10398         (compare
10399           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400                      (match_operand:QI 2 "immediate_operand" "e"))
10401           (const_int 0)))
10402    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403         (ashift:DI (match_dup 1) (match_dup 2)))]
10404   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10406    && (optimize_size
10407        || !TARGET_PARTIAL_FLAG_REG_STALL
10408        || (operands[2] == const1_rtx
10409            && (TARGET_SHIFT1
10410                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10411 {
10412   switch (get_attr_type (insn))
10413     {
10414     case TYPE_ALU:
10415       gcc_assert (operands[2] == const1_rtx);
10416       return "add{q}\t{%0, %0|%0, %0}";
10417
10418     default:
10419       if (REG_P (operands[2]))
10420         return "sal{q}\t{%b2, %0|%0, %b2}";
10421       else if (operands[2] == const1_rtx
10422                && (TARGET_SHIFT1 || optimize_size))
10423         return "sal{q}\t%0";
10424       else
10425         return "sal{q}\t{%2, %0|%0, %2}";
10426     }
10427 }
10428   [(set (attr "type")
10429      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10430                           (const_int 0))
10431                       (match_operand 0 "register_operand" ""))
10432                  (match_operand 2 "const1_operand" ""))
10433               (const_string "alu")
10434            ]
10435            (const_string "ishift")))
10436    (set_attr "mode" "DI")])
10437
10438 (define_insn "*ashldi3_cconly_rex64"
10439   [(set (reg FLAGS_REG)
10440         (compare
10441           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10442                      (match_operand:QI 2 "immediate_operand" "e"))
10443           (const_int 0)))
10444    (clobber (match_scratch:DI 0 "=r"))]
10445   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10446    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10447    && (optimize_size
10448        || !TARGET_PARTIAL_FLAG_REG_STALL
10449        || (operands[2] == const1_rtx
10450            && (TARGET_SHIFT1
10451                || TARGET_DOUBLE_WITH_ADD)))"
10452 {
10453   switch (get_attr_type (insn))
10454     {
10455     case TYPE_ALU:
10456       gcc_assert (operands[2] == const1_rtx);
10457       return "add{q}\t{%0, %0|%0, %0}";
10458
10459     default:
10460       if (REG_P (operands[2]))
10461         return "sal{q}\t{%b2, %0|%0, %b2}";
10462       else if (operands[2] == const1_rtx
10463                && (TARGET_SHIFT1 || optimize_size))
10464         return "sal{q}\t%0";
10465       else
10466         return "sal{q}\t{%2, %0|%0, %2}";
10467     }
10468 }
10469   [(set (attr "type")
10470      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10471                           (const_int 0))
10472                       (match_operand 0 "register_operand" ""))
10473                  (match_operand 2 "const1_operand" ""))
10474               (const_string "alu")
10475            ]
10476            (const_string "ishift")))
10477    (set_attr "mode" "DI")])
10478
10479 (define_insn "*ashldi3_1"
10480   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10481         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10482                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10483    (clobber (reg:CC FLAGS_REG))]
10484   "!TARGET_64BIT"
10485   "#"
10486   [(set_attr "type" "multi")])
10487
10488 ;; By default we don't ask for a scratch register, because when DImode
10489 ;; values are manipulated, registers are already at a premium.  But if
10490 ;; we have one handy, we won't turn it away.
10491 (define_peephole2
10492   [(match_scratch:SI 3 "r")
10493    (parallel [(set (match_operand:DI 0 "register_operand" "")
10494                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10495                               (match_operand:QI 2 "nonmemory_operand" "")))
10496               (clobber (reg:CC FLAGS_REG))])
10497    (match_dup 3)]
10498   "!TARGET_64BIT && TARGET_CMOVE"
10499   [(const_int 0)]
10500   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10501
10502 (define_split
10503   [(set (match_operand:DI 0 "register_operand" "")
10504         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10505                    (match_operand:QI 2 "nonmemory_operand" "")))
10506    (clobber (reg:CC FLAGS_REG))]
10507   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10508                      ? flow2_completed : reload_completed)"
10509   [(const_int 0)]
10510   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10511
10512 (define_insn "x86_shld_1"
10513   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10514         (ior:SI (ashift:SI (match_dup 0)
10515                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10516                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10517                   (minus:QI (const_int 32) (match_dup 2)))))
10518    (clobber (reg:CC FLAGS_REG))]
10519   ""
10520   "@
10521    shld{l}\t{%2, %1, %0|%0, %1, %2}
10522    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10523   [(set_attr "type" "ishift")
10524    (set_attr "prefix_0f" "1")
10525    (set_attr "mode" "SI")
10526    (set_attr "pent_pair" "np")
10527    (set_attr "athlon_decode" "vector")])
10528
10529 (define_expand "x86_shift_adj_1"
10530   [(set (reg:CCZ FLAGS_REG)
10531         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10532                              (const_int 32))
10533                      (const_int 0)))
10534    (set (match_operand:SI 0 "register_operand" "")
10535         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10536                          (match_operand:SI 1 "register_operand" "")
10537                          (match_dup 0)))
10538    (set (match_dup 1)
10539         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10540                          (match_operand:SI 3 "register_operand" "r")
10541                          (match_dup 1)))]
10542   "TARGET_CMOVE"
10543   "")
10544
10545 (define_expand "x86_shift_adj_2"
10546   [(use (match_operand:SI 0 "register_operand" ""))
10547    (use (match_operand:SI 1 "register_operand" ""))
10548    (use (match_operand:QI 2 "register_operand" ""))]
10549   ""
10550 {
10551   rtx label = gen_label_rtx ();
10552   rtx tmp;
10553
10554   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10555
10556   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10557   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10558   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10559                               gen_rtx_LABEL_REF (VOIDmode, label),
10560                               pc_rtx);
10561   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10562   JUMP_LABEL (tmp) = label;
10563
10564   emit_move_insn (operands[0], operands[1]);
10565   ix86_expand_clear (operands[1]);
10566
10567   emit_label (label);
10568   LABEL_NUSES (label) = 1;
10569
10570   DONE;
10571 })
10572
10573 (define_expand "ashlsi3"
10574   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10575         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10576                    (match_operand:QI 2 "nonmemory_operand" "")))
10577    (clobber (reg:CC FLAGS_REG))]
10578   ""
10579   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10580
10581 (define_insn "*ashlsi3_1"
10582   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10583         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10584                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10585    (clobber (reg:CC FLAGS_REG))]
10586   "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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10593       return "add{l}\t{%0, %0|%0, %0}";
10594
10595     case TYPE_LEA:
10596       return "#";
10597
10598     default:
10599       if (REG_P (operands[2]))
10600         return "sal{l}\t{%b2, %0|%0, %b2}";
10601       else if (operands[2] == const1_rtx
10602                && (TARGET_SHIFT1 || optimize_size))
10603         return "sal{l}\t%0";
10604       else
10605         return "sal{l}\t{%2, %0|%0, %2}";
10606     }
10607 }
10608   [(set (attr "type")
10609      (cond [(eq_attr "alternative" "1")
10610               (const_string "lea")
10611             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10612                           (const_int 0))
10613                       (match_operand 0 "register_operand" ""))
10614                  (match_operand 2 "const1_operand" ""))
10615               (const_string "alu")
10616            ]
10617            (const_string "ishift")))
10618    (set_attr "mode" "SI")])
10619
10620 ;; Convert lea to the lea pattern to avoid flags dependency.
10621 (define_split
10622   [(set (match_operand 0 "register_operand" "")
10623         (ashift (match_operand 1 "index_register_operand" "")
10624                 (match_operand:QI 2 "const_int_operand" "")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "reload_completed
10627    && true_regnum (operands[0]) != true_regnum (operands[1])
10628    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10629   [(const_int 0)]
10630 {
10631   rtx pat;
10632   enum machine_mode mode = GET_MODE (operands[0]);
10633
10634   if (GET_MODE_SIZE (mode) < 4)
10635     operands[0] = gen_lowpart (SImode, operands[0]);
10636   if (mode != Pmode)
10637     operands[1] = gen_lowpart (Pmode, operands[1]);
10638   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10639
10640   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10641   if (Pmode != SImode)
10642     pat = gen_rtx_SUBREG (SImode, pat, 0);
10643   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10644   DONE;
10645 })
10646
10647 ;; Rare case of shifting RSP is handled by generating move and shift
10648 (define_split
10649   [(set (match_operand 0 "register_operand" "")
10650         (ashift (match_operand 1 "register_operand" "")
10651                 (match_operand:QI 2 "const_int_operand" "")))
10652    (clobber (reg:CC FLAGS_REG))]
10653   "reload_completed
10654    && true_regnum (operands[0]) != true_regnum (operands[1])"
10655   [(const_int 0)]
10656 {
10657   rtx pat, clob;
10658   emit_move_insn (operands[0], operands[1]);
10659   pat = gen_rtx_SET (VOIDmode, operands[0],
10660                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10661                                      operands[0], operands[2]));
10662   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10663   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10664   DONE;
10665 })
10666
10667 (define_insn "*ashlsi3_1_zext"
10668   [(set (match_operand:DI 0 "register_operand" "=r,r")
10669         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10670                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10671    (clobber (reg:CC FLAGS_REG))]
10672   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10673 {
10674   switch (get_attr_type (insn))
10675     {
10676     case TYPE_ALU:
10677       gcc_assert (operands[2] == const1_rtx);
10678       return "add{l}\t{%k0, %k0|%k0, %k0}";
10679
10680     case TYPE_LEA:
10681       return "#";
10682
10683     default:
10684       if (REG_P (operands[2]))
10685         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10686       else if (operands[2] == const1_rtx
10687                && (TARGET_SHIFT1 || optimize_size))
10688         return "sal{l}\t%k0";
10689       else
10690         return "sal{l}\t{%2, %k0|%k0, %2}";
10691     }
10692 }
10693   [(set (attr "type")
10694      (cond [(eq_attr "alternative" "1")
10695               (const_string "lea")
10696             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697                      (const_int 0))
10698                  (match_operand 2 "const1_operand" ""))
10699               (const_string "alu")
10700            ]
10701            (const_string "ishift")))
10702    (set_attr "mode" "SI")])
10703
10704 ;; Convert lea to the lea pattern to avoid flags dependency.
10705 (define_split
10706   [(set (match_operand:DI 0 "register_operand" "")
10707         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10708                                 (match_operand:QI 2 "const_int_operand" ""))))
10709    (clobber (reg:CC FLAGS_REG))]
10710   "TARGET_64BIT && reload_completed
10711    && true_regnum (operands[0]) != true_regnum (operands[1])"
10712   [(set (match_dup 0) (zero_extend:DI
10713                         (subreg:SI (mult:SI (match_dup 1)
10714                                             (match_dup 2)) 0)))]
10715 {
10716   operands[1] = gen_lowpart (Pmode, operands[1]);
10717   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10718 })
10719
10720 ;; This pattern can't accept a variable shift count, since shifts by
10721 ;; zero don't affect the flags.  We assume that shifts by constant
10722 ;; zero are optimized away.
10723 (define_insn "*ashlsi3_cmp"
10724   [(set (reg FLAGS_REG)
10725         (compare
10726           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10727                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10728           (const_int 0)))
10729    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10730         (ashift:SI (match_dup 1) (match_dup 2)))]
10731   "ix86_match_ccmode (insn, CCGOCmode)
10732    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10733    && (optimize_size
10734        || !TARGET_PARTIAL_FLAG_REG_STALL
10735        || (operands[2] == const1_rtx
10736            && (TARGET_SHIFT1
10737                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10738 {
10739   switch (get_attr_type (insn))
10740     {
10741     case TYPE_ALU:
10742       gcc_assert (operands[2] == const1_rtx);
10743       return "add{l}\t{%0, %0|%0, %0}";
10744
10745     default:
10746       if (REG_P (operands[2]))
10747         return "sal{l}\t{%b2, %0|%0, %b2}";
10748       else if (operands[2] == const1_rtx
10749                && (TARGET_SHIFT1 || optimize_size))
10750         return "sal{l}\t%0";
10751       else
10752         return "sal{l}\t{%2, %0|%0, %2}";
10753     }
10754 }
10755   [(set (attr "type")
10756      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10757                           (const_int 0))
10758                       (match_operand 0 "register_operand" ""))
10759                  (match_operand 2 "const1_operand" ""))
10760               (const_string "alu")
10761            ]
10762            (const_string "ishift")))
10763    (set_attr "mode" "SI")])
10764
10765 (define_insn "*ashlsi3_cconly"
10766   [(set (reg FLAGS_REG)
10767         (compare
10768           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10769                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10770           (const_int 0)))
10771    (clobber (match_scratch:SI 0 "=r"))]
10772   "ix86_match_ccmode (insn, CCGOCmode)
10773    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10774    && (optimize_size
10775        || !TARGET_PARTIAL_FLAG_REG_STALL
10776        || (operands[2] == const1_rtx
10777            && (TARGET_SHIFT1
10778                || TARGET_DOUBLE_WITH_ADD)))"
10779 {
10780   switch (get_attr_type (insn))
10781     {
10782     case TYPE_ALU:
10783       gcc_assert (operands[2] == const1_rtx);
10784       return "add{l}\t{%0, %0|%0, %0}";
10785
10786     default:
10787       if (REG_P (operands[2]))
10788         return "sal{l}\t{%b2, %0|%0, %b2}";
10789       else if (operands[2] == const1_rtx
10790                && (TARGET_SHIFT1 || optimize_size))
10791         return "sal{l}\t%0";
10792       else
10793         return "sal{l}\t{%2, %0|%0, %2}";
10794     }
10795 }
10796   [(set (attr "type")
10797      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10798                           (const_int 0))
10799                       (match_operand 0 "register_operand" ""))
10800                  (match_operand 2 "const1_operand" ""))
10801               (const_string "alu")
10802            ]
10803            (const_string "ishift")))
10804    (set_attr "mode" "SI")])
10805
10806 (define_insn "*ashlsi3_cmp_zext"
10807   [(set (reg FLAGS_REG)
10808         (compare
10809           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10810                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10811           (const_int 0)))
10812    (set (match_operand:DI 0 "register_operand" "=r")
10813         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10814   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10815    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10816    && (optimize_size
10817        || !TARGET_PARTIAL_FLAG_REG_STALL
10818        || (operands[2] == const1_rtx
10819            && (TARGET_SHIFT1
10820                || TARGET_DOUBLE_WITH_ADD)))"
10821 {
10822   switch (get_attr_type (insn))
10823     {
10824     case TYPE_ALU:
10825       gcc_assert (operands[2] == const1_rtx);
10826       return "add{l}\t{%k0, %k0|%k0, %k0}";
10827
10828     default:
10829       if (REG_P (operands[2]))
10830         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831       else if (operands[2] == const1_rtx
10832                && (TARGET_SHIFT1 || optimize_size))
10833         return "sal{l}\t%k0";
10834       else
10835         return "sal{l}\t{%2, %k0|%k0, %2}";
10836     }
10837 }
10838   [(set (attr "type")
10839      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10840                      (const_int 0))
10841                  (match_operand 2 "const1_operand" ""))
10842               (const_string "alu")
10843            ]
10844            (const_string "ishift")))
10845    (set_attr "mode" "SI")])
10846
10847 (define_expand "ashlhi3"
10848   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10849         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10850                    (match_operand:QI 2 "nonmemory_operand" "")))
10851    (clobber (reg:CC FLAGS_REG))]
10852   "TARGET_HIMODE_MATH"
10853   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10854
10855 (define_insn "*ashlhi3_1_lea"
10856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10857         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10858                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10859    (clobber (reg:CC FLAGS_REG))]
10860   "!TARGET_PARTIAL_REG_STALL
10861    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10862 {
10863   switch (get_attr_type (insn))
10864     {
10865     case TYPE_LEA:
10866       return "#";
10867     case TYPE_ALU:
10868       gcc_assert (operands[2] == const1_rtx);
10869       return "add{w}\t{%0, %0|%0, %0}";
10870
10871     default:
10872       if (REG_P (operands[2]))
10873         return "sal{w}\t{%b2, %0|%0, %b2}";
10874       else if (operands[2] == const1_rtx
10875                && (TARGET_SHIFT1 || optimize_size))
10876         return "sal{w}\t%0";
10877       else
10878         return "sal{w}\t{%2, %0|%0, %2}";
10879     }
10880 }
10881   [(set (attr "type")
10882      (cond [(eq_attr "alternative" "1")
10883               (const_string "lea")
10884             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10885                           (const_int 0))
10886                       (match_operand 0 "register_operand" ""))
10887                  (match_operand 2 "const1_operand" ""))
10888               (const_string "alu")
10889            ]
10890            (const_string "ishift")))
10891    (set_attr "mode" "HI,SI")])
10892
10893 (define_insn "*ashlhi3_1"
10894   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10895         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10896                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "TARGET_PARTIAL_REG_STALL
10899    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10900 {
10901   switch (get_attr_type (insn))
10902     {
10903     case TYPE_ALU:
10904       gcc_assert (operands[2] == const1_rtx);
10905       return "add{w}\t{%0, %0|%0, %0}";
10906
10907     default:
10908       if (REG_P (operands[2]))
10909         return "sal{w}\t{%b2, %0|%0, %b2}";
10910       else if (operands[2] == const1_rtx
10911                && (TARGET_SHIFT1 || optimize_size))
10912         return "sal{w}\t%0";
10913       else
10914         return "sal{w}\t{%2, %0|%0, %2}";
10915     }
10916 }
10917   [(set (attr "type")
10918      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10919                           (const_int 0))
10920                       (match_operand 0 "register_operand" ""))
10921                  (match_operand 2 "const1_operand" ""))
10922               (const_string "alu")
10923            ]
10924            (const_string "ishift")))
10925    (set_attr "mode" "HI")])
10926
10927 ;; This pattern can't accept a variable shift count, since shifts by
10928 ;; zero don't affect the flags.  We assume that shifts by constant
10929 ;; zero are optimized away.
10930 (define_insn "*ashlhi3_cmp"
10931   [(set (reg FLAGS_REG)
10932         (compare
10933           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10934                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10935           (const_int 0)))
10936    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10937         (ashift:HI (match_dup 1) (match_dup 2)))]
10938   "ix86_match_ccmode (insn, CCGOCmode)
10939    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10940    && (optimize_size
10941        || !TARGET_PARTIAL_FLAG_REG_STALL
10942        || (operands[2] == const1_rtx
10943            && (TARGET_SHIFT1
10944                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10945 {
10946   switch (get_attr_type (insn))
10947     {
10948     case TYPE_ALU:
10949       gcc_assert (operands[2] == const1_rtx);
10950       return "add{w}\t{%0, %0|%0, %0}";
10951
10952     default:
10953       if (REG_P (operands[2]))
10954         return "sal{w}\t{%b2, %0|%0, %b2}";
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         return "sal{w}\t%0";
10958       else
10959         return "sal{w}\t{%2, %0|%0, %2}";
10960     }
10961 }
10962   [(set (attr "type")
10963      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964                           (const_int 0))
10965                       (match_operand 0 "register_operand" ""))
10966                  (match_operand 2 "const1_operand" ""))
10967               (const_string "alu")
10968            ]
10969            (const_string "ishift")))
10970    (set_attr "mode" "HI")])
10971
10972 (define_insn "*ashlhi3_cconly"
10973   [(set (reg FLAGS_REG)
10974         (compare
10975           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10976                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10977           (const_int 0)))
10978    (clobber (match_scratch:HI 0 "=r"))]
10979   "ix86_match_ccmode (insn, CCGOCmode)
10980    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10981    && (optimize_size
10982        || !TARGET_PARTIAL_FLAG_REG_STALL
10983        || (operands[2] == const1_rtx
10984            && (TARGET_SHIFT1
10985                || TARGET_DOUBLE_WITH_ADD)))"
10986 {
10987   switch (get_attr_type (insn))
10988     {
10989     case TYPE_ALU:
10990       gcc_assert (operands[2] == const1_rtx);
10991       return "add{w}\t{%0, %0|%0, %0}";
10992
10993     default:
10994       if (REG_P (operands[2]))
10995         return "sal{w}\t{%b2, %0|%0, %b2}";
10996       else if (operands[2] == const1_rtx
10997                && (TARGET_SHIFT1 || optimize_size))
10998         return "sal{w}\t%0";
10999       else
11000         return "sal{w}\t{%2, %0|%0, %2}";
11001     }
11002 }
11003   [(set (attr "type")
11004      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11005                           (const_int 0))
11006                       (match_operand 0 "register_operand" ""))
11007                  (match_operand 2 "const1_operand" ""))
11008               (const_string "alu")
11009            ]
11010            (const_string "ishift")))
11011    (set_attr "mode" "HI")])
11012
11013 (define_expand "ashlqi3"
11014   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11015         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11016                    (match_operand:QI 2 "nonmemory_operand" "")))
11017    (clobber (reg:CC FLAGS_REG))]
11018   "TARGET_QIMODE_MATH"
11019   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11020
11021 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11022
11023 (define_insn "*ashlqi3_1_lea"
11024   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11025         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11026                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11027    (clobber (reg:CC FLAGS_REG))]
11028   "!TARGET_PARTIAL_REG_STALL
11029    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11030 {
11031   switch (get_attr_type (insn))
11032     {
11033     case TYPE_LEA:
11034       return "#";
11035     case TYPE_ALU:
11036       gcc_assert (operands[2] == const1_rtx);
11037       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11038         return "add{l}\t{%k0, %k0|%k0, %k0}";
11039       else
11040         return "add{b}\t{%0, %0|%0, %0}";
11041
11042     default:
11043       if (REG_P (operands[2]))
11044         {
11045           if (get_attr_mode (insn) == MODE_SI)
11046             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11047           else
11048             return "sal{b}\t{%b2, %0|%0, %b2}";
11049         }
11050       else if (operands[2] == const1_rtx
11051                && (TARGET_SHIFT1 || optimize_size))
11052         {
11053           if (get_attr_mode (insn) == MODE_SI)
11054             return "sal{l}\t%0";
11055           else
11056             return "sal{b}\t%0";
11057         }
11058       else
11059         {
11060           if (get_attr_mode (insn) == MODE_SI)
11061             return "sal{l}\t{%2, %k0|%k0, %2}";
11062           else
11063             return "sal{b}\t{%2, %0|%0, %2}";
11064         }
11065     }
11066 }
11067   [(set (attr "type")
11068      (cond [(eq_attr "alternative" "2")
11069               (const_string "lea")
11070             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11071                           (const_int 0))
11072                       (match_operand 0 "register_operand" ""))
11073                  (match_operand 2 "const1_operand" ""))
11074               (const_string "alu")
11075            ]
11076            (const_string "ishift")))
11077    (set_attr "mode" "QI,SI,SI")])
11078
11079 (define_insn "*ashlqi3_1"
11080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11081         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11082                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_PARTIAL_REG_STALL
11085    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11086 {
11087   switch (get_attr_type (insn))
11088     {
11089     case TYPE_ALU:
11090       gcc_assert (operands[2] == const1_rtx);
11091       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11092         return "add{l}\t{%k0, %k0|%k0, %k0}";
11093       else
11094         return "add{b}\t{%0, %0|%0, %0}";
11095
11096     default:
11097       if (REG_P (operands[2]))
11098         {
11099           if (get_attr_mode (insn) == MODE_SI)
11100             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11101           else
11102             return "sal{b}\t{%b2, %0|%0, %b2}";
11103         }
11104       else if (operands[2] == const1_rtx
11105                && (TARGET_SHIFT1 || optimize_size))
11106         {
11107           if (get_attr_mode (insn) == MODE_SI)
11108             return "sal{l}\t%0";
11109           else
11110             return "sal{b}\t%0";
11111         }
11112       else
11113         {
11114           if (get_attr_mode (insn) == MODE_SI)
11115             return "sal{l}\t{%2, %k0|%k0, %2}";
11116           else
11117             return "sal{b}\t{%2, %0|%0, %2}";
11118         }
11119     }
11120 }
11121   [(set (attr "type")
11122      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123                           (const_int 0))
11124                       (match_operand 0 "register_operand" ""))
11125                  (match_operand 2 "const1_operand" ""))
11126               (const_string "alu")
11127            ]
11128            (const_string "ishift")))
11129    (set_attr "mode" "QI,SI")])
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 "*ashlqi3_cmp"
11135   [(set (reg FLAGS_REG)
11136         (compare
11137           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11138                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11139           (const_int 0)))
11140    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11141         (ashift:QI (match_dup 1) (match_dup 2)))]
11142   "ix86_match_ccmode (insn, CCGOCmode)
11143    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11144    && (optimize_size
11145        || !TARGET_PARTIAL_FLAG_REG_STALL
11146        || (operands[2] == const1_rtx
11147            && (TARGET_SHIFT1
11148                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11149 {
11150   switch (get_attr_type (insn))
11151     {
11152     case TYPE_ALU:
11153       gcc_assert (operands[2] == const1_rtx);
11154       return "add{b}\t{%0, %0|%0, %0}";
11155
11156     default:
11157       if (REG_P (operands[2]))
11158         return "sal{b}\t{%b2, %0|%0, %b2}";
11159       else if (operands[2] == const1_rtx
11160                && (TARGET_SHIFT1 || optimize_size))
11161         return "sal{b}\t%0";
11162       else
11163         return "sal{b}\t{%2, %0|%0, %2}";
11164     }
11165 }
11166   [(set (attr "type")
11167      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168                           (const_int 0))
11169                       (match_operand 0 "register_operand" ""))
11170                  (match_operand 2 "const1_operand" ""))
11171               (const_string "alu")
11172            ]
11173            (const_string "ishift")))
11174    (set_attr "mode" "QI")])
11175
11176 (define_insn "*ashlqi3_cconly"
11177   [(set (reg FLAGS_REG)
11178         (compare
11179           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11180                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11181           (const_int 0)))
11182    (clobber (match_scratch:QI 0 "=q"))]
11183   "ix86_match_ccmode (insn, CCGOCmode)
11184    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11185    && (optimize_size
11186        || !TARGET_PARTIAL_FLAG_REG_STALL
11187        || (operands[2] == const1_rtx
11188            && (TARGET_SHIFT1
11189                || TARGET_DOUBLE_WITH_ADD)))"
11190 {
11191   switch (get_attr_type (insn))
11192     {
11193     case TYPE_ALU:
11194       gcc_assert (operands[2] == const1_rtx);
11195       return "add{b}\t{%0, %0|%0, %0}";
11196
11197     default:
11198       if (REG_P (operands[2]))
11199         return "sal{b}\t{%b2, %0|%0, %b2}";
11200       else if (operands[2] == const1_rtx
11201                && (TARGET_SHIFT1 || optimize_size))
11202         return "sal{b}\t%0";
11203       else
11204         return "sal{b}\t{%2, %0|%0, %2}";
11205     }
11206 }
11207   [(set (attr "type")
11208      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11209                           (const_int 0))
11210                       (match_operand 0 "register_operand" ""))
11211                  (match_operand 2 "const1_operand" ""))
11212               (const_string "alu")
11213            ]
11214            (const_string "ishift")))
11215    (set_attr "mode" "QI")])
11216
11217 ;; See comment above `ashldi3' about how this works.
11218
11219 (define_expand "ashrti3"
11220   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11221                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11222                                 (match_operand:QI 2 "nonmemory_operand" "")))
11223               (clobber (reg:CC FLAGS_REG))])]
11224   "TARGET_64BIT"
11225 {
11226   if (! immediate_operand (operands[2], QImode))
11227     {
11228       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11229       DONE;
11230     }
11231   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11232   DONE;
11233 })
11234
11235 (define_insn "ashrti3_1"
11236   [(set (match_operand:TI 0 "register_operand" "=r")
11237         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11238                      (match_operand:QI 2 "register_operand" "c")))
11239    (clobber (match_scratch:DI 3 "=&r"))
11240    (clobber (reg:CC FLAGS_REG))]
11241   "TARGET_64BIT"
11242   "#"
11243   [(set_attr "type" "multi")])
11244
11245 (define_insn "*ashrti3_2"
11246   [(set (match_operand:TI 0 "register_operand" "=r")
11247         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11248                      (match_operand:QI 2 "immediate_operand" "O")))
11249    (clobber (reg:CC FLAGS_REG))]
11250   "TARGET_64BIT"
11251   "#"
11252   [(set_attr "type" "multi")])
11253
11254 (define_split
11255   [(set (match_operand:TI 0 "register_operand" "")
11256         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11257                      (match_operand:QI 2 "register_operand" "")))
11258    (clobber (match_scratch:DI 3 ""))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "TARGET_64BIT && reload_completed"
11261   [(const_int 0)]
11262   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11263
11264 (define_split
11265   [(set (match_operand:TI 0 "register_operand" "")
11266         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11267                      (match_operand:QI 2 "immediate_operand" "")))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_64BIT && reload_completed"
11270   [(const_int 0)]
11271   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11272
11273 (define_insn "x86_64_shrd"
11274   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11275         (ior:DI (ashiftrt:DI (match_dup 0)
11276                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11277                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11278                   (minus:QI (const_int 64) (match_dup 2)))))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "TARGET_64BIT"
11281   "@
11282    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11283    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11284   [(set_attr "type" "ishift")
11285    (set_attr "prefix_0f" "1")
11286    (set_attr "mode" "DI")
11287    (set_attr "athlon_decode" "vector")])
11288
11289 (define_expand "ashrdi3"
11290   [(set (match_operand:DI 0 "shiftdi_operand" "")
11291         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11292                      (match_operand:QI 2 "nonmemory_operand" "")))]
11293   ""
11294   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11295
11296 (define_insn "*ashrdi3_63_rex64"
11297   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11298         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11299                      (match_operand:DI 2 "const_int_operand" "i,i")))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && INTVAL (operands[2]) == 63
11302    && (TARGET_USE_CLTD || optimize_size)
11303    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11304   "@
11305    {cqto|cqo}
11306    sar{q}\t{%2, %0|%0, %2}"
11307   [(set_attr "type" "imovx,ishift")
11308    (set_attr "prefix_0f" "0,*")
11309    (set_attr "length_immediate" "0,*")
11310    (set_attr "modrm" "0,1")
11311    (set_attr "mode" "DI")])
11312
11313 (define_insn "*ashrdi3_1_one_bit_rex64"
11314   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11316                      (match_operand:QI 2 "const1_operand" "")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11319    && (TARGET_SHIFT1 || optimize_size)"
11320   "sar{q}\t%0"
11321   [(set_attr "type" "ishift")
11322    (set (attr "length") 
11323      (if_then_else (match_operand:DI 0 "register_operand" "") 
11324         (const_string "2")
11325         (const_string "*")))])
11326
11327 (define_insn "*ashrdi3_1_rex64"
11328   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11329         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11330                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11333   "@
11334    sar{q}\t{%2, %0|%0, %2}
11335    sar{q}\t{%b2, %0|%0, %b2}"
11336   [(set_attr "type" "ishift")
11337    (set_attr "mode" "DI")])
11338
11339 ;; This pattern can't accept a variable shift count, since shifts by
11340 ;; zero don't affect the flags.  We assume that shifts by constant
11341 ;; zero are optimized away.
11342 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11343   [(set (reg FLAGS_REG)
11344         (compare
11345           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11346                        (match_operand:QI 2 "const1_operand" ""))
11347           (const_int 0)))
11348    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11350   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11351    && (TARGET_SHIFT1 || optimize_size)
11352    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "sar{q}\t%0"
11354   [(set_attr "type" "ishift")
11355    (set (attr "length") 
11356      (if_then_else (match_operand:DI 0 "register_operand" "") 
11357         (const_string "2")
11358         (const_string "*")))])
11359
11360 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11361   [(set (reg FLAGS_REG)
11362         (compare
11363           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364                        (match_operand:QI 2 "const1_operand" ""))
11365           (const_int 0)))
11366    (clobber (match_scratch:DI 0 "=r"))]
11367   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11368    && (TARGET_SHIFT1 || optimize_size)
11369    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370   "sar{q}\t%0"
11371   [(set_attr "type" "ishift")
11372    (set_attr "length" "2")])
11373
11374 ;; This pattern can't accept a variable shift count, since shifts by
11375 ;; zero don't affect the flags.  We assume that shifts by constant
11376 ;; zero are optimized away.
11377 (define_insn "*ashrdi3_cmp_rex64"
11378   [(set (reg FLAGS_REG)
11379         (compare
11380           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381                        (match_operand:QI 2 "const_int_operand" "n"))
11382           (const_int 0)))
11383    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11387    && (optimize_size
11388        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11389   "sar{q}\t{%2, %0|%0, %2}"
11390   [(set_attr "type" "ishift")
11391    (set_attr "mode" "DI")])
11392
11393 (define_insn "*ashrdi3_cconly_rex64"
11394   [(set (reg FLAGS_REG)
11395         (compare
11396           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397                        (match_operand:QI 2 "const_int_operand" "n"))
11398           (const_int 0)))
11399    (clobber (match_scratch:DI 0 "=r"))]
11400   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11402    && (optimize_size
11403        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11404   "sar{q}\t{%2, %0|%0, %2}"
11405   [(set_attr "type" "ishift")
11406    (set_attr "mode" "DI")])
11407
11408 (define_insn "*ashrdi3_1"
11409   [(set (match_operand:DI 0 "register_operand" "=r")
11410         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11411                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "!TARGET_64BIT"
11414   "#"
11415   [(set_attr "type" "multi")])
11416
11417 ;; By default we don't ask for a scratch register, because when DImode
11418 ;; values are manipulated, registers are already at a premium.  But if
11419 ;; we have one handy, we won't turn it away.
11420 (define_peephole2
11421   [(match_scratch:SI 3 "r")
11422    (parallel [(set (match_operand:DI 0 "register_operand" "")
11423                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424                                 (match_operand:QI 2 "nonmemory_operand" "")))
11425               (clobber (reg:CC FLAGS_REG))])
11426    (match_dup 3)]
11427   "!TARGET_64BIT && TARGET_CMOVE"
11428   [(const_int 0)]
11429   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11430
11431 (define_split
11432   [(set (match_operand:DI 0 "register_operand" "")
11433         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11434                      (match_operand:QI 2 "nonmemory_operand" "")))
11435    (clobber (reg:CC FLAGS_REG))]
11436   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11437                      ? flow2_completed : reload_completed)"
11438   [(const_int 0)]
11439   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11440
11441 (define_insn "x86_shrd_1"
11442   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11443         (ior:SI (ashiftrt:SI (match_dup 0)
11444                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11445                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11446                   (minus:QI (const_int 32) (match_dup 2)))))
11447    (clobber (reg:CC FLAGS_REG))]
11448   ""
11449   "@
11450    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11451    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11452   [(set_attr "type" "ishift")
11453    (set_attr "prefix_0f" "1")
11454    (set_attr "pent_pair" "np")
11455    (set_attr "mode" "SI")])
11456
11457 (define_expand "x86_shift_adj_3"
11458   [(use (match_operand:SI 0 "register_operand" ""))
11459    (use (match_operand:SI 1 "register_operand" ""))
11460    (use (match_operand:QI 2 "register_operand" ""))]
11461   ""
11462 {
11463   rtx label = gen_label_rtx ();
11464   rtx tmp;
11465
11466   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11467
11468   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11469   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11470   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11471                               gen_rtx_LABEL_REF (VOIDmode, label),
11472                               pc_rtx);
11473   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11474   JUMP_LABEL (tmp) = label;
11475
11476   emit_move_insn (operands[0], operands[1]);
11477   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11478
11479   emit_label (label);
11480   LABEL_NUSES (label) = 1;
11481
11482   DONE;
11483 })
11484
11485 (define_insn "ashrsi3_31"
11486   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11487         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11488                      (match_operand:SI 2 "const_int_operand" "i,i")))
11489    (clobber (reg:CC FLAGS_REG))]
11490   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11491    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11492   "@
11493    {cltd|cdq}
11494    sar{l}\t{%2, %0|%0, %2}"
11495   [(set_attr "type" "imovx,ishift")
11496    (set_attr "prefix_0f" "0,*")
11497    (set_attr "length_immediate" "0,*")
11498    (set_attr "modrm" "0,1")
11499    (set_attr "mode" "SI")])
11500
11501 (define_insn "*ashrsi3_31_zext"
11502   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11503         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11504                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11505    (clobber (reg:CC FLAGS_REG))]
11506   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11507    && INTVAL (operands[2]) == 31
11508    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11509   "@
11510    {cltd|cdq}
11511    sar{l}\t{%2, %k0|%k0, %2}"
11512   [(set_attr "type" "imovx,ishift")
11513    (set_attr "prefix_0f" "0,*")
11514    (set_attr "length_immediate" "0,*")
11515    (set_attr "modrm" "0,1")
11516    (set_attr "mode" "SI")])
11517
11518 (define_expand "ashrsi3"
11519   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11520         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11521                      (match_operand:QI 2 "nonmemory_operand" "")))
11522    (clobber (reg:CC FLAGS_REG))]
11523   ""
11524   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11525
11526 (define_insn "*ashrsi3_1_one_bit"
11527   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11529                      (match_operand:QI 2 "const1_operand" "")))
11530    (clobber (reg:CC FLAGS_REG))]
11531   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11532    && (TARGET_SHIFT1 || optimize_size)"
11533   "sar{l}\t%0"
11534   [(set_attr "type" "ishift")
11535    (set (attr "length") 
11536      (if_then_else (match_operand:SI 0 "register_operand" "") 
11537         (const_string "2")
11538         (const_string "*")))])
11539
11540 (define_insn "*ashrsi3_1_one_bit_zext"
11541   [(set (match_operand:DI 0 "register_operand" "=r")
11542         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543                                      (match_operand:QI 2 "const1_operand" ""))))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11546    && (TARGET_SHIFT1 || optimize_size)"
11547   "sar{l}\t%k0"
11548   [(set_attr "type" "ishift")
11549    (set_attr "length" "2")])
11550
11551 (define_insn "*ashrsi3_1"
11552   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11553         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11554                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11555    (clobber (reg:CC FLAGS_REG))]
11556   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557   "@
11558    sar{l}\t{%2, %0|%0, %2}
11559    sar{l}\t{%b2, %0|%0, %b2}"
11560   [(set_attr "type" "ishift")
11561    (set_attr "mode" "SI")])
11562
11563 (define_insn "*ashrsi3_1_zext"
11564   [(set (match_operand:DI 0 "register_operand" "=r,r")
11565         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11566                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11567    (clobber (reg:CC FLAGS_REG))]
11568   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569   "@
11570    sar{l}\t{%2, %k0|%k0, %2}
11571    sar{l}\t{%b2, %k0|%k0, %b2}"
11572   [(set_attr "type" "ishift")
11573    (set_attr "mode" "SI")])
11574
11575 ;; This pattern can't accept a variable shift count, since shifts by
11576 ;; zero don't affect the flags.  We assume that shifts by constant
11577 ;; zero are optimized away.
11578 (define_insn "*ashrsi3_one_bit_cmp"
11579   [(set (reg FLAGS_REG)
11580         (compare
11581           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582                        (match_operand:QI 2 "const1_operand" ""))
11583           (const_int 0)))
11584    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11585         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11586   "ix86_match_ccmode (insn, CCGOCmode)
11587    && (TARGET_SHIFT1 || optimize_size)
11588    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589   "sar{l}\t%0"
11590   [(set_attr "type" "ishift")
11591    (set (attr "length") 
11592      (if_then_else (match_operand:SI 0 "register_operand" "") 
11593         (const_string "2")
11594         (const_string "*")))])
11595
11596 (define_insn "*ashrsi3_one_bit_cconly"
11597   [(set (reg FLAGS_REG)
11598         (compare
11599           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11600                        (match_operand:QI 2 "const1_operand" ""))
11601           (const_int 0)))
11602    (clobber (match_scratch:SI 0 "=r"))]
11603   "ix86_match_ccmode (insn, CCGOCmode)
11604    && (TARGET_SHIFT1 || optimize_size)
11605    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606   "sar{l}\t%0"
11607   [(set_attr "type" "ishift")
11608    (set_attr "length" "2")])
11609
11610 (define_insn "*ashrsi3_one_bit_cmp_zext"
11611   [(set (reg FLAGS_REG)
11612         (compare
11613           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11614                        (match_operand:QI 2 "const1_operand" ""))
11615           (const_int 0)))
11616    (set (match_operand:DI 0 "register_operand" "=r")
11617         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11618   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11619    && (TARGET_SHIFT1 || optimize_size)
11620    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621   "sar{l}\t%k0"
11622   [(set_attr "type" "ishift")
11623    (set_attr "length" "2")])
11624
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags.  We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashrsi3_cmp"
11629   [(set (reg FLAGS_REG)
11630         (compare
11631           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11633           (const_int 0)))
11634    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636   "ix86_match_ccmode (insn, CCGOCmode)
11637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11638    && (optimize_size
11639        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11640   "sar{l}\t{%2, %0|%0, %2}"
11641   [(set_attr "type" "ishift")
11642    (set_attr "mode" "SI")])
11643
11644 (define_insn "*ashrsi3_cconly"
11645   [(set (reg FLAGS_REG)
11646         (compare
11647           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11649           (const_int 0)))
11650    (clobber (match_scratch:SI 0 "=r"))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11653    && (optimize_size
11654        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11655   "sar{l}\t{%2, %0|%0, %2}"
11656   [(set_attr "type" "ishift")
11657    (set_attr "mode" "SI")])
11658
11659 (define_insn "*ashrsi3_cmp_zext"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664           (const_int 0)))
11665    (set (match_operand:DI 0 "register_operand" "=r")
11666         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11668    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11669    && (optimize_size
11670        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671   "sar{l}\t{%2, %k0|%k0, %2}"
11672   [(set_attr "type" "ishift")
11673    (set_attr "mode" "SI")])
11674
11675 (define_expand "ashrhi3"
11676   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11677         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11678                      (match_operand:QI 2 "nonmemory_operand" "")))
11679    (clobber (reg:CC FLAGS_REG))]
11680   "TARGET_HIMODE_MATH"
11681   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11682
11683 (define_insn "*ashrhi3_1_one_bit"
11684   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11685         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11686                      (match_operand:QI 2 "const1_operand" "")))
11687    (clobber (reg:CC FLAGS_REG))]
11688   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11689    && (TARGET_SHIFT1 || optimize_size)"
11690   "sar{w}\t%0"
11691   [(set_attr "type" "ishift")
11692    (set (attr "length") 
11693      (if_then_else (match_operand 0 "register_operand" "") 
11694         (const_string "2")
11695         (const_string "*")))])
11696
11697 (define_insn "*ashrhi3_1"
11698   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11699         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11700                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701    (clobber (reg:CC FLAGS_REG))]
11702   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703   "@
11704    sar{w}\t{%2, %0|%0, %2}
11705    sar{w}\t{%b2, %0|%0, %b2}"
11706   [(set_attr "type" "ishift")
11707    (set_attr "mode" "HI")])
11708
11709 ;; This pattern can't accept a variable shift count, since shifts by
11710 ;; zero don't affect the flags.  We assume that shifts by constant
11711 ;; zero are optimized away.
11712 (define_insn "*ashrhi3_one_bit_cmp"
11713   [(set (reg FLAGS_REG)
11714         (compare
11715           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716                        (match_operand:QI 2 "const1_operand" ""))
11717           (const_int 0)))
11718    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720   "ix86_match_ccmode (insn, CCGOCmode)
11721    && (TARGET_SHIFT1 || optimize_size)
11722    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723   "sar{w}\t%0"
11724   [(set_attr "type" "ishift")
11725    (set (attr "length") 
11726      (if_then_else (match_operand 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11729
11730 (define_insn "*ashrhi3_one_bit_cconly"
11731   [(set (reg FLAGS_REG)
11732         (compare
11733           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734                        (match_operand:QI 2 "const1_operand" ""))
11735           (const_int 0)))
11736    (clobber (match_scratch:HI 0 "=r"))]
11737   "ix86_match_ccmode (insn, CCGOCmode)
11738    && (TARGET_SHIFT1 || optimize_size)
11739    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11740   "sar{w}\t%0"
11741   [(set_attr "type" "ishift")
11742    (set_attr "length" "2")])
11743
11744 ;; This pattern can't accept a variable shift count, since shifts by
11745 ;; zero don't affect the flags.  We assume that shifts by constant
11746 ;; zero are optimized away.
11747 (define_insn "*ashrhi3_cmp"
11748   [(set (reg FLAGS_REG)
11749         (compare
11750           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11751                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11752           (const_int 0)))
11753    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11755   "ix86_match_ccmode (insn, CCGOCmode)
11756    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11757    && (optimize_size
11758        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759   "sar{w}\t{%2, %0|%0, %2}"
11760   [(set_attr "type" "ishift")
11761    (set_attr "mode" "HI")])
11762
11763 (define_insn "*ashrhi3_cconly"
11764   [(set (reg FLAGS_REG)
11765         (compare
11766           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11767                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768           (const_int 0)))
11769    (clobber (match_scratch:HI 0 "=r"))]
11770   "ix86_match_ccmode (insn, CCGOCmode)
11771    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11772    && (optimize_size
11773        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11774   "sar{w}\t{%2, %0|%0, %2}"
11775   [(set_attr "type" "ishift")
11776    (set_attr "mode" "HI")])
11777
11778 (define_expand "ashrqi3"
11779   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781                      (match_operand:QI 2 "nonmemory_operand" "")))
11782    (clobber (reg:CC FLAGS_REG))]
11783   "TARGET_QIMODE_MATH"
11784   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786 (define_insn "*ashrqi3_1_one_bit"
11787   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789                      (match_operand:QI 2 "const1_operand" "")))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792    && (TARGET_SHIFT1 || optimize_size)"
11793   "sar{b}\t%0"
11794   [(set_attr "type" "ishift")
11795    (set (attr "length") 
11796      (if_then_else (match_operand 0 "register_operand" "") 
11797         (const_string "2")
11798         (const_string "*")))])
11799
11800 (define_insn "*ashrqi3_1_one_bit_slp"
11801   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802         (ashiftrt:QI (match_dup 0)
11803                      (match_operand:QI 1 "const1_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807    && (TARGET_SHIFT1 || optimize_size)"
11808   "sar{b}\t%0"
11809   [(set_attr "type" "ishift1")
11810    (set (attr "length") 
11811      (if_then_else (match_operand 0 "register_operand" "") 
11812         (const_string "2")
11813         (const_string "*")))])
11814
11815 (define_insn "*ashrqi3_1"
11816   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821   "@
11822    sar{b}\t{%2, %0|%0, %2}
11823    sar{b}\t{%b2, %0|%0, %b2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "QI")])
11826
11827 (define_insn "*ashrqi3_1_slp"
11828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829         (ashiftrt:QI (match_dup 0)
11830                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834   "@
11835    sar{b}\t{%1, %0|%0, %1}
11836    sar{b}\t{%b1, %0|%0, %b1}"
11837   [(set_attr "type" "ishift1")
11838    (set_attr "mode" "QI")])
11839
11840 ;; This pattern can't accept a variable shift count, since shifts by
11841 ;; zero don't affect the flags.  We assume that shifts by constant
11842 ;; zero are optimized away.
11843 (define_insn "*ashrqi3_one_bit_cmp"
11844   [(set (reg FLAGS_REG)
11845         (compare
11846           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847                        (match_operand:QI 2 "const1_operand" "I"))
11848           (const_int 0)))
11849    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851   "ix86_match_ccmode (insn, CCGOCmode)
11852    && (TARGET_SHIFT1 || optimize_size)
11853    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854   "sar{b}\t%0"
11855   [(set_attr "type" "ishift")
11856    (set (attr "length") 
11857      (if_then_else (match_operand 0 "register_operand" "") 
11858         (const_string "2")
11859         (const_string "*")))])
11860
11861 (define_insn "*ashrqi3_one_bit_cconly"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865                        (match_operand:QI 2 "const1_operand" "I"))
11866           (const_int 0)))
11867    (clobber (match_scratch:QI 0 "=q"))]
11868   "ix86_match_ccmode (insn, CCGOCmode)
11869    && (TARGET_SHIFT1 || optimize_size)
11870    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11871   "sar{b}\t%0"
11872   [(set_attr "type" "ishift")
11873    (set_attr "length" "2")])
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 "*ashrqi3_cmp"
11879   [(set (reg FLAGS_REG)
11880         (compare
11881           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11882                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11883           (const_int 0)))
11884    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11885         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11886   "ix86_match_ccmode (insn, CCGOCmode)
11887    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888    && (optimize_size
11889        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11890   "sar{b}\t{%2, %0|%0, %2}"
11891   [(set_attr "type" "ishift")
11892    (set_attr "mode" "QI")])
11893
11894 (define_insn "*ashrqi3_cconly"
11895   [(set (reg FLAGS_REG)
11896         (compare
11897           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11898                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899           (const_int 0)))
11900    (clobber (match_scratch:QI 0 "=q"))]
11901   "ix86_match_ccmode (insn, CCGOCmode)
11902    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11903    && (optimize_size
11904        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905   "sar{b}\t{%2, %0|%0, %2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "QI")])
11908
11909 \f
11910 ;; Logical shift instructions
11911
11912 ;; See comment above `ashldi3' about how this works.
11913
11914 (define_expand "lshrti3"
11915   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11916                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11917                                 (match_operand:QI 2 "nonmemory_operand" "")))
11918               (clobber (reg:CC FLAGS_REG))])]
11919   "TARGET_64BIT"
11920 {
11921   if (! immediate_operand (operands[2], QImode))
11922     {
11923       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11924       DONE;
11925     }
11926   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11927   DONE;
11928 })
11929
11930 (define_insn "lshrti3_1"
11931   [(set (match_operand:TI 0 "register_operand" "=r")
11932         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933                      (match_operand:QI 2 "register_operand" "c")))
11934    (clobber (match_scratch:DI 3 "=&r"))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "TARGET_64BIT"
11937   "#"
11938   [(set_attr "type" "multi")])
11939
11940 (define_insn "*lshrti3_2"
11941   [(set (match_operand:TI 0 "register_operand" "=r")
11942         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11943                      (match_operand:QI 2 "immediate_operand" "O")))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "TARGET_64BIT"
11946   "#"
11947   [(set_attr "type" "multi")])
11948
11949 (define_split 
11950   [(set (match_operand:TI 0 "register_operand" "")
11951         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11952                      (match_operand:QI 2 "register_operand" "")))
11953    (clobber (match_scratch:DI 3 ""))
11954    (clobber (reg:CC FLAGS_REG))]
11955   "TARGET_64BIT && reload_completed"
11956   [(const_int 0)]
11957   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11958
11959 (define_split 
11960   [(set (match_operand:TI 0 "register_operand" "")
11961         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11962                      (match_operand:QI 2 "immediate_operand" "")))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "TARGET_64BIT && reload_completed"
11965   [(const_int 0)]
11966   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11967
11968 (define_expand "lshrdi3"
11969   [(set (match_operand:DI 0 "shiftdi_operand" "")
11970         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11971                      (match_operand:QI 2 "nonmemory_operand" "")))]
11972   ""
11973   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11974
11975 (define_insn "*lshrdi3_1_one_bit_rex64"
11976   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978                      (match_operand:QI 2 "const1_operand" "")))
11979    (clobber (reg:CC FLAGS_REG))]
11980   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981    && (TARGET_SHIFT1 || optimize_size)"
11982   "shr{q}\t%0"
11983   [(set_attr "type" "ishift")
11984    (set (attr "length") 
11985      (if_then_else (match_operand:DI 0 "register_operand" "") 
11986         (const_string "2")
11987         (const_string "*")))])
11988
11989 (define_insn "*lshrdi3_1_rex64"
11990   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11991         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11992                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11993    (clobber (reg:CC FLAGS_REG))]
11994   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995   "@
11996    shr{q}\t{%2, %0|%0, %2}
11997    shr{q}\t{%b2, %0|%0, %b2}"
11998   [(set_attr "type" "ishift")
11999    (set_attr "mode" "DI")])
12000
12001 ;; This pattern can't accept a variable shift count, since shifts by
12002 ;; zero don't affect the flags.  We assume that shifts by constant
12003 ;; zero are optimized away.
12004 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12005   [(set (reg FLAGS_REG)
12006         (compare
12007           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12008                        (match_operand:QI 2 "const1_operand" ""))
12009           (const_int 0)))
12010    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12012   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013    && (TARGET_SHIFT1 || optimize_size)
12014    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015   "shr{q}\t%0"
12016   [(set_attr "type" "ishift")
12017    (set (attr "length") 
12018      (if_then_else (match_operand:DI 0 "register_operand" "") 
12019         (const_string "2")
12020         (const_string "*")))])
12021
12022 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12023   [(set (reg FLAGS_REG)
12024         (compare
12025           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026                        (match_operand:QI 2 "const1_operand" ""))
12027           (const_int 0)))
12028    (clobber (match_scratch:DI 0 "=r"))]
12029   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12030    && (TARGET_SHIFT1 || optimize_size)
12031    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032   "shr{q}\t%0"
12033   [(set_attr "type" "ishift")
12034    (set_attr "length" "2")])
12035
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags.  We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*lshrdi3_cmp_rex64"
12040   [(set (reg FLAGS_REG)
12041         (compare
12042           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043                        (match_operand:QI 2 "const_int_operand" "e"))
12044           (const_int 0)))
12045    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12047   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12048    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12049    && (optimize_size
12050        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051   "shr{q}\t{%2, %0|%0, %2}"
12052   [(set_attr "type" "ishift")
12053    (set_attr "mode" "DI")])
12054
12055 (define_insn "*lshrdi3_cconly_rex64"
12056   [(set (reg FLAGS_REG)
12057         (compare
12058           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059                        (match_operand:QI 2 "const_int_operand" "e"))
12060           (const_int 0)))
12061    (clobber (match_scratch:DI 0 "=r"))]
12062   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12064    && (optimize_size
12065        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12066   "shr{q}\t{%2, %0|%0, %2}"
12067   [(set_attr "type" "ishift")
12068    (set_attr "mode" "DI")])
12069
12070 (define_insn "*lshrdi3_1"
12071   [(set (match_operand:DI 0 "register_operand" "=r")
12072         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074    (clobber (reg:CC FLAGS_REG))]
12075   "!TARGET_64BIT"
12076   "#"
12077   [(set_attr "type" "multi")])
12078
12079 ;; By default we don't ask for a scratch register, because when DImode
12080 ;; values are manipulated, registers are already at a premium.  But if
12081 ;; we have one handy, we won't turn it away.
12082 (define_peephole2
12083   [(match_scratch:SI 3 "r")
12084    (parallel [(set (match_operand:DI 0 "register_operand" "")
12085                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12086                                 (match_operand:QI 2 "nonmemory_operand" "")))
12087               (clobber (reg:CC FLAGS_REG))])
12088    (match_dup 3)]
12089   "!TARGET_64BIT && TARGET_CMOVE"
12090   [(const_int 0)]
12091   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12092
12093 (define_split 
12094   [(set (match_operand:DI 0 "register_operand" "")
12095         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12096                      (match_operand:QI 2 "nonmemory_operand" "")))
12097    (clobber (reg:CC FLAGS_REG))]
12098   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099                      ? flow2_completed : reload_completed)"
12100   [(const_int 0)]
12101   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12102
12103 (define_expand "lshrsi3"
12104   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12105         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12106                      (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   ""
12109   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12110
12111 (define_insn "*lshrsi3_1_one_bit"
12112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12113         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12114                      (match_operand:QI 2 "const1_operand" "")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117    && (TARGET_SHIFT1 || optimize_size)"
12118   "shr{l}\t%0"
12119   [(set_attr "type" "ishift")
12120    (set (attr "length") 
12121      (if_then_else (match_operand:SI 0 "register_operand" "") 
12122         (const_string "2")
12123         (const_string "*")))])
12124
12125 (define_insn "*lshrsi3_1_one_bit_zext"
12126   [(set (match_operand:DI 0 "register_operand" "=r")
12127         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12128                      (match_operand:QI 2 "const1_operand" "")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12131    && (TARGET_SHIFT1 || optimize_size)"
12132   "shr{l}\t%k0"
12133   [(set_attr "type" "ishift")
12134    (set_attr "length" "2")])
12135
12136 (define_insn "*lshrsi3_1"
12137   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12138         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12139                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142   "@
12143    shr{l}\t{%2, %0|%0, %2}
12144    shr{l}\t{%b2, %0|%0, %b2}"
12145   [(set_attr "type" "ishift")
12146    (set_attr "mode" "SI")])
12147
12148 (define_insn "*lshrsi3_1_zext"
12149   [(set (match_operand:DI 0 "register_operand" "=r,r")
12150         (zero_extend:DI
12151           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12152                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12155   "@
12156    shr{l}\t{%2, %k0|%k0, %2}
12157    shr{l}\t{%b2, %k0|%k0, %b2}"
12158   [(set_attr "type" "ishift")
12159    (set_attr "mode" "SI")])
12160
12161 ;; This pattern can't accept a variable shift count, since shifts by
12162 ;; zero don't affect the flags.  We assume that shifts by constant
12163 ;; zero are optimized away.
12164 (define_insn "*lshrsi3_one_bit_cmp"
12165   [(set (reg FLAGS_REG)
12166         (compare
12167           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12168                        (match_operand:QI 2 "const1_operand" ""))
12169           (const_int 0)))
12170    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12171         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12172   "ix86_match_ccmode (insn, CCGOCmode)
12173    && (TARGET_SHIFT1 || optimize_size)
12174    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12175   "shr{l}\t%0"
12176   [(set_attr "type" "ishift")
12177    (set (attr "length") 
12178      (if_then_else (match_operand:SI 0 "register_operand" "") 
12179         (const_string "2")
12180         (const_string "*")))])
12181
12182 (define_insn "*lshrsi3_one_bit_cconly"
12183   [(set (reg FLAGS_REG)
12184         (compare
12185           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12186                        (match_operand:QI 2 "const1_operand" ""))
12187           (const_int 0)))
12188    (clobber (match_scratch:SI 0 "=r"))]
12189   "ix86_match_ccmode (insn, CCGOCmode)
12190    && (TARGET_SHIFT1 || optimize_size)
12191    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12192   "shr{l}\t%0"
12193   [(set_attr "type" "ishift")
12194    (set_attr "length" "2")])
12195
12196 (define_insn "*lshrsi3_cmp_one_bit_zext"
12197   [(set (reg FLAGS_REG)
12198         (compare
12199           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12200                        (match_operand:QI 2 "const1_operand" ""))
12201           (const_int 0)))
12202    (set (match_operand:DI 0 "register_operand" "=r")
12203         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12204   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12205    && (TARGET_SHIFT1 || optimize_size)
12206    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12207   "shr{l}\t%k0"
12208   [(set_attr "type" "ishift")
12209    (set_attr "length" "2")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags.  We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrsi3_cmp"
12215   [(set (reg FLAGS_REG)
12216         (compare
12217           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12219           (const_int 0)))
12220    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222   "ix86_match_ccmode (insn, CCGOCmode)
12223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12224    && (optimize_size
12225        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12226   "shr{l}\t{%2, %0|%0, %2}"
12227   [(set_attr "type" "ishift")
12228    (set_attr "mode" "SI")])
12229
12230 (define_insn "*lshrsi3_cconly"
12231   [(set (reg FLAGS_REG)
12232       (compare
12233         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12235         (const_int 0)))
12236    (clobber (match_scratch:SI 0 "=r"))]
12237   "ix86_match_ccmode (insn, CCGOCmode)
12238    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12239    && (optimize_size
12240        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12241   "shr{l}\t{%2, %0|%0, %2}"
12242   [(set_attr "type" "ishift")
12243    (set_attr "mode" "SI")])
12244
12245 (define_insn "*lshrsi3_cmp_zext"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12250           (const_int 0)))
12251    (set (match_operand:DI 0 "register_operand" "=r")
12252         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255    && (optimize_size
12256        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257   "shr{l}\t{%2, %k0|%k0, %2}"
12258   [(set_attr "type" "ishift")
12259    (set_attr "mode" "SI")])
12260
12261 (define_expand "lshrhi3"
12262   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12263         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12264                      (match_operand:QI 2 "nonmemory_operand" "")))
12265    (clobber (reg:CC FLAGS_REG))]
12266   "TARGET_HIMODE_MATH"
12267   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12268
12269 (define_insn "*lshrhi3_1_one_bit"
12270   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12271         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12272                      (match_operand:QI 2 "const1_operand" "")))
12273    (clobber (reg:CC FLAGS_REG))]
12274   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275    && (TARGET_SHIFT1 || optimize_size)"
12276   "shr{w}\t%0"
12277   [(set_attr "type" "ishift")
12278    (set (attr "length") 
12279      (if_then_else (match_operand 0 "register_operand" "") 
12280         (const_string "2")
12281         (const_string "*")))])
12282
12283 (define_insn "*lshrhi3_1"
12284   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12285         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12286                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12287    (clobber (reg:CC FLAGS_REG))]
12288   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289   "@
12290    shr{w}\t{%2, %0|%0, %2}
12291    shr{w}\t{%b2, %0|%0, %b2}"
12292   [(set_attr "type" "ishift")
12293    (set_attr "mode" "HI")])
12294
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags.  We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*lshrhi3_one_bit_cmp"
12299   [(set (reg FLAGS_REG)
12300         (compare
12301           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12302                        (match_operand:QI 2 "const1_operand" ""))
12303           (const_int 0)))
12304    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12306   "ix86_match_ccmode (insn, CCGOCmode)
12307    && (TARGET_SHIFT1 || optimize_size)
12308    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309   "shr{w}\t%0"
12310   [(set_attr "type" "ishift")
12311    (set (attr "length") 
12312      (if_then_else (match_operand:SI 0 "register_operand" "") 
12313         (const_string "2")
12314         (const_string "*")))])
12315
12316 (define_insn "*lshrhi3_one_bit_cconly"
12317   [(set (reg FLAGS_REG)
12318         (compare
12319           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320                        (match_operand:QI 2 "const1_operand" ""))
12321           (const_int 0)))
12322    (clobber (match_scratch:HI 0 "=r"))]
12323   "ix86_match_ccmode (insn, CCGOCmode)
12324    && (TARGET_SHIFT1 || optimize_size)
12325    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12326   "shr{w}\t%0"
12327   [(set_attr "type" "ishift")
12328    (set_attr "length" "2")])
12329
12330 ;; This pattern can't accept a variable shift count, since shifts by
12331 ;; zero don't affect the flags.  We assume that shifts by constant
12332 ;; zero are optimized away.
12333 (define_insn "*lshrhi3_cmp"
12334   [(set (reg FLAGS_REG)
12335         (compare
12336           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12337                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12338           (const_int 0)))
12339    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12340         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12341   "ix86_match_ccmode (insn, CCGOCmode)
12342    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12343    && (optimize_size
12344        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12345   "shr{w}\t{%2, %0|%0, %2}"
12346   [(set_attr "type" "ishift")
12347    (set_attr "mode" "HI")])
12348
12349 (define_insn "*lshrhi3_cconly"
12350   [(set (reg FLAGS_REG)
12351         (compare
12352           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12354           (const_int 0)))
12355    (clobber (match_scratch:HI 0 "=r"))]
12356   "ix86_match_ccmode (insn, CCGOCmode)
12357    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12358    && (optimize_size
12359        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12360   "shr{w}\t{%2, %0|%0, %2}"
12361   [(set_attr "type" "ishift")
12362    (set_attr "mode" "HI")])
12363
12364 (define_expand "lshrqi3"
12365   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12366         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12367                      (match_operand:QI 2 "nonmemory_operand" "")))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "TARGET_QIMODE_MATH"
12370   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12371
12372 (define_insn "*lshrqi3_1_one_bit"
12373   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375                      (match_operand:QI 2 "const1_operand" "")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12378    && (TARGET_SHIFT1 || optimize_size)"
12379   "shr{b}\t%0"
12380   [(set_attr "type" "ishift")
12381    (set (attr "length") 
12382      (if_then_else (match_operand 0 "register_operand" "") 
12383         (const_string "2")
12384         (const_string "*")))])
12385
12386 (define_insn "*lshrqi3_1_one_bit_slp"
12387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388         (lshiftrt:QI (match_dup 0)
12389                      (match_operand:QI 1 "const1_operand" "")))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392    && (TARGET_SHIFT1 || optimize_size)"
12393   "shr{b}\t%0"
12394   [(set_attr "type" "ishift1")
12395    (set (attr "length") 
12396      (if_then_else (match_operand 0 "register_operand" "") 
12397         (const_string "2")
12398         (const_string "*")))])
12399
12400 (define_insn "*lshrqi3_1"
12401   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12402         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12403                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404    (clobber (reg:CC FLAGS_REG))]
12405   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12406   "@
12407    shr{b}\t{%2, %0|%0, %2}
12408    shr{b}\t{%b2, %0|%0, %b2}"
12409   [(set_attr "type" "ishift")
12410    (set_attr "mode" "QI")])
12411
12412 (define_insn "*lshrqi3_1_slp"
12413   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12414         (lshiftrt:QI (match_dup 0)
12415                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12418    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12419   "@
12420    shr{b}\t{%1, %0|%0, %1}
12421    shr{b}\t{%b1, %0|%0, %b1}"
12422   [(set_attr "type" "ishift1")
12423    (set_attr "mode" "QI")])
12424
12425 ;; This pattern can't accept a variable shift count, since shifts by
12426 ;; zero don't affect the flags.  We assume that shifts by constant
12427 ;; zero are optimized away.
12428 (define_insn "*lshrqi2_one_bit_cmp"
12429   [(set (reg FLAGS_REG)
12430         (compare
12431           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12432                        (match_operand:QI 2 "const1_operand" ""))
12433           (const_int 0)))
12434    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12435         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12436   "ix86_match_ccmode (insn, CCGOCmode)
12437    && (TARGET_SHIFT1 || optimize_size)
12438    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12439   "shr{b}\t%0"
12440   [(set_attr "type" "ishift")
12441    (set (attr "length") 
12442      (if_then_else (match_operand:SI 0 "register_operand" "") 
12443         (const_string "2")
12444         (const_string "*")))])
12445
12446 (define_insn "*lshrqi2_one_bit_cconly"
12447   [(set (reg FLAGS_REG)
12448         (compare
12449           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450                        (match_operand:QI 2 "const1_operand" ""))
12451           (const_int 0)))
12452    (clobber (match_scratch:QI 0 "=q"))]
12453   "ix86_match_ccmode (insn, CCGOCmode)
12454    && (TARGET_SHIFT1 || optimize_size)
12455    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12456   "shr{b}\t%0"
12457   [(set_attr "type" "ishift")
12458    (set_attr "length" "2")])
12459
12460 ;; This pattern can't accept a variable shift count, since shifts by
12461 ;; zero don't affect the flags.  We assume that shifts by constant
12462 ;; zero are optimized away.
12463 (define_insn "*lshrqi2_cmp"
12464   [(set (reg FLAGS_REG)
12465         (compare
12466           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12468           (const_int 0)))
12469    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12471   "ix86_match_ccmode (insn, CCGOCmode)
12472    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12473    && (optimize_size
12474        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12475   "shr{b}\t{%2, %0|%0, %2}"
12476   [(set_attr "type" "ishift")
12477    (set_attr "mode" "QI")])
12478
12479 (define_insn "*lshrqi2_cconly"
12480   [(set (reg FLAGS_REG)
12481         (compare
12482           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12484           (const_int 0)))
12485    (clobber (match_scratch:QI 0 "=q"))]
12486   "ix86_match_ccmode (insn, CCGOCmode)
12487    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12488    && (optimize_size
12489        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12490   "shr{b}\t{%2, %0|%0, %2}"
12491   [(set_attr "type" "ishift")
12492    (set_attr "mode" "QI")])
12493 \f
12494 ;; Rotate instructions
12495
12496 (define_expand "rotldi3"
12497   [(set (match_operand:DI 0 "shiftdi_operand" "")
12498         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12499                    (match_operand:QI 2 "nonmemory_operand" "")))
12500    (clobber (reg:CC FLAGS_REG))]
12501  ""
12502 {
12503   if (TARGET_64BIT)
12504     {
12505       ix86_expand_binary_operator (ROTATE, DImode, operands);
12506       DONE;
12507     }
12508   if (!const_1_to_31_operand (operands[2], VOIDmode))
12509     FAIL;
12510   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12511   DONE;
12512 })
12513
12514 ;; Implement rotation using two double-precision shift instructions
12515 ;; and a scratch register.   
12516 (define_insn_and_split "ix86_rotldi3"
12517  [(set (match_operand:DI 0 "register_operand" "=r")
12518        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12519                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12520   (clobber (reg:CC FLAGS_REG))
12521   (clobber (match_scratch:SI 3 "=&r"))]
12522  "!TARGET_64BIT"
12523  "" 
12524  "&& reload_completed"
12525  [(set (match_dup 3) (match_dup 4))
12526   (parallel
12527    [(set (match_dup 4)
12528          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12529                  (lshiftrt:SI (match_dup 5)
12530                               (minus:QI (const_int 32) (match_dup 2)))))
12531     (clobber (reg:CC FLAGS_REG))])
12532   (parallel
12533    [(set (match_dup 5)
12534          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12535                  (lshiftrt:SI (match_dup 3)
12536                               (minus:QI (const_int 32) (match_dup 2)))))
12537     (clobber (reg:CC FLAGS_REG))])]
12538  "split_di (operands, 1, operands + 4, operands + 5);")
12539  
12540 (define_insn "*rotlsi3_1_one_bit_rex64"
12541   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12542         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12543                    (match_operand:QI 2 "const1_operand" "")))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12546    && (TARGET_SHIFT1 || optimize_size)"
12547   "rol{q}\t%0"
12548   [(set_attr "type" "rotate")
12549    (set (attr "length") 
12550      (if_then_else (match_operand:DI 0 "register_operand" "") 
12551         (const_string "2")
12552         (const_string "*")))])
12553
12554 (define_insn "*rotldi3_1_rex64"
12555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12556         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12557                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12558    (clobber (reg:CC FLAGS_REG))]
12559   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12560   "@
12561    rol{q}\t{%2, %0|%0, %2}
12562    rol{q}\t{%b2, %0|%0, %b2}"
12563   [(set_attr "type" "rotate")
12564    (set_attr "mode" "DI")])
12565
12566 (define_expand "rotlsi3"
12567   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12568         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12569                    (match_operand:QI 2 "nonmemory_operand" "")))
12570    (clobber (reg:CC FLAGS_REG))]
12571   ""
12572   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12573
12574 (define_insn "*rotlsi3_1_one_bit"
12575   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12577                    (match_operand:QI 2 "const1_operand" "")))
12578    (clobber (reg:CC FLAGS_REG))]
12579   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12580    && (TARGET_SHIFT1 || optimize_size)"
12581   "rol{l}\t%0"
12582   [(set_attr "type" "rotate")
12583    (set (attr "length") 
12584      (if_then_else (match_operand:SI 0 "register_operand" "") 
12585         (const_string "2")
12586         (const_string "*")))])
12587
12588 (define_insn "*rotlsi3_1_one_bit_zext"
12589   [(set (match_operand:DI 0 "register_operand" "=r")
12590         (zero_extend:DI
12591           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12592                      (match_operand:QI 2 "const1_operand" ""))))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12595    && (TARGET_SHIFT1 || optimize_size)"
12596   "rol{l}\t%k0"
12597   [(set_attr "type" "rotate")
12598    (set_attr "length" "2")])
12599
12600 (define_insn "*rotlsi3_1"
12601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12602         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12603                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12604    (clobber (reg:CC FLAGS_REG))]
12605   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12606   "@
12607    rol{l}\t{%2, %0|%0, %2}
12608    rol{l}\t{%b2, %0|%0, %b2}"
12609   [(set_attr "type" "rotate")
12610    (set_attr "mode" "SI")])
12611
12612 (define_insn "*rotlsi3_1_zext"
12613   [(set (match_operand:DI 0 "register_operand" "=r,r")
12614         (zero_extend:DI
12615           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12616                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12617    (clobber (reg:CC FLAGS_REG))]
12618   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12619   "@
12620    rol{l}\t{%2, %k0|%k0, %2}
12621    rol{l}\t{%b2, %k0|%k0, %b2}"
12622   [(set_attr "type" "rotate")
12623    (set_attr "mode" "SI")])
12624
12625 (define_expand "rotlhi3"
12626   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12627         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12628                    (match_operand:QI 2 "nonmemory_operand" "")))
12629    (clobber (reg:CC FLAGS_REG))]
12630   "TARGET_HIMODE_MATH"
12631   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12632
12633 (define_insn "*rotlhi3_1_one_bit"
12634   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12635         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12636                    (match_operand:QI 2 "const1_operand" "")))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12639    && (TARGET_SHIFT1 || optimize_size)"
12640   "rol{w}\t%0"
12641   [(set_attr "type" "rotate")
12642    (set (attr "length") 
12643      (if_then_else (match_operand 0 "register_operand" "") 
12644         (const_string "2")
12645         (const_string "*")))])
12646
12647 (define_insn "*rotlhi3_1"
12648   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12649         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12650                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12653   "@
12654    rol{w}\t{%2, %0|%0, %2}
12655    rol{w}\t{%b2, %0|%0, %b2}"
12656   [(set_attr "type" "rotate")
12657    (set_attr "mode" "HI")])
12658
12659 (define_expand "rotlqi3"
12660   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12661         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12662                    (match_operand:QI 2 "nonmemory_operand" "")))
12663    (clobber (reg:CC FLAGS_REG))]
12664   "TARGET_QIMODE_MATH"
12665   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12666
12667 (define_insn "*rotlqi3_1_one_bit_slp"
12668   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12669         (rotate:QI (match_dup 0)
12670                    (match_operand:QI 1 "const1_operand" "")))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12673    && (TARGET_SHIFT1 || optimize_size)"
12674   "rol{b}\t%0"
12675   [(set_attr "type" "rotate1")
12676    (set (attr "length") 
12677      (if_then_else (match_operand 0 "register_operand" "") 
12678         (const_string "2")
12679         (const_string "*")))])
12680
12681 (define_insn "*rotlqi3_1_one_bit"
12682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12683         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12684                    (match_operand:QI 2 "const1_operand" "")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12687    && (TARGET_SHIFT1 || optimize_size)"
12688   "rol{b}\t%0"
12689   [(set_attr "type" "rotate")
12690    (set (attr "length") 
12691      (if_then_else (match_operand 0 "register_operand" "") 
12692         (const_string "2")
12693         (const_string "*")))])
12694
12695 (define_insn "*rotlqi3_1_slp"
12696   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12697         (rotate:QI (match_dup 0)
12698                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12699    (clobber (reg:CC FLAGS_REG))]
12700   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12702   "@
12703    rol{b}\t{%1, %0|%0, %1}
12704    rol{b}\t{%b1, %0|%0, %b1}"
12705   [(set_attr "type" "rotate1")
12706    (set_attr "mode" "QI")])
12707
12708 (define_insn "*rotlqi3_1"
12709   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12710         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12711                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12714   "@
12715    rol{b}\t{%2, %0|%0, %2}
12716    rol{b}\t{%b2, %0|%0, %b2}"
12717   [(set_attr "type" "rotate")
12718    (set_attr "mode" "QI")])
12719
12720 (define_expand "rotrdi3"
12721   [(set (match_operand:DI 0 "shiftdi_operand" "")
12722         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12723                    (match_operand:QI 2 "nonmemory_operand" "")))
12724    (clobber (reg:CC FLAGS_REG))]
12725  ""
12726 {
12727   if (TARGET_64BIT)
12728     {
12729       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12730       DONE;
12731     }
12732   if (!const_1_to_31_operand (operands[2], VOIDmode))
12733     FAIL;
12734   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12735   DONE;
12736 })
12737   
12738 ;; Implement rotation using two double-precision shift instructions
12739 ;; and a scratch register.   
12740 (define_insn_and_split "ix86_rotrdi3"
12741  [(set (match_operand:DI 0 "register_operand" "=r")
12742        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12743                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12744   (clobber (reg:CC FLAGS_REG))
12745   (clobber (match_scratch:SI 3 "=&r"))]
12746  "!TARGET_64BIT"
12747  ""
12748  "&& reload_completed"
12749  [(set (match_dup 3) (match_dup 4))
12750   (parallel
12751    [(set (match_dup 4)
12752          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12753                  (ashift:SI (match_dup 5)
12754                             (minus:QI (const_int 32) (match_dup 2)))))
12755     (clobber (reg:CC FLAGS_REG))])
12756   (parallel
12757    [(set (match_dup 5)
12758          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12759                  (ashift:SI (match_dup 3)
12760                             (minus:QI (const_int 32) (match_dup 2)))))
12761     (clobber (reg:CC FLAGS_REG))])]
12762  "split_di (operands, 1, operands + 4, operands + 5);")
12763
12764 (define_insn "*rotrdi3_1_one_bit_rex64"
12765   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12766         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12767                      (match_operand:QI 2 "const1_operand" "")))
12768    (clobber (reg:CC FLAGS_REG))]
12769   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12770    && (TARGET_SHIFT1 || optimize_size)"
12771   "ror{q}\t%0"
12772   [(set_attr "type" "rotate")
12773    (set (attr "length") 
12774      (if_then_else (match_operand:DI 0 "register_operand" "") 
12775         (const_string "2")
12776         (const_string "*")))])
12777
12778 (define_insn "*rotrdi3_1_rex64"
12779   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12780         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12781                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12782    (clobber (reg:CC FLAGS_REG))]
12783   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12784   "@
12785    ror{q}\t{%2, %0|%0, %2}
12786    ror{q}\t{%b2, %0|%0, %b2}"
12787   [(set_attr "type" "rotate")
12788    (set_attr "mode" "DI")])
12789
12790 (define_expand "rotrsi3"
12791   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12792         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12793                      (match_operand:QI 2 "nonmemory_operand" "")))
12794    (clobber (reg:CC FLAGS_REG))]
12795   ""
12796   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12797
12798 (define_insn "*rotrsi3_1_one_bit"
12799   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12800         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12801                      (match_operand:QI 2 "const1_operand" "")))
12802    (clobber (reg:CC FLAGS_REG))]
12803   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12804    && (TARGET_SHIFT1 || optimize_size)"
12805   "ror{l}\t%0"
12806   [(set_attr "type" "rotate")
12807    (set (attr "length") 
12808      (if_then_else (match_operand:SI 0 "register_operand" "") 
12809         (const_string "2")
12810         (const_string "*")))])
12811
12812 (define_insn "*rotrsi3_1_one_bit_zext"
12813   [(set (match_operand:DI 0 "register_operand" "=r")
12814         (zero_extend:DI
12815           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12816                        (match_operand:QI 2 "const1_operand" ""))))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12819    && (TARGET_SHIFT1 || optimize_size)"
12820   "ror{l}\t%k0"
12821   [(set_attr "type" "rotate")
12822    (set (attr "length") 
12823      (if_then_else (match_operand:SI 0 "register_operand" "") 
12824         (const_string "2")
12825         (const_string "*")))])
12826
12827 (define_insn "*rotrsi3_1"
12828   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12829         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12833   "@
12834    ror{l}\t{%2, %0|%0, %2}
12835    ror{l}\t{%b2, %0|%0, %b2}"
12836   [(set_attr "type" "rotate")
12837    (set_attr "mode" "SI")])
12838
12839 (define_insn "*rotrsi3_1_zext"
12840   [(set (match_operand:DI 0 "register_operand" "=r,r")
12841         (zero_extend:DI
12842           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12843                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12846   "@
12847    ror{l}\t{%2, %k0|%k0, %2}
12848    ror{l}\t{%b2, %k0|%k0, %b2}"
12849   [(set_attr "type" "rotate")
12850    (set_attr "mode" "SI")])
12851
12852 (define_expand "rotrhi3"
12853   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12854         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12855                      (match_operand:QI 2 "nonmemory_operand" "")))
12856    (clobber (reg:CC FLAGS_REG))]
12857   "TARGET_HIMODE_MATH"
12858   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12859
12860 (define_insn "*rotrhi3_one_bit"
12861   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12862         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12863                      (match_operand:QI 2 "const1_operand" "")))
12864    (clobber (reg:CC FLAGS_REG))]
12865   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12866    && (TARGET_SHIFT1 || optimize_size)"
12867   "ror{w}\t%0"
12868   [(set_attr "type" "rotate")
12869    (set (attr "length") 
12870      (if_then_else (match_operand 0 "register_operand" "") 
12871         (const_string "2")
12872         (const_string "*")))])
12873
12874 (define_insn "*rotrhi3"
12875   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12876         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12877                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12880   "@
12881    ror{w}\t{%2, %0|%0, %2}
12882    ror{w}\t{%b2, %0|%0, %b2}"
12883   [(set_attr "type" "rotate")
12884    (set_attr "mode" "HI")])
12885
12886 (define_expand "rotrqi3"
12887   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12888         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12889                      (match_operand:QI 2 "nonmemory_operand" "")))
12890    (clobber (reg:CC FLAGS_REG))]
12891   "TARGET_QIMODE_MATH"
12892   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12893
12894 (define_insn "*rotrqi3_1_one_bit"
12895   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12896         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12897                      (match_operand:QI 2 "const1_operand" "")))
12898    (clobber (reg:CC FLAGS_REG))]
12899   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12900    && (TARGET_SHIFT1 || optimize_size)"
12901   "ror{b}\t%0"
12902   [(set_attr "type" "rotate")
12903    (set (attr "length") 
12904      (if_then_else (match_operand 0 "register_operand" "") 
12905         (const_string "2")
12906         (const_string "*")))])
12907
12908 (define_insn "*rotrqi3_1_one_bit_slp"
12909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12910         (rotatert:QI (match_dup 0)
12911                      (match_operand:QI 1 "const1_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12914    && (TARGET_SHIFT1 || optimize_size)"
12915   "ror{b}\t%0"
12916   [(set_attr "type" "rotate1")
12917    (set (attr "length") 
12918      (if_then_else (match_operand 0 "register_operand" "") 
12919         (const_string "2")
12920         (const_string "*")))])
12921
12922 (define_insn "*rotrqi3_1"
12923   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12924         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12925                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12928   "@
12929    ror{b}\t{%2, %0|%0, %2}
12930    ror{b}\t{%b2, %0|%0, %b2}"
12931   [(set_attr "type" "rotate")
12932    (set_attr "mode" "QI")])
12933
12934 (define_insn "*rotrqi3_1_slp"
12935   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12936         (rotatert:QI (match_dup 0)
12937                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12938    (clobber (reg:CC FLAGS_REG))]
12939   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12940    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12941   "@
12942    ror{b}\t{%1, %0|%0, %1}
12943    ror{b}\t{%b1, %0|%0, %b1}"
12944   [(set_attr "type" "rotate1")
12945    (set_attr "mode" "QI")])
12946 \f
12947 ;; Bit set / bit test instructions
12948
12949 (define_expand "extv"
12950   [(set (match_operand:SI 0 "register_operand" "")
12951         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12952                          (match_operand:SI 2 "const8_operand" "")
12953                          (match_operand:SI 3 "const8_operand" "")))]
12954   ""
12955 {
12956   /* Handle extractions from %ah et al.  */
12957   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12958     FAIL;
12959
12960   /* From mips.md: extract_bit_field doesn't verify that our source
12961      matches the predicate, so check it again here.  */
12962   if (! ext_register_operand (operands[1], VOIDmode))
12963     FAIL;
12964 })
12965
12966 (define_expand "extzv"
12967   [(set (match_operand:SI 0 "register_operand" "")
12968         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12969                          (match_operand:SI 2 "const8_operand" "")
12970                          (match_operand:SI 3 "const8_operand" "")))]
12971   ""
12972 {
12973   /* Handle extractions from %ah et al.  */
12974   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12975     FAIL;
12976
12977   /* From mips.md: extract_bit_field doesn't verify that our source
12978      matches the predicate, so check it again here.  */
12979   if (! ext_register_operand (operands[1], VOIDmode))
12980     FAIL;
12981 })
12982
12983 (define_expand "insv"
12984   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12985                       (match_operand 1 "const8_operand" "")
12986                       (match_operand 2 "const8_operand" ""))
12987         (match_operand 3 "register_operand" ""))]
12988   ""
12989 {
12990   /* Handle insertions to %ah et al.  */
12991   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12992     FAIL;
12993
12994   /* From mips.md: insert_bit_field doesn't verify that our source
12995      matches the predicate, so check it again here.  */
12996   if (! ext_register_operand (operands[0], VOIDmode))
12997     FAIL;
12998
12999   if (TARGET_64BIT)
13000     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13001   else
13002     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13003
13004   DONE;
13005 })
13006
13007 ;; %%% bts, btr, btc, bt.
13008 ;; In general these instructions are *slow* when applied to memory,
13009 ;; since they enforce atomic operation.  When applied to registers,
13010 ;; it depends on the cpu implementation.  They're never faster than
13011 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13012 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13013 ;; within the instruction itself, so operating on bits in the high
13014 ;; 32-bits of a register becomes easier.
13015 ;;
13016 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13017 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13018 ;; negdf respectively, so they can never be disabled entirely.
13019
13020 (define_insn "*btsq"
13021   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13022                          (const_int 1)
13023                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13024         (const_int 1))
13025    (clobber (reg:CC FLAGS_REG))]
13026   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13027   "bts{q} %1,%0"
13028   [(set_attr "type" "alu1")])
13029
13030 (define_insn "*btrq"
13031   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13032                          (const_int 1)
13033                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13034         (const_int 0))
13035    (clobber (reg:CC FLAGS_REG))]
13036   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13037   "btr{q} %1,%0"
13038   [(set_attr "type" "alu1")])
13039
13040 (define_insn "*btcq"
13041   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13042                          (const_int 1)
13043                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13044         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13045    (clobber (reg:CC FLAGS_REG))]
13046   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13047   "btc{q} %1,%0"
13048   [(set_attr "type" "alu1")])
13049
13050 ;; Allow Nocona to avoid these instructions if a register is available.
13051
13052 (define_peephole2
13053   [(match_scratch:DI 2 "r")
13054    (parallel [(set (zero_extract:DI
13055                      (match_operand:DI 0 "register_operand" "")
13056                      (const_int 1)
13057                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13058                    (const_int 1))
13059               (clobber (reg:CC FLAGS_REG))])]
13060   "TARGET_64BIT && !TARGET_USE_BT"
13061   [(const_int 0)]
13062 {
13063   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13064   rtx op1;
13065
13066   if (HOST_BITS_PER_WIDE_INT >= 64)
13067     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13068   else if (i < HOST_BITS_PER_WIDE_INT)
13069     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13070   else
13071     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13072
13073   op1 = immed_double_const (lo, hi, DImode);
13074   if (i >= 31)
13075     {
13076       emit_move_insn (operands[2], op1);
13077       op1 = operands[2];
13078     }
13079
13080   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13081   DONE;
13082 })
13083
13084 (define_peephole2
13085   [(match_scratch:DI 2 "r")
13086    (parallel [(set (zero_extract:DI
13087                      (match_operand:DI 0 "register_operand" "")
13088                      (const_int 1)
13089                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13090                    (const_int 0))
13091               (clobber (reg:CC FLAGS_REG))])]
13092   "TARGET_64BIT && !TARGET_USE_BT"
13093   [(const_int 0)]
13094 {
13095   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13096   rtx op1;
13097
13098   if (HOST_BITS_PER_WIDE_INT >= 64)
13099     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13100   else if (i < HOST_BITS_PER_WIDE_INT)
13101     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102   else
13103     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13104
13105   op1 = immed_double_const (~lo, ~hi, DImode);
13106   if (i >= 32)
13107     {
13108       emit_move_insn (operands[2], op1);
13109       op1 = operands[2];
13110     }
13111
13112   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13113   DONE;
13114 })
13115
13116 (define_peephole2
13117   [(match_scratch:DI 2 "r")
13118    (parallel [(set (zero_extract:DI
13119                      (match_operand:DI 0 "register_operand" "")
13120                      (const_int 1)
13121                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13122               (not:DI (zero_extract:DI
13123                         (match_dup 0) (const_int 1) (match_dup 1))))
13124               (clobber (reg:CC FLAGS_REG))])]
13125   "TARGET_64BIT && !TARGET_USE_BT"
13126   [(const_int 0)]
13127 {
13128   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13129   rtx op1;
13130
13131   if (HOST_BITS_PER_WIDE_INT >= 64)
13132     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133   else if (i < HOST_BITS_PER_WIDE_INT)
13134     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13135   else
13136     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13137
13138   op1 = immed_double_const (lo, hi, DImode);
13139   if (i >= 31)
13140     {
13141       emit_move_insn (operands[2], op1);
13142       op1 = operands[2];
13143     }
13144
13145   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13146   DONE;
13147 })
13148 \f
13149 ;; Store-flag instructions.
13150
13151 ;; For all sCOND expanders, also expand the compare or test insn that
13152 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13153
13154 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13155 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13156 ;; way, which can later delete the movzx if only QImode is needed.
13157
13158 (define_expand "seq"
13159   [(set (match_operand:QI 0 "register_operand" "")
13160         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13161   ""
13162   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13163
13164 (define_expand "sne"
13165   [(set (match_operand:QI 0 "register_operand" "")
13166         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167   ""
13168   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13169
13170 (define_expand "sgt"
13171   [(set (match_operand:QI 0 "register_operand" "")
13172         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173   ""
13174   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13175
13176 (define_expand "sgtu"
13177   [(set (match_operand:QI 0 "register_operand" "")
13178         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179   ""
13180   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13181
13182 (define_expand "slt"
13183   [(set (match_operand:QI 0 "register_operand" "")
13184         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185   ""
13186   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13187
13188 (define_expand "sltu"
13189   [(set (match_operand:QI 0 "register_operand" "")
13190         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191   ""
13192   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13193
13194 (define_expand "sge"
13195   [(set (match_operand:QI 0 "register_operand" "")
13196         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197   ""
13198   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13199
13200 (define_expand "sgeu"
13201   [(set (match_operand:QI 0 "register_operand" "")
13202         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203   ""
13204   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13205
13206 (define_expand "sle"
13207   [(set (match_operand:QI 0 "register_operand" "")
13208         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209   ""
13210   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13211
13212 (define_expand "sleu"
13213   [(set (match_operand:QI 0 "register_operand" "")
13214         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215   ""
13216   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13217
13218 (define_expand "sunordered"
13219   [(set (match_operand:QI 0 "register_operand" "")
13220         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221   "TARGET_80387 || TARGET_SSE"
13222   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13223
13224 (define_expand "sordered"
13225   [(set (match_operand:QI 0 "register_operand" "")
13226         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227   "TARGET_80387"
13228   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13229
13230 (define_expand "suneq"
13231   [(set (match_operand:QI 0 "register_operand" "")
13232         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233   "TARGET_80387 || TARGET_SSE"
13234   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13235
13236 (define_expand "sunge"
13237   [(set (match_operand:QI 0 "register_operand" "")
13238         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239   "TARGET_80387 || TARGET_SSE"
13240   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13241
13242 (define_expand "sungt"
13243   [(set (match_operand:QI 0 "register_operand" "")
13244         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245   "TARGET_80387 || TARGET_SSE"
13246   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13247
13248 (define_expand "sunle"
13249   [(set (match_operand:QI 0 "register_operand" "")
13250         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251   "TARGET_80387 || TARGET_SSE"
13252   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13253
13254 (define_expand "sunlt"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   "TARGET_80387 || TARGET_SSE"
13258   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13259
13260 (define_expand "sltgt"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   "TARGET_80387 || TARGET_SSE"
13264   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13265
13266 (define_insn "*setcc_1"
13267   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268         (match_operator:QI 1 "ix86_comparison_operator"
13269           [(reg FLAGS_REG) (const_int 0)]))]
13270   ""
13271   "set%C1\t%0"
13272   [(set_attr "type" "setcc")
13273    (set_attr "mode" "QI")])
13274
13275 (define_insn "*setcc_2"
13276   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13277         (match_operator:QI 1 "ix86_comparison_operator"
13278           [(reg FLAGS_REG) (const_int 0)]))]
13279   ""
13280   "set%C1\t%0"
13281   [(set_attr "type" "setcc")
13282    (set_attr "mode" "QI")])
13283
13284 ;; In general it is not safe to assume too much about CCmode registers,
13285 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13286 ;; conditions this is safe on x86, so help combine not create
13287 ;;
13288 ;;      seta    %al
13289 ;;      testb   %al, %al
13290 ;;      sete    %al
13291
13292 (define_split 
13293   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13294         (ne:QI (match_operator 1 "ix86_comparison_operator"
13295                  [(reg FLAGS_REG) (const_int 0)])
13296             (const_int 0)))]
13297   ""
13298   [(set (match_dup 0) (match_dup 1))]
13299 {
13300   PUT_MODE (operands[1], QImode);
13301 })
13302
13303 (define_split 
13304   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13305         (ne:QI (match_operator 1 "ix86_comparison_operator"
13306                  [(reg FLAGS_REG) (const_int 0)])
13307             (const_int 0)))]
13308   ""
13309   [(set (match_dup 0) (match_dup 1))]
13310 {
13311   PUT_MODE (operands[1], QImode);
13312 })
13313
13314 (define_split 
13315   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316         (eq:QI (match_operator 1 "ix86_comparison_operator"
13317                  [(reg FLAGS_REG) (const_int 0)])
13318             (const_int 0)))]
13319   ""
13320   [(set (match_dup 0) (match_dup 1))]
13321 {
13322   rtx new_op1 = copy_rtx (operands[1]);
13323   operands[1] = new_op1;
13324   PUT_MODE (new_op1, QImode);
13325   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13326                                              GET_MODE (XEXP (new_op1, 0))));
13327
13328   /* Make sure that (a) the CCmode we have for the flags is strong
13329      enough for the reversed compare or (b) we have a valid FP compare.  */
13330   if (! ix86_comparison_operator (new_op1, VOIDmode))
13331     FAIL;
13332 })
13333
13334 (define_split 
13335   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336         (eq:QI (match_operator 1 "ix86_comparison_operator"
13337                  [(reg FLAGS_REG) (const_int 0)])
13338             (const_int 0)))]
13339   ""
13340   [(set (match_dup 0) (match_dup 1))]
13341 {
13342   rtx new_op1 = copy_rtx (operands[1]);
13343   operands[1] = new_op1;
13344   PUT_MODE (new_op1, QImode);
13345   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13346                                              GET_MODE (XEXP (new_op1, 0))));
13347
13348   /* Make sure that (a) the CCmode we have for the flags is strong
13349      enough for the reversed compare or (b) we have a valid FP compare.  */
13350   if (! ix86_comparison_operator (new_op1, VOIDmode))
13351     FAIL;
13352 })
13353
13354 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13355 ;; subsequent logical operations are used to imitate conditional moves.
13356 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13357 ;; it directly.
13358
13359 (define_insn "*sse_setccsf"
13360   [(set (match_operand:SF 0 "register_operand" "=x")
13361         (match_operator:SF 1 "sse_comparison_operator"
13362           [(match_operand:SF 2 "register_operand" "0")
13363            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13364   "TARGET_SSE"
13365   "cmp%D1ss\t{%3, %0|%0, %3}"
13366   [(set_attr "type" "ssecmp")
13367    (set_attr "mode" "SF")])
13368
13369 (define_insn "*sse_setccdf"
13370   [(set (match_operand:DF 0 "register_operand" "=Y")
13371         (match_operator:DF 1 "sse_comparison_operator"
13372           [(match_operand:DF 2 "register_operand" "0")
13373            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13374   "TARGET_SSE2"
13375   "cmp%D1sd\t{%3, %0|%0, %3}"
13376   [(set_attr "type" "ssecmp")
13377    (set_attr "mode" "DF")])
13378 \f
13379 ;; Basic conditional jump instructions.
13380 ;; We ignore the overflow flag for signed branch instructions.
13381
13382 ;; For all bCOND expanders, also expand the compare or test insn that
13383 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13384
13385 (define_expand "beq"
13386   [(set (pc)
13387         (if_then_else (match_dup 1)
13388                       (label_ref (match_operand 0 "" ""))
13389                       (pc)))]
13390   ""
13391   "ix86_expand_branch (EQ, operands[0]); DONE;")
13392
13393 (define_expand "bne"
13394   [(set (pc)
13395         (if_then_else (match_dup 1)
13396                       (label_ref (match_operand 0 "" ""))
13397                       (pc)))]
13398   ""
13399   "ix86_expand_branch (NE, operands[0]); DONE;")
13400
13401 (define_expand "bgt"
13402   [(set (pc)
13403         (if_then_else (match_dup 1)
13404                       (label_ref (match_operand 0 "" ""))
13405                       (pc)))]
13406   ""
13407   "ix86_expand_branch (GT, operands[0]); DONE;")
13408
13409 (define_expand "bgtu"
13410   [(set (pc)
13411         (if_then_else (match_dup 1)
13412                       (label_ref (match_operand 0 "" ""))
13413                       (pc)))]
13414   ""
13415   "ix86_expand_branch (GTU, operands[0]); DONE;")
13416
13417 (define_expand "blt"
13418   [(set (pc)
13419         (if_then_else (match_dup 1)
13420                       (label_ref (match_operand 0 "" ""))
13421                       (pc)))]
13422   ""
13423   "ix86_expand_branch (LT, operands[0]); DONE;")
13424
13425 (define_expand "bltu"
13426   [(set (pc)
13427         (if_then_else (match_dup 1)
13428                       (label_ref (match_operand 0 "" ""))
13429                       (pc)))]
13430   ""
13431   "ix86_expand_branch (LTU, operands[0]); DONE;")
13432
13433 (define_expand "bge"
13434   [(set (pc)
13435         (if_then_else (match_dup 1)
13436                       (label_ref (match_operand 0 "" ""))
13437                       (pc)))]
13438   ""
13439   "ix86_expand_branch (GE, operands[0]); DONE;")
13440
13441 (define_expand "bgeu"
13442   [(set (pc)
13443         (if_then_else (match_dup 1)
13444                       (label_ref (match_operand 0 "" ""))
13445                       (pc)))]
13446   ""
13447   "ix86_expand_branch (GEU, operands[0]); DONE;")
13448
13449 (define_expand "ble"
13450   [(set (pc)
13451         (if_then_else (match_dup 1)
13452                       (label_ref (match_operand 0 "" ""))
13453                       (pc)))]
13454   ""
13455   "ix86_expand_branch (LE, operands[0]); DONE;")
13456
13457 (define_expand "bleu"
13458   [(set (pc)
13459         (if_then_else (match_dup 1)
13460                       (label_ref (match_operand 0 "" ""))
13461                       (pc)))]
13462   ""
13463   "ix86_expand_branch (LEU, operands[0]); DONE;")
13464
13465 (define_expand "bunordered"
13466   [(set (pc)
13467         (if_then_else (match_dup 1)
13468                       (label_ref (match_operand 0 "" ""))
13469                       (pc)))]
13470   "TARGET_80387 || TARGET_SSE_MATH"
13471   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13472
13473 (define_expand "bordered"
13474   [(set (pc)
13475         (if_then_else (match_dup 1)
13476                       (label_ref (match_operand 0 "" ""))
13477                       (pc)))]
13478   "TARGET_80387 || TARGET_SSE_MATH"
13479   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13480
13481 (define_expand "buneq"
13482   [(set (pc)
13483         (if_then_else (match_dup 1)
13484                       (label_ref (match_operand 0 "" ""))
13485                       (pc)))]
13486   "TARGET_80387 || TARGET_SSE_MATH"
13487   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13488
13489 (define_expand "bunge"
13490   [(set (pc)
13491         (if_then_else (match_dup 1)
13492                       (label_ref (match_operand 0 "" ""))
13493                       (pc)))]
13494   "TARGET_80387 || TARGET_SSE_MATH"
13495   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13496
13497 (define_expand "bungt"
13498   [(set (pc)
13499         (if_then_else (match_dup 1)
13500                       (label_ref (match_operand 0 "" ""))
13501                       (pc)))]
13502   "TARGET_80387 || TARGET_SSE_MATH"
13503   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13504
13505 (define_expand "bunle"
13506   [(set (pc)
13507         (if_then_else (match_dup 1)
13508                       (label_ref (match_operand 0 "" ""))
13509                       (pc)))]
13510   "TARGET_80387 || TARGET_SSE_MATH"
13511   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13512
13513 (define_expand "bunlt"
13514   [(set (pc)
13515         (if_then_else (match_dup 1)
13516                       (label_ref (match_operand 0 "" ""))
13517                       (pc)))]
13518   "TARGET_80387 || TARGET_SSE_MATH"
13519   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13520
13521 (define_expand "bltgt"
13522   [(set (pc)
13523         (if_then_else (match_dup 1)
13524                       (label_ref (match_operand 0 "" ""))
13525                       (pc)))]
13526   "TARGET_80387 || TARGET_SSE_MATH"
13527   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13528
13529 (define_insn "*jcc_1"
13530   [(set (pc)
13531         (if_then_else (match_operator 1 "ix86_comparison_operator"
13532                                       [(reg FLAGS_REG) (const_int 0)])
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   ""
13536   "%+j%C1\t%l0"
13537   [(set_attr "type" "ibr")
13538    (set_attr "modrm" "0")
13539    (set (attr "length")
13540            (if_then_else (and (ge (minus (match_dup 0) (pc))
13541                                   (const_int -126))
13542                               (lt (minus (match_dup 0) (pc))
13543                                   (const_int 128)))
13544              (const_int 2)
13545              (const_int 6)))])
13546
13547 (define_insn "*jcc_2"
13548   [(set (pc)
13549         (if_then_else (match_operator 1 "ix86_comparison_operator"
13550                                       [(reg FLAGS_REG) (const_int 0)])
13551                       (pc)
13552                       (label_ref (match_operand 0 "" ""))))]
13553   ""
13554   "%+j%c1\t%l0"
13555   [(set_attr "type" "ibr")
13556    (set_attr "modrm" "0")
13557    (set (attr "length")
13558            (if_then_else (and (ge (minus (match_dup 0) (pc))
13559                                   (const_int -126))
13560                               (lt (minus (match_dup 0) (pc))
13561                                   (const_int 128)))
13562              (const_int 2)
13563              (const_int 6)))])
13564
13565 ;; In general it is not safe to assume too much about CCmode registers,
13566 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13567 ;; conditions this is safe on x86, so help combine not create
13568 ;;
13569 ;;      seta    %al
13570 ;;      testb   %al, %al
13571 ;;      je      Lfoo
13572
13573 (define_split 
13574   [(set (pc)
13575         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13576                                       [(reg FLAGS_REG) (const_int 0)])
13577                           (const_int 0))
13578                       (label_ref (match_operand 1 "" ""))
13579                       (pc)))]
13580   ""
13581   [(set (pc)
13582         (if_then_else (match_dup 0)
13583                       (label_ref (match_dup 1))
13584                       (pc)))]
13585 {
13586   PUT_MODE (operands[0], VOIDmode);
13587 })
13588   
13589 (define_split 
13590   [(set (pc)
13591         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13592                                       [(reg FLAGS_REG) (const_int 0)])
13593                           (const_int 0))
13594                       (label_ref (match_operand 1 "" ""))
13595                       (pc)))]
13596   ""
13597   [(set (pc)
13598         (if_then_else (match_dup 0)
13599                       (label_ref (match_dup 1))
13600                       (pc)))]
13601 {
13602   rtx new_op0 = copy_rtx (operands[0]);
13603   operands[0] = new_op0;
13604   PUT_MODE (new_op0, VOIDmode);
13605   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13606                                              GET_MODE (XEXP (new_op0, 0))));
13607
13608   /* Make sure that (a) the CCmode we have for the flags is strong
13609      enough for the reversed compare or (b) we have a valid FP compare.  */
13610   if (! ix86_comparison_operator (new_op0, VOIDmode))
13611     FAIL;
13612 })
13613
13614 ;; Define combination compare-and-branch fp compare instructions to use
13615 ;; during early optimization.  Splitting the operation apart early makes
13616 ;; for bad code when we want to reverse the operation.
13617
13618 (define_insn "*fp_jcc_1_mixed"
13619   [(set (pc)
13620         (if_then_else (match_operator 0 "comparison_operator"
13621                         [(match_operand 1 "register_operand" "f,x")
13622                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13623           (label_ref (match_operand 3 "" ""))
13624           (pc)))
13625    (clobber (reg:CCFP FPSR_REG))
13626    (clobber (reg:CCFP FLAGS_REG))]
13627   "TARGET_MIX_SSE_I387
13628    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13629    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13630    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13631   "#")
13632
13633 (define_insn "*fp_jcc_1_sse"
13634   [(set (pc)
13635         (if_then_else (match_operator 0 "comparison_operator"
13636                         [(match_operand 1 "register_operand" "x")
13637                          (match_operand 2 "nonimmediate_operand" "xm")])
13638           (label_ref (match_operand 3 "" ""))
13639           (pc)))
13640    (clobber (reg:CCFP FPSR_REG))
13641    (clobber (reg:CCFP FLAGS_REG))]
13642   "TARGET_SSE_MATH
13643    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13644    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13645    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13646   "#")
13647
13648 (define_insn "*fp_jcc_1_387"
13649   [(set (pc)
13650         (if_then_else (match_operator 0 "comparison_operator"
13651                         [(match_operand 1 "register_operand" "f")
13652                          (match_operand 2 "register_operand" "f")])
13653           (label_ref (match_operand 3 "" ""))
13654           (pc)))
13655    (clobber (reg:CCFP FPSR_REG))
13656    (clobber (reg:CCFP FLAGS_REG))]
13657   "TARGET_CMOVE && TARGET_80387
13658    && FLOAT_MODE_P (GET_MODE (operands[1]))
13659    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13660    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13661   "#")
13662
13663 (define_insn "*fp_jcc_2_mixed"
13664   [(set (pc)
13665         (if_then_else (match_operator 0 "comparison_operator"
13666                         [(match_operand 1 "register_operand" "f,x")
13667                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13668           (pc)
13669           (label_ref (match_operand 3 "" ""))))
13670    (clobber (reg:CCFP FPSR_REG))
13671    (clobber (reg:CCFP FLAGS_REG))]
13672   "TARGET_MIX_SSE_I387
13673    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13674    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13675    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676   "#")
13677
13678 (define_insn "*fp_jcc_2_sse"
13679   [(set (pc)
13680         (if_then_else (match_operator 0 "comparison_operator"
13681                         [(match_operand 1 "register_operand" "x")
13682                          (match_operand 2 "nonimmediate_operand" "xm")])
13683           (pc)
13684           (label_ref (match_operand 3 "" ""))))
13685    (clobber (reg:CCFP FPSR_REG))
13686    (clobber (reg:CCFP FLAGS_REG))]
13687   "TARGET_SSE_MATH
13688    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13689    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13690    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13691   "#")
13692
13693 (define_insn "*fp_jcc_2_387"
13694   [(set (pc)
13695         (if_then_else (match_operator 0 "comparison_operator"
13696                         [(match_operand 1 "register_operand" "f")
13697                          (match_operand 2 "register_operand" "f")])
13698           (pc)
13699           (label_ref (match_operand 3 "" ""))))
13700    (clobber (reg:CCFP FPSR_REG))
13701    (clobber (reg:CCFP FLAGS_REG))]
13702   "TARGET_CMOVE && TARGET_80387
13703    && FLOAT_MODE_P (GET_MODE (operands[1]))
13704    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13705    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13706   "#")
13707
13708 (define_insn "*fp_jcc_3_387"
13709   [(set (pc)
13710         (if_then_else (match_operator 0 "comparison_operator"
13711                         [(match_operand 1 "register_operand" "f")
13712                          (match_operand 2 "nonimmediate_operand" "fm")])
13713           (label_ref (match_operand 3 "" ""))
13714           (pc)))
13715    (clobber (reg:CCFP FPSR_REG))
13716    (clobber (reg:CCFP FLAGS_REG))
13717    (clobber (match_scratch:HI 4 "=a"))]
13718   "TARGET_80387
13719    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13720    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13722    && SELECT_CC_MODE (GET_CODE (operands[0]),
13723                       operands[1], operands[2]) == CCFPmode
13724    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725   "#")
13726
13727 (define_insn "*fp_jcc_4_387"
13728   [(set (pc)
13729         (if_then_else (match_operator 0 "comparison_operator"
13730                         [(match_operand 1 "register_operand" "f")
13731                          (match_operand 2 "nonimmediate_operand" "fm")])
13732           (pc)
13733           (label_ref (match_operand 3 "" ""))))
13734    (clobber (reg:CCFP FPSR_REG))
13735    (clobber (reg:CCFP FLAGS_REG))
13736    (clobber (match_scratch:HI 4 "=a"))]
13737   "TARGET_80387
13738    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13739    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13741    && SELECT_CC_MODE (GET_CODE (operands[0]),
13742                       operands[1], operands[2]) == CCFPmode
13743    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744   "#")
13745
13746 (define_insn "*fp_jcc_5_387"
13747   [(set (pc)
13748         (if_then_else (match_operator 0 "comparison_operator"
13749                         [(match_operand 1 "register_operand" "f")
13750                          (match_operand 2 "register_operand" "f")])
13751           (label_ref (match_operand 3 "" ""))
13752           (pc)))
13753    (clobber (reg:CCFP FPSR_REG))
13754    (clobber (reg:CCFP FLAGS_REG))
13755    (clobber (match_scratch:HI 4 "=a"))]
13756   "TARGET_80387
13757    && FLOAT_MODE_P (GET_MODE (operands[1]))
13758    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13759    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13760   "#")
13761
13762 (define_insn "*fp_jcc_6_387"
13763   [(set (pc)
13764         (if_then_else (match_operator 0 "comparison_operator"
13765                         [(match_operand 1 "register_operand" "f")
13766                          (match_operand 2 "register_operand" "f")])
13767           (pc)
13768           (label_ref (match_operand 3 "" ""))))
13769    (clobber (reg:CCFP FPSR_REG))
13770    (clobber (reg:CCFP FLAGS_REG))
13771    (clobber (match_scratch:HI 4 "=a"))]
13772   "TARGET_80387
13773    && FLOAT_MODE_P (GET_MODE (operands[1]))
13774    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13775    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13776   "#")
13777
13778 (define_insn "*fp_jcc_7_387"
13779   [(set (pc)
13780         (if_then_else (match_operator 0 "comparison_operator"
13781                         [(match_operand 1 "register_operand" "f")
13782                          (match_operand 2 "const0_operand" "X")])
13783           (label_ref (match_operand 3 "" ""))
13784           (pc)))
13785    (clobber (reg:CCFP FPSR_REG))
13786    (clobber (reg:CCFP FLAGS_REG))
13787    (clobber (match_scratch:HI 4 "=a"))]
13788   "TARGET_80387
13789    && FLOAT_MODE_P (GET_MODE (operands[1]))
13790    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13792    && SELECT_CC_MODE (GET_CODE (operands[0]),
13793                       operands[1], operands[2]) == CCFPmode
13794    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13795   "#")
13796
13797 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13798 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13799 ;; with a precedence over other operators and is always put in the first
13800 ;; place. Swap condition and operands to match ficom instruction.
13801
13802 (define_insn "*fp_jcc_8<mode>_387"
13803   [(set (pc)
13804         (if_then_else (match_operator 0 "comparison_operator"
13805                         [(match_operator 1 "float_operator"
13806                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13807                            (match_operand 3 "register_operand" "f,f")])
13808           (label_ref (match_operand 4 "" ""))
13809           (pc)))
13810    (clobber (reg:CCFP FPSR_REG))
13811    (clobber (reg:CCFP FLAGS_REG))
13812    (clobber (match_scratch:HI 5 "=a,a"))]
13813   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13814    && FLOAT_MODE_P (GET_MODE (operands[3]))
13815    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13816    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13817    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13818    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13819   "#")
13820
13821 (define_split
13822   [(set (pc)
13823         (if_then_else (match_operator 0 "comparison_operator"
13824                         [(match_operand 1 "register_operand" "")
13825                          (match_operand 2 "nonimmediate_operand" "")])
13826           (match_operand 3 "" "")
13827           (match_operand 4 "" "")))
13828    (clobber (reg:CCFP FPSR_REG))
13829    (clobber (reg:CCFP FLAGS_REG))]
13830   "reload_completed"
13831   [(const_int 0)]
13832 {
13833   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13834                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13835   DONE;
13836 })
13837
13838 (define_split
13839   [(set (pc)
13840         (if_then_else (match_operator 0 "comparison_operator"
13841                         [(match_operand 1 "register_operand" "")
13842                          (match_operand 2 "general_operand" "")])
13843           (match_operand 3 "" "")
13844           (match_operand 4 "" "")))
13845    (clobber (reg:CCFP FPSR_REG))
13846    (clobber (reg:CCFP FLAGS_REG))
13847    (clobber (match_scratch:HI 5 "=a"))]
13848   "reload_completed"
13849   [(const_int 0)]
13850 {
13851   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13852                         operands[3], operands[4], operands[5], NULL_RTX);
13853   DONE;
13854 })
13855
13856 (define_split
13857   [(set (pc)
13858         (if_then_else (match_operator 0 "comparison_operator"
13859                         [(match_operator 1 "float_operator"
13860                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13861                            (match_operand 3 "register_operand" "")])
13862           (match_operand 4 "" "")
13863           (match_operand 5 "" "")))
13864    (clobber (reg:CCFP FPSR_REG))
13865    (clobber (reg:CCFP FLAGS_REG))
13866    (clobber (match_scratch:HI 6 "=a"))]
13867   "reload_completed"
13868   [(const_int 0)]
13869 {
13870   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13871   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13872                         operands[3], operands[7],
13873                         operands[4], operands[5], operands[6], NULL_RTX);
13874   DONE;
13875 })
13876
13877 ;; %%% Kill this when reload knows how to do it.
13878 (define_split
13879   [(set (pc)
13880         (if_then_else (match_operator 0 "comparison_operator"
13881                         [(match_operator 1 "float_operator"
13882                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13883                            (match_operand 3 "register_operand" "")])
13884           (match_operand 4 "" "")
13885           (match_operand 5 "" "")))
13886    (clobber (reg:CCFP FPSR_REG))
13887    (clobber (reg:CCFP FLAGS_REG))
13888    (clobber (match_scratch:HI 6 "=a"))]
13889   "reload_completed"
13890   [(const_int 0)]
13891 {
13892   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13893   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13894   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13895                         operands[3], operands[7],
13896                         operands[4], operands[5], operands[6], operands[2]);
13897   DONE;
13898 })
13899 \f
13900 ;; Unconditional and other jump instructions
13901
13902 (define_insn "jump"
13903   [(set (pc)
13904         (label_ref (match_operand 0 "" "")))]
13905   ""
13906   "jmp\t%l0"
13907   [(set_attr "type" "ibr")
13908    (set (attr "length")
13909            (if_then_else (and (ge (minus (match_dup 0) (pc))
13910                                   (const_int -126))
13911                               (lt (minus (match_dup 0) (pc))
13912                                   (const_int 128)))
13913              (const_int 2)
13914              (const_int 5)))
13915    (set_attr "modrm" "0")])
13916
13917 (define_expand "indirect_jump"
13918   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13919   ""
13920   "")
13921
13922 (define_insn "*indirect_jump"
13923   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13924   "!TARGET_64BIT"
13925   "jmp\t%A0"
13926   [(set_attr "type" "ibr")
13927    (set_attr "length_immediate" "0")])
13928
13929 (define_insn "*indirect_jump_rtx64"
13930   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13931   "TARGET_64BIT"
13932   "jmp\t%A0"
13933   [(set_attr "type" "ibr")
13934    (set_attr "length_immediate" "0")])
13935
13936 (define_expand "tablejump"
13937   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13938               (use (label_ref (match_operand 1 "" "")))])]
13939   ""
13940 {
13941   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13942      relative.  Convert the relative address to an absolute address.  */
13943   if (flag_pic)
13944     {
13945       rtx op0, op1;
13946       enum rtx_code code;
13947
13948       if (TARGET_64BIT)
13949         {
13950           code = PLUS;
13951           op0 = operands[0];
13952           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13953         }
13954       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13955         {
13956           code = PLUS;
13957           op0 = operands[0];
13958           op1 = pic_offset_table_rtx;
13959         }
13960       else
13961         {
13962           code = MINUS;
13963           op0 = pic_offset_table_rtx;
13964           op1 = operands[0];
13965         }
13966
13967       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13968                                          OPTAB_DIRECT);
13969     }
13970 })
13971
13972 (define_insn "*tablejump_1"
13973   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13974    (use (label_ref (match_operand 1 "" "")))]
13975   "!TARGET_64BIT"
13976   "jmp\t%A0"
13977   [(set_attr "type" "ibr")
13978    (set_attr "length_immediate" "0")])
13979
13980 (define_insn "*tablejump_1_rtx64"
13981   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13982    (use (label_ref (match_operand 1 "" "")))]
13983   "TARGET_64BIT"
13984   "jmp\t%A0"
13985   [(set_attr "type" "ibr")
13986    (set_attr "length_immediate" "0")])
13987 \f
13988 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13989
13990 (define_peephole2
13991   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13992    (set (match_operand:QI 1 "register_operand" "")
13993         (match_operator:QI 2 "ix86_comparison_operator"
13994           [(reg FLAGS_REG) (const_int 0)]))
13995    (set (match_operand 3 "q_regs_operand" "")
13996         (zero_extend (match_dup 1)))]
13997   "(peep2_reg_dead_p (3, operands[1])
13998     || operands_match_p (operands[1], operands[3]))
13999    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14000   [(set (match_dup 4) (match_dup 0))
14001    (set (strict_low_part (match_dup 5))
14002         (match_dup 2))]
14003 {
14004   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14005   operands[5] = gen_lowpart (QImode, operands[3]);
14006   ix86_expand_clear (operands[3]);
14007 })
14008
14009 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14010
14011 (define_peephole2
14012   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14013    (set (match_operand:QI 1 "register_operand" "")
14014         (match_operator:QI 2 "ix86_comparison_operator"
14015           [(reg FLAGS_REG) (const_int 0)]))
14016    (parallel [(set (match_operand 3 "q_regs_operand" "")
14017                    (zero_extend (match_dup 1)))
14018               (clobber (reg:CC FLAGS_REG))])]
14019   "(peep2_reg_dead_p (3, operands[1])
14020     || operands_match_p (operands[1], operands[3]))
14021    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14022   [(set (match_dup 4) (match_dup 0))
14023    (set (strict_low_part (match_dup 5))
14024         (match_dup 2))]
14025 {
14026   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14027   operands[5] = gen_lowpart (QImode, operands[3]);
14028   ix86_expand_clear (operands[3]);
14029 })
14030 \f
14031 ;; Call instructions.
14032
14033 ;; The predicates normally associated with named expanders are not properly
14034 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14035 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14036
14037 ;; Call subroutine returning no value.
14038
14039 (define_expand "call_pop"
14040   [(parallel [(call (match_operand:QI 0 "" "")
14041                     (match_operand:SI 1 "" ""))
14042               (set (reg:SI SP_REG)
14043                    (plus:SI (reg:SI SP_REG)
14044                             (match_operand:SI 3 "" "")))])]
14045   "!TARGET_64BIT"
14046 {
14047   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14048   DONE;
14049 })
14050
14051 (define_insn "*call_pop_0"
14052   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14053          (match_operand:SI 1 "" ""))
14054    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14055                             (match_operand:SI 2 "immediate_operand" "")))]
14056   "!TARGET_64BIT"
14057 {
14058   if (SIBLING_CALL_P (insn))
14059     return "jmp\t%P0";
14060   else
14061     return "call\t%P0";
14062 }
14063   [(set_attr "type" "call")])
14064   
14065 (define_insn "*call_pop_1"
14066   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14067          (match_operand:SI 1 "" ""))
14068    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14069                             (match_operand:SI 2 "immediate_operand" "i")))]
14070   "!TARGET_64BIT"
14071 {
14072   if (constant_call_address_operand (operands[0], Pmode))
14073     {
14074       if (SIBLING_CALL_P (insn))
14075         return "jmp\t%P0";
14076       else
14077         return "call\t%P0";
14078     }
14079   if (SIBLING_CALL_P (insn))
14080     return "jmp\t%A0";
14081   else
14082     return "call\t%A0";
14083 }
14084   [(set_attr "type" "call")])
14085
14086 (define_expand "call"
14087   [(call (match_operand:QI 0 "" "")
14088          (match_operand 1 "" ""))
14089    (use (match_operand 2 "" ""))]
14090   ""
14091 {
14092   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14093   DONE;
14094 })
14095
14096 (define_expand "sibcall"
14097   [(call (match_operand:QI 0 "" "")
14098          (match_operand 1 "" ""))
14099    (use (match_operand 2 "" ""))]
14100   ""
14101 {
14102   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14103   DONE;
14104 })
14105
14106 (define_insn "*call_0"
14107   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14108          (match_operand 1 "" ""))]
14109   ""
14110 {
14111   if (SIBLING_CALL_P (insn))
14112     return "jmp\t%P0";
14113   else
14114     return "call\t%P0";
14115 }
14116   [(set_attr "type" "call")])
14117
14118 (define_insn "*call_1"
14119   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14120          (match_operand 1 "" ""))]
14121   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14122 {
14123   if (constant_call_address_operand (operands[0], Pmode))
14124     return "call\t%P0";
14125   return "call\t%A0";
14126 }
14127   [(set_attr "type" "call")])
14128
14129 (define_insn "*sibcall_1"
14130   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14131          (match_operand 1 "" ""))]
14132   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14133 {
14134   if (constant_call_address_operand (operands[0], Pmode))
14135     return "jmp\t%P0";
14136   return "jmp\t%A0";
14137 }
14138   [(set_attr "type" "call")])
14139
14140 (define_insn "*call_1_rex64"
14141   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14142          (match_operand 1 "" ""))]
14143   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14144 {
14145   if (constant_call_address_operand (operands[0], Pmode))
14146     return "call\t%P0";
14147   return "call\t%A0";
14148 }
14149   [(set_attr "type" "call")])
14150
14151 (define_insn "*sibcall_1_rex64"
14152   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14153          (match_operand 1 "" ""))]
14154   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14155   "jmp\t%P0"
14156   [(set_attr "type" "call")])
14157
14158 (define_insn "*sibcall_1_rex64_v"
14159   [(call (mem:QI (reg:DI 40))
14160          (match_operand 0 "" ""))]
14161   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14162   "jmp\t*%%r11"
14163   [(set_attr "type" "call")])
14164
14165
14166 ;; Call subroutine, returning value in operand 0
14167
14168 (define_expand "call_value_pop"
14169   [(parallel [(set (match_operand 0 "" "")
14170                    (call (match_operand:QI 1 "" "")
14171                          (match_operand:SI 2 "" "")))
14172               (set (reg:SI SP_REG)
14173                    (plus:SI (reg:SI SP_REG)
14174                             (match_operand:SI 4 "" "")))])]
14175   "!TARGET_64BIT"
14176 {
14177   ix86_expand_call (operands[0], operands[1], operands[2],
14178                     operands[3], operands[4], 0);
14179   DONE;
14180 })
14181
14182 (define_expand "call_value"
14183   [(set (match_operand 0 "" "")
14184         (call (match_operand:QI 1 "" "")
14185               (match_operand:SI 2 "" "")))
14186    (use (match_operand:SI 3 "" ""))]
14187   ;; Operand 2 not used on the i386.
14188   ""
14189 {
14190   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14191   DONE;
14192 })
14193
14194 (define_expand "sibcall_value"
14195   [(set (match_operand 0 "" "")
14196         (call (match_operand:QI 1 "" "")
14197               (match_operand:SI 2 "" "")))
14198    (use (match_operand:SI 3 "" ""))]
14199   ;; Operand 2 not used on the i386.
14200   ""
14201 {
14202   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14203   DONE;
14204 })
14205
14206 ;; Call subroutine returning any type.
14207
14208 (define_expand "untyped_call"
14209   [(parallel [(call (match_operand 0 "" "")
14210                     (const_int 0))
14211               (match_operand 1 "" "")
14212               (match_operand 2 "" "")])]
14213   ""
14214 {
14215   int i;
14216
14217   /* In order to give reg-stack an easier job in validating two
14218      coprocessor registers as containing a possible return value,
14219      simply pretend the untyped call returns a complex long double
14220      value.  */
14221
14222   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14223                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14224                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14225                     NULL, 0);
14226
14227   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14228     {
14229       rtx set = XVECEXP (operands[2], 0, i);
14230       emit_move_insn (SET_DEST (set), SET_SRC (set));
14231     }
14232
14233   /* The optimizer does not know that the call sets the function value
14234      registers we stored in the result block.  We avoid problems by
14235      claiming that all hard registers are used and clobbered at this
14236      point.  */
14237   emit_insn (gen_blockage (const0_rtx));
14238
14239   DONE;
14240 })
14241 \f
14242 ;; Prologue and epilogue instructions
14243
14244 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14245 ;; all of memory.  This blocks insns from being moved across this point.
14246
14247 (define_insn "blockage"
14248   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14249   ""
14250   ""
14251   [(set_attr "length" "0")])
14252
14253 ;; Insn emitted into the body of a function to return from a function.
14254 ;; This is only done if the function's epilogue is known to be simple.
14255 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14256
14257 (define_expand "return"
14258   [(return)]
14259   "ix86_can_use_return_insn_p ()"
14260 {
14261   if (current_function_pops_args)
14262     {
14263       rtx popc = GEN_INT (current_function_pops_args);
14264       emit_jump_insn (gen_return_pop_internal (popc));
14265       DONE;
14266     }
14267 })
14268
14269 (define_insn "return_internal"
14270   [(return)]
14271   "reload_completed"
14272   "ret"
14273   [(set_attr "length" "1")
14274    (set_attr "length_immediate" "0")
14275    (set_attr "modrm" "0")])
14276
14277 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14278 ;; instruction Athlon and K8 have.
14279
14280 (define_insn "return_internal_long"
14281   [(return)
14282    (unspec [(const_int 0)] UNSPEC_REP)]
14283   "reload_completed"
14284   "rep {;} ret"
14285   [(set_attr "length" "1")
14286    (set_attr "length_immediate" "0")
14287    (set_attr "prefix_rep" "1")
14288    (set_attr "modrm" "0")])
14289
14290 (define_insn "return_pop_internal"
14291   [(return)
14292    (use (match_operand:SI 0 "const_int_operand" ""))]
14293   "reload_completed"
14294   "ret\t%0"
14295   [(set_attr "length" "3")
14296    (set_attr "length_immediate" "2")
14297    (set_attr "modrm" "0")])
14298
14299 (define_insn "return_indirect_internal"
14300   [(return)
14301    (use (match_operand:SI 0 "register_operand" "r"))]
14302   "reload_completed"
14303   "jmp\t%A0"
14304   [(set_attr "type" "ibr")
14305    (set_attr "length_immediate" "0")])
14306
14307 (define_insn "nop"
14308   [(const_int 0)]
14309   ""
14310   "nop"
14311   [(set_attr "length" "1")
14312    (set_attr "length_immediate" "0")
14313    (set_attr "modrm" "0")])
14314
14315 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14316 ;; branch prediction penalty for the third jump in a 16-byte
14317 ;; block on K8.
14318
14319 (define_insn "align"
14320   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14321   ""
14322 {
14323 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14324   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14325 #else
14326   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14327      The align insn is used to avoid 3 jump instructions in the row to improve
14328      branch prediction and the benefits hardly outweigh the cost of extra 8
14329      nops on the average inserted by full alignment pseudo operation.  */
14330 #endif
14331   return "";
14332 }
14333   [(set_attr "length" "16")])
14334
14335 (define_expand "prologue"
14336   [(const_int 1)]
14337   ""
14338   "ix86_expand_prologue (); DONE;")
14339
14340 (define_insn "set_got"
14341   [(set (match_operand:SI 0 "register_operand" "=r")
14342         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14343    (clobber (reg:CC FLAGS_REG))]
14344   "!TARGET_64BIT"
14345   { return output_set_got (operands[0], NULL_RTX); }
14346   [(set_attr "type" "multi")
14347    (set_attr "length" "12")])
14348
14349 (define_insn "set_got_labelled"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14352          UNSPEC_SET_GOT))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "!TARGET_64BIT"
14355   { return output_set_got (operands[0], operands[1]); }
14356   [(set_attr "type" "multi")
14357    (set_attr "length" "12")])
14358
14359 (define_insn "set_got_rex64"
14360   [(set (match_operand:DI 0 "register_operand" "=r")
14361         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14362   "TARGET_64BIT"
14363   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14364   [(set_attr "type" "lea")
14365    (set_attr "length" "6")])
14366
14367 (define_expand "epilogue"
14368   [(const_int 1)]
14369   ""
14370   "ix86_expand_epilogue (1); DONE;")
14371
14372 (define_expand "sibcall_epilogue"
14373   [(const_int 1)]
14374   ""
14375   "ix86_expand_epilogue (0); DONE;")
14376
14377 (define_expand "eh_return"
14378   [(use (match_operand 0 "register_operand" ""))]
14379   ""
14380 {
14381   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14382
14383   /* Tricky bit: we write the address of the handler to which we will
14384      be returning into someone else's stack frame, one word below the
14385      stack address we wish to restore.  */
14386   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14387   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14388   tmp = gen_rtx_MEM (Pmode, tmp);
14389   emit_move_insn (tmp, ra);
14390
14391   if (Pmode == SImode)
14392     emit_jump_insn (gen_eh_return_si (sa));
14393   else
14394     emit_jump_insn (gen_eh_return_di (sa));
14395   emit_barrier ();
14396   DONE;
14397 })
14398
14399 (define_insn_and_split "eh_return_si"
14400   [(set (pc) 
14401         (unspec [(match_operand:SI 0 "register_operand" "c")]
14402                  UNSPEC_EH_RETURN))]
14403   "!TARGET_64BIT"
14404   "#"
14405   "reload_completed"
14406   [(const_int 1)]
14407   "ix86_expand_epilogue (2); DONE;")
14408
14409 (define_insn_and_split "eh_return_di"
14410   [(set (pc) 
14411         (unspec [(match_operand:DI 0 "register_operand" "c")]
14412                  UNSPEC_EH_RETURN))]
14413   "TARGET_64BIT"
14414   "#"
14415   "reload_completed"
14416   [(const_int 1)]
14417   "ix86_expand_epilogue (2); DONE;")
14418
14419 (define_insn "leave"
14420   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14421    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14422    (clobber (mem:BLK (scratch)))]
14423   "!TARGET_64BIT"
14424   "leave"
14425   [(set_attr "type" "leave")])
14426
14427 (define_insn "leave_rex64"
14428   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14429    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14430    (clobber (mem:BLK (scratch)))]
14431   "TARGET_64BIT"
14432   "leave"
14433   [(set_attr "type" "leave")])
14434 \f
14435 (define_expand "ffssi2"
14436   [(parallel
14437      [(set (match_operand:SI 0 "register_operand" "") 
14438            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14439       (clobber (match_scratch:SI 2 ""))
14440       (clobber (reg:CC FLAGS_REG))])]
14441   ""
14442   "")
14443
14444 (define_insn_and_split "*ffs_cmove"
14445   [(set (match_operand:SI 0 "register_operand" "=r") 
14446         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14447    (clobber (match_scratch:SI 2 "=&r"))
14448    (clobber (reg:CC FLAGS_REG))]
14449   "TARGET_CMOVE"
14450   "#"
14451   "&& reload_completed"
14452   [(set (match_dup 2) (const_int -1))
14453    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14454               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14455    (set (match_dup 0) (if_then_else:SI
14456                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14457                         (match_dup 2)
14458                         (match_dup 0)))
14459    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460               (clobber (reg:CC FLAGS_REG))])]
14461   "")
14462
14463 (define_insn_and_split "*ffs_no_cmove"
14464   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14465         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14466    (clobber (match_scratch:SI 2 "=&q"))
14467    (clobber (reg:CC FLAGS_REG))]
14468   ""
14469   "#"
14470   "reload_completed"
14471   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14472               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14473    (set (strict_low_part (match_dup 3))
14474         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14475    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14476               (clobber (reg:CC FLAGS_REG))])
14477    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14478               (clobber (reg:CC FLAGS_REG))])
14479    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14480               (clobber (reg:CC FLAGS_REG))])]
14481 {
14482   operands[3] = gen_lowpart (QImode, operands[2]);
14483   ix86_expand_clear (operands[2]);
14484 })
14485
14486 (define_insn "*ffssi_1"
14487   [(set (reg:CCZ FLAGS_REG)
14488         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14489                      (const_int 0)))
14490    (set (match_operand:SI 0 "register_operand" "=r")
14491         (ctz:SI (match_dup 1)))]
14492   ""
14493   "bsf{l}\t{%1, %0|%0, %1}"
14494   [(set_attr "prefix_0f" "1")])
14495
14496 (define_expand "ffsdi2"
14497   [(parallel
14498      [(set (match_operand:DI 0 "register_operand" "") 
14499            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14500       (clobber (match_scratch:DI 2 ""))
14501       (clobber (reg:CC FLAGS_REG))])]
14502   "TARGET_64BIT && TARGET_CMOVE"
14503   "")
14504
14505 (define_insn_and_split "*ffs_rex64"
14506   [(set (match_operand:DI 0 "register_operand" "=r") 
14507         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14508    (clobber (match_scratch:DI 2 "=&r"))
14509    (clobber (reg:CC FLAGS_REG))]
14510   "TARGET_64BIT && TARGET_CMOVE"
14511   "#"
14512   "&& reload_completed"
14513   [(set (match_dup 2) (const_int -1))
14514    (parallel [(set (reg:CCZ FLAGS_REG)
14515                    (compare:CCZ (match_dup 1) (const_int 0)))
14516               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14517    (set (match_dup 0) (if_then_else:DI
14518                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14519                         (match_dup 2)
14520                         (match_dup 0)))
14521    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14522               (clobber (reg:CC FLAGS_REG))])]
14523   "")
14524
14525 (define_insn "*ffsdi_1"
14526   [(set (reg:CCZ FLAGS_REG)
14527         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14528                      (const_int 0)))
14529    (set (match_operand:DI 0 "register_operand" "=r")
14530         (ctz:DI (match_dup 1)))]
14531   "TARGET_64BIT"
14532   "bsf{q}\t{%1, %0|%0, %1}"
14533   [(set_attr "prefix_0f" "1")])
14534
14535 (define_insn "ctzsi2"
14536   [(set (match_operand:SI 0 "register_operand" "=r")
14537         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14538    (clobber (reg:CC FLAGS_REG))]
14539   ""
14540   "bsf{l}\t{%1, %0|%0, %1}"
14541   [(set_attr "prefix_0f" "1")])
14542
14543 (define_insn "ctzdi2"
14544   [(set (match_operand:DI 0 "register_operand" "=r")
14545         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14546    (clobber (reg:CC FLAGS_REG))]
14547   "TARGET_64BIT"
14548   "bsf{q}\t{%1, %0|%0, %1}"
14549   [(set_attr "prefix_0f" "1")])
14550
14551 (define_expand "clzsi2"
14552   [(parallel
14553      [(set (match_operand:SI 0 "register_operand" "")
14554            (minus:SI (const_int 31)
14555                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14556       (clobber (reg:CC FLAGS_REG))])
14557    (parallel
14558      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14559       (clobber (reg:CC FLAGS_REG))])]
14560   ""
14561   "")
14562
14563 (define_insn "*bsr"
14564   [(set (match_operand:SI 0 "register_operand" "=r")
14565         (minus:SI (const_int 31)
14566                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14567    (clobber (reg:CC FLAGS_REG))]
14568   ""
14569   "bsr{l}\t{%1, %0|%0, %1}"
14570   [(set_attr "prefix_0f" "1")])
14571
14572 (define_expand "clzdi2"
14573   [(parallel
14574      [(set (match_operand:DI 0 "register_operand" "")
14575            (minus:DI (const_int 63)
14576                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14577       (clobber (reg:CC FLAGS_REG))])
14578    (parallel
14579      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14580       (clobber (reg:CC FLAGS_REG))])]
14581   "TARGET_64BIT"
14582   "")
14583
14584 (define_insn "*bsr_rex64"
14585   [(set (match_operand:DI 0 "register_operand" "=r")
14586         (minus:DI (const_int 63)
14587                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14588    (clobber (reg:CC FLAGS_REG))]
14589   "TARGET_64BIT"
14590   "bsr{q}\t{%1, %0|%0, %1}"
14591   [(set_attr "prefix_0f" "1")])
14592 \f
14593 ;; Thread-local storage patterns for ELF.
14594 ;;
14595 ;; Note that these code sequences must appear exactly as shown
14596 ;; in order to allow linker relaxation.
14597
14598 (define_insn "*tls_global_dynamic_32_gnu"
14599   [(set (match_operand:SI 0 "register_operand" "=a")
14600         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14601                     (match_operand:SI 2 "tls_symbolic_operand" "")
14602                     (match_operand:SI 3 "call_insn_operand" "")]
14603                     UNSPEC_TLS_GD))
14604    (clobber (match_scratch:SI 4 "=d"))
14605    (clobber (match_scratch:SI 5 "=c"))
14606    (clobber (reg:CC FLAGS_REG))]
14607   "!TARGET_64BIT && TARGET_GNU_TLS"
14608   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14609   [(set_attr "type" "multi")
14610    (set_attr "length" "12")])
14611
14612 (define_insn "*tls_global_dynamic_32_sun"
14613   [(set (match_operand:SI 0 "register_operand" "=a")
14614         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14615                     (match_operand:SI 2 "tls_symbolic_operand" "")
14616                     (match_operand:SI 3 "call_insn_operand" "")]
14617                     UNSPEC_TLS_GD))
14618    (clobber (match_scratch:SI 4 "=d"))
14619    (clobber (match_scratch:SI 5 "=c"))
14620    (clobber (reg:CC FLAGS_REG))]
14621   "!TARGET_64BIT && TARGET_SUN_TLS"
14622   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14623         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14624   [(set_attr "type" "multi")
14625    (set_attr "length" "14")])
14626
14627 (define_expand "tls_global_dynamic_32"
14628   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14629                    (unspec:SI
14630                     [(match_dup 2)
14631                      (match_operand:SI 1 "tls_symbolic_operand" "")
14632                      (match_dup 3)]
14633                     UNSPEC_TLS_GD))
14634               (clobber (match_scratch:SI 4 ""))
14635               (clobber (match_scratch:SI 5 ""))
14636               (clobber (reg:CC FLAGS_REG))])]
14637   ""
14638 {
14639   if (flag_pic)
14640     operands[2] = pic_offset_table_rtx;
14641   else
14642     {
14643       operands[2] = gen_reg_rtx (Pmode);
14644       emit_insn (gen_set_got (operands[2]));
14645     }
14646   if (TARGET_GNU2_TLS)
14647     {
14648        emit_insn (gen_tls_dynamic_gnu2_32
14649                   (operands[0], operands[1], operands[2]));
14650        DONE;
14651     }
14652   operands[3] = ix86_tls_get_addr ();
14653 })
14654
14655 (define_insn "*tls_global_dynamic_64"
14656   [(set (match_operand:DI 0 "register_operand" "=a")
14657         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14658                  (match_operand:DI 3 "" "")))
14659    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14660               UNSPEC_TLS_GD)]
14661   "TARGET_64BIT"
14662   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14663   [(set_attr "type" "multi")
14664    (set_attr "length" "16")])
14665
14666 (define_expand "tls_global_dynamic_64"
14667   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14668                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14669               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14670                          UNSPEC_TLS_GD)])]
14671   ""
14672 {
14673   if (TARGET_GNU2_TLS)
14674     {
14675        emit_insn (gen_tls_dynamic_gnu2_64
14676                   (operands[0], operands[1]));
14677        DONE;
14678     }
14679   operands[2] = ix86_tls_get_addr ();
14680 })
14681
14682 (define_insn "*tls_local_dynamic_base_32_gnu"
14683   [(set (match_operand:SI 0 "register_operand" "=a")
14684         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685                     (match_operand:SI 2 "call_insn_operand" "")]
14686                    UNSPEC_TLS_LD_BASE))
14687    (clobber (match_scratch:SI 3 "=d"))
14688    (clobber (match_scratch:SI 4 "=c"))
14689    (clobber (reg:CC FLAGS_REG))]
14690   "!TARGET_64BIT && TARGET_GNU_TLS"
14691   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14692   [(set_attr "type" "multi")
14693    (set_attr "length" "11")])
14694
14695 (define_insn "*tls_local_dynamic_base_32_sun"
14696   [(set (match_operand:SI 0 "register_operand" "=a")
14697         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14698                     (match_operand:SI 2 "call_insn_operand" "")]
14699                    UNSPEC_TLS_LD_BASE))
14700    (clobber (match_scratch:SI 3 "=d"))
14701    (clobber (match_scratch:SI 4 "=c"))
14702    (clobber (reg:CC FLAGS_REG))]
14703   "!TARGET_64BIT && TARGET_SUN_TLS"
14704   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14705         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14706   [(set_attr "type" "multi")
14707    (set_attr "length" "13")])
14708
14709 (define_expand "tls_local_dynamic_base_32"
14710   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14711                    (unspec:SI [(match_dup 1) (match_dup 2)]
14712                               UNSPEC_TLS_LD_BASE))
14713               (clobber (match_scratch:SI 3 ""))
14714               (clobber (match_scratch:SI 4 ""))
14715               (clobber (reg:CC FLAGS_REG))])]
14716   ""
14717 {
14718   if (flag_pic)
14719     operands[1] = pic_offset_table_rtx;
14720   else
14721     {
14722       operands[1] = gen_reg_rtx (Pmode);
14723       emit_insn (gen_set_got (operands[1]));
14724     }
14725   if (TARGET_GNU2_TLS)
14726     {
14727        emit_insn (gen_tls_dynamic_gnu2_32
14728                   (operands[0], ix86_tls_module_base (), operands[1]));
14729        DONE;
14730     }
14731   operands[2] = ix86_tls_get_addr ();
14732 })
14733
14734 (define_insn "*tls_local_dynamic_base_64"
14735   [(set (match_operand:DI 0 "register_operand" "=a")
14736         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14737                  (match_operand:DI 2 "" "")))
14738    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14739   "TARGET_64BIT"
14740   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14741   [(set_attr "type" "multi")
14742    (set_attr "length" "12")])
14743
14744 (define_expand "tls_local_dynamic_base_64"
14745   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14746                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14747               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14748   ""
14749 {
14750   if (TARGET_GNU2_TLS)
14751     {
14752        emit_insn (gen_tls_dynamic_gnu2_64
14753                   (operands[0], ix86_tls_module_base ()));
14754        DONE;
14755     }
14756   operands[1] = ix86_tls_get_addr ();
14757 })
14758
14759 ;; Local dynamic of a single variable is a lose.  Show combine how
14760 ;; to convert that back to global dynamic.
14761
14762 (define_insn_and_split "*tls_local_dynamic_32_once"
14763   [(set (match_operand:SI 0 "register_operand" "=a")
14764         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765                              (match_operand:SI 2 "call_insn_operand" "")]
14766                             UNSPEC_TLS_LD_BASE)
14767                  (const:SI (unspec:SI
14768                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14769                             UNSPEC_DTPOFF))))
14770    (clobber (match_scratch:SI 4 "=d"))
14771    (clobber (match_scratch:SI 5 "=c"))
14772    (clobber (reg:CC FLAGS_REG))]
14773   ""
14774   "#"
14775   ""
14776   [(parallel [(set (match_dup 0)
14777                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14778                               UNSPEC_TLS_GD))
14779               (clobber (match_dup 4))
14780               (clobber (match_dup 5))
14781               (clobber (reg:CC FLAGS_REG))])]
14782   "")
14783
14784 ;; Load and add the thread base pointer from %gs:0.
14785
14786 (define_insn "*load_tp_si"
14787   [(set (match_operand:SI 0 "register_operand" "=r")
14788         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14789   "!TARGET_64BIT"
14790   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14791   [(set_attr "type" "imov")
14792    (set_attr "modrm" "0")
14793    (set_attr "length" "7")
14794    (set_attr "memory" "load")
14795    (set_attr "imm_disp" "false")])
14796
14797 (define_insn "*add_tp_si"
14798   [(set (match_operand:SI 0 "register_operand" "=r")
14799         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14800                  (match_operand:SI 1 "register_operand" "0")))
14801    (clobber (reg:CC FLAGS_REG))]
14802   "!TARGET_64BIT"
14803   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14804   [(set_attr "type" "alu")
14805    (set_attr "modrm" "0")
14806    (set_attr "length" "7")
14807    (set_attr "memory" "load")
14808    (set_attr "imm_disp" "false")])
14809
14810 (define_insn "*load_tp_di"
14811   [(set (match_operand:DI 0 "register_operand" "=r")
14812         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14813   "TARGET_64BIT"
14814   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14815   [(set_attr "type" "imov")
14816    (set_attr "modrm" "0")
14817    (set_attr "length" "7")
14818    (set_attr "memory" "load")
14819    (set_attr "imm_disp" "false")])
14820
14821 (define_insn "*add_tp_di"
14822   [(set (match_operand:DI 0 "register_operand" "=r")
14823         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14824                  (match_operand:DI 1 "register_operand" "0")))
14825    (clobber (reg:CC FLAGS_REG))]
14826   "TARGET_64BIT"
14827   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14828   [(set_attr "type" "alu")
14829    (set_attr "modrm" "0")
14830    (set_attr "length" "7")
14831    (set_attr "memory" "load")
14832    (set_attr "imm_disp" "false")])
14833
14834 ;; GNU2 TLS patterns can be split.
14835
14836 (define_expand "tls_dynamic_gnu2_32"
14837   [(set (match_dup 3)
14838         (plus:SI (match_operand:SI 2 "register_operand" "")
14839                  (const:SI
14840                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14841                              UNSPEC_TLSDESC))))
14842    (parallel
14843     [(set (match_operand:SI 0 "register_operand" "")
14844           (unspec:SI [(match_dup 1) (match_dup 3)
14845                       (match_dup 2) (reg:SI SP_REG)]
14846                       UNSPEC_TLSDESC))
14847      (clobber (reg:CC FLAGS_REG))])]
14848   "!TARGET_64BIT && TARGET_GNU2_TLS"
14849 {
14850   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14851   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14852 })
14853
14854 (define_insn "*tls_dynamic_lea_32"
14855   [(set (match_operand:SI 0 "register_operand" "=r")
14856         (plus:SI (match_operand:SI 1 "register_operand" "b")
14857                  (const:SI
14858                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14859                               UNSPEC_TLSDESC))))]
14860   "!TARGET_64BIT && TARGET_GNU2_TLS"
14861   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14862   [(set_attr "type" "lea")
14863    (set_attr "mode" "SI")
14864    (set_attr "length" "6")
14865    (set_attr "length_address" "4")])
14866
14867 (define_insn "*tls_dynamic_call_32"
14868   [(set (match_operand:SI 0 "register_operand" "=a")
14869         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14870                     (match_operand:SI 2 "register_operand" "0")
14871                     ;; we have to make sure %ebx still points to the GOT
14872                     (match_operand:SI 3 "register_operand" "b")
14873                     (reg:SI SP_REG)]
14874                    UNSPEC_TLSDESC))
14875    (clobber (reg:CC FLAGS_REG))]
14876   "!TARGET_64BIT && TARGET_GNU2_TLS"
14877   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14878   [(set_attr "type" "call")
14879    (set_attr "length" "2")
14880    (set_attr "length_address" "0")])
14881
14882 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14883   [(set (match_operand:SI 0 "register_operand" "=&a")
14884         (plus:SI
14885          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14886                      (match_operand:SI 4 "" "")
14887                      (match_operand:SI 2 "register_operand" "b")
14888                      (reg:SI SP_REG)]
14889                     UNSPEC_TLSDESC)
14890          (const:SI (unspec:SI
14891                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14892                     UNSPEC_DTPOFF))))
14893    (clobber (reg:CC FLAGS_REG))]
14894   "!TARGET_64BIT && TARGET_GNU2_TLS"
14895   "#"
14896   ""
14897   [(set (match_dup 0) (match_dup 5))]
14898 {
14899   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14901 })
14902
14903 (define_expand "tls_dynamic_gnu2_64"
14904   [(set (match_dup 2)
14905         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14906                    UNSPEC_TLSDESC))
14907    (parallel
14908     [(set (match_operand:DI 0 "register_operand" "")
14909           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14910                      UNSPEC_TLSDESC))
14911      (clobber (reg:CC FLAGS_REG))])]
14912   "TARGET_64BIT && TARGET_GNU2_TLS"
14913 {
14914   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14915   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14916 })
14917
14918 (define_insn "*tls_dynamic_lea_64"
14919   [(set (match_operand:DI 0 "register_operand" "=r")
14920         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14921                    UNSPEC_TLSDESC))]
14922   "TARGET_64BIT && TARGET_GNU2_TLS"
14923   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14924   [(set_attr "type" "lea")
14925    (set_attr "mode" "DI")
14926    (set_attr "length" "7")
14927    (set_attr "length_address" "4")])
14928
14929 (define_insn "*tls_dynamic_call_64"
14930   [(set (match_operand:DI 0 "register_operand" "=a")
14931         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14932                     (match_operand:DI 2 "register_operand" "0")
14933                     (reg:DI SP_REG)]
14934                    UNSPEC_TLSDESC))
14935    (clobber (reg:CC FLAGS_REG))]
14936   "TARGET_64BIT && TARGET_GNU2_TLS"
14937   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14938   [(set_attr "type" "call")
14939    (set_attr "length" "2")
14940    (set_attr "length_address" "0")])
14941
14942 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14943   [(set (match_operand:DI 0 "register_operand" "=&a")
14944         (plus:DI
14945          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14946                      (match_operand:DI 3 "" "")
14947                      (reg:DI SP_REG)]
14948                     UNSPEC_TLSDESC)
14949          (const:DI (unspec:DI
14950                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14951                     UNSPEC_DTPOFF))))
14952    (clobber (reg:CC FLAGS_REG))]
14953   "TARGET_64BIT && TARGET_GNU2_TLS"
14954   "#"
14955   ""
14956   [(set (match_dup 0) (match_dup 4))]
14957 {
14958   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14959   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14960 })
14961
14962 ;;
14963 \f
14964 ;; These patterns match the binary 387 instructions for addM3, subM3,
14965 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14966 ;; SFmode.  The first is the normal insn, the second the same insn but
14967 ;; with one operand a conversion, and the third the same insn but with
14968 ;; the other operand a conversion.  The conversion may be SFmode or
14969 ;; SImode if the target mode DFmode, but only SImode if the target mode
14970 ;; is SFmode.
14971
14972 ;; Gcc is slightly more smart about handling normal two address instructions
14973 ;; so use special patterns for add and mull.
14974
14975 (define_insn "*fop_sf_comm_mixed"
14976   [(set (match_operand:SF 0 "register_operand" "=f,x")
14977         (match_operator:SF 3 "binary_fp_operator"
14978                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14979                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14980   "TARGET_MIX_SSE_I387
14981    && COMMUTATIVE_ARITH_P (operands[3])
14982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14983   "* return output_387_binary_op (insn, operands);"
14984   [(set (attr "type") 
14985         (if_then_else (eq_attr "alternative" "1")
14986            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14987               (const_string "ssemul")
14988               (const_string "sseadd"))
14989            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14990               (const_string "fmul")
14991               (const_string "fop"))))
14992    (set_attr "mode" "SF")])
14993
14994 (define_insn "*fop_sf_comm_sse"
14995   [(set (match_operand:SF 0 "register_operand" "=x")
14996         (match_operator:SF 3 "binary_fp_operator"
14997                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14998                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14999   "TARGET_SSE_MATH
15000    && COMMUTATIVE_ARITH_P (operands[3])
15001    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15002   "* return output_387_binary_op (insn, operands);"
15003   [(set (attr "type") 
15004         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15005            (const_string "ssemul")
15006            (const_string "sseadd")))
15007    (set_attr "mode" "SF")])
15008
15009 (define_insn "*fop_sf_comm_i387"
15010   [(set (match_operand:SF 0 "register_operand" "=f")
15011         (match_operator:SF 3 "binary_fp_operator"
15012                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15013                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15014   "TARGET_80387
15015    && COMMUTATIVE_ARITH_P (operands[3])
15016    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15017   "* return output_387_binary_op (insn, operands);"
15018   [(set (attr "type") 
15019         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15020            (const_string "fmul")
15021            (const_string "fop")))
15022    (set_attr "mode" "SF")])
15023
15024 (define_insn "*fop_sf_1_mixed"
15025   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15026         (match_operator:SF 3 "binary_fp_operator"
15027                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15028                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15029   "TARGET_MIX_SSE_I387
15030    && !COMMUTATIVE_ARITH_P (operands[3])
15031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032   "* return output_387_binary_op (insn, operands);"
15033   [(set (attr "type") 
15034         (cond [(and (eq_attr "alternative" "2")
15035                     (match_operand:SF 3 "mult_operator" ""))
15036                  (const_string "ssemul")
15037                (and (eq_attr "alternative" "2")
15038                     (match_operand:SF 3 "div_operator" ""))
15039                  (const_string "ssediv")
15040                (eq_attr "alternative" "2")
15041                  (const_string "sseadd")
15042                (match_operand:SF 3 "mult_operator" "") 
15043                  (const_string "fmul")
15044                (match_operand:SF 3 "div_operator" "") 
15045                  (const_string "fdiv")
15046               ]
15047               (const_string "fop")))
15048    (set_attr "mode" "SF")])
15049
15050 (define_insn "*fop_sf_1_sse"
15051   [(set (match_operand:SF 0 "register_operand" "=x")
15052         (match_operator:SF 3 "binary_fp_operator"
15053                         [(match_operand:SF 1 "register_operand" "0")
15054                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15055   "TARGET_SSE_MATH
15056    && !COMMUTATIVE_ARITH_P (operands[3])"
15057   "* return output_387_binary_op (insn, operands);"
15058   [(set (attr "type") 
15059         (cond [(match_operand:SF 3 "mult_operator" "")
15060                  (const_string "ssemul")
15061                (match_operand:SF 3 "div_operator" "")
15062                  (const_string "ssediv")
15063               ]
15064               (const_string "sseadd")))
15065    (set_attr "mode" "SF")])
15066
15067 ;; This pattern is not fully shadowed by the pattern above.
15068 (define_insn "*fop_sf_1_i387"
15069   [(set (match_operand:SF 0 "register_operand" "=f,f")
15070         (match_operator:SF 3 "binary_fp_operator"
15071                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15072                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15073   "TARGET_80387 && !TARGET_SSE_MATH
15074    && !COMMUTATIVE_ARITH_P (operands[3])
15075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15076   "* return output_387_binary_op (insn, operands);"
15077   [(set (attr "type") 
15078         (cond [(match_operand:SF 3 "mult_operator" "") 
15079                  (const_string "fmul")
15080                (match_operand:SF 3 "div_operator" "") 
15081                  (const_string "fdiv")
15082               ]
15083               (const_string "fop")))
15084    (set_attr "mode" "SF")])
15085
15086 ;; ??? Add SSE splitters for these!
15087 (define_insn "*fop_sf_2<mode>_i387"
15088   [(set (match_operand:SF 0 "register_operand" "=f,f")
15089         (match_operator:SF 3 "binary_fp_operator"
15090           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15091            (match_operand:SF 2 "register_operand" "0,0")]))]
15092   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15093   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15094   [(set (attr "type") 
15095         (cond [(match_operand:SF 3 "mult_operator" "") 
15096                  (const_string "fmul")
15097                (match_operand:SF 3 "div_operator" "") 
15098                  (const_string "fdiv")
15099               ]
15100               (const_string "fop")))
15101    (set_attr "fp_int_src" "true")
15102    (set_attr "mode" "<MODE>")])
15103
15104 (define_insn "*fop_sf_3<mode>_i387"
15105   [(set (match_operand:SF 0 "register_operand" "=f,f")
15106         (match_operator:SF 3 "binary_fp_operator"
15107           [(match_operand:SF 1 "register_operand" "0,0")
15108            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15109   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15110   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15111   [(set (attr "type") 
15112         (cond [(match_operand:SF 3 "mult_operator" "") 
15113                  (const_string "fmul")
15114                (match_operand:SF 3 "div_operator" "") 
15115                  (const_string "fdiv")
15116               ]
15117               (const_string "fop")))
15118    (set_attr "fp_int_src" "true")
15119    (set_attr "mode" "<MODE>")])
15120
15121 (define_insn "*fop_df_comm_mixed"
15122   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15123         (match_operator:DF 3 "binary_fp_operator"
15124                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15125                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15126   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15127    && COMMUTATIVE_ARITH_P (operands[3])
15128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15129   "* return output_387_binary_op (insn, operands);"
15130   [(set (attr "type") 
15131         (if_then_else (eq_attr "alternative" "1")
15132            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15133               (const_string "ssemul")
15134               (const_string "sseadd"))
15135            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15136               (const_string "fmul")
15137               (const_string "fop"))))
15138    (set_attr "mode" "DF")])
15139
15140 (define_insn "*fop_df_comm_sse"
15141   [(set (match_operand:DF 0 "register_operand" "=Y")
15142         (match_operator:DF 3 "binary_fp_operator"
15143                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15144                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15145   "TARGET_SSE2 && TARGET_SSE_MATH
15146    && COMMUTATIVE_ARITH_P (operands[3])
15147    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15148   "* return output_387_binary_op (insn, operands);"
15149   [(set (attr "type") 
15150         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15151            (const_string "ssemul")
15152            (const_string "sseadd")))
15153    (set_attr "mode" "DF")])
15154
15155 (define_insn "*fop_df_comm_i387"
15156   [(set (match_operand:DF 0 "register_operand" "=f")
15157         (match_operator:DF 3 "binary_fp_operator"
15158                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15159                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15160   "TARGET_80387
15161    && COMMUTATIVE_ARITH_P (operands[3])
15162    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15163   "* return output_387_binary_op (insn, operands);"
15164   [(set (attr "type") 
15165         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15166            (const_string "fmul")
15167            (const_string "fop")))
15168    (set_attr "mode" "DF")])
15169
15170 (define_insn "*fop_df_1_mixed"
15171   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15172         (match_operator:DF 3 "binary_fp_operator"
15173                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15174                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15175   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15176    && !COMMUTATIVE_ARITH_P (operands[3])
15177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178   "* return output_387_binary_op (insn, operands);"
15179   [(set (attr "type") 
15180         (cond [(and (eq_attr "alternative" "2")
15181                     (match_operand:DF 3 "mult_operator" ""))
15182                  (const_string "ssemul")
15183                (and (eq_attr "alternative" "2")
15184                     (match_operand:DF 3 "div_operator" ""))
15185                  (const_string "ssediv")
15186                (eq_attr "alternative" "2")
15187                  (const_string "sseadd")
15188                (match_operand:DF 3 "mult_operator" "") 
15189                  (const_string "fmul")
15190                (match_operand:DF 3 "div_operator" "") 
15191                  (const_string "fdiv")
15192               ]
15193               (const_string "fop")))
15194    (set_attr "mode" "DF")])
15195
15196 (define_insn "*fop_df_1_sse"
15197   [(set (match_operand:DF 0 "register_operand" "=Y")
15198         (match_operator:DF 3 "binary_fp_operator"
15199                         [(match_operand:DF 1 "register_operand" "0")
15200                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15201   "TARGET_SSE2 && TARGET_SSE_MATH
15202    && !COMMUTATIVE_ARITH_P (operands[3])"
15203   "* return output_387_binary_op (insn, operands);"
15204   [(set_attr "mode" "DF")
15205    (set (attr "type") 
15206         (cond [(match_operand:DF 3 "mult_operator" "")
15207                  (const_string "ssemul")
15208                (match_operand:DF 3 "div_operator" "")
15209                  (const_string "ssediv")
15210               ]
15211               (const_string "sseadd")))])
15212
15213 ;; This pattern is not fully shadowed by the pattern above.
15214 (define_insn "*fop_df_1_i387"
15215   [(set (match_operand:DF 0 "register_operand" "=f,f")
15216         (match_operator:DF 3 "binary_fp_operator"
15217                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15218                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15219   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15220    && !COMMUTATIVE_ARITH_P (operands[3])
15221    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15222   "* return output_387_binary_op (insn, operands);"
15223   [(set (attr "type") 
15224         (cond [(match_operand:DF 3 "mult_operator" "") 
15225                  (const_string "fmul")
15226                (match_operand:DF 3 "div_operator" "")
15227                  (const_string "fdiv")
15228               ]
15229               (const_string "fop")))
15230    (set_attr "mode" "DF")])
15231
15232 ;; ??? Add SSE splitters for these!
15233 (define_insn "*fop_df_2<mode>_i387"
15234   [(set (match_operand:DF 0 "register_operand" "=f,f")
15235         (match_operator:DF 3 "binary_fp_operator"
15236            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15237             (match_operand:DF 2 "register_operand" "0,0")]))]
15238   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15239    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15240   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15241   [(set (attr "type") 
15242         (cond [(match_operand:DF 3 "mult_operator" "") 
15243                  (const_string "fmul")
15244                (match_operand:DF 3 "div_operator" "") 
15245                  (const_string "fdiv")
15246               ]
15247               (const_string "fop")))
15248    (set_attr "fp_int_src" "true")
15249    (set_attr "mode" "<MODE>")])
15250
15251 (define_insn "*fop_df_3<mode>_i387"
15252   [(set (match_operand:DF 0 "register_operand" "=f,f")
15253         (match_operator:DF 3 "binary_fp_operator"
15254            [(match_operand:DF 1 "register_operand" "0,0")
15255             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15256   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15257    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15258   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15259   [(set (attr "type") 
15260         (cond [(match_operand:DF 3 "mult_operator" "") 
15261                  (const_string "fmul")
15262                (match_operand:DF 3 "div_operator" "") 
15263                  (const_string "fdiv")
15264               ]
15265               (const_string "fop")))
15266    (set_attr "fp_int_src" "true")
15267    (set_attr "mode" "<MODE>")])
15268
15269 (define_insn "*fop_df_4_i387"
15270   [(set (match_operand:DF 0 "register_operand" "=f,f")
15271         (match_operator:DF 3 "binary_fp_operator"
15272            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15273             (match_operand:DF 2 "register_operand" "0,f")]))]
15274   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15276   "* return output_387_binary_op (insn, operands);"
15277   [(set (attr "type") 
15278         (cond [(match_operand:DF 3 "mult_operator" "") 
15279                  (const_string "fmul")
15280                (match_operand:DF 3 "div_operator" "") 
15281                  (const_string "fdiv")
15282               ]
15283               (const_string "fop")))
15284    (set_attr "mode" "SF")])
15285
15286 (define_insn "*fop_df_5_i387"
15287   [(set (match_operand:DF 0 "register_operand" "=f,f")
15288         (match_operator:DF 3 "binary_fp_operator"
15289           [(match_operand:DF 1 "register_operand" "0,f")
15290            (float_extend:DF
15291             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15292   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15293   "* return output_387_binary_op (insn, operands);"
15294   [(set (attr "type") 
15295         (cond [(match_operand:DF 3 "mult_operator" "") 
15296                  (const_string "fmul")
15297                (match_operand:DF 3 "div_operator" "") 
15298                  (const_string "fdiv")
15299               ]
15300               (const_string "fop")))
15301    (set_attr "mode" "SF")])
15302
15303 (define_insn "*fop_df_6_i387"
15304   [(set (match_operand:DF 0 "register_operand" "=f,f")
15305         (match_operator:DF 3 "binary_fp_operator"
15306           [(float_extend:DF
15307             (match_operand:SF 1 "register_operand" "0,f"))
15308            (float_extend:DF
15309             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15311   "* return output_387_binary_op (insn, operands);"
15312   [(set (attr "type") 
15313         (cond [(match_operand:DF 3 "mult_operator" "") 
15314                  (const_string "fmul")
15315                (match_operand:DF 3 "div_operator" "") 
15316                  (const_string "fdiv")
15317               ]
15318               (const_string "fop")))
15319    (set_attr "mode" "SF")])
15320
15321 (define_insn "*fop_xf_comm_i387"
15322   [(set (match_operand:XF 0 "register_operand" "=f")
15323         (match_operator:XF 3 "binary_fp_operator"
15324                         [(match_operand:XF 1 "register_operand" "%0")
15325                          (match_operand:XF 2 "register_operand" "f")]))]
15326   "TARGET_80387
15327    && COMMUTATIVE_ARITH_P (operands[3])"
15328   "* return output_387_binary_op (insn, operands);"
15329   [(set (attr "type") 
15330         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15331            (const_string "fmul")
15332            (const_string "fop")))
15333    (set_attr "mode" "XF")])
15334
15335 (define_insn "*fop_xf_1_i387"
15336   [(set (match_operand:XF 0 "register_operand" "=f,f")
15337         (match_operator:XF 3 "binary_fp_operator"
15338                         [(match_operand:XF 1 "register_operand" "0,f")
15339                          (match_operand:XF 2 "register_operand" "f,0")]))]
15340   "TARGET_80387
15341    && !COMMUTATIVE_ARITH_P (operands[3])"
15342   "* return output_387_binary_op (insn, operands);"
15343   [(set (attr "type") 
15344         (cond [(match_operand:XF 3 "mult_operator" "") 
15345                  (const_string "fmul")
15346                (match_operand:XF 3 "div_operator" "") 
15347                  (const_string "fdiv")
15348               ]
15349               (const_string "fop")))
15350    (set_attr "mode" "XF")])
15351
15352 (define_insn "*fop_xf_2<mode>_i387"
15353   [(set (match_operand:XF 0 "register_operand" "=f,f")
15354         (match_operator:XF 3 "binary_fp_operator"
15355            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15356             (match_operand:XF 2 "register_operand" "0,0")]))]
15357   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15358   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15359   [(set (attr "type") 
15360         (cond [(match_operand:XF 3 "mult_operator" "") 
15361                  (const_string "fmul")
15362                (match_operand:XF 3 "div_operator" "") 
15363                  (const_string "fdiv")
15364               ]
15365               (const_string "fop")))
15366    (set_attr "fp_int_src" "true")
15367    (set_attr "mode" "<MODE>")])
15368
15369 (define_insn "*fop_xf_3<mode>_i387"
15370   [(set (match_operand:XF 0 "register_operand" "=f,f")
15371         (match_operator:XF 3 "binary_fp_operator"
15372           [(match_operand:XF 1 "register_operand" "0,0")
15373            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15374   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15375   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15376   [(set (attr "type") 
15377         (cond [(match_operand:XF 3 "mult_operator" "") 
15378                  (const_string "fmul")
15379                (match_operand:XF 3 "div_operator" "") 
15380                  (const_string "fdiv")
15381               ]
15382               (const_string "fop")))
15383    (set_attr "fp_int_src" "true")
15384    (set_attr "mode" "<MODE>")])
15385
15386 (define_insn "*fop_xf_4_i387"
15387   [(set (match_operand:XF 0 "register_operand" "=f,f")
15388         (match_operator:XF 3 "binary_fp_operator"
15389            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15390             (match_operand:XF 2 "register_operand" "0,f")]))]
15391   "TARGET_80387"
15392   "* return output_387_binary_op (insn, operands);"
15393   [(set (attr "type") 
15394         (cond [(match_operand:XF 3 "mult_operator" "") 
15395                  (const_string "fmul")
15396                (match_operand:XF 3 "div_operator" "") 
15397                  (const_string "fdiv")
15398               ]
15399               (const_string "fop")))
15400    (set_attr "mode" "SF")])
15401
15402 (define_insn "*fop_xf_5_i387"
15403   [(set (match_operand:XF 0 "register_operand" "=f,f")
15404         (match_operator:XF 3 "binary_fp_operator"
15405           [(match_operand:XF 1 "register_operand" "0,f")
15406            (float_extend:XF
15407             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15408   "TARGET_80387"
15409   "* return output_387_binary_op (insn, operands);"
15410   [(set (attr "type") 
15411         (cond [(match_operand:XF 3 "mult_operator" "") 
15412                  (const_string "fmul")
15413                (match_operand:XF 3 "div_operator" "") 
15414                  (const_string "fdiv")
15415               ]
15416               (const_string "fop")))
15417    (set_attr "mode" "SF")])
15418
15419 (define_insn "*fop_xf_6_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f,f")
15421         (match_operator:XF 3 "binary_fp_operator"
15422           [(float_extend:XF
15423             (match_operand 1 "register_operand" "0,f"))
15424            (float_extend:XF
15425             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15426   "TARGET_80387"
15427   "* return output_387_binary_op (insn, operands);"
15428   [(set (attr "type") 
15429         (cond [(match_operand:XF 3 "mult_operator" "") 
15430                  (const_string "fmul")
15431                (match_operand:XF 3 "div_operator" "") 
15432                  (const_string "fdiv")
15433               ]
15434               (const_string "fop")))
15435    (set_attr "mode" "SF")])
15436
15437 (define_split
15438   [(set (match_operand 0 "register_operand" "")
15439         (match_operator 3 "binary_fp_operator"
15440            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15441             (match_operand 2 "register_operand" "")]))]
15442   "TARGET_80387 && reload_completed
15443    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15444   [(const_int 0)]
15445
15446   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15447   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15448   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15449                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15450                                           GET_MODE (operands[3]),
15451                                           operands[4],
15452                                           operands[2])));
15453   ix86_free_from_memory (GET_MODE (operands[1]));
15454   DONE;
15455 })
15456
15457 (define_split
15458   [(set (match_operand 0 "register_operand" "")
15459         (match_operator 3 "binary_fp_operator"
15460            [(match_operand 1 "register_operand" "")
15461             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15462   "TARGET_80387 && reload_completed
15463    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15464   [(const_int 0)]
15465 {
15466   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15467   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15468   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15469                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15470                                           GET_MODE (operands[3]),
15471                                           operands[1],
15472                                           operands[4])));
15473   ix86_free_from_memory (GET_MODE (operands[2]));
15474   DONE;
15475 })
15476 \f
15477 ;; FPU special functions.
15478
15479 (define_expand "sqrtsf2"
15480   [(set (match_operand:SF 0 "register_operand" "")
15481         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15482   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15483 {
15484   if (!TARGET_SSE_MATH)
15485     operands[1] = force_reg (SFmode, operands[1]);
15486 })
15487
15488 (define_insn "*sqrtsf2_mixed"
15489   [(set (match_operand:SF 0 "register_operand" "=f,x")
15490         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15491   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15492   "@
15493    fsqrt
15494    sqrtss\t{%1, %0|%0, %1}"
15495   [(set_attr "type" "fpspc,sse")
15496    (set_attr "mode" "SF,SF")
15497    (set_attr "athlon_decode" "direct,*")])
15498
15499 (define_insn "*sqrtsf2_sse"
15500   [(set (match_operand:SF 0 "register_operand" "=x")
15501         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15502   "TARGET_SSE_MATH"
15503   "sqrtss\t{%1, %0|%0, %1}"
15504   [(set_attr "type" "sse")
15505    (set_attr "mode" "SF")
15506    (set_attr "athlon_decode" "*")])
15507
15508 (define_insn "*sqrtsf2_i387"
15509   [(set (match_operand:SF 0 "register_operand" "=f")
15510         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15511   "TARGET_USE_FANCY_MATH_387"
15512   "fsqrt"
15513   [(set_attr "type" "fpspc")
15514    (set_attr "mode" "SF")
15515    (set_attr "athlon_decode" "direct")])
15516
15517 (define_expand "sqrtdf2"
15518   [(set (match_operand:DF 0 "register_operand" "")
15519         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15520   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15521 {
15522   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15523     operands[1] = force_reg (DFmode, operands[1]);
15524 })
15525
15526 (define_insn "*sqrtdf2_mixed"
15527   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15528         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15529   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15530   "@
15531    fsqrt
15532    sqrtsd\t{%1, %0|%0, %1}"
15533   [(set_attr "type" "fpspc,sse")
15534    (set_attr "mode" "DF,DF")
15535    (set_attr "athlon_decode" "direct,*")])
15536
15537 (define_insn "*sqrtdf2_sse"
15538   [(set (match_operand:DF 0 "register_operand" "=Y")
15539         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15540   "TARGET_SSE2 && TARGET_SSE_MATH"
15541   "sqrtsd\t{%1, %0|%0, %1}"
15542   [(set_attr "type" "sse")
15543    (set_attr "mode" "DF")
15544    (set_attr "athlon_decode" "*")])
15545
15546 (define_insn "*sqrtdf2_i387"
15547   [(set (match_operand:DF 0 "register_operand" "=f")
15548         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15549   "TARGET_USE_FANCY_MATH_387"
15550   "fsqrt"
15551   [(set_attr "type" "fpspc")
15552    (set_attr "mode" "DF")
15553    (set_attr "athlon_decode" "direct")])
15554
15555 (define_insn "*sqrtextendsfdf2_i387"
15556   [(set (match_operand:DF 0 "register_operand" "=f")
15557         (sqrt:DF (float_extend:DF
15558                   (match_operand:SF 1 "register_operand" "0"))))]
15559   "TARGET_USE_FANCY_MATH_387
15560    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15561   "fsqrt"
15562   [(set_attr "type" "fpspc")
15563    (set_attr "mode" "DF")
15564    (set_attr "athlon_decode" "direct")])
15565
15566 (define_insn "sqrtxf2"
15567   [(set (match_operand:XF 0 "register_operand" "=f")
15568         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15569   "TARGET_USE_FANCY_MATH_387"
15570   "fsqrt"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "XF")
15573    (set_attr "athlon_decode" "direct")])
15574
15575 (define_insn "*sqrtextendsfxf2_i387"
15576   [(set (match_operand:XF 0 "register_operand" "=f")
15577         (sqrt:XF (float_extend:XF
15578                   (match_operand:SF 1 "register_operand" "0"))))]
15579   "TARGET_USE_FANCY_MATH_387"
15580   "fsqrt"
15581   [(set_attr "type" "fpspc")
15582    (set_attr "mode" "XF")
15583    (set_attr "athlon_decode" "direct")])
15584
15585 (define_insn "*sqrtextenddfxf2_i387"
15586   [(set (match_operand:XF 0 "register_operand" "=f")
15587         (sqrt:XF (float_extend:XF
15588                   (match_operand:DF 1 "register_operand" "0"))))]
15589   "TARGET_USE_FANCY_MATH_387"
15590   "fsqrt"
15591   [(set_attr "type" "fpspc")
15592    (set_attr "mode" "XF")
15593    (set_attr "athlon_decode" "direct")])
15594
15595 (define_insn "fpremxf4"
15596   [(set (match_operand:XF 0 "register_operand" "=f")
15597         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15598                     (match_operand:XF 3 "register_operand" "1")]
15599                    UNSPEC_FPREM_F))
15600    (set (match_operand:XF 1 "register_operand" "=u")
15601         (unspec:XF [(match_dup 2) (match_dup 3)]
15602                    UNSPEC_FPREM_U))
15603    (set (reg:CCFP FPSR_REG)
15604         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15605   "TARGET_USE_FANCY_MATH_387
15606    && flag_unsafe_math_optimizations"
15607   "fprem"
15608   [(set_attr "type" "fpspc")
15609    (set_attr "mode" "XF")])
15610
15611 (define_expand "fmodsf3"
15612   [(use (match_operand:SF 0 "register_operand" ""))
15613    (use (match_operand:SF 1 "register_operand" ""))
15614    (use (match_operand:SF 2 "register_operand" ""))]
15615   "TARGET_USE_FANCY_MATH_387
15616    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617    && flag_unsafe_math_optimizations"
15618 {
15619   rtx label = gen_label_rtx ();
15620
15621   rtx op1 = gen_reg_rtx (XFmode);
15622   rtx op2 = gen_reg_rtx (XFmode);
15623
15624   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15625   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15626
15627   emit_label (label);
15628
15629   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15630   ix86_emit_fp_unordered_jump (label);
15631
15632   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15633   DONE;
15634 })
15635
15636 (define_expand "fmoddf3"
15637   [(use (match_operand:DF 0 "register_operand" ""))
15638    (use (match_operand:DF 1 "register_operand" ""))
15639    (use (match_operand:DF 2 "register_operand" ""))]
15640   "TARGET_USE_FANCY_MATH_387
15641    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15642    && flag_unsafe_math_optimizations"
15643 {
15644   rtx label = gen_label_rtx ();
15645
15646   rtx op1 = gen_reg_rtx (XFmode);
15647   rtx op2 = gen_reg_rtx (XFmode);
15648
15649   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15650   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15651
15652   emit_label (label);
15653
15654   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15655   ix86_emit_fp_unordered_jump (label);
15656
15657   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15658   DONE;
15659 })
15660
15661 (define_expand "fmodxf3"
15662   [(use (match_operand:XF 0 "register_operand" ""))
15663    (use (match_operand:XF 1 "register_operand" ""))
15664    (use (match_operand:XF 2 "register_operand" ""))]
15665   "TARGET_USE_FANCY_MATH_387
15666    && flag_unsafe_math_optimizations"
15667 {
15668   rtx label = gen_label_rtx ();
15669
15670   emit_label (label);
15671
15672   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15673                            operands[1], operands[2]));
15674   ix86_emit_fp_unordered_jump (label);
15675
15676   emit_move_insn (operands[0], operands[1]);
15677   DONE;
15678 })
15679
15680 (define_insn "fprem1xf4"
15681   [(set (match_operand:XF 0 "register_operand" "=f")
15682         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683                     (match_operand:XF 3 "register_operand" "1")]
15684                    UNSPEC_FPREM1_F))
15685    (set (match_operand:XF 1 "register_operand" "=u")
15686         (unspec:XF [(match_dup 2) (match_dup 3)]
15687                    UNSPEC_FPREM1_U))
15688    (set (reg:CCFP FPSR_REG)
15689         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690   "TARGET_USE_FANCY_MATH_387
15691    && flag_unsafe_math_optimizations"
15692   "fprem1"
15693   [(set_attr "type" "fpspc")
15694    (set_attr "mode" "XF")])
15695
15696 (define_expand "dremsf3"
15697   [(use (match_operand:SF 0 "register_operand" ""))
15698    (use (match_operand:SF 1 "register_operand" ""))
15699    (use (match_operand:SF 2 "register_operand" ""))]
15700   "TARGET_USE_FANCY_MATH_387
15701    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15702    && flag_unsafe_math_optimizations"
15703 {
15704   rtx label = gen_label_rtx ();
15705
15706   rtx op1 = gen_reg_rtx (XFmode);
15707   rtx op2 = gen_reg_rtx (XFmode);
15708
15709   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15710   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15711
15712   emit_label (label);
15713
15714   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15715   ix86_emit_fp_unordered_jump (label);
15716
15717   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15718   DONE;
15719 })
15720
15721 (define_expand "dremdf3"
15722   [(use (match_operand:DF 0 "register_operand" ""))
15723    (use (match_operand:DF 1 "register_operand" ""))
15724    (use (match_operand:DF 2 "register_operand" ""))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727    && flag_unsafe_math_optimizations"
15728 {
15729   rtx label = gen_label_rtx ();
15730
15731   rtx op1 = gen_reg_rtx (XFmode);
15732   rtx op2 = gen_reg_rtx (XFmode);
15733
15734   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15735   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15736
15737   emit_label (label);
15738
15739   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15740   ix86_emit_fp_unordered_jump (label);
15741
15742   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15743   DONE;
15744 })
15745
15746 (define_expand "dremxf3"
15747   [(use (match_operand:XF 0 "register_operand" ""))
15748    (use (match_operand:XF 1 "register_operand" ""))
15749    (use (match_operand:XF 2 "register_operand" ""))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && flag_unsafe_math_optimizations"
15752 {
15753   rtx label = gen_label_rtx ();
15754
15755   emit_label (label);
15756
15757   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15758                             operands[1], operands[2]));
15759   ix86_emit_fp_unordered_jump (label);
15760
15761   emit_move_insn (operands[0], operands[1]);
15762   DONE;
15763 })
15764
15765 (define_insn "*sindf2"
15766   [(set (match_operand:DF 0 "register_operand" "=f")
15767         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations"
15771   "fsin"
15772   [(set_attr "type" "fpspc")
15773    (set_attr "mode" "DF")])
15774
15775 (define_insn "*sinsf2"
15776   [(set (match_operand:SF 0 "register_operand" "=f")
15777         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15778   "TARGET_USE_FANCY_MATH_387
15779    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15780    && flag_unsafe_math_optimizations"
15781   "fsin"
15782   [(set_attr "type" "fpspc")
15783    (set_attr "mode" "SF")])
15784
15785 (define_insn "*sinextendsfdf2"
15786   [(set (match_operand:DF 0 "register_operand" "=f")
15787         (unspec:DF [(float_extend:DF
15788                      (match_operand:SF 1 "register_operand" "0"))]
15789                    UNSPEC_SIN))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792    && flag_unsafe_math_optimizations"
15793   "fsin"
15794   [(set_attr "type" "fpspc")
15795    (set_attr "mode" "DF")])
15796
15797 (define_insn "*sinxf2"
15798   [(set (match_operand:XF 0 "register_operand" "=f")
15799         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15800   "TARGET_USE_FANCY_MATH_387
15801    && flag_unsafe_math_optimizations"
15802   "fsin"
15803   [(set_attr "type" "fpspc")
15804    (set_attr "mode" "XF")])
15805
15806 (define_insn "*cosdf2"
15807   [(set (match_operand:DF 0 "register_operand" "=f")
15808         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15809   "TARGET_USE_FANCY_MATH_387
15810    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811    && flag_unsafe_math_optimizations"
15812   "fcos"
15813   [(set_attr "type" "fpspc")
15814    (set_attr "mode" "DF")])
15815
15816 (define_insn "*cossf2"
15817   [(set (match_operand:SF 0 "register_operand" "=f")
15818         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821    && flag_unsafe_math_optimizations"
15822   "fcos"
15823   [(set_attr "type" "fpspc")
15824    (set_attr "mode" "SF")])
15825
15826 (define_insn "*cosextendsfdf2"
15827   [(set (match_operand:DF 0 "register_operand" "=f")
15828         (unspec:DF [(float_extend:DF
15829                      (match_operand:SF 1 "register_operand" "0"))]
15830                    UNSPEC_COS))]
15831   "TARGET_USE_FANCY_MATH_387
15832    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833    && flag_unsafe_math_optimizations"
15834   "fcos"
15835   [(set_attr "type" "fpspc")
15836    (set_attr "mode" "DF")])
15837
15838 (define_insn "*cosxf2"
15839   [(set (match_operand:XF 0 "register_operand" "=f")
15840         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15841   "TARGET_USE_FANCY_MATH_387
15842    && flag_unsafe_math_optimizations"
15843   "fcos"
15844   [(set_attr "type" "fpspc")
15845    (set_attr "mode" "XF")])
15846
15847 ;; With sincos pattern defined, sin and cos builtin function will be
15848 ;; expanded to sincos pattern with one of its outputs left unused. 
15849 ;; Cse pass  will detected, if two sincos patterns can be combined,
15850 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15851 ;; depending on the unused output.
15852
15853 (define_insn "sincosdf3"
15854   [(set (match_operand:DF 0 "register_operand" "=f")
15855         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15856                    UNSPEC_SINCOS_COS))
15857    (set (match_operand:DF 1 "register_operand" "=u")
15858         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859   "TARGET_USE_FANCY_MATH_387
15860    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15861    && flag_unsafe_math_optimizations"
15862   "fsincos"
15863   [(set_attr "type" "fpspc")
15864    (set_attr "mode" "DF")])
15865
15866 (define_split
15867   [(set (match_operand:DF 0 "register_operand" "")
15868         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15869                    UNSPEC_SINCOS_COS))
15870    (set (match_operand:DF 1 "register_operand" "")
15871         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873    && !reload_completed && !reload_in_progress"
15874   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15875   "")
15876
15877 (define_split
15878   [(set (match_operand:DF 0 "register_operand" "")
15879         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15880                    UNSPEC_SINCOS_COS))
15881    (set (match_operand:DF 1 "register_operand" "")
15882         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884    && !reload_completed && !reload_in_progress"
15885   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15886   "")
15887
15888 (define_insn "sincossf3"
15889   [(set (match_operand:SF 0 "register_operand" "=f")
15890         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15891                    UNSPEC_SINCOS_COS))
15892    (set (match_operand:SF 1 "register_operand" "=u")
15893         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15894   "TARGET_USE_FANCY_MATH_387
15895    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15896    && flag_unsafe_math_optimizations"
15897   "fsincos"
15898   [(set_attr "type" "fpspc")
15899    (set_attr "mode" "SF")])
15900
15901 (define_split
15902   [(set (match_operand:SF 0 "register_operand" "")
15903         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15904                    UNSPEC_SINCOS_COS))
15905    (set (match_operand:SF 1 "register_operand" "")
15906         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15907   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15908    && !reload_completed && !reload_in_progress"
15909   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15910   "")
15911
15912 (define_split
15913   [(set (match_operand:SF 0 "register_operand" "")
15914         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15915                    UNSPEC_SINCOS_COS))
15916    (set (match_operand:SF 1 "register_operand" "")
15917         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15918   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15919    && !reload_completed && !reload_in_progress"
15920   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15921   "")
15922
15923 (define_insn "*sincosextendsfdf3"
15924   [(set (match_operand:DF 0 "register_operand" "=f")
15925         (unspec:DF [(float_extend:DF
15926                      (match_operand:SF 2 "register_operand" "0"))]
15927                    UNSPEC_SINCOS_COS))
15928    (set (match_operand:DF 1 "register_operand" "=u")
15929         (unspec:DF [(float_extend:DF
15930                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15931   "TARGET_USE_FANCY_MATH_387
15932    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15933    && flag_unsafe_math_optimizations"
15934   "fsincos"
15935   [(set_attr "type" "fpspc")
15936    (set_attr "mode" "DF")])
15937
15938 (define_split
15939   [(set (match_operand:DF 0 "register_operand" "")
15940         (unspec:DF [(float_extend:DF
15941                      (match_operand:SF 2 "register_operand" ""))]
15942                    UNSPEC_SINCOS_COS))
15943    (set (match_operand:DF 1 "register_operand" "")
15944         (unspec:DF [(float_extend:DF
15945                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15946   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15947    && !reload_completed && !reload_in_progress"
15948   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15949                                    (match_dup 2))] UNSPEC_SIN))]
15950   "")
15951
15952 (define_split
15953   [(set (match_operand:DF 0 "register_operand" "")
15954         (unspec:DF [(float_extend:DF
15955                      (match_operand:SF 2 "register_operand" ""))]
15956                    UNSPEC_SINCOS_COS))
15957    (set (match_operand:DF 1 "register_operand" "")
15958         (unspec:DF [(float_extend:DF
15959                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15960   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961    && !reload_completed && !reload_in_progress"
15962   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15963                                    (match_dup 2))] UNSPEC_COS))]
15964   "")
15965
15966 (define_insn "sincosxf3"
15967   [(set (match_operand:XF 0 "register_operand" "=f")
15968         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15969                    UNSPEC_SINCOS_COS))
15970    (set (match_operand:XF 1 "register_operand" "=u")
15971         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && flag_unsafe_math_optimizations"
15974   "fsincos"
15975   [(set_attr "type" "fpspc")
15976    (set_attr "mode" "XF")])
15977
15978 (define_split
15979   [(set (match_operand:XF 0 "register_operand" "")
15980         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15981                    UNSPEC_SINCOS_COS))
15982    (set (match_operand:XF 1 "register_operand" "")
15983         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15984   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15985    && !reload_completed && !reload_in_progress"
15986   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15987   "")
15988
15989 (define_split
15990   [(set (match_operand:XF 0 "register_operand" "")
15991         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15992                    UNSPEC_SINCOS_COS))
15993    (set (match_operand:XF 1 "register_operand" "")
15994         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15995   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15996    && !reload_completed && !reload_in_progress"
15997   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15998   "")
15999
16000 (define_insn "*tandf3_1"
16001   [(set (match_operand:DF 0 "register_operand" "=f")
16002         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16003                    UNSPEC_TAN_ONE))
16004    (set (match_operand:DF 1 "register_operand" "=u")
16005         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16006   "TARGET_USE_FANCY_MATH_387
16007    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16008    && flag_unsafe_math_optimizations"
16009   "fptan"
16010   [(set_attr "type" "fpspc")
16011    (set_attr "mode" "DF")])
16012
16013 ;; optimize sequence: fptan
16014 ;;                    fstp    %st(0)
16015 ;;                    fld1
16016 ;; into fptan insn.
16017
16018 (define_peephole2
16019   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16020                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16021                              UNSPEC_TAN_ONE))
16022              (set (match_operand:DF 1 "register_operand" "")
16023                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16024    (set (match_dup 0)
16025         (match_operand:DF 3 "immediate_operand" ""))]
16026   "standard_80387_constant_p (operands[3]) == 2"
16027   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16028              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16029   "")
16030
16031 (define_expand "tandf2"
16032   [(parallel [(set (match_dup 2)
16033                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16034                               UNSPEC_TAN_ONE))
16035               (set (match_operand:DF 0 "register_operand" "")
16036                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16037   "TARGET_USE_FANCY_MATH_387
16038    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16039    && flag_unsafe_math_optimizations"
16040 {
16041   operands[2] = gen_reg_rtx (DFmode);
16042 })
16043
16044 (define_insn "*tansf3_1"
16045   [(set (match_operand:SF 0 "register_operand" "=f")
16046         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16047                    UNSPEC_TAN_ONE))
16048    (set (match_operand:SF 1 "register_operand" "=u")
16049         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16052    && flag_unsafe_math_optimizations"
16053   "fptan"
16054   [(set_attr "type" "fpspc")
16055    (set_attr "mode" "SF")])
16056
16057 ;; optimize sequence: fptan
16058 ;;                    fstp    %st(0)
16059 ;;                    fld1
16060 ;; into fptan insn.
16061
16062 (define_peephole2
16063   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16064                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16065                              UNSPEC_TAN_ONE))
16066              (set (match_operand:SF 1 "register_operand" "")
16067                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16068    (set (match_dup 0)
16069         (match_operand:SF 3 "immediate_operand" ""))]
16070   "standard_80387_constant_p (operands[3]) == 2"
16071   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16072              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16073   "")
16074
16075 (define_expand "tansf2"
16076   [(parallel [(set (match_dup 2)
16077                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16078                               UNSPEC_TAN_ONE))
16079               (set (match_operand:SF 0 "register_operand" "")
16080                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16081   "TARGET_USE_FANCY_MATH_387
16082    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16083    && flag_unsafe_math_optimizations"
16084 {
16085   operands[2] = gen_reg_rtx (SFmode);
16086 })
16087
16088 (define_insn "*tanxf3_1"
16089   [(set (match_operand:XF 0 "register_operand" "=f")
16090         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16091                    UNSPEC_TAN_ONE))
16092    (set (match_operand:XF 1 "register_operand" "=u")
16093         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16094   "TARGET_USE_FANCY_MATH_387
16095    && flag_unsafe_math_optimizations"
16096   "fptan"
16097   [(set_attr "type" "fpspc")
16098    (set_attr "mode" "XF")])
16099
16100 ;; optimize sequence: fptan
16101 ;;                    fstp    %st(0)
16102 ;;                    fld1
16103 ;; into fptan insn.
16104
16105 (define_peephole2
16106   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16107                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16108                              UNSPEC_TAN_ONE))
16109              (set (match_operand:XF 1 "register_operand" "")
16110                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16111    (set (match_dup 0)
16112         (match_operand:XF 3 "immediate_operand" ""))]
16113   "standard_80387_constant_p (operands[3]) == 2"
16114   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16115              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16116   "")
16117
16118 (define_expand "tanxf2"
16119   [(parallel [(set (match_dup 2)
16120                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16121                               UNSPEC_TAN_ONE))
16122               (set (match_operand:XF 0 "register_operand" "")
16123                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16124   "TARGET_USE_FANCY_MATH_387
16125    && flag_unsafe_math_optimizations"
16126 {
16127   operands[2] = gen_reg_rtx (XFmode);
16128 })
16129
16130 (define_insn "atan2df3_1"
16131   [(set (match_operand:DF 0 "register_operand" "=f")
16132         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16133                     (match_operand:DF 1 "register_operand" "u")]
16134                    UNSPEC_FPATAN))
16135    (clobber (match_scratch:DF 3 "=1"))]
16136   "TARGET_USE_FANCY_MATH_387
16137    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16139   "fpatan"
16140   [(set_attr "type" "fpspc")
16141    (set_attr "mode" "DF")])
16142
16143 (define_expand "atan2df3"
16144   [(use (match_operand:DF 0 "register_operand" ""))
16145    (use (match_operand:DF 2 "register_operand" ""))
16146    (use (match_operand:DF 1 "register_operand" ""))]
16147   "TARGET_USE_FANCY_MATH_387
16148    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16149    && flag_unsafe_math_optimizations"
16150 {
16151   rtx copy = gen_reg_rtx (DFmode);
16152   emit_move_insn (copy, operands[1]);
16153   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16154   DONE;
16155 })
16156
16157 (define_expand "atandf2"
16158   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16159                    (unspec:DF [(match_dup 2)
16160                                (match_operand:DF 1 "register_operand" "")]
16161                     UNSPEC_FPATAN))
16162               (clobber (match_scratch:DF 3 ""))])]
16163   "TARGET_USE_FANCY_MATH_387
16164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16165    && flag_unsafe_math_optimizations"
16166 {
16167   operands[2] = gen_reg_rtx (DFmode);
16168   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16169 })
16170
16171 (define_insn "atan2sf3_1"
16172   [(set (match_operand:SF 0 "register_operand" "=f")
16173         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16174                     (match_operand:SF 1 "register_operand" "u")]
16175                    UNSPEC_FPATAN))
16176    (clobber (match_scratch:SF 3 "=1"))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179    && flag_unsafe_math_optimizations"
16180   "fpatan"
16181   [(set_attr "type" "fpspc")
16182    (set_attr "mode" "SF")])
16183
16184 (define_expand "atan2sf3"
16185   [(use (match_operand:SF 0 "register_operand" ""))
16186    (use (match_operand:SF 2 "register_operand" ""))
16187    (use (match_operand:SF 1 "register_operand" ""))]
16188   "TARGET_USE_FANCY_MATH_387
16189    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190    && flag_unsafe_math_optimizations"
16191 {
16192   rtx copy = gen_reg_rtx (SFmode);
16193   emit_move_insn (copy, operands[1]);
16194   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16195   DONE;
16196 })
16197
16198 (define_expand "atansf2"
16199   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16200                    (unspec:SF [(match_dup 2)
16201                                (match_operand:SF 1 "register_operand" "")]
16202                     UNSPEC_FPATAN))
16203               (clobber (match_scratch:SF 3 ""))])]
16204   "TARGET_USE_FANCY_MATH_387
16205    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16206    && flag_unsafe_math_optimizations"
16207 {
16208   operands[2] = gen_reg_rtx (SFmode);
16209   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16210 })
16211
16212 (define_insn "atan2xf3_1"
16213   [(set (match_operand:XF 0 "register_operand" "=f")
16214         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16215                     (match_operand:XF 1 "register_operand" "u")]
16216                    UNSPEC_FPATAN))
16217    (clobber (match_scratch:XF 3 "=1"))]
16218   "TARGET_USE_FANCY_MATH_387
16219    && flag_unsafe_math_optimizations"
16220   "fpatan"
16221   [(set_attr "type" "fpspc")
16222    (set_attr "mode" "XF")])
16223
16224 (define_expand "atan2xf3"
16225   [(use (match_operand:XF 0 "register_operand" ""))
16226    (use (match_operand:XF 2 "register_operand" ""))
16227    (use (match_operand:XF 1 "register_operand" ""))]
16228   "TARGET_USE_FANCY_MATH_387
16229    && flag_unsafe_math_optimizations"
16230 {
16231   rtx copy = gen_reg_rtx (XFmode);
16232   emit_move_insn (copy, operands[1]);
16233   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16234   DONE;
16235 })
16236
16237 (define_expand "atanxf2"
16238   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16239                    (unspec:XF [(match_dup 2)
16240                                (match_operand:XF 1 "register_operand" "")]
16241                     UNSPEC_FPATAN))
16242               (clobber (match_scratch:XF 3 ""))])]
16243   "TARGET_USE_FANCY_MATH_387
16244    && flag_unsafe_math_optimizations"
16245 {
16246   operands[2] = gen_reg_rtx (XFmode);
16247   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16248 })
16249
16250 (define_expand "asindf2"
16251   [(set (match_dup 2)
16252         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16254    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16255    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16256    (parallel [(set (match_dup 7)
16257                    (unspec:XF [(match_dup 6) (match_dup 2)]
16258                               UNSPEC_FPATAN))
16259               (clobber (match_scratch:XF 8 ""))])
16260    (set (match_operand:DF 0 "register_operand" "")
16261         (float_truncate:DF (match_dup 7)))]
16262   "TARGET_USE_FANCY_MATH_387
16263    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16264    && flag_unsafe_math_optimizations"
16265 {
16266   int i;
16267
16268   for (i=2; i<8; i++)
16269     operands[i] = gen_reg_rtx (XFmode);
16270
16271   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16272 })
16273
16274 (define_expand "asinsf2"
16275   [(set (match_dup 2)
16276         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16277    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16278    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16279    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16280    (parallel [(set (match_dup 7)
16281                    (unspec:XF [(match_dup 6) (match_dup 2)]
16282                               UNSPEC_FPATAN))
16283               (clobber (match_scratch:XF 8 ""))])
16284    (set (match_operand:SF 0 "register_operand" "")
16285         (float_truncate:SF (match_dup 7)))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16288    && flag_unsafe_math_optimizations"
16289 {
16290   int i;
16291
16292   for (i=2; i<8; i++)
16293     operands[i] = gen_reg_rtx (XFmode);
16294
16295   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16296 })
16297
16298 (define_expand "asinxf2"
16299   [(set (match_dup 2)
16300         (mult:XF (match_operand:XF 1 "register_operand" "")
16301                  (match_dup 1)))
16302    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16303    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16304    (parallel [(set (match_operand:XF 0 "register_operand" "")
16305                    (unspec:XF [(match_dup 5) (match_dup 1)]
16306                               UNSPEC_FPATAN))
16307               (clobber (match_scratch:XF 6 ""))])]
16308   "TARGET_USE_FANCY_MATH_387
16309    && flag_unsafe_math_optimizations"
16310 {
16311   int i;
16312
16313   for (i=2; i<6; i++)
16314     operands[i] = gen_reg_rtx (XFmode);
16315
16316   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16317 })
16318
16319 (define_expand "acosdf2"
16320   [(set (match_dup 2)
16321         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16322    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16323    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16324    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16325    (parallel [(set (match_dup 7)
16326                    (unspec:XF [(match_dup 2) (match_dup 6)]
16327                               UNSPEC_FPATAN))
16328               (clobber (match_scratch:XF 8 ""))])
16329    (set (match_operand:DF 0 "register_operand" "")
16330         (float_truncate:DF (match_dup 7)))]
16331   "TARGET_USE_FANCY_MATH_387
16332    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16333    && flag_unsafe_math_optimizations"
16334 {
16335   int i;
16336
16337   for (i=2; i<8; i++)
16338     operands[i] = gen_reg_rtx (XFmode);
16339
16340   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16341 })
16342
16343 (define_expand "acossf2"
16344   [(set (match_dup 2)
16345         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16346    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16347    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16348    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16349    (parallel [(set (match_dup 7)
16350                    (unspec:XF [(match_dup 2) (match_dup 6)]
16351                               UNSPEC_FPATAN))
16352               (clobber (match_scratch:XF 8 ""))])
16353    (set (match_operand:SF 0 "register_operand" "")
16354         (float_truncate:SF (match_dup 7)))]
16355   "TARGET_USE_FANCY_MATH_387
16356    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16357    && flag_unsafe_math_optimizations"
16358 {
16359   int i;
16360
16361   for (i=2; i<8; i++)
16362     operands[i] = gen_reg_rtx (XFmode);
16363
16364   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16365 })
16366
16367 (define_expand "acosxf2"
16368   [(set (match_dup 2)
16369         (mult:XF (match_operand:XF 1 "register_operand" "")
16370                  (match_dup 1)))
16371    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16372    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16373    (parallel [(set (match_operand:XF 0 "register_operand" "")
16374                    (unspec:XF [(match_dup 1) (match_dup 5)]
16375                               UNSPEC_FPATAN))
16376               (clobber (match_scratch:XF 6 ""))])]
16377   "TARGET_USE_FANCY_MATH_387
16378    && flag_unsafe_math_optimizations"
16379 {
16380   int i;
16381
16382   for (i=2; i<6; i++)
16383     operands[i] = gen_reg_rtx (XFmode);
16384
16385   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16386 })
16387
16388 (define_insn "fyl2x_xf3"
16389   [(set (match_operand:XF 0 "register_operand" "=f")
16390         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16391                     (match_operand:XF 1 "register_operand" "u")]
16392                    UNSPEC_FYL2X))
16393    (clobber (match_scratch:XF 3 "=1"))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && flag_unsafe_math_optimizations"
16396   "fyl2x"
16397   [(set_attr "type" "fpspc")
16398    (set_attr "mode" "XF")])
16399
16400 (define_expand "logsf2"
16401   [(set (match_dup 2)
16402         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16403    (parallel [(set (match_dup 4)
16404                    (unspec:XF [(match_dup 2)
16405                                (match_dup 3)] UNSPEC_FYL2X))
16406               (clobber (match_scratch:XF 5 ""))])
16407    (set (match_operand:SF 0 "register_operand" "")
16408         (float_truncate:SF (match_dup 4)))]
16409   "TARGET_USE_FANCY_MATH_387
16410    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16411    && flag_unsafe_math_optimizations"
16412 {
16413   rtx temp;
16414
16415   operands[2] = gen_reg_rtx (XFmode);
16416   operands[3] = gen_reg_rtx (XFmode);
16417   operands[4] = gen_reg_rtx (XFmode);
16418
16419   temp = standard_80387_constant_rtx (4); /* fldln2 */
16420   emit_move_insn (operands[3], temp);
16421 })
16422
16423 (define_expand "logdf2"
16424   [(set (match_dup 2)
16425         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16426    (parallel [(set (match_dup 4)
16427                    (unspec:XF [(match_dup 2)
16428                                (match_dup 3)] UNSPEC_FYL2X))
16429               (clobber (match_scratch:XF 5 ""))])
16430    (set (match_operand:DF 0 "register_operand" "")
16431         (float_truncate:DF (match_dup 4)))]
16432   "TARGET_USE_FANCY_MATH_387
16433    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16434    && flag_unsafe_math_optimizations"
16435 {
16436   rtx temp;
16437
16438   operands[2] = gen_reg_rtx (XFmode);
16439   operands[3] = gen_reg_rtx (XFmode);
16440   operands[4] = gen_reg_rtx (XFmode);
16441
16442   temp = standard_80387_constant_rtx (4); /* fldln2 */
16443   emit_move_insn (operands[3], temp);
16444 })
16445
16446 (define_expand "logxf2"
16447   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16448                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16449                                (match_dup 2)] UNSPEC_FYL2X))
16450               (clobber (match_scratch:XF 3 ""))])]
16451   "TARGET_USE_FANCY_MATH_387
16452    && flag_unsafe_math_optimizations"
16453 {
16454   rtx temp;
16455
16456   operands[2] = gen_reg_rtx (XFmode);
16457   temp = standard_80387_constant_rtx (4); /* fldln2 */
16458   emit_move_insn (operands[2], temp);
16459 })
16460
16461 (define_expand "log10sf2"
16462   [(set (match_dup 2)
16463         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464    (parallel [(set (match_dup 4)
16465                    (unspec:XF [(match_dup 2)
16466                                (match_dup 3)] UNSPEC_FYL2X))
16467               (clobber (match_scratch:XF 5 ""))])
16468    (set (match_operand:SF 0 "register_operand" "")
16469         (float_truncate:SF (match_dup 4)))]
16470   "TARGET_USE_FANCY_MATH_387
16471    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16472    && flag_unsafe_math_optimizations"
16473 {
16474   rtx temp;
16475
16476   operands[2] = gen_reg_rtx (XFmode);
16477   operands[3] = gen_reg_rtx (XFmode);
16478   operands[4] = gen_reg_rtx (XFmode);
16479
16480   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16481   emit_move_insn (operands[3], temp);
16482 })
16483
16484 (define_expand "log10df2"
16485   [(set (match_dup 2)
16486         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16487    (parallel [(set (match_dup 4)
16488                    (unspec:XF [(match_dup 2)
16489                                (match_dup 3)] UNSPEC_FYL2X))
16490               (clobber (match_scratch:XF 5 ""))])
16491    (set (match_operand:DF 0 "register_operand" "")
16492         (float_truncate:DF (match_dup 4)))]
16493   "TARGET_USE_FANCY_MATH_387
16494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495    && flag_unsafe_math_optimizations"
16496 {
16497   rtx temp;
16498
16499   operands[2] = gen_reg_rtx (XFmode);
16500   operands[3] = gen_reg_rtx (XFmode);
16501   operands[4] = gen_reg_rtx (XFmode);
16502
16503   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16504   emit_move_insn (operands[3], temp);
16505 })
16506
16507 (define_expand "log10xf2"
16508   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16509                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16510                                (match_dup 2)] UNSPEC_FYL2X))
16511               (clobber (match_scratch:XF 3 ""))])]
16512   "TARGET_USE_FANCY_MATH_387
16513    && flag_unsafe_math_optimizations"
16514 {
16515   rtx temp;
16516
16517   operands[2] = gen_reg_rtx (XFmode);
16518   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16519   emit_move_insn (operands[2], temp);
16520 })
16521
16522 (define_expand "log2sf2"
16523   [(set (match_dup 2)
16524         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16525    (parallel [(set (match_dup 4)
16526                    (unspec:XF [(match_dup 2)
16527                                (match_dup 3)] UNSPEC_FYL2X))
16528               (clobber (match_scratch:XF 5 ""))])
16529    (set (match_operand:SF 0 "register_operand" "")
16530         (float_truncate:SF (match_dup 4)))]
16531   "TARGET_USE_FANCY_MATH_387
16532    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16533    && flag_unsafe_math_optimizations"
16534 {
16535   operands[2] = gen_reg_rtx (XFmode);
16536   operands[3] = gen_reg_rtx (XFmode);
16537   operands[4] = gen_reg_rtx (XFmode);
16538
16539   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16540 })
16541
16542 (define_expand "log2df2"
16543   [(set (match_dup 2)
16544         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16545    (parallel [(set (match_dup 4)
16546                    (unspec:XF [(match_dup 2)
16547                                (match_dup 3)] UNSPEC_FYL2X))
16548               (clobber (match_scratch:XF 5 ""))])
16549    (set (match_operand:DF 0 "register_operand" "")
16550         (float_truncate:DF (match_dup 4)))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553    && flag_unsafe_math_optimizations"
16554 {
16555   operands[2] = gen_reg_rtx (XFmode);
16556   operands[3] = gen_reg_rtx (XFmode);
16557   operands[4] = gen_reg_rtx (XFmode);
16558
16559   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16560 })
16561
16562 (define_expand "log2xf2"
16563   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565                                (match_dup 2)] UNSPEC_FYL2X))
16566               (clobber (match_scratch:XF 3 ""))])]
16567   "TARGET_USE_FANCY_MATH_387
16568    && flag_unsafe_math_optimizations"
16569 {
16570   operands[2] = gen_reg_rtx (XFmode);
16571   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16572 })
16573
16574 (define_insn "fyl2xp1_xf3"
16575   [(set (match_operand:XF 0 "register_operand" "=f")
16576         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16577                     (match_operand:XF 1 "register_operand" "u")]
16578                    UNSPEC_FYL2XP1))
16579    (clobber (match_scratch:XF 3 "=1"))]
16580   "TARGET_USE_FANCY_MATH_387
16581    && flag_unsafe_math_optimizations"
16582   "fyl2xp1"
16583   [(set_attr "type" "fpspc")
16584    (set_attr "mode" "XF")])
16585
16586 (define_expand "log1psf2"
16587   [(use (match_operand:SF 0 "register_operand" ""))
16588    (use (match_operand:SF 1 "register_operand" ""))]
16589   "TARGET_USE_FANCY_MATH_387
16590    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16591    && flag_unsafe_math_optimizations"
16592 {
16593   rtx op0 = gen_reg_rtx (XFmode);
16594   rtx op1 = gen_reg_rtx (XFmode);
16595
16596   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16597   ix86_emit_i387_log1p (op0, op1);
16598   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16599   DONE;
16600 })
16601
16602 (define_expand "log1pdf2"
16603   [(use (match_operand:DF 0 "register_operand" ""))
16604    (use (match_operand:DF 1 "register_operand" ""))]
16605   "TARGET_USE_FANCY_MATH_387
16606    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16607    && flag_unsafe_math_optimizations"
16608 {
16609   rtx op0 = gen_reg_rtx (XFmode);
16610   rtx op1 = gen_reg_rtx (XFmode);
16611
16612   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16613   ix86_emit_i387_log1p (op0, op1);
16614   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16615   DONE;
16616 })
16617
16618 (define_expand "log1pxf2"
16619   [(use (match_operand:XF 0 "register_operand" ""))
16620    (use (match_operand:XF 1 "register_operand" ""))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623 {
16624   ix86_emit_i387_log1p (operands[0], operands[1]);
16625   DONE;
16626 })
16627
16628 (define_insn "*fxtractxf3"
16629   [(set (match_operand:XF 0 "register_operand" "=f")
16630         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16631                    UNSPEC_XTRACT_FRACT))
16632    (set (match_operand:XF 1 "register_operand" "=u")
16633         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16634   "TARGET_USE_FANCY_MATH_387
16635    && flag_unsafe_math_optimizations"
16636   "fxtract"
16637   [(set_attr "type" "fpspc")
16638    (set_attr "mode" "XF")])
16639
16640 (define_expand "logbsf2"
16641   [(set (match_dup 2)
16642         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16643    (parallel [(set (match_dup 3)
16644                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16645               (set (match_dup 4)
16646                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16647    (set (match_operand:SF 0 "register_operand" "")
16648         (float_truncate:SF (match_dup 4)))]
16649   "TARGET_USE_FANCY_MATH_387
16650    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16652 {
16653   operands[2] = gen_reg_rtx (XFmode);
16654   operands[3] = gen_reg_rtx (XFmode);
16655   operands[4] = gen_reg_rtx (XFmode);
16656 })
16657
16658 (define_expand "logbdf2"
16659   [(set (match_dup 2)
16660         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16661    (parallel [(set (match_dup 3)
16662                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16663               (set (match_dup 4)
16664                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16665    (set (match_operand:DF 0 "register_operand" "")
16666         (float_truncate:DF (match_dup 4)))]
16667   "TARGET_USE_FANCY_MATH_387
16668    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16669    && flag_unsafe_math_optimizations"
16670 {
16671   operands[2] = gen_reg_rtx (XFmode);
16672   operands[3] = gen_reg_rtx (XFmode);
16673   operands[4] = gen_reg_rtx (XFmode);
16674 })
16675
16676 (define_expand "logbxf2"
16677   [(parallel [(set (match_dup 2)
16678                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16679                               UNSPEC_XTRACT_FRACT))
16680               (set (match_operand:XF 0 "register_operand" "")
16681                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16682   "TARGET_USE_FANCY_MATH_387
16683    && flag_unsafe_math_optimizations"
16684 {
16685   operands[2] = gen_reg_rtx (XFmode);
16686 })
16687
16688 (define_expand "ilogbsi2"
16689   [(parallel [(set (match_dup 2)
16690                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16691                               UNSPEC_XTRACT_FRACT))
16692               (set (match_operand:XF 3 "register_operand" "")
16693                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16694    (parallel [(set (match_operand:SI 0 "register_operand" "")
16695                    (fix:SI (match_dup 3)))
16696               (clobber (reg:CC FLAGS_REG))])]
16697   "TARGET_USE_FANCY_MATH_387
16698    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16699    && flag_unsafe_math_optimizations"
16700 {
16701   operands[2] = gen_reg_rtx (XFmode);
16702   operands[3] = gen_reg_rtx (XFmode);
16703 })
16704
16705 (define_insn "*f2xm1xf2"
16706   [(set (match_operand:XF 0 "register_operand" "=f")
16707         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16708          UNSPEC_F2XM1))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && flag_unsafe_math_optimizations"
16711   "f2xm1"
16712   [(set_attr "type" "fpspc")
16713    (set_attr "mode" "XF")])
16714
16715 (define_insn "*fscalexf4"
16716   [(set (match_operand:XF 0 "register_operand" "=f")
16717         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16718                     (match_operand:XF 3 "register_operand" "1")]
16719                    UNSPEC_FSCALE_FRACT))
16720    (set (match_operand:XF 1 "register_operand" "=u")
16721         (unspec:XF [(match_dup 2) (match_dup 3)]
16722                    UNSPEC_FSCALE_EXP))]
16723   "TARGET_USE_FANCY_MATH_387
16724    && flag_unsafe_math_optimizations"
16725   "fscale"
16726   [(set_attr "type" "fpspc")
16727    (set_attr "mode" "XF")])
16728
16729 (define_expand "expsf2"
16730   [(set (match_dup 2)
16731         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16732    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16733    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16734    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16735    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16736    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16737    (parallel [(set (match_dup 10)
16738                    (unspec:XF [(match_dup 9) (match_dup 5)]
16739                               UNSPEC_FSCALE_FRACT))
16740               (set (match_dup 11)
16741                    (unspec:XF [(match_dup 9) (match_dup 5)]
16742                               UNSPEC_FSCALE_EXP))])
16743    (set (match_operand:SF 0 "register_operand" "")
16744         (float_truncate:SF (match_dup 10)))]
16745   "TARGET_USE_FANCY_MATH_387
16746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747    && flag_unsafe_math_optimizations"
16748 {
16749   rtx temp;
16750   int i;
16751
16752   for (i=2; i<12; i++)
16753     operands[i] = gen_reg_rtx (XFmode);
16754   temp = standard_80387_constant_rtx (5); /* fldl2e */
16755   emit_move_insn (operands[3], temp);
16756   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16757 })
16758
16759 (define_expand "expdf2"
16760   [(set (match_dup 2)
16761         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16762    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16763    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16764    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16765    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16766    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16767    (parallel [(set (match_dup 10)
16768                    (unspec:XF [(match_dup 9) (match_dup 5)]
16769                               UNSPEC_FSCALE_FRACT))
16770               (set (match_dup 11)
16771                    (unspec:XF [(match_dup 9) (match_dup 5)]
16772                               UNSPEC_FSCALE_EXP))])
16773    (set (match_operand:DF 0 "register_operand" "")
16774         (float_truncate:DF (match_dup 10)))]
16775   "TARGET_USE_FANCY_MATH_387
16776    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16777    && flag_unsafe_math_optimizations"
16778 {
16779   rtx temp;
16780   int i;
16781
16782   for (i=2; i<12; i++)
16783     operands[i] = gen_reg_rtx (XFmode);
16784   temp = standard_80387_constant_rtx (5); /* fldl2e */
16785   emit_move_insn (operands[3], temp);
16786   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16787 })
16788
16789 (define_expand "expxf2"
16790   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16791                                (match_dup 2)))
16792    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16793    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16794    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16795    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16796    (parallel [(set (match_operand:XF 0 "register_operand" "")
16797                    (unspec:XF [(match_dup 8) (match_dup 4)]
16798                               UNSPEC_FSCALE_FRACT))
16799               (set (match_dup 9)
16800                    (unspec:XF [(match_dup 8) (match_dup 4)]
16801                               UNSPEC_FSCALE_EXP))])]
16802   "TARGET_USE_FANCY_MATH_387
16803    && flag_unsafe_math_optimizations"
16804 {
16805   rtx temp;
16806   int i;
16807
16808   for (i=2; i<10; i++)
16809     operands[i] = gen_reg_rtx (XFmode);
16810   temp = standard_80387_constant_rtx (5); /* fldl2e */
16811   emit_move_insn (operands[2], temp);
16812   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16813 })
16814
16815 (define_expand "exp10sf2"
16816   [(set (match_dup 2)
16817         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16818    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16819    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16820    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16821    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16822    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16823    (parallel [(set (match_dup 10)
16824                    (unspec:XF [(match_dup 9) (match_dup 5)]
16825                               UNSPEC_FSCALE_FRACT))
16826               (set (match_dup 11)
16827                    (unspec:XF [(match_dup 9) (match_dup 5)]
16828                               UNSPEC_FSCALE_EXP))])
16829    (set (match_operand:SF 0 "register_operand" "")
16830         (float_truncate:SF (match_dup 10)))]
16831   "TARGET_USE_FANCY_MATH_387
16832    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16833    && flag_unsafe_math_optimizations"
16834 {
16835   rtx temp;
16836   int i;
16837
16838   for (i=2; i<12; i++)
16839     operands[i] = gen_reg_rtx (XFmode);
16840   temp = standard_80387_constant_rtx (6); /* fldl2t */
16841   emit_move_insn (operands[3], temp);
16842   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16843 })
16844
16845 (define_expand "exp10df2"
16846   [(set (match_dup 2)
16847         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16848    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16849    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16850    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16851    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16852    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16853    (parallel [(set (match_dup 10)
16854                    (unspec:XF [(match_dup 9) (match_dup 5)]
16855                               UNSPEC_FSCALE_FRACT))
16856               (set (match_dup 11)
16857                    (unspec:XF [(match_dup 9) (match_dup 5)]
16858                               UNSPEC_FSCALE_EXP))])
16859    (set (match_operand:DF 0 "register_operand" "")
16860         (float_truncate:DF (match_dup 10)))]
16861   "TARGET_USE_FANCY_MATH_387
16862    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863    && flag_unsafe_math_optimizations"
16864 {
16865   rtx temp;
16866   int i;
16867
16868   for (i=2; i<12; i++)
16869     operands[i] = gen_reg_rtx (XFmode);
16870   temp = standard_80387_constant_rtx (6); /* fldl2t */
16871   emit_move_insn (operands[3], temp);
16872   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16873 })
16874
16875 (define_expand "exp10xf2"
16876   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16877                                (match_dup 2)))
16878    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16879    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16880    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16881    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16882    (parallel [(set (match_operand:XF 0 "register_operand" "")
16883                    (unspec:XF [(match_dup 8) (match_dup 4)]
16884                               UNSPEC_FSCALE_FRACT))
16885               (set (match_dup 9)
16886                    (unspec:XF [(match_dup 8) (match_dup 4)]
16887                               UNSPEC_FSCALE_EXP))])]
16888   "TARGET_USE_FANCY_MATH_387
16889    && flag_unsafe_math_optimizations"
16890 {
16891   rtx temp;
16892   int i;
16893
16894   for (i=2; i<10; i++)
16895     operands[i] = gen_reg_rtx (XFmode);
16896   temp = standard_80387_constant_rtx (6); /* fldl2t */
16897   emit_move_insn (operands[2], temp);
16898   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16899 })
16900
16901 (define_expand "exp2sf2"
16902   [(set (match_dup 2)
16903         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16904    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16905    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16906    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16907    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16908    (parallel [(set (match_dup 8)
16909                    (unspec:XF [(match_dup 7) (match_dup 3)]
16910                               UNSPEC_FSCALE_FRACT))
16911               (set (match_dup 9)
16912                    (unspec:XF [(match_dup 7) (match_dup 3)]
16913                               UNSPEC_FSCALE_EXP))])
16914    (set (match_operand:SF 0 "register_operand" "")
16915         (float_truncate:SF (match_dup 8)))]
16916   "TARGET_USE_FANCY_MATH_387
16917    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16918    && flag_unsafe_math_optimizations"
16919 {
16920   int i;
16921
16922   for (i=2; i<10; i++)
16923     operands[i] = gen_reg_rtx (XFmode);
16924   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16925 })
16926
16927 (define_expand "exp2df2"
16928   [(set (match_dup 2)
16929         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16930    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16931    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16932    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16933    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16934    (parallel [(set (match_dup 8)
16935                    (unspec:XF [(match_dup 7) (match_dup 3)]
16936                               UNSPEC_FSCALE_FRACT))
16937               (set (match_dup 9)
16938                    (unspec:XF [(match_dup 7) (match_dup 3)]
16939                               UNSPEC_FSCALE_EXP))])
16940    (set (match_operand:DF 0 "register_operand" "")
16941         (float_truncate:DF (match_dup 8)))]
16942   "TARGET_USE_FANCY_MATH_387
16943    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16944    && flag_unsafe_math_optimizations"
16945 {
16946   int i;
16947
16948   for (i=2; i<10; i++)
16949     operands[i] = gen_reg_rtx (XFmode);
16950   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16951 })
16952
16953 (define_expand "exp2xf2"
16954   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16955    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16956    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16957    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16958    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16959    (parallel [(set (match_operand:XF 0 "register_operand" "")
16960                    (unspec:XF [(match_dup 7) (match_dup 3)]
16961                               UNSPEC_FSCALE_FRACT))
16962               (set (match_dup 8)
16963                    (unspec:XF [(match_dup 7) (match_dup 3)]
16964                               UNSPEC_FSCALE_EXP))])]
16965   "TARGET_USE_FANCY_MATH_387
16966    && flag_unsafe_math_optimizations"
16967 {
16968   int i;
16969
16970   for (i=2; i<9; i++)
16971     operands[i] = gen_reg_rtx (XFmode);
16972   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16973 })
16974
16975 (define_expand "expm1df2"
16976   [(set (match_dup 2)
16977         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16978    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16979    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16980    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16981    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16982    (parallel [(set (match_dup 8)
16983                    (unspec:XF [(match_dup 7) (match_dup 5)]
16984                               UNSPEC_FSCALE_FRACT))
16985                    (set (match_dup 9)
16986                    (unspec:XF [(match_dup 7) (match_dup 5)]
16987                               UNSPEC_FSCALE_EXP))])
16988    (parallel [(set (match_dup 11)
16989                    (unspec:XF [(match_dup 10) (match_dup 9)]
16990                               UNSPEC_FSCALE_FRACT))
16991               (set (match_dup 12)
16992                    (unspec:XF [(match_dup 10) (match_dup 9)]
16993                               UNSPEC_FSCALE_EXP))])
16994    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16995    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16996    (set (match_operand:DF 0 "register_operand" "")
16997         (float_truncate:DF (match_dup 14)))]
16998   "TARGET_USE_FANCY_MATH_387
16999    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17000    && flag_unsafe_math_optimizations"
17001 {
17002   rtx temp;
17003   int i;
17004
17005   for (i=2; i<15; i++)
17006     operands[i] = gen_reg_rtx (XFmode);
17007   temp = standard_80387_constant_rtx (5); /* fldl2e */
17008   emit_move_insn (operands[3], temp);
17009   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17010 })
17011
17012 (define_expand "expm1sf2"
17013   [(set (match_dup 2)
17014         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17015    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17016    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17017    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17018    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17019    (parallel [(set (match_dup 8)
17020                    (unspec:XF [(match_dup 7) (match_dup 5)]
17021                               UNSPEC_FSCALE_FRACT))
17022                    (set (match_dup 9)
17023                    (unspec:XF [(match_dup 7) (match_dup 5)]
17024                               UNSPEC_FSCALE_EXP))])
17025    (parallel [(set (match_dup 11)
17026                    (unspec:XF [(match_dup 10) (match_dup 9)]
17027                               UNSPEC_FSCALE_FRACT))
17028               (set (match_dup 12)
17029                    (unspec:XF [(match_dup 10) (match_dup 9)]
17030                               UNSPEC_FSCALE_EXP))])
17031    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17032    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17033    (set (match_operand:SF 0 "register_operand" "")
17034         (float_truncate:SF (match_dup 14)))]
17035   "TARGET_USE_FANCY_MATH_387
17036    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17037    && flag_unsafe_math_optimizations"
17038 {
17039   rtx temp;
17040   int i;
17041
17042   for (i=2; i<15; i++)
17043     operands[i] = gen_reg_rtx (XFmode);
17044   temp = standard_80387_constant_rtx (5); /* fldl2e */
17045   emit_move_insn (operands[3], temp);
17046   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17047 })
17048
17049 (define_expand "expm1xf2"
17050   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17051                                (match_dup 2)))
17052    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055    (parallel [(set (match_dup 7)
17056                    (unspec:XF [(match_dup 6) (match_dup 4)]
17057                               UNSPEC_FSCALE_FRACT))
17058                    (set (match_dup 8)
17059                    (unspec:XF [(match_dup 6) (match_dup 4)]
17060                               UNSPEC_FSCALE_EXP))])
17061    (parallel [(set (match_dup 10)
17062                    (unspec:XF [(match_dup 9) (match_dup 8)]
17063                               UNSPEC_FSCALE_FRACT))
17064               (set (match_dup 11)
17065                    (unspec:XF [(match_dup 9) (match_dup 8)]
17066                               UNSPEC_FSCALE_EXP))])
17067    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17068    (set (match_operand:XF 0 "register_operand" "")
17069         (plus:XF (match_dup 12) (match_dup 7)))]
17070   "TARGET_USE_FANCY_MATH_387
17071    && flag_unsafe_math_optimizations"
17072 {
17073   rtx temp;
17074   int i;
17075
17076   for (i=2; i<13; i++)
17077     operands[i] = gen_reg_rtx (XFmode);
17078   temp = standard_80387_constant_rtx (5); /* fldl2e */
17079   emit_move_insn (operands[2], temp);
17080   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17081 })
17082
17083 (define_expand "ldexpdf3"
17084   [(set (match_dup 3)
17085         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17086    (set (match_dup 4)
17087         (float:XF (match_operand:SI 2 "register_operand" "")))
17088    (parallel [(set (match_dup 5)
17089                    (unspec:XF [(match_dup 3) (match_dup 4)]
17090                               UNSPEC_FSCALE_FRACT))
17091               (set (match_dup 6)
17092                    (unspec:XF [(match_dup 3) (match_dup 4)]
17093                               UNSPEC_FSCALE_EXP))])
17094    (set (match_operand:DF 0 "register_operand" "")
17095         (float_truncate:DF (match_dup 5)))]
17096   "TARGET_USE_FANCY_MATH_387
17097    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17098    && flag_unsafe_math_optimizations"
17099 {
17100   int i;
17101
17102   for (i=3; i<7; i++)
17103     operands[i] = gen_reg_rtx (XFmode);
17104 })
17105
17106 (define_expand "ldexpsf3"
17107   [(set (match_dup 3)
17108         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17109    (set (match_dup 4)
17110         (float:XF (match_operand:SI 2 "register_operand" "")))
17111    (parallel [(set (match_dup 5)
17112                    (unspec:XF [(match_dup 3) (match_dup 4)]
17113                               UNSPEC_FSCALE_FRACT))
17114               (set (match_dup 6)
17115                    (unspec:XF [(match_dup 3) (match_dup 4)]
17116                               UNSPEC_FSCALE_EXP))])
17117    (set (match_operand:SF 0 "register_operand" "")
17118         (float_truncate:SF (match_dup 5)))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17121    && flag_unsafe_math_optimizations"
17122 {
17123   int i;
17124
17125   for (i=3; i<7; i++)
17126     operands[i] = gen_reg_rtx (XFmode);
17127 })
17128
17129 (define_expand "ldexpxf3"
17130   [(set (match_dup 3)
17131         (float:XF (match_operand:SI 2 "register_operand" "")))
17132    (parallel [(set (match_operand:XF 0 " register_operand" "")
17133                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17134                                (match_dup 3)]
17135                               UNSPEC_FSCALE_FRACT))
17136               (set (match_dup 4)
17137                    (unspec:XF [(match_dup 1) (match_dup 3)]
17138                               UNSPEC_FSCALE_EXP))])]
17139   "TARGET_USE_FANCY_MATH_387
17140    && flag_unsafe_math_optimizations"
17141 {
17142   int i;
17143
17144   for (i=3; i<5; i++)
17145     operands[i] = gen_reg_rtx (XFmode);
17146 })
17147 \f
17148
17149 (define_insn "frndintxf2"
17150   [(set (match_operand:XF 0 "register_operand" "=f")
17151         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17152          UNSPEC_FRNDINT))]
17153   "TARGET_USE_FANCY_MATH_387
17154    && flag_unsafe_math_optimizations"
17155   "frndint"
17156   [(set_attr "type" "fpspc")
17157    (set_attr "mode" "XF")])
17158
17159 (define_expand "rintdf2"
17160   [(use (match_operand:DF 0 "register_operand" ""))
17161    (use (match_operand:DF 1 "register_operand" ""))]
17162   "TARGET_USE_FANCY_MATH_387
17163    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17164    && flag_unsafe_math_optimizations"
17165 {
17166   rtx op0 = gen_reg_rtx (XFmode);
17167   rtx op1 = gen_reg_rtx (XFmode);
17168
17169   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17170   emit_insn (gen_frndintxf2 (op0, op1));
17171
17172   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17173   DONE;
17174 })
17175
17176 (define_expand "rintsf2"
17177   [(use (match_operand:SF 0 "register_operand" ""))
17178    (use (match_operand:SF 1 "register_operand" ""))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17181    && flag_unsafe_math_optimizations"
17182 {
17183   rtx op0 = gen_reg_rtx (XFmode);
17184   rtx op1 = gen_reg_rtx (XFmode);
17185
17186   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17187   emit_insn (gen_frndintxf2 (op0, op1));
17188
17189   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17190   DONE;
17191 })
17192
17193 (define_expand "rintxf2"
17194   [(use (match_operand:XF 0 "register_operand" ""))
17195    (use (match_operand:XF 1 "register_operand" ""))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && flag_unsafe_math_optimizations"
17198 {
17199   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17200   DONE;
17201 })
17202
17203 (define_insn_and_split "*fistdi2_1"
17204   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17205         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17206          UNSPEC_FIST))]
17207   "TARGET_USE_FANCY_MATH_387
17208    && flag_unsafe_math_optimizations
17209    && !(reload_completed || reload_in_progress)"
17210   "#"
17211   "&& 1"
17212   [(const_int 0)]
17213 {
17214   if (memory_operand (operands[0], VOIDmode))
17215     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17216   else
17217     {
17218       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17220                                          operands[2]));
17221     }
17222   DONE;
17223 }
17224   [(set_attr "type" "fpspc")
17225    (set_attr "mode" "DI")])
17226
17227 (define_insn "fistdi2"
17228   [(set (match_operand:DI 0 "memory_operand" "=m")
17229         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17230          UNSPEC_FIST))
17231    (clobber (match_scratch:XF 2 "=&1f"))]
17232   "TARGET_USE_FANCY_MATH_387
17233    && flag_unsafe_math_optimizations"
17234   "* return output_fix_trunc (insn, operands, 0);"
17235   [(set_attr "type" "fpspc")
17236    (set_attr "mode" "DI")])
17237
17238 (define_insn "fistdi2_with_temp"
17239   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17240         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17241          UNSPEC_FIST))
17242    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17243    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17244   "TARGET_USE_FANCY_MATH_387
17245    && flag_unsafe_math_optimizations"
17246   "#"
17247   [(set_attr "type" "fpspc")
17248    (set_attr "mode" "DI")])
17249
17250 (define_split 
17251   [(set (match_operand:DI 0 "register_operand" "")
17252         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17253          UNSPEC_FIST))
17254    (clobber (match_operand:DI 2 "memory_operand" ""))
17255    (clobber (match_scratch 3 ""))]
17256   "reload_completed"
17257   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17258               (clobber (match_dup 3))])
17259    (set (match_dup 0) (match_dup 2))]
17260   "")
17261
17262 (define_split 
17263   [(set (match_operand:DI 0 "memory_operand" "")
17264         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17265          UNSPEC_FIST))
17266    (clobber (match_operand:DI 2 "memory_operand" ""))
17267    (clobber (match_scratch 3 ""))]
17268   "reload_completed"
17269   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17270               (clobber (match_dup 3))])]
17271   "")
17272
17273 (define_insn_and_split "*fist<mode>2_1"
17274   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17275         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17276          UNSPEC_FIST))]
17277   "TARGET_USE_FANCY_MATH_387
17278    && flag_unsafe_math_optimizations
17279    && !(reload_completed || reload_in_progress)"
17280   "#"
17281   "&& 1"
17282   [(const_int 0)]
17283 {
17284   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17285   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17286                                         operands[2]));
17287   DONE;
17288 }
17289   [(set_attr "type" "fpspc")
17290    (set_attr "mode" "<MODE>")])
17291
17292 (define_insn "fist<mode>2"
17293   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17295          UNSPEC_FIST))]
17296   "TARGET_USE_FANCY_MATH_387
17297    && flag_unsafe_math_optimizations"
17298   "* return output_fix_trunc (insn, operands, 0);"
17299   [(set_attr "type" "fpspc")
17300    (set_attr "mode" "<MODE>")])
17301
17302 (define_insn "fist<mode>2_with_temp"
17303   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17304         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17305          UNSPEC_FIST))
17306    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17307   "TARGET_USE_FANCY_MATH_387
17308    && flag_unsafe_math_optimizations"
17309   "#"
17310   [(set_attr "type" "fpspc")
17311    (set_attr "mode" "<MODE>")])
17312
17313 (define_split 
17314   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17315         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17316          UNSPEC_FIST))
17317    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17318   "reload_completed"
17319   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17320                        UNSPEC_FIST))
17321    (set (match_dup 0) (match_dup 2))]
17322   "")
17323
17324 (define_split 
17325   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17326         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17327          UNSPEC_FIST))
17328    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17329   "reload_completed"
17330   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17331                        UNSPEC_FIST))]
17332   "")
17333
17334 (define_expand "lrint<mode>2"
17335   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17336         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17337          UNSPEC_FIST))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17340    && flag_unsafe_math_optimizations"
17341   "")
17342
17343 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17344 (define_insn_and_split "frndintxf2_floor"
17345   [(set (match_operand:XF 0 "register_operand" "=f")
17346         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17347          UNSPEC_FRNDINT_FLOOR))
17348    (clobber (reg:CC FLAGS_REG))]
17349   "TARGET_USE_FANCY_MATH_387
17350    && flag_unsafe_math_optimizations
17351    && !(reload_completed || reload_in_progress)"
17352   "#"
17353   "&& 1"
17354   [(const_int 0)]
17355 {
17356   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17357
17358   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17359   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17360
17361   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17362                                         operands[2], operands[3]));
17363   DONE;
17364 }
17365   [(set_attr "type" "frndint")
17366    (set_attr "i387_cw" "floor")
17367    (set_attr "mode" "XF")])
17368
17369 (define_insn "frndintxf2_floor_i387"
17370   [(set (match_operand:XF 0 "register_operand" "=f")
17371         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17372          UNSPEC_FRNDINT_FLOOR))
17373    (use (match_operand:HI 2 "memory_operand" "m"))
17374    (use (match_operand:HI 3 "memory_operand" "m"))]
17375   "TARGET_USE_FANCY_MATH_387
17376    && flag_unsafe_math_optimizations"
17377   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17378   [(set_attr "type" "frndint")
17379    (set_attr "i387_cw" "floor")
17380    (set_attr "mode" "XF")])
17381
17382 (define_expand "floorxf2"
17383   [(use (match_operand:XF 0 "register_operand" ""))
17384    (use (match_operand:XF 1 "register_operand" ""))]
17385   "TARGET_USE_FANCY_MATH_387
17386    && flag_unsafe_math_optimizations"
17387 {
17388   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17389   DONE;
17390 })
17391
17392 (define_expand "floordf2"
17393   [(use (match_operand:DF 0 "register_operand" ""))
17394    (use (match_operand:DF 1 "register_operand" ""))]
17395   "TARGET_USE_FANCY_MATH_387
17396    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17397    && flag_unsafe_math_optimizations"
17398 {
17399   rtx op0 = gen_reg_rtx (XFmode);
17400   rtx op1 = gen_reg_rtx (XFmode);
17401
17402   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17403   emit_insn (gen_frndintxf2_floor (op0, op1));
17404
17405   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17406   DONE;
17407 })
17408
17409 (define_expand "floorsf2"
17410   [(use (match_operand:SF 0 "register_operand" ""))
17411    (use (match_operand:SF 1 "register_operand" ""))]
17412   "TARGET_USE_FANCY_MATH_387
17413    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17414    && flag_unsafe_math_optimizations"
17415 {
17416   rtx op0 = gen_reg_rtx (XFmode);
17417   rtx op1 = gen_reg_rtx (XFmode);
17418
17419   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17420   emit_insn (gen_frndintxf2_floor (op0, op1));
17421
17422   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17423   DONE;
17424 })
17425
17426 (define_insn_and_split "*fist<mode>2_floor_1"
17427   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17428         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17429          UNSPEC_FIST_FLOOR))
17430    (clobber (reg:CC FLAGS_REG))]
17431   "TARGET_USE_FANCY_MATH_387
17432    && flag_unsafe_math_optimizations
17433    && !(reload_completed || reload_in_progress)"
17434   "#"
17435   "&& 1"
17436   [(const_int 0)]
17437 {
17438   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17439
17440   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17441   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17442   if (memory_operand (operands[0], VOIDmode))
17443     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17444                                       operands[2], operands[3]));
17445   else
17446     {
17447       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17448       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17449                                                   operands[2], operands[3],
17450                                                   operands[4]));
17451     }
17452   DONE;
17453 }
17454   [(set_attr "type" "fistp")
17455    (set_attr "i387_cw" "floor")
17456    (set_attr "mode" "<MODE>")])
17457
17458 (define_insn "fistdi2_floor"
17459   [(set (match_operand:DI 0 "memory_operand" "=m")
17460         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17461          UNSPEC_FIST_FLOOR))
17462    (use (match_operand:HI 2 "memory_operand" "m"))
17463    (use (match_operand:HI 3 "memory_operand" "m"))
17464    (clobber (match_scratch:XF 4 "=&1f"))]
17465   "TARGET_USE_FANCY_MATH_387
17466    && flag_unsafe_math_optimizations"
17467   "* return output_fix_trunc (insn, operands, 0);"
17468   [(set_attr "type" "fistp")
17469    (set_attr "i387_cw" "floor")
17470    (set_attr "mode" "DI")])
17471
17472 (define_insn "fistdi2_floor_with_temp"
17473   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17474         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17475          UNSPEC_FIST_FLOOR))
17476    (use (match_operand:HI 2 "memory_operand" "m,m"))
17477    (use (match_operand:HI 3 "memory_operand" "m,m"))
17478    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17479    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17480   "TARGET_USE_FANCY_MATH_387
17481    && flag_unsafe_math_optimizations"
17482   "#"
17483   [(set_attr "type" "fistp")
17484    (set_attr "i387_cw" "floor")
17485    (set_attr "mode" "DI")])
17486
17487 (define_split 
17488   [(set (match_operand:DI 0 "register_operand" "")
17489         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17490          UNSPEC_FIST_FLOOR))
17491    (use (match_operand:HI 2 "memory_operand" ""))
17492    (use (match_operand:HI 3 "memory_operand" ""))
17493    (clobber (match_operand:DI 4 "memory_operand" ""))
17494    (clobber (match_scratch 5 ""))]
17495   "reload_completed"
17496   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17497               (use (match_dup 2))
17498               (use (match_dup 3))
17499               (clobber (match_dup 5))])
17500    (set (match_dup 0) (match_dup 4))]
17501   "")
17502
17503 (define_split 
17504   [(set (match_operand:DI 0 "memory_operand" "")
17505         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17506          UNSPEC_FIST_FLOOR))
17507    (use (match_operand:HI 2 "memory_operand" ""))
17508    (use (match_operand:HI 3 "memory_operand" ""))
17509    (clobber (match_operand:DI 4 "memory_operand" ""))
17510    (clobber (match_scratch 5 ""))]
17511   "reload_completed"
17512   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17513               (use (match_dup 2))
17514               (use (match_dup 3))
17515               (clobber (match_dup 5))])]
17516   "")
17517
17518 (define_insn "fist<mode>2_floor"
17519   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17520         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17521          UNSPEC_FIST_FLOOR))
17522    (use (match_operand:HI 2 "memory_operand" "m"))
17523    (use (match_operand:HI 3 "memory_operand" "m"))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && flag_unsafe_math_optimizations"
17526   "* return output_fix_trunc (insn, operands, 0);"
17527   [(set_attr "type" "fistp")
17528    (set_attr "i387_cw" "floor")
17529    (set_attr "mode" "<MODE>")])
17530
17531 (define_insn "fist<mode>2_floor_with_temp"
17532   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17533         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17534          UNSPEC_FIST_FLOOR))
17535    (use (match_operand:HI 2 "memory_operand" "m,m"))
17536    (use (match_operand:HI 3 "memory_operand" "m,m"))
17537    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17538   "TARGET_USE_FANCY_MATH_387
17539    && flag_unsafe_math_optimizations"
17540   "#"
17541   [(set_attr "type" "fistp")
17542    (set_attr "i387_cw" "floor")
17543    (set_attr "mode" "<MODE>")])
17544
17545 (define_split 
17546   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17547         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17548          UNSPEC_FIST_FLOOR))
17549    (use (match_operand:HI 2 "memory_operand" ""))
17550    (use (match_operand:HI 3 "memory_operand" ""))
17551    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17552   "reload_completed"
17553   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17554                                   UNSPEC_FIST_FLOOR))
17555               (use (match_dup 2))
17556               (use (match_dup 3))])
17557    (set (match_dup 0) (match_dup 4))]
17558   "")
17559
17560 (define_split 
17561   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17562         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563          UNSPEC_FIST_FLOOR))
17564    (use (match_operand:HI 2 "memory_operand" ""))
17565    (use (match_operand:HI 3 "memory_operand" ""))
17566    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17567   "reload_completed"
17568   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17569                                   UNSPEC_FIST_FLOOR))
17570               (use (match_dup 2))
17571               (use (match_dup 3))])]
17572   "")
17573
17574 (define_expand "lfloor<mode>2"
17575   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17576                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17577                     UNSPEC_FIST_FLOOR))
17578               (clobber (reg:CC FLAGS_REG))])]
17579   "TARGET_USE_FANCY_MATH_387
17580    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17581    && flag_unsafe_math_optimizations"
17582   "")
17583
17584 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17585 (define_insn_and_split "frndintxf2_ceil"
17586   [(set (match_operand:XF 0 "register_operand" "=f")
17587         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17588          UNSPEC_FRNDINT_CEIL))
17589    (clobber (reg:CC FLAGS_REG))]
17590   "TARGET_USE_FANCY_MATH_387
17591    && flag_unsafe_math_optimizations
17592    && !(reload_completed || reload_in_progress)"
17593   "#"
17594   "&& 1"
17595   [(const_int 0)]
17596 {
17597   ix86_optimize_mode_switching[I387_CEIL] = 1;
17598
17599   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17600   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17601
17602   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17603                                        operands[2], operands[3]));
17604   DONE;
17605 }
17606   [(set_attr "type" "frndint")
17607    (set_attr "i387_cw" "ceil")
17608    (set_attr "mode" "XF")])
17609
17610 (define_insn "frndintxf2_ceil_i387"
17611   [(set (match_operand:XF 0 "register_operand" "=f")
17612         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17613          UNSPEC_FRNDINT_CEIL))
17614    (use (match_operand:HI 2 "memory_operand" "m"))
17615    (use (match_operand:HI 3 "memory_operand" "m"))]
17616   "TARGET_USE_FANCY_MATH_387
17617    && flag_unsafe_math_optimizations"
17618   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17619   [(set_attr "type" "frndint")
17620    (set_attr "i387_cw" "ceil")
17621    (set_attr "mode" "XF")])
17622
17623 (define_expand "ceilxf2"
17624   [(use (match_operand:XF 0 "register_operand" ""))
17625    (use (match_operand:XF 1 "register_operand" ""))]
17626   "TARGET_USE_FANCY_MATH_387
17627    && flag_unsafe_math_optimizations"
17628 {
17629   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17630   DONE;
17631 })
17632
17633 (define_expand "ceildf2"
17634   [(use (match_operand:DF 0 "register_operand" ""))
17635    (use (match_operand:DF 1 "register_operand" ""))]
17636   "TARGET_USE_FANCY_MATH_387
17637    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17638    && flag_unsafe_math_optimizations"
17639 {
17640   rtx op0 = gen_reg_rtx (XFmode);
17641   rtx op1 = gen_reg_rtx (XFmode);
17642
17643   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17644   emit_insn (gen_frndintxf2_ceil (op0, op1));
17645
17646   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17647   DONE;
17648 })
17649
17650 (define_expand "ceilsf2"
17651   [(use (match_operand:SF 0 "register_operand" ""))
17652    (use (match_operand:SF 1 "register_operand" ""))]
17653   "TARGET_USE_FANCY_MATH_387
17654    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17655    && flag_unsafe_math_optimizations"
17656 {
17657   rtx op0 = gen_reg_rtx (XFmode);
17658   rtx op1 = gen_reg_rtx (XFmode);
17659
17660   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17661   emit_insn (gen_frndintxf2_ceil (op0, op1));
17662
17663   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17664   DONE;
17665 })
17666
17667 (define_insn_and_split "*fist<mode>2_ceil_1"
17668   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17669         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17670          UNSPEC_FIST_CEIL))
17671    (clobber (reg:CC FLAGS_REG))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && flag_unsafe_math_optimizations
17674    && !(reload_completed || reload_in_progress)"
17675   "#"
17676   "&& 1"
17677   [(const_int 0)]
17678 {
17679   ix86_optimize_mode_switching[I387_CEIL] = 1;
17680
17681   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17683   if (memory_operand (operands[0], VOIDmode))
17684     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17685                                      operands[2], operands[3]));
17686   else
17687     {
17688       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17689       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17690                                                  operands[2], operands[3],
17691                                                  operands[4]));
17692     }
17693   DONE;
17694 }
17695   [(set_attr "type" "fistp")
17696    (set_attr "i387_cw" "ceil")
17697    (set_attr "mode" "<MODE>")])
17698
17699 (define_insn "fistdi2_ceil"
17700   [(set (match_operand:DI 0 "memory_operand" "=m")
17701         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17702          UNSPEC_FIST_CEIL))
17703    (use (match_operand:HI 2 "memory_operand" "m"))
17704    (use (match_operand:HI 3 "memory_operand" "m"))
17705    (clobber (match_scratch:XF 4 "=&1f"))]
17706   "TARGET_USE_FANCY_MATH_387
17707    && flag_unsafe_math_optimizations"
17708   "* return output_fix_trunc (insn, operands, 0);"
17709   [(set_attr "type" "fistp")
17710    (set_attr "i387_cw" "ceil")
17711    (set_attr "mode" "DI")])
17712
17713 (define_insn "fistdi2_ceil_with_temp"
17714   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17715         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17716          UNSPEC_FIST_CEIL))
17717    (use (match_operand:HI 2 "memory_operand" "m,m"))
17718    (use (match_operand:HI 3 "memory_operand" "m,m"))
17719    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17720    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17721   "TARGET_USE_FANCY_MATH_387
17722    && flag_unsafe_math_optimizations"
17723   "#"
17724   [(set_attr "type" "fistp")
17725    (set_attr "i387_cw" "ceil")
17726    (set_attr "mode" "DI")])
17727
17728 (define_split 
17729   [(set (match_operand:DI 0 "register_operand" "")
17730         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17731          UNSPEC_FIST_CEIL))
17732    (use (match_operand:HI 2 "memory_operand" ""))
17733    (use (match_operand:HI 3 "memory_operand" ""))
17734    (clobber (match_operand:DI 4 "memory_operand" ""))
17735    (clobber (match_scratch 5 ""))]
17736   "reload_completed"
17737   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17738               (use (match_dup 2))
17739               (use (match_dup 3))
17740               (clobber (match_dup 5))])
17741    (set (match_dup 0) (match_dup 4))]
17742   "")
17743
17744 (define_split 
17745   [(set (match_operand:DI 0 "memory_operand" "")
17746         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17747          UNSPEC_FIST_CEIL))
17748    (use (match_operand:HI 2 "memory_operand" ""))
17749    (use (match_operand:HI 3 "memory_operand" ""))
17750    (clobber (match_operand:DI 4 "memory_operand" ""))
17751    (clobber (match_scratch 5 ""))]
17752   "reload_completed"
17753   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17754               (use (match_dup 2))
17755               (use (match_dup 3))
17756               (clobber (match_dup 5))])]
17757   "")
17758
17759 (define_insn "fist<mode>2_ceil"
17760   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17761         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17762          UNSPEC_FIST_CEIL))
17763    (use (match_operand:HI 2 "memory_operand" "m"))
17764    (use (match_operand:HI 3 "memory_operand" "m"))]
17765   "TARGET_USE_FANCY_MATH_387
17766    && flag_unsafe_math_optimizations"
17767   "* return output_fix_trunc (insn, operands, 0);"
17768   [(set_attr "type" "fistp")
17769    (set_attr "i387_cw" "ceil")
17770    (set_attr "mode" "<MODE>")])
17771
17772 (define_insn "fist<mode>2_ceil_with_temp"
17773   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17774         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17775          UNSPEC_FIST_CEIL))
17776    (use (match_operand:HI 2 "memory_operand" "m,m"))
17777    (use (match_operand:HI 3 "memory_operand" "m,m"))
17778    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17779   "TARGET_USE_FANCY_MATH_387
17780    && flag_unsafe_math_optimizations"
17781   "#"
17782   [(set_attr "type" "fistp")
17783    (set_attr "i387_cw" "ceil")
17784    (set_attr "mode" "<MODE>")])
17785
17786 (define_split 
17787   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17788         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17789          UNSPEC_FIST_CEIL))
17790    (use (match_operand:HI 2 "memory_operand" ""))
17791    (use (match_operand:HI 3 "memory_operand" ""))
17792    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17793   "reload_completed"
17794   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17795                                   UNSPEC_FIST_CEIL))
17796               (use (match_dup 2))
17797               (use (match_dup 3))])
17798    (set (match_dup 0) (match_dup 4))]
17799   "")
17800
17801 (define_split 
17802   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17803         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17804          UNSPEC_FIST_CEIL))
17805    (use (match_operand:HI 2 "memory_operand" ""))
17806    (use (match_operand:HI 3 "memory_operand" ""))
17807    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17808   "reload_completed"
17809   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17810                                   UNSPEC_FIST_CEIL))
17811               (use (match_dup 2))
17812               (use (match_dup 3))])]
17813   "")
17814
17815 (define_expand "lceil<mode>2"
17816   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17817                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17818                     UNSPEC_FIST_CEIL))
17819               (clobber (reg:CC FLAGS_REG))])]
17820   "TARGET_USE_FANCY_MATH_387
17821    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17822    && flag_unsafe_math_optimizations"
17823   "")
17824
17825 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17826 (define_insn_and_split "frndintxf2_trunc"
17827   [(set (match_operand:XF 0 "register_operand" "=f")
17828         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17829          UNSPEC_FRNDINT_TRUNC))
17830    (clobber (reg:CC FLAGS_REG))]
17831   "TARGET_USE_FANCY_MATH_387
17832    && flag_unsafe_math_optimizations
17833    && !(reload_completed || reload_in_progress)"
17834   "#"
17835   "&& 1"
17836   [(const_int 0)]
17837 {
17838   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17839
17840   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17841   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17842
17843   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17844                                         operands[2], operands[3]));
17845   DONE;
17846 }
17847   [(set_attr "type" "frndint")
17848    (set_attr "i387_cw" "trunc")
17849    (set_attr "mode" "XF")])
17850
17851 (define_insn "frndintxf2_trunc_i387"
17852   [(set (match_operand:XF 0 "register_operand" "=f")
17853         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17854          UNSPEC_FRNDINT_TRUNC))
17855    (use (match_operand:HI 2 "memory_operand" "m"))
17856    (use (match_operand:HI 3 "memory_operand" "m"))]
17857   "TARGET_USE_FANCY_MATH_387
17858    && flag_unsafe_math_optimizations"
17859   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17860   [(set_attr "type" "frndint")
17861    (set_attr "i387_cw" "trunc")
17862    (set_attr "mode" "XF")])
17863
17864 (define_expand "btruncxf2"
17865   [(use (match_operand:XF 0 "register_operand" ""))
17866    (use (match_operand:XF 1 "register_operand" ""))]
17867   "TARGET_USE_FANCY_MATH_387
17868    && flag_unsafe_math_optimizations"
17869 {
17870   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17871   DONE;
17872 })
17873
17874 (define_expand "btruncdf2"
17875   [(use (match_operand:DF 0 "register_operand" ""))
17876    (use (match_operand:DF 1 "register_operand" ""))]
17877   "TARGET_USE_FANCY_MATH_387
17878    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17879    && flag_unsafe_math_optimizations"
17880 {
17881   rtx op0 = gen_reg_rtx (XFmode);
17882   rtx op1 = gen_reg_rtx (XFmode);
17883
17884   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17885   emit_insn (gen_frndintxf2_trunc (op0, op1));
17886
17887   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17888   DONE;
17889 })
17890
17891 (define_expand "btruncsf2"
17892   [(use (match_operand:SF 0 "register_operand" ""))
17893    (use (match_operand:SF 1 "register_operand" ""))]
17894   "TARGET_USE_FANCY_MATH_387
17895    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17896    && flag_unsafe_math_optimizations"
17897 {
17898   rtx op0 = gen_reg_rtx (XFmode);
17899   rtx op1 = gen_reg_rtx (XFmode);
17900
17901   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902   emit_insn (gen_frndintxf2_trunc (op0, op1));
17903
17904   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17905   DONE;
17906 })
17907
17908 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17909 (define_insn_and_split "frndintxf2_mask_pm"
17910   [(set (match_operand:XF 0 "register_operand" "=f")
17911         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912          UNSPEC_FRNDINT_MASK_PM))
17913    (clobber (reg:CC FLAGS_REG))]
17914   "TARGET_USE_FANCY_MATH_387
17915    && flag_unsafe_math_optimizations
17916    && !(reload_completed || reload_in_progress)"
17917   "#"
17918   "&& 1"
17919   [(const_int 0)]
17920 {
17921   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17922
17923   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17925
17926   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17927                                           operands[2], operands[3]));
17928   DONE;
17929 }
17930   [(set_attr "type" "frndint")
17931    (set_attr "i387_cw" "mask_pm")
17932    (set_attr "mode" "XF")])
17933
17934 (define_insn "frndintxf2_mask_pm_i387"
17935   [(set (match_operand:XF 0 "register_operand" "=f")
17936         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937          UNSPEC_FRNDINT_MASK_PM))
17938    (use (match_operand:HI 2 "memory_operand" "m"))
17939    (use (match_operand:HI 3 "memory_operand" "m"))]
17940   "TARGET_USE_FANCY_MATH_387
17941    && flag_unsafe_math_optimizations"
17942   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17943   [(set_attr "type" "frndint")
17944    (set_attr "i387_cw" "mask_pm")
17945    (set_attr "mode" "XF")])
17946
17947 (define_expand "nearbyintxf2"
17948   [(use (match_operand:XF 0 "register_operand" ""))
17949    (use (match_operand:XF 1 "register_operand" ""))]
17950   "TARGET_USE_FANCY_MATH_387
17951    && flag_unsafe_math_optimizations"
17952 {
17953   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17954
17955   DONE;
17956 })
17957
17958 (define_expand "nearbyintdf2"
17959   [(use (match_operand:DF 0 "register_operand" ""))
17960    (use (match_operand:DF 1 "register_operand" ""))]
17961   "TARGET_USE_FANCY_MATH_387
17962    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17963    && flag_unsafe_math_optimizations"
17964 {
17965   rtx op0 = gen_reg_rtx (XFmode);
17966   rtx op1 = gen_reg_rtx (XFmode);
17967
17968   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17969   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17970
17971   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17972   DONE;
17973 })
17974
17975 (define_expand "nearbyintsf2"
17976   [(use (match_operand:SF 0 "register_operand" ""))
17977    (use (match_operand:SF 1 "register_operand" ""))]
17978   "TARGET_USE_FANCY_MATH_387
17979    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980    && flag_unsafe_math_optimizations"
17981 {
17982   rtx op0 = gen_reg_rtx (XFmode);
17983   rtx op1 = gen_reg_rtx (XFmode);
17984
17985   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17986   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17987
17988   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17989   DONE;
17990 })
17991
17992 \f
17993 ;; Block operation instructions
17994
17995 (define_insn "cld"
17996  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17997  ""
17998  "cld"
17999   [(set_attr "type" "cld")])
18000
18001 (define_expand "movmemsi"
18002   [(use (match_operand:BLK 0 "memory_operand" ""))
18003    (use (match_operand:BLK 1 "memory_operand" ""))
18004    (use (match_operand:SI 2 "nonmemory_operand" ""))
18005    (use (match_operand:SI 3 "const_int_operand" ""))]
18006   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18007 {
18008  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18009    DONE;
18010  else
18011    FAIL;
18012 })
18013
18014 (define_expand "movmemdi"
18015   [(use (match_operand:BLK 0 "memory_operand" ""))
18016    (use (match_operand:BLK 1 "memory_operand" ""))
18017    (use (match_operand:DI 2 "nonmemory_operand" ""))
18018    (use (match_operand:DI 3 "const_int_operand" ""))]
18019   "TARGET_64BIT"
18020 {
18021  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18022    DONE;
18023  else
18024    FAIL;
18025 })
18026
18027 ;; Most CPUs don't like single string operations
18028 ;; Handle this case here to simplify previous expander.
18029
18030 (define_expand "strmov"
18031   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18032    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18033    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18034               (clobber (reg:CC FLAGS_REG))])
18035    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18036               (clobber (reg:CC FLAGS_REG))])]
18037   ""
18038 {
18039   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18040
18041   /* If .md ever supports :P for Pmode, these can be directly
18042      in the pattern above.  */
18043   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18044   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18045
18046   if (TARGET_SINGLE_STRINGOP || optimize_size)
18047     {
18048       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18049                                       operands[2], operands[3],
18050                                       operands[5], operands[6]));
18051       DONE;
18052     }
18053
18054   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18055 })
18056
18057 (define_expand "strmov_singleop"
18058   [(parallel [(set (match_operand 1 "memory_operand" "")
18059                    (match_operand 3 "memory_operand" ""))
18060               (set (match_operand 0 "register_operand" "")
18061                    (match_operand 4 "" ""))
18062               (set (match_operand 2 "register_operand" "")
18063                    (match_operand 5 "" ""))
18064               (use (reg:SI DIRFLAG_REG))])]
18065   "TARGET_SINGLE_STRINGOP || optimize_size"
18066   "")
18067
18068 (define_insn "*strmovdi_rex_1"
18069   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18070         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18071    (set (match_operand:DI 0 "register_operand" "=D")
18072         (plus:DI (match_dup 2)
18073                  (const_int 8)))
18074    (set (match_operand:DI 1 "register_operand" "=S")
18075         (plus:DI (match_dup 3)
18076                  (const_int 8)))
18077    (use (reg:SI DIRFLAG_REG))]
18078   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18079   "movsq"
18080   [(set_attr "type" "str")
18081    (set_attr "mode" "DI")
18082    (set_attr "memory" "both")])
18083
18084 (define_insn "*strmovsi_1"
18085   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18086         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18087    (set (match_operand:SI 0 "register_operand" "=D")
18088         (plus:SI (match_dup 2)
18089                  (const_int 4)))
18090    (set (match_operand:SI 1 "register_operand" "=S")
18091         (plus:SI (match_dup 3)
18092                  (const_int 4)))
18093    (use (reg:SI DIRFLAG_REG))]
18094   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18095   "{movsl|movsd}"
18096   [(set_attr "type" "str")
18097    (set_attr "mode" "SI")
18098    (set_attr "memory" "both")])
18099
18100 (define_insn "*strmovsi_rex_1"
18101   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18102         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18103    (set (match_operand:DI 0 "register_operand" "=D")
18104         (plus:DI (match_dup 2)
18105                  (const_int 4)))
18106    (set (match_operand:DI 1 "register_operand" "=S")
18107         (plus:DI (match_dup 3)
18108                  (const_int 4)))
18109    (use (reg:SI DIRFLAG_REG))]
18110   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18111   "{movsl|movsd}"
18112   [(set_attr "type" "str")
18113    (set_attr "mode" "SI")
18114    (set_attr "memory" "both")])
18115
18116 (define_insn "*strmovhi_1"
18117   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18118         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18119    (set (match_operand:SI 0 "register_operand" "=D")
18120         (plus:SI (match_dup 2)
18121                  (const_int 2)))
18122    (set (match_operand:SI 1 "register_operand" "=S")
18123         (plus:SI (match_dup 3)
18124                  (const_int 2)))
18125    (use (reg:SI DIRFLAG_REG))]
18126   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18127   "movsw"
18128   [(set_attr "type" "str")
18129    (set_attr "memory" "both")
18130    (set_attr "mode" "HI")])
18131
18132 (define_insn "*strmovhi_rex_1"
18133   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18135    (set (match_operand:DI 0 "register_operand" "=D")
18136         (plus:DI (match_dup 2)
18137                  (const_int 2)))
18138    (set (match_operand:DI 1 "register_operand" "=S")
18139         (plus:DI (match_dup 3)
18140                  (const_int 2)))
18141    (use (reg:SI DIRFLAG_REG))]
18142   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18143   "movsw"
18144   [(set_attr "type" "str")
18145    (set_attr "memory" "both")
18146    (set_attr "mode" "HI")])
18147
18148 (define_insn "*strmovqi_1"
18149   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18150         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18151    (set (match_operand:SI 0 "register_operand" "=D")
18152         (plus:SI (match_dup 2)
18153                  (const_int 1)))
18154    (set (match_operand:SI 1 "register_operand" "=S")
18155         (plus:SI (match_dup 3)
18156                  (const_int 1)))
18157    (use (reg:SI DIRFLAG_REG))]
18158   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18159   "movsb"
18160   [(set_attr "type" "str")
18161    (set_attr "memory" "both")
18162    (set_attr "mode" "QI")])
18163
18164 (define_insn "*strmovqi_rex_1"
18165   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18166         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18167    (set (match_operand:DI 0 "register_operand" "=D")
18168         (plus:DI (match_dup 2)
18169                  (const_int 1)))
18170    (set (match_operand:DI 1 "register_operand" "=S")
18171         (plus:DI (match_dup 3)
18172                  (const_int 1)))
18173    (use (reg:SI DIRFLAG_REG))]
18174   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18175   "movsb"
18176   [(set_attr "type" "str")
18177    (set_attr "memory" "both")
18178    (set_attr "mode" "QI")])
18179
18180 (define_expand "rep_mov"
18181   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18182               (set (match_operand 0 "register_operand" "")
18183                    (match_operand 5 "" ""))
18184               (set (match_operand 2 "register_operand" "")
18185                    (match_operand 6 "" ""))
18186               (set (match_operand 1 "memory_operand" "")
18187                    (match_operand 3 "memory_operand" ""))
18188               (use (match_dup 4))
18189               (use (reg:SI DIRFLAG_REG))])]
18190   ""
18191   "")
18192
18193 (define_insn "*rep_movdi_rex64"
18194   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18195    (set (match_operand:DI 0 "register_operand" "=D") 
18196         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18197                             (const_int 3))
18198                  (match_operand:DI 3 "register_operand" "0")))
18199    (set (match_operand:DI 1 "register_operand" "=S") 
18200         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18201                  (match_operand:DI 4 "register_operand" "1")))
18202    (set (mem:BLK (match_dup 3))
18203         (mem:BLK (match_dup 4)))
18204    (use (match_dup 5))
18205    (use (reg:SI DIRFLAG_REG))]
18206   "TARGET_64BIT"
18207   "{rep\;movsq|rep movsq}"
18208   [(set_attr "type" "str")
18209    (set_attr "prefix_rep" "1")
18210    (set_attr "memory" "both")
18211    (set_attr "mode" "DI")])
18212
18213 (define_insn "*rep_movsi"
18214   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215    (set (match_operand:SI 0 "register_operand" "=D") 
18216         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18217                             (const_int 2))
18218                  (match_operand:SI 3 "register_operand" "0")))
18219    (set (match_operand:SI 1 "register_operand" "=S") 
18220         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221                  (match_operand:SI 4 "register_operand" "1")))
18222    (set (mem:BLK (match_dup 3))
18223         (mem:BLK (match_dup 4)))
18224    (use (match_dup 5))
18225    (use (reg:SI DIRFLAG_REG))]
18226   "!TARGET_64BIT"
18227   "{rep\;movsl|rep movsd}"
18228   [(set_attr "type" "str")
18229    (set_attr "prefix_rep" "1")
18230    (set_attr "memory" "both")
18231    (set_attr "mode" "SI")])
18232
18233 (define_insn "*rep_movsi_rex64"
18234   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18235    (set (match_operand:DI 0 "register_operand" "=D") 
18236         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18237                             (const_int 2))
18238                  (match_operand:DI 3 "register_operand" "0")))
18239    (set (match_operand:DI 1 "register_operand" "=S") 
18240         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18241                  (match_operand:DI 4 "register_operand" "1")))
18242    (set (mem:BLK (match_dup 3))
18243         (mem:BLK (match_dup 4)))
18244    (use (match_dup 5))
18245    (use (reg:SI DIRFLAG_REG))]
18246   "TARGET_64BIT"
18247   "{rep\;movsl|rep movsd}"
18248   [(set_attr "type" "str")
18249    (set_attr "prefix_rep" "1")
18250    (set_attr "memory" "both")
18251    (set_attr "mode" "SI")])
18252
18253 (define_insn "*rep_movqi"
18254   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18255    (set (match_operand:SI 0 "register_operand" "=D") 
18256         (plus:SI (match_operand:SI 3 "register_operand" "0")
18257                  (match_operand:SI 5 "register_operand" "2")))
18258    (set (match_operand:SI 1 "register_operand" "=S") 
18259         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18260    (set (mem:BLK (match_dup 3))
18261         (mem:BLK (match_dup 4)))
18262    (use (match_dup 5))
18263    (use (reg:SI DIRFLAG_REG))]
18264   "!TARGET_64BIT"
18265   "{rep\;movsb|rep movsb}"
18266   [(set_attr "type" "str")
18267    (set_attr "prefix_rep" "1")
18268    (set_attr "memory" "both")
18269    (set_attr "mode" "SI")])
18270
18271 (define_insn "*rep_movqi_rex64"
18272   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18273    (set (match_operand:DI 0 "register_operand" "=D") 
18274         (plus:DI (match_operand:DI 3 "register_operand" "0")
18275                  (match_operand:DI 5 "register_operand" "2")))
18276    (set (match_operand:DI 1 "register_operand" "=S") 
18277         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18278    (set (mem:BLK (match_dup 3))
18279         (mem:BLK (match_dup 4)))
18280    (use (match_dup 5))
18281    (use (reg:SI DIRFLAG_REG))]
18282   "TARGET_64BIT"
18283   "{rep\;movsb|rep movsb}"
18284   [(set_attr "type" "str")
18285    (set_attr "prefix_rep" "1")
18286    (set_attr "memory" "both")
18287    (set_attr "mode" "SI")])
18288
18289 (define_expand "setmemsi"
18290    [(use (match_operand:BLK 0 "memory_operand" ""))
18291     (use (match_operand:SI 1 "nonmemory_operand" ""))
18292     (use (match_operand 2 "const_int_operand" ""))
18293     (use (match_operand 3 "const_int_operand" ""))]
18294   ""
18295 {
18296  /* If value to set is not zero, use the library routine.  */
18297  if (operands[2] != const0_rtx)
18298    FAIL;
18299
18300  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18301    DONE;
18302  else
18303    FAIL;
18304 })
18305
18306 (define_expand "setmemdi"
18307    [(use (match_operand:BLK 0 "memory_operand" ""))
18308     (use (match_operand:DI 1 "nonmemory_operand" ""))
18309     (use (match_operand 2 "const_int_operand" ""))
18310     (use (match_operand 3 "const_int_operand" ""))]
18311   "TARGET_64BIT"
18312 {
18313  /* If value to set is not zero, use the library routine.  */
18314  if (operands[2] != const0_rtx)
18315    FAIL;
18316
18317  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18318    DONE;
18319  else
18320    FAIL;
18321 })
18322
18323 ;; Most CPUs don't like single string operations
18324 ;; Handle this case here to simplify previous expander.
18325
18326 (define_expand "strset"
18327   [(set (match_operand 1 "memory_operand" "")
18328         (match_operand 2 "register_operand" ""))
18329    (parallel [(set (match_operand 0 "register_operand" "")
18330                    (match_dup 3))
18331               (clobber (reg:CC FLAGS_REG))])]
18332   ""
18333 {
18334   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18335     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18336
18337   /* If .md ever supports :P for Pmode, this can be directly
18338      in the pattern above.  */
18339   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18340                               GEN_INT (GET_MODE_SIZE (GET_MODE
18341                                                       (operands[2]))));
18342   if (TARGET_SINGLE_STRINGOP || optimize_size)
18343     {
18344       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18345                                       operands[3]));
18346       DONE;
18347     }
18348 })
18349
18350 (define_expand "strset_singleop"
18351   [(parallel [(set (match_operand 1 "memory_operand" "")
18352                    (match_operand 2 "register_operand" ""))
18353               (set (match_operand 0 "register_operand" "")
18354                    (match_operand 3 "" ""))
18355               (use (reg:SI DIRFLAG_REG))])]
18356   "TARGET_SINGLE_STRINGOP || optimize_size"
18357   "")
18358
18359 (define_insn "*strsetdi_rex_1"
18360   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18361         (match_operand:DI 2 "register_operand" "a"))
18362    (set (match_operand:DI 0 "register_operand" "=D")
18363         (plus:DI (match_dup 1)
18364                  (const_int 8)))
18365    (use (reg:SI DIRFLAG_REG))]
18366   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18367   "stosq"
18368   [(set_attr "type" "str")
18369    (set_attr "memory" "store")
18370    (set_attr "mode" "DI")])
18371
18372 (define_insn "*strsetsi_1"
18373   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18374         (match_operand:SI 2 "register_operand" "a"))
18375    (set (match_operand:SI 0 "register_operand" "=D")
18376         (plus:SI (match_dup 1)
18377                  (const_int 4)))
18378    (use (reg:SI DIRFLAG_REG))]
18379   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18380   "{stosl|stosd}"
18381   [(set_attr "type" "str")
18382    (set_attr "memory" "store")
18383    (set_attr "mode" "SI")])
18384
18385 (define_insn "*strsetsi_rex_1"
18386   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18387         (match_operand:SI 2 "register_operand" "a"))
18388    (set (match_operand:DI 0 "register_operand" "=D")
18389         (plus:DI (match_dup 1)
18390                  (const_int 4)))
18391    (use (reg:SI DIRFLAG_REG))]
18392   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18393   "{stosl|stosd}"
18394   [(set_attr "type" "str")
18395    (set_attr "memory" "store")
18396    (set_attr "mode" "SI")])
18397
18398 (define_insn "*strsethi_1"
18399   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18400         (match_operand:HI 2 "register_operand" "a"))
18401    (set (match_operand:SI 0 "register_operand" "=D")
18402         (plus:SI (match_dup 1)
18403                  (const_int 2)))
18404    (use (reg:SI DIRFLAG_REG))]
18405   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406   "stosw"
18407   [(set_attr "type" "str")
18408    (set_attr "memory" "store")
18409    (set_attr "mode" "HI")])
18410
18411 (define_insn "*strsethi_rex_1"
18412   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18413         (match_operand:HI 2 "register_operand" "a"))
18414    (set (match_operand:DI 0 "register_operand" "=D")
18415         (plus:DI (match_dup 1)
18416                  (const_int 2)))
18417    (use (reg:SI DIRFLAG_REG))]
18418   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419   "stosw"
18420   [(set_attr "type" "str")
18421    (set_attr "memory" "store")
18422    (set_attr "mode" "HI")])
18423
18424 (define_insn "*strsetqi_1"
18425   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18426         (match_operand:QI 2 "register_operand" "a"))
18427    (set (match_operand:SI 0 "register_operand" "=D")
18428         (plus:SI (match_dup 1)
18429                  (const_int 1)))
18430    (use (reg:SI DIRFLAG_REG))]
18431   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18432   "stosb"
18433   [(set_attr "type" "str")
18434    (set_attr "memory" "store")
18435    (set_attr "mode" "QI")])
18436
18437 (define_insn "*strsetqi_rex_1"
18438   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18439         (match_operand:QI 2 "register_operand" "a"))
18440    (set (match_operand:DI 0 "register_operand" "=D")
18441         (plus:DI (match_dup 1)
18442                  (const_int 1)))
18443    (use (reg:SI DIRFLAG_REG))]
18444   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18445   "stosb"
18446   [(set_attr "type" "str")
18447    (set_attr "memory" "store")
18448    (set_attr "mode" "QI")])
18449
18450 (define_expand "rep_stos"
18451   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18452               (set (match_operand 0 "register_operand" "")
18453                    (match_operand 4 "" ""))
18454               (set (match_operand 2 "memory_operand" "") (const_int 0))
18455               (use (match_operand 3 "register_operand" ""))
18456               (use (match_dup 1))
18457               (use (reg:SI DIRFLAG_REG))])]
18458   ""
18459   "")
18460
18461 (define_insn "*rep_stosdi_rex64"
18462   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18463    (set (match_operand:DI 0 "register_operand" "=D") 
18464         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18465                             (const_int 3))
18466                  (match_operand:DI 3 "register_operand" "0")))
18467    (set (mem:BLK (match_dup 3))
18468         (const_int 0))
18469    (use (match_operand:DI 2 "register_operand" "a"))
18470    (use (match_dup 4))
18471    (use (reg:SI DIRFLAG_REG))]
18472   "TARGET_64BIT"
18473   "{rep\;stosq|rep stosq}"
18474   [(set_attr "type" "str")
18475    (set_attr "prefix_rep" "1")
18476    (set_attr "memory" "store")
18477    (set_attr "mode" "DI")])
18478
18479 (define_insn "*rep_stossi"
18480   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18481    (set (match_operand:SI 0 "register_operand" "=D") 
18482         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18483                             (const_int 2))
18484                  (match_operand:SI 3 "register_operand" "0")))
18485    (set (mem:BLK (match_dup 3))
18486         (const_int 0))
18487    (use (match_operand:SI 2 "register_operand" "a"))
18488    (use (match_dup 4))
18489    (use (reg:SI DIRFLAG_REG))]
18490   "!TARGET_64BIT"
18491   "{rep\;stosl|rep stosd}"
18492   [(set_attr "type" "str")
18493    (set_attr "prefix_rep" "1")
18494    (set_attr "memory" "store")
18495    (set_attr "mode" "SI")])
18496
18497 (define_insn "*rep_stossi_rex64"
18498   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18499    (set (match_operand:DI 0 "register_operand" "=D") 
18500         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18501                             (const_int 2))
18502                  (match_operand:DI 3 "register_operand" "0")))
18503    (set (mem:BLK (match_dup 3))
18504         (const_int 0))
18505    (use (match_operand:SI 2 "register_operand" "a"))
18506    (use (match_dup 4))
18507    (use (reg:SI DIRFLAG_REG))]
18508   "TARGET_64BIT"
18509   "{rep\;stosl|rep stosd}"
18510   [(set_attr "type" "str")
18511    (set_attr "prefix_rep" "1")
18512    (set_attr "memory" "store")
18513    (set_attr "mode" "SI")])
18514
18515 (define_insn "*rep_stosqi"
18516   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18517    (set (match_operand:SI 0 "register_operand" "=D") 
18518         (plus:SI (match_operand:SI 3 "register_operand" "0")
18519                  (match_operand:SI 4 "register_operand" "1")))
18520    (set (mem:BLK (match_dup 3))
18521         (const_int 0))
18522    (use (match_operand:QI 2 "register_operand" "a"))
18523    (use (match_dup 4))
18524    (use (reg:SI DIRFLAG_REG))]
18525   "!TARGET_64BIT"
18526   "{rep\;stosb|rep stosb}"
18527   [(set_attr "type" "str")
18528    (set_attr "prefix_rep" "1")
18529    (set_attr "memory" "store")
18530    (set_attr "mode" "QI")])
18531
18532 (define_insn "*rep_stosqi_rex64"
18533   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18534    (set (match_operand:DI 0 "register_operand" "=D") 
18535         (plus:DI (match_operand:DI 3 "register_operand" "0")
18536                  (match_operand:DI 4 "register_operand" "1")))
18537    (set (mem:BLK (match_dup 3))
18538         (const_int 0))
18539    (use (match_operand:QI 2 "register_operand" "a"))
18540    (use (match_dup 4))
18541    (use (reg:SI DIRFLAG_REG))]
18542   "TARGET_64BIT"
18543   "{rep\;stosb|rep stosb}"
18544   [(set_attr "type" "str")
18545    (set_attr "prefix_rep" "1")
18546    (set_attr "memory" "store")
18547    (set_attr "mode" "QI")])
18548
18549 (define_expand "cmpstrnsi"
18550   [(set (match_operand:SI 0 "register_operand" "")
18551         (compare:SI (match_operand:BLK 1 "general_operand" "")
18552                     (match_operand:BLK 2 "general_operand" "")))
18553    (use (match_operand 3 "general_operand" ""))
18554    (use (match_operand 4 "immediate_operand" ""))]
18555   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18556 {
18557   rtx addr1, addr2, out, outlow, count, countreg, align;
18558
18559   /* Can't use this if the user has appropriated esi or edi.  */
18560   if (global_regs[4] || global_regs[5])
18561     FAIL;
18562
18563   out = operands[0];
18564   if (GET_CODE (out) != REG)
18565     out = gen_reg_rtx (SImode);
18566
18567   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18568   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18569   if (addr1 != XEXP (operands[1], 0))
18570     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18571   if (addr2 != XEXP (operands[2], 0))
18572     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18573
18574   count = operands[3];
18575   countreg = ix86_zero_extend_to_Pmode (count);
18576
18577   /* %%% Iff we are testing strict equality, we can use known alignment
18578      to good advantage.  This may be possible with combine, particularly
18579      once cc0 is dead.  */
18580   align = operands[4];
18581
18582   emit_insn (gen_cld ());
18583   if (GET_CODE (count) == CONST_INT)
18584     {
18585       if (INTVAL (count) == 0)
18586         {
18587           emit_move_insn (operands[0], const0_rtx);
18588           DONE;
18589         }
18590       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18591                                      operands[1], operands[2]));
18592     }
18593   else
18594     {
18595       if (TARGET_64BIT)
18596         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18597       else
18598         emit_insn (gen_cmpsi_1 (countreg, countreg));
18599       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18600                                   operands[1], operands[2]));
18601     }
18602
18603   outlow = gen_lowpart (QImode, out);
18604   emit_insn (gen_cmpintqi (outlow));
18605   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18606
18607   if (operands[0] != out)
18608     emit_move_insn (operands[0], out);
18609
18610   DONE;
18611 })
18612
18613 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18614
18615 (define_expand "cmpintqi"
18616   [(set (match_dup 1)
18617         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18618    (set (match_dup 2)
18619         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18620    (parallel [(set (match_operand:QI 0 "register_operand" "")
18621                    (minus:QI (match_dup 1)
18622                              (match_dup 2)))
18623               (clobber (reg:CC FLAGS_REG))])]
18624   ""
18625   "operands[1] = gen_reg_rtx (QImode);
18626    operands[2] = gen_reg_rtx (QImode);")
18627
18628 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18629 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18630
18631 (define_expand "cmpstrnqi_nz_1"
18632   [(parallel [(set (reg:CC FLAGS_REG)
18633                    (compare:CC (match_operand 4 "memory_operand" "")
18634                                (match_operand 5 "memory_operand" "")))
18635               (use (match_operand 2 "register_operand" ""))
18636               (use (match_operand:SI 3 "immediate_operand" ""))
18637               (use (reg:SI DIRFLAG_REG))
18638               (clobber (match_operand 0 "register_operand" ""))
18639               (clobber (match_operand 1 "register_operand" ""))
18640               (clobber (match_dup 2))])]
18641   ""
18642   "")
18643
18644 (define_insn "*cmpstrnqi_nz_1"
18645   [(set (reg:CC FLAGS_REG)
18646         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18647                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18648    (use (match_operand:SI 6 "register_operand" "2"))
18649    (use (match_operand:SI 3 "immediate_operand" "i"))
18650    (use (reg:SI DIRFLAG_REG))
18651    (clobber (match_operand:SI 0 "register_operand" "=S"))
18652    (clobber (match_operand:SI 1 "register_operand" "=D"))
18653    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18654   "!TARGET_64BIT"
18655   "repz{\;| }cmpsb"
18656   [(set_attr "type" "str")
18657    (set_attr "mode" "QI")
18658    (set_attr "prefix_rep" "1")])
18659
18660 (define_insn "*cmpstrnqi_nz_rex_1"
18661   [(set (reg:CC FLAGS_REG)
18662         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18663                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18664    (use (match_operand:DI 6 "register_operand" "2"))
18665    (use (match_operand:SI 3 "immediate_operand" "i"))
18666    (use (reg:SI DIRFLAG_REG))
18667    (clobber (match_operand:DI 0 "register_operand" "=S"))
18668    (clobber (match_operand:DI 1 "register_operand" "=D"))
18669    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18670   "TARGET_64BIT"
18671   "repz{\;| }cmpsb"
18672   [(set_attr "type" "str")
18673    (set_attr "mode" "QI")
18674    (set_attr "prefix_rep" "1")])
18675
18676 ;; The same, but the count is not known to not be zero.
18677
18678 (define_expand "cmpstrnqi_1"
18679   [(parallel [(set (reg:CC FLAGS_REG)
18680                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18681                                      (const_int 0))
18682                   (compare:CC (match_operand 4 "memory_operand" "")
18683                               (match_operand 5 "memory_operand" ""))
18684                   (const_int 0)))
18685               (use (match_operand:SI 3 "immediate_operand" ""))
18686               (use (reg:CC FLAGS_REG))
18687               (use (reg:SI DIRFLAG_REG))
18688               (clobber (match_operand 0 "register_operand" ""))
18689               (clobber (match_operand 1 "register_operand" ""))
18690               (clobber (match_dup 2))])]
18691   ""
18692   "")
18693
18694 (define_insn "*cmpstrnqi_1"
18695   [(set (reg:CC FLAGS_REG)
18696         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18697                              (const_int 0))
18698           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18699                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18700           (const_int 0)))
18701    (use (match_operand:SI 3 "immediate_operand" "i"))
18702    (use (reg:CC FLAGS_REG))
18703    (use (reg:SI DIRFLAG_REG))
18704    (clobber (match_operand:SI 0 "register_operand" "=S"))
18705    (clobber (match_operand:SI 1 "register_operand" "=D"))
18706    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18707   "!TARGET_64BIT"
18708   "repz{\;| }cmpsb"
18709   [(set_attr "type" "str")
18710    (set_attr "mode" "QI")
18711    (set_attr "prefix_rep" "1")])
18712
18713 (define_insn "*cmpstrnqi_rex_1"
18714   [(set (reg:CC FLAGS_REG)
18715         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18716                              (const_int 0))
18717           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18718                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18719           (const_int 0)))
18720    (use (match_operand:SI 3 "immediate_operand" "i"))
18721    (use (reg:CC FLAGS_REG))
18722    (use (reg:SI DIRFLAG_REG))
18723    (clobber (match_operand:DI 0 "register_operand" "=S"))
18724    (clobber (match_operand:DI 1 "register_operand" "=D"))
18725    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18726   "TARGET_64BIT"
18727   "repz{\;| }cmpsb"
18728   [(set_attr "type" "str")
18729    (set_attr "mode" "QI")
18730    (set_attr "prefix_rep" "1")])
18731
18732 (define_expand "strlensi"
18733   [(set (match_operand:SI 0 "register_operand" "")
18734         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18735                     (match_operand:QI 2 "immediate_operand" "")
18736                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18737   ""
18738 {
18739  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18740    DONE;
18741  else
18742    FAIL;
18743 })
18744
18745 (define_expand "strlendi"
18746   [(set (match_operand:DI 0 "register_operand" "")
18747         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18748                     (match_operand:QI 2 "immediate_operand" "")
18749                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18750   ""
18751 {
18752  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18753    DONE;
18754  else
18755    FAIL;
18756 })
18757
18758 (define_expand "strlenqi_1"
18759   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18760               (use (reg:SI DIRFLAG_REG))
18761               (clobber (match_operand 1 "register_operand" ""))
18762               (clobber (reg:CC FLAGS_REG))])]
18763   ""
18764   "")
18765
18766 (define_insn "*strlenqi_1"
18767   [(set (match_operand:SI 0 "register_operand" "=&c")
18768         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18769                     (match_operand:QI 2 "register_operand" "a")
18770                     (match_operand:SI 3 "immediate_operand" "i")
18771                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18772    (use (reg:SI DIRFLAG_REG))
18773    (clobber (match_operand:SI 1 "register_operand" "=D"))
18774    (clobber (reg:CC FLAGS_REG))]
18775   "!TARGET_64BIT"
18776   "repnz{\;| }scasb"
18777   [(set_attr "type" "str")
18778    (set_attr "mode" "QI")
18779    (set_attr "prefix_rep" "1")])
18780
18781 (define_insn "*strlenqi_rex_1"
18782   [(set (match_operand:DI 0 "register_operand" "=&c")
18783         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18784                     (match_operand:QI 2 "register_operand" "a")
18785                     (match_operand:DI 3 "immediate_operand" "i")
18786                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18787    (use (reg:SI DIRFLAG_REG))
18788    (clobber (match_operand:DI 1 "register_operand" "=D"))
18789    (clobber (reg:CC FLAGS_REG))]
18790   "TARGET_64BIT"
18791   "repnz{\;| }scasb"
18792   [(set_attr "type" "str")
18793    (set_attr "mode" "QI")
18794    (set_attr "prefix_rep" "1")])
18795
18796 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18797 ;; handled in combine, but it is not currently up to the task.
18798 ;; When used for their truth value, the cmpstrn* expanders generate
18799 ;; code like this:
18800 ;;
18801 ;;   repz cmpsb
18802 ;;   seta       %al
18803 ;;   setb       %dl
18804 ;;   cmpb       %al, %dl
18805 ;;   jcc        label
18806 ;;
18807 ;; The intermediate three instructions are unnecessary.
18808
18809 ;; This one handles cmpstrn*_nz_1...
18810 (define_peephole2
18811   [(parallel[
18812      (set (reg:CC FLAGS_REG)
18813           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814                       (mem:BLK (match_operand 5 "register_operand" ""))))
18815      (use (match_operand 6 "register_operand" ""))
18816      (use (match_operand:SI 3 "immediate_operand" ""))
18817      (use (reg:SI DIRFLAG_REG))
18818      (clobber (match_operand 0 "register_operand" ""))
18819      (clobber (match_operand 1 "register_operand" ""))
18820      (clobber (match_operand 2 "register_operand" ""))])
18821    (set (match_operand:QI 7 "register_operand" "")
18822         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18823    (set (match_operand:QI 8 "register_operand" "")
18824         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18825    (set (reg FLAGS_REG)
18826         (compare (match_dup 7) (match_dup 8)))
18827   ]
18828   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18829   [(parallel[
18830      (set (reg:CC FLAGS_REG)
18831           (compare:CC (mem:BLK (match_dup 4))
18832                       (mem:BLK (match_dup 5))))
18833      (use (match_dup 6))
18834      (use (match_dup 3))
18835      (use (reg:SI DIRFLAG_REG))
18836      (clobber (match_dup 0))
18837      (clobber (match_dup 1))
18838      (clobber (match_dup 2))])]
18839   "")
18840
18841 ;; ...and this one handles cmpstrn*_1.
18842 (define_peephole2
18843   [(parallel[
18844      (set (reg:CC FLAGS_REG)
18845           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18846                                (const_int 0))
18847             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18848                         (mem:BLK (match_operand 5 "register_operand" "")))
18849             (const_int 0)))
18850      (use (match_operand:SI 3 "immediate_operand" ""))
18851      (use (reg:CC FLAGS_REG))
18852      (use (reg:SI DIRFLAG_REG))
18853      (clobber (match_operand 0 "register_operand" ""))
18854      (clobber (match_operand 1 "register_operand" ""))
18855      (clobber (match_operand 2 "register_operand" ""))])
18856    (set (match_operand:QI 7 "register_operand" "")
18857         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18858    (set (match_operand:QI 8 "register_operand" "")
18859         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18860    (set (reg FLAGS_REG)
18861         (compare (match_dup 7) (match_dup 8)))
18862   ]
18863   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18864   [(parallel[
18865      (set (reg:CC FLAGS_REG)
18866           (if_then_else:CC (ne (match_dup 6)
18867                                (const_int 0))
18868             (compare:CC (mem:BLK (match_dup 4))
18869                         (mem:BLK (match_dup 5)))
18870             (const_int 0)))
18871      (use (match_dup 3))
18872      (use (reg:CC FLAGS_REG))
18873      (use (reg:SI DIRFLAG_REG))
18874      (clobber (match_dup 0))
18875      (clobber (match_dup 1))
18876      (clobber (match_dup 2))])]
18877   "")
18878
18879
18880 \f
18881 ;; Conditional move instructions.
18882
18883 (define_expand "movdicc"
18884   [(set (match_operand:DI 0 "register_operand" "")
18885         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18886                          (match_operand:DI 2 "general_operand" "")
18887                          (match_operand:DI 3 "general_operand" "")))]
18888   "TARGET_64BIT"
18889   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18890
18891 (define_insn "x86_movdicc_0_m1_rex64"
18892   [(set (match_operand:DI 0 "register_operand" "=r")
18893         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18894           (const_int -1)
18895           (const_int 0)))
18896    (clobber (reg:CC FLAGS_REG))]
18897   "TARGET_64BIT"
18898   "sbb{q}\t%0, %0"
18899   ; Since we don't have the proper number of operands for an alu insn,
18900   ; fill in all the blanks.
18901   [(set_attr "type" "alu")
18902    (set_attr "pent_pair" "pu")
18903    (set_attr "memory" "none")
18904    (set_attr "imm_disp" "false")
18905    (set_attr "mode" "DI")
18906    (set_attr "length_immediate" "0")])
18907
18908 (define_insn "*movdicc_c_rex64"
18909   [(set (match_operand:DI 0 "register_operand" "=r,r")
18910         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18911                                 [(reg FLAGS_REG) (const_int 0)])
18912                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18913                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18914   "TARGET_64BIT && TARGET_CMOVE
18915    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18916   "@
18917    cmov%O2%C1\t{%2, %0|%0, %2}
18918    cmov%O2%c1\t{%3, %0|%0, %3}"
18919   [(set_attr "type" "icmov")
18920    (set_attr "mode" "DI")])
18921
18922 (define_expand "movsicc"
18923   [(set (match_operand:SI 0 "register_operand" "")
18924         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18925                          (match_operand:SI 2 "general_operand" "")
18926                          (match_operand:SI 3 "general_operand" "")))]
18927   ""
18928   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18929
18930 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18931 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18932 ;; So just document what we're doing explicitly.
18933
18934 (define_insn "x86_movsicc_0_m1"
18935   [(set (match_operand:SI 0 "register_operand" "=r")
18936         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18937           (const_int -1)
18938           (const_int 0)))
18939    (clobber (reg:CC FLAGS_REG))]
18940   ""
18941   "sbb{l}\t%0, %0"
18942   ; Since we don't have the proper number of operands for an alu insn,
18943   ; fill in all the blanks.
18944   [(set_attr "type" "alu")
18945    (set_attr "pent_pair" "pu")
18946    (set_attr "memory" "none")
18947    (set_attr "imm_disp" "false")
18948    (set_attr "mode" "SI")
18949    (set_attr "length_immediate" "0")])
18950
18951 (define_insn "*movsicc_noc"
18952   [(set (match_operand:SI 0 "register_operand" "=r,r")
18953         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18954                                 [(reg FLAGS_REG) (const_int 0)])
18955                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18956                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18957   "TARGET_CMOVE
18958    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18959   "@
18960    cmov%O2%C1\t{%2, %0|%0, %2}
18961    cmov%O2%c1\t{%3, %0|%0, %3}"
18962   [(set_attr "type" "icmov")
18963    (set_attr "mode" "SI")])
18964
18965 (define_expand "movhicc"
18966   [(set (match_operand:HI 0 "register_operand" "")
18967         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18968                          (match_operand:HI 2 "general_operand" "")
18969                          (match_operand:HI 3 "general_operand" "")))]
18970   "TARGET_HIMODE_MATH"
18971   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18972
18973 (define_insn "*movhicc_noc"
18974   [(set (match_operand:HI 0 "register_operand" "=r,r")
18975         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18976                                 [(reg FLAGS_REG) (const_int 0)])
18977                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18978                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18979   "TARGET_CMOVE
18980    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18981   "@
18982    cmov%O2%C1\t{%2, %0|%0, %2}
18983    cmov%O2%c1\t{%3, %0|%0, %3}"
18984   [(set_attr "type" "icmov")
18985    (set_attr "mode" "HI")])
18986
18987 (define_expand "movqicc"
18988   [(set (match_operand:QI 0 "register_operand" "")
18989         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18990                          (match_operand:QI 2 "general_operand" "")
18991                          (match_operand:QI 3 "general_operand" "")))]
18992   "TARGET_QIMODE_MATH"
18993   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18994
18995 (define_insn_and_split "*movqicc_noc"
18996   [(set (match_operand:QI 0 "register_operand" "=r,r")
18997         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18998                                 [(match_operand 4 "flags_reg_operand" "")
18999                                  (const_int 0)])
19000                       (match_operand:QI 2 "register_operand" "r,0")
19001                       (match_operand:QI 3 "register_operand" "0,r")))]
19002   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19003   "#"
19004   "&& reload_completed"
19005   [(set (match_dup 0)
19006         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19007                       (match_dup 2)
19008                       (match_dup 3)))]
19009   "operands[0] = gen_lowpart (SImode, operands[0]);
19010    operands[2] = gen_lowpart (SImode, operands[2]);
19011    operands[3] = gen_lowpart (SImode, operands[3]);"
19012   [(set_attr "type" "icmov")
19013    (set_attr "mode" "SI")])
19014
19015 (define_expand "movsfcc"
19016   [(set (match_operand:SF 0 "register_operand" "")
19017         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19018                          (match_operand:SF 2 "register_operand" "")
19019                          (match_operand:SF 3 "register_operand" "")))]
19020   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19021   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19022
19023 (define_insn "*movsfcc_1_387"
19024   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19025         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19026                                 [(reg FLAGS_REG) (const_int 0)])
19027                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19028                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19029   "TARGET_80387 && TARGET_CMOVE
19030    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19031   "@
19032    fcmov%F1\t{%2, %0|%0, %2}
19033    fcmov%f1\t{%3, %0|%0, %3}
19034    cmov%O2%C1\t{%2, %0|%0, %2}
19035    cmov%O2%c1\t{%3, %0|%0, %3}"
19036   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19037    (set_attr "mode" "SF,SF,SI,SI")])
19038
19039 (define_expand "movdfcc"
19040   [(set (match_operand:DF 0 "register_operand" "")
19041         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19042                          (match_operand:DF 2 "register_operand" "")
19043                          (match_operand:DF 3 "register_operand" "")))]
19044   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19045   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19046
19047 (define_insn "*movdfcc_1"
19048   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19049         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19050                                 [(reg FLAGS_REG) (const_int 0)])
19051                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19052                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19053   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19054    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19055   "@
19056    fcmov%F1\t{%2, %0|%0, %2}
19057    fcmov%f1\t{%3, %0|%0, %3}
19058    #
19059    #"
19060   [(set_attr "type" "fcmov,fcmov,multi,multi")
19061    (set_attr "mode" "DF")])
19062
19063 (define_insn "*movdfcc_1_rex64"
19064   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19065         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19066                                 [(reg FLAGS_REG) (const_int 0)])
19067                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19068                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19069   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19070    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19071   "@
19072    fcmov%F1\t{%2, %0|%0, %2}
19073    fcmov%f1\t{%3, %0|%0, %3}
19074    cmov%O2%C1\t{%2, %0|%0, %2}
19075    cmov%O2%c1\t{%3, %0|%0, %3}"
19076   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19077    (set_attr "mode" "DF")])
19078
19079 (define_split
19080   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19081         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19082                                 [(match_operand 4 "flags_reg_operand" "")
19083                                  (const_int 0)])
19084                       (match_operand:DF 2 "nonimmediate_operand" "")
19085                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19086   "!TARGET_64BIT && reload_completed"
19087   [(set (match_dup 2)
19088         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19089                       (match_dup 5)
19090                       (match_dup 7)))
19091    (set (match_dup 3)
19092         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19093                       (match_dup 6)
19094                       (match_dup 8)))]
19095   "split_di (operands+2, 1, operands+5, operands+6);
19096    split_di (operands+3, 1, operands+7, operands+8);
19097    split_di (operands, 1, operands+2, operands+3);")
19098
19099 (define_expand "movxfcc"
19100   [(set (match_operand:XF 0 "register_operand" "")
19101         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19102                          (match_operand:XF 2 "register_operand" "")
19103                          (match_operand:XF 3 "register_operand" "")))]
19104   "TARGET_80387 && TARGET_CMOVE"
19105   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19106
19107 (define_insn "*movxfcc_1"
19108   [(set (match_operand:XF 0 "register_operand" "=f,f")
19109         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19110                                 [(reg FLAGS_REG) (const_int 0)])
19111                       (match_operand:XF 2 "register_operand" "f,0")
19112                       (match_operand:XF 3 "register_operand" "0,f")))]
19113   "TARGET_80387 && TARGET_CMOVE"
19114   "@
19115    fcmov%F1\t{%2, %0|%0, %2}
19116    fcmov%f1\t{%3, %0|%0, %3}"
19117   [(set_attr "type" "fcmov")
19118    (set_attr "mode" "XF")])
19119
19120 ;; These versions of the min/max patterns are intentionally ignorant of
19121 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19122 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19123 ;; are undefined in this condition, we're certain this is correct.
19124
19125 (define_insn "sminsf3"
19126   [(set (match_operand:SF 0 "register_operand" "=x")
19127         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19128                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19129   "TARGET_SSE_MATH"
19130   "minss\t{%2, %0|%0, %2}"
19131   [(set_attr "type" "sseadd")
19132    (set_attr "mode" "SF")])
19133
19134 (define_insn "smaxsf3"
19135   [(set (match_operand:SF 0 "register_operand" "=x")
19136         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19137                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19138   "TARGET_SSE_MATH"
19139   "maxss\t{%2, %0|%0, %2}"
19140   [(set_attr "type" "sseadd")
19141    (set_attr "mode" "SF")])
19142
19143 (define_insn "smindf3"
19144   [(set (match_operand:DF 0 "register_operand" "=x")
19145         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19146                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19147   "TARGET_SSE2 && TARGET_SSE_MATH"
19148   "minsd\t{%2, %0|%0, %2}"
19149   [(set_attr "type" "sseadd")
19150    (set_attr "mode" "DF")])
19151
19152 (define_insn "smaxdf3"
19153   [(set (match_operand:DF 0 "register_operand" "=x")
19154         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19155                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19156   "TARGET_SSE2 && TARGET_SSE_MATH"
19157   "maxsd\t{%2, %0|%0, %2}"
19158   [(set_attr "type" "sseadd")
19159    (set_attr "mode" "DF")])
19160
19161 ;; These versions of the min/max patterns implement exactly the operations
19162 ;;   min = (op1 < op2 ? op1 : op2)
19163 ;;   max = (!(op1 < op2) ? op1 : op2)
19164 ;; Their operands are not commutative, and thus they may be used in the
19165 ;; presence of -0.0 and NaN.
19166
19167 (define_insn "*ieee_sminsf3"
19168   [(set (match_operand:SF 0 "register_operand" "=x")
19169         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19170                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19171                    UNSPEC_IEEE_MIN))]
19172   "TARGET_SSE_MATH"
19173   "minss\t{%2, %0|%0, %2}"
19174   [(set_attr "type" "sseadd")
19175    (set_attr "mode" "SF")])
19176
19177 (define_insn "*ieee_smaxsf3"
19178   [(set (match_operand:SF 0 "register_operand" "=x")
19179         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19180                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19181                    UNSPEC_IEEE_MAX))]
19182   "TARGET_SSE_MATH"
19183   "maxss\t{%2, %0|%0, %2}"
19184   [(set_attr "type" "sseadd")
19185    (set_attr "mode" "SF")])
19186
19187 (define_insn "*ieee_smindf3"
19188   [(set (match_operand:DF 0 "register_operand" "=x")
19189         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19190                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19191                    UNSPEC_IEEE_MIN))]
19192   "TARGET_SSE2 && TARGET_SSE_MATH"
19193   "minsd\t{%2, %0|%0, %2}"
19194   [(set_attr "type" "sseadd")
19195    (set_attr "mode" "DF")])
19196
19197 (define_insn "*ieee_smaxdf3"
19198   [(set (match_operand:DF 0 "register_operand" "=x")
19199         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19200                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19201                    UNSPEC_IEEE_MAX))]
19202   "TARGET_SSE2 && TARGET_SSE_MATH"
19203   "maxsd\t{%2, %0|%0, %2}"
19204   [(set_attr "type" "sseadd")
19205    (set_attr "mode" "DF")])
19206
19207 ;; Make two stack loads independent:
19208 ;;   fld aa              fld aa
19209 ;;   fld %st(0)     ->   fld bb
19210 ;;   fmul bb             fmul %st(1), %st
19211 ;;
19212 ;; Actually we only match the last two instructions for simplicity.
19213 (define_peephole2
19214   [(set (match_operand 0 "fp_register_operand" "")
19215         (match_operand 1 "fp_register_operand" ""))
19216    (set (match_dup 0)
19217         (match_operator 2 "binary_fp_operator"
19218            [(match_dup 0)
19219             (match_operand 3 "memory_operand" "")]))]
19220   "REGNO (operands[0]) != REGNO (operands[1])"
19221   [(set (match_dup 0) (match_dup 3))
19222    (set (match_dup 0) (match_dup 4))]
19223
19224   ;; The % modifier is not operational anymore in peephole2's, so we have to
19225   ;; swap the operands manually in the case of addition and multiplication.
19226   "if (COMMUTATIVE_ARITH_P (operands[2]))
19227      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19228                                  operands[0], operands[1]);
19229    else
19230      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19231                                  operands[1], operands[0]);")
19232
19233 ;; Conditional addition patterns
19234 (define_expand "addqicc"
19235   [(match_operand:QI 0 "register_operand" "")
19236    (match_operand 1 "comparison_operator" "")
19237    (match_operand:QI 2 "register_operand" "")
19238    (match_operand:QI 3 "const_int_operand" "")]
19239   ""
19240   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19241
19242 (define_expand "addhicc"
19243   [(match_operand:HI 0 "register_operand" "")
19244    (match_operand 1 "comparison_operator" "")
19245    (match_operand:HI 2 "register_operand" "")
19246    (match_operand:HI 3 "const_int_operand" "")]
19247   ""
19248   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19249
19250 (define_expand "addsicc"
19251   [(match_operand:SI 0 "register_operand" "")
19252    (match_operand 1 "comparison_operator" "")
19253    (match_operand:SI 2 "register_operand" "")
19254    (match_operand:SI 3 "const_int_operand" "")]
19255   ""
19256   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19257
19258 (define_expand "adddicc"
19259   [(match_operand:DI 0 "register_operand" "")
19260    (match_operand 1 "comparison_operator" "")
19261    (match_operand:DI 2 "register_operand" "")
19262    (match_operand:DI 3 "const_int_operand" "")]
19263   "TARGET_64BIT"
19264   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19265
19266 \f
19267 ;; Misc patterns (?)
19268
19269 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19270 ;; Otherwise there will be nothing to keep
19271 ;; 
19272 ;; [(set (reg ebp) (reg esp))]
19273 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19274 ;;  (clobber (eflags)]
19275 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19276 ;;
19277 ;; in proper program order.
19278 (define_insn "pro_epilogue_adjust_stack_1"
19279   [(set (match_operand:SI 0 "register_operand" "=r,r")
19280         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19281                  (match_operand:SI 2 "immediate_operand" "i,i")))
19282    (clobber (reg:CC FLAGS_REG))
19283    (clobber (mem:BLK (scratch)))]
19284   "!TARGET_64BIT"
19285 {
19286   switch (get_attr_type (insn))
19287     {
19288     case TYPE_IMOV:
19289       return "mov{l}\t{%1, %0|%0, %1}";
19290
19291     case TYPE_ALU:
19292       if (GET_CODE (operands[2]) == CONST_INT
19293           && (INTVAL (operands[2]) == 128
19294               || (INTVAL (operands[2]) < 0
19295                   && INTVAL (operands[2]) != -128)))
19296         {
19297           operands[2] = GEN_INT (-INTVAL (operands[2]));
19298           return "sub{l}\t{%2, %0|%0, %2}";
19299         }
19300       return "add{l}\t{%2, %0|%0, %2}";
19301
19302     case TYPE_LEA:
19303       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19304       return "lea{l}\t{%a2, %0|%0, %a2}";
19305
19306     default:
19307       gcc_unreachable ();
19308     }
19309 }
19310   [(set (attr "type")
19311         (cond [(eq_attr "alternative" "0")
19312                  (const_string "alu")
19313                (match_operand:SI 2 "const0_operand" "")
19314                  (const_string "imov")
19315               ]
19316               (const_string "lea")))
19317    (set_attr "mode" "SI")])
19318
19319 (define_insn "pro_epilogue_adjust_stack_rex64"
19320   [(set (match_operand:DI 0 "register_operand" "=r,r")
19321         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19322                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19323    (clobber (reg:CC FLAGS_REG))
19324    (clobber (mem:BLK (scratch)))]
19325   "TARGET_64BIT"
19326 {
19327   switch (get_attr_type (insn))
19328     {
19329     case TYPE_IMOV:
19330       return "mov{q}\t{%1, %0|%0, %1}";
19331
19332     case TYPE_ALU:
19333       if (GET_CODE (operands[2]) == CONST_INT
19334           /* Avoid overflows.  */
19335           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19336           && (INTVAL (operands[2]) == 128
19337               || (INTVAL (operands[2]) < 0
19338                   && INTVAL (operands[2]) != -128)))
19339         {
19340           operands[2] = GEN_INT (-INTVAL (operands[2]));
19341           return "sub{q}\t{%2, %0|%0, %2}";
19342         }
19343       return "add{q}\t{%2, %0|%0, %2}";
19344
19345     case TYPE_LEA:
19346       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19347       return "lea{q}\t{%a2, %0|%0, %a2}";
19348
19349     default:
19350       gcc_unreachable ();
19351     }
19352 }
19353   [(set (attr "type")
19354         (cond [(eq_attr "alternative" "0")
19355                  (const_string "alu")
19356                (match_operand:DI 2 "const0_operand" "")
19357                  (const_string "imov")
19358               ]
19359               (const_string "lea")))
19360    (set_attr "mode" "DI")])
19361
19362 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19363   [(set (match_operand:DI 0 "register_operand" "=r,r")
19364         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19365                  (match_operand:DI 3 "immediate_operand" "i,i")))
19366    (use (match_operand:DI 2 "register_operand" "r,r"))
19367    (clobber (reg:CC FLAGS_REG))
19368    (clobber (mem:BLK (scratch)))]
19369   "TARGET_64BIT"
19370 {
19371   switch (get_attr_type (insn))
19372     {
19373     case TYPE_ALU:
19374       return "add{q}\t{%2, %0|%0, %2}";
19375
19376     case TYPE_LEA:
19377       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19378       return "lea{q}\t{%a2, %0|%0, %a2}";
19379
19380     default:
19381       gcc_unreachable ();
19382     }
19383 }
19384   [(set_attr "type" "alu,lea")
19385    (set_attr "mode" "DI")])
19386
19387 (define_expand "allocate_stack_worker"
19388   [(match_operand:SI 0 "register_operand" "")]
19389   "TARGET_STACK_PROBE"
19390 {
19391   if (reload_completed)
19392     {
19393       if (TARGET_64BIT)
19394         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19395       else
19396         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19397     }
19398   else
19399     {
19400       if (TARGET_64BIT)
19401         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19402       else
19403         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19404     }
19405   DONE;
19406 })
19407
19408 (define_insn "allocate_stack_worker_1"
19409   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19410     UNSPECV_STACK_PROBE)
19411    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19412    (clobber (match_scratch:SI 1 "=0"))
19413    (clobber (reg:CC FLAGS_REG))]
19414   "!TARGET_64BIT && TARGET_STACK_PROBE"
19415   "call\t__alloca"
19416   [(set_attr "type" "multi")
19417    (set_attr "length" "5")])
19418
19419 (define_expand "allocate_stack_worker_postreload"
19420   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19421                                     UNSPECV_STACK_PROBE)
19422               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19423               (clobber (match_dup 0))
19424               (clobber (reg:CC FLAGS_REG))])]
19425   ""
19426   "")
19427
19428 (define_insn "allocate_stack_worker_rex64"
19429   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19430     UNSPECV_STACK_PROBE)
19431    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19432    (clobber (match_scratch:DI 1 "=0"))
19433    (clobber (reg:CC FLAGS_REG))]
19434   "TARGET_64BIT && TARGET_STACK_PROBE"
19435   "call\t__alloca"
19436   [(set_attr "type" "multi")
19437    (set_attr "length" "5")])
19438
19439 (define_expand "allocate_stack_worker_rex64_postreload"
19440   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19441                                     UNSPECV_STACK_PROBE)
19442               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19443               (clobber (match_dup 0))
19444               (clobber (reg:CC FLAGS_REG))])]
19445   ""
19446   "")
19447
19448 (define_expand "allocate_stack"
19449   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19450                    (minus:SI (reg:SI SP_REG)
19451                              (match_operand:SI 1 "general_operand" "")))
19452               (clobber (reg:CC FLAGS_REG))])
19453    (parallel [(set (reg:SI SP_REG)
19454                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "TARGET_STACK_PROBE"
19457 {
19458 #ifdef CHECK_STACK_LIMIT
19459   if (GET_CODE (operands[1]) == CONST_INT
19460       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19461     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19462                            operands[1]));
19463   else 
19464 #endif
19465     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19466                                                             operands[1])));
19467
19468   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19469   DONE;
19470 })
19471
19472 (define_expand "builtin_setjmp_receiver"
19473   [(label_ref (match_operand 0 "" ""))]
19474   "!TARGET_64BIT && flag_pic"
19475 {
19476   if (TARGET_MACHO)
19477     {
19478       rtx xops[3];
19479       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19480       rtx label_rtx = gen_label_rtx ();
19481       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19482       xops[0] = xops[1] = picreg;
19483       xops[2] = gen_rtx_CONST (SImode,
19484                   gen_rtx_MINUS (SImode,
19485                     gen_rtx_LABEL_REF (SImode, label_rtx),
19486                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19487       ix86_expand_binary_operator (MINUS, SImode, xops);
19488     }
19489   else
19490     emit_insn (gen_set_got (pic_offset_table_rtx));
19491   DONE;
19492 })
19493 \f
19494 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19495
19496 (define_split
19497   [(set (match_operand 0 "register_operand" "")
19498         (match_operator 3 "promotable_binary_operator"
19499            [(match_operand 1 "register_operand" "")
19500             (match_operand 2 "aligned_operand" "")]))
19501    (clobber (reg:CC FLAGS_REG))]
19502   "! TARGET_PARTIAL_REG_STALL && reload_completed
19503    && ((GET_MODE (operands[0]) == HImode 
19504         && ((!optimize_size && !TARGET_FAST_PREFIX)
19505             /* ??? next two lines just !satisfies_constraint_K (...) */
19506             || GET_CODE (operands[2]) != CONST_INT
19507             || satisfies_constraint_K (operands[2])))
19508        || (GET_MODE (operands[0]) == QImode 
19509            && (TARGET_PROMOTE_QImode || optimize_size)))"
19510   [(parallel [(set (match_dup 0)
19511                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19512               (clobber (reg:CC FLAGS_REG))])]
19513   "operands[0] = gen_lowpart (SImode, operands[0]);
19514    operands[1] = gen_lowpart (SImode, operands[1]);
19515    if (GET_CODE (operands[3]) != ASHIFT)
19516      operands[2] = gen_lowpart (SImode, operands[2]);
19517    PUT_MODE (operands[3], SImode);")
19518
19519 ; Promote the QImode tests, as i386 has encoding of the AND
19520 ; instruction with 32-bit sign-extended immediate and thus the
19521 ; instruction size is unchanged, except in the %eax case for
19522 ; which it is increased by one byte, hence the ! optimize_size.
19523 (define_split
19524   [(set (match_operand 0 "flags_reg_operand" "")
19525         (match_operator 2 "compare_operator"
19526           [(and (match_operand 3 "aligned_operand" "")
19527                 (match_operand 4 "const_int_operand" ""))
19528            (const_int 0)]))
19529    (set (match_operand 1 "register_operand" "")
19530         (and (match_dup 3) (match_dup 4)))]
19531   "! TARGET_PARTIAL_REG_STALL && reload_completed
19532    /* Ensure that the operand will remain sign-extended immediate.  */
19533    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19534    && ! optimize_size
19535    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19536        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19537   [(parallel [(set (match_dup 0)
19538                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19539                                     (const_int 0)]))
19540               (set (match_dup 1)
19541                    (and:SI (match_dup 3) (match_dup 4)))])]
19542 {
19543   operands[4]
19544     = gen_int_mode (INTVAL (operands[4])
19545                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19546   operands[1] = gen_lowpart (SImode, operands[1]);
19547   operands[3] = gen_lowpart (SImode, operands[3]);
19548 })
19549
19550 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19551 ; the TEST instruction with 32-bit sign-extended immediate and thus
19552 ; the instruction size would at least double, which is not what we
19553 ; want even with ! optimize_size.
19554 (define_split
19555   [(set (match_operand 0 "flags_reg_operand" "")
19556         (match_operator 1 "compare_operator"
19557           [(and (match_operand:HI 2 "aligned_operand" "")
19558                 (match_operand:HI 3 "const_int_operand" ""))
19559            (const_int 0)]))]
19560   "! TARGET_PARTIAL_REG_STALL && reload_completed
19561    /* Ensure that the operand will remain sign-extended immediate.  */
19562    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19563    && ! TARGET_FAST_PREFIX
19564    && ! optimize_size"
19565   [(set (match_dup 0)
19566         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19567                          (const_int 0)]))]
19568 {
19569   operands[3]
19570     = gen_int_mode (INTVAL (operands[3])
19571                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19572   operands[2] = gen_lowpart (SImode, operands[2]);
19573 })
19574
19575 (define_split
19576   [(set (match_operand 0 "register_operand" "")
19577         (neg (match_operand 1 "register_operand" "")))
19578    (clobber (reg:CC FLAGS_REG))]
19579   "! TARGET_PARTIAL_REG_STALL && reload_completed
19580    && (GET_MODE (operands[0]) == HImode
19581        || (GET_MODE (operands[0]) == QImode 
19582            && (TARGET_PROMOTE_QImode || optimize_size)))"
19583   [(parallel [(set (match_dup 0)
19584                    (neg:SI (match_dup 1)))
19585               (clobber (reg:CC FLAGS_REG))])]
19586   "operands[0] = gen_lowpart (SImode, operands[0]);
19587    operands[1] = gen_lowpart (SImode, operands[1]);")
19588
19589 (define_split
19590   [(set (match_operand 0 "register_operand" "")
19591         (not (match_operand 1 "register_operand" "")))]
19592   "! TARGET_PARTIAL_REG_STALL && reload_completed
19593    && (GET_MODE (operands[0]) == HImode
19594        || (GET_MODE (operands[0]) == QImode 
19595            && (TARGET_PROMOTE_QImode || optimize_size)))"
19596   [(set (match_dup 0)
19597         (not:SI (match_dup 1)))]
19598   "operands[0] = gen_lowpart (SImode, operands[0]);
19599    operands[1] = gen_lowpart (SImode, operands[1]);")
19600
19601 (define_split 
19602   [(set (match_operand 0 "register_operand" "")
19603         (if_then_else (match_operator 1 "comparison_operator" 
19604                                 [(reg FLAGS_REG) (const_int 0)])
19605                       (match_operand 2 "register_operand" "")
19606                       (match_operand 3 "register_operand" "")))]
19607   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19608    && (GET_MODE (operands[0]) == HImode
19609        || (GET_MODE (operands[0]) == QImode 
19610            && (TARGET_PROMOTE_QImode || optimize_size)))"
19611   [(set (match_dup 0)
19612         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19613   "operands[0] = gen_lowpart (SImode, operands[0]);
19614    operands[2] = gen_lowpart (SImode, operands[2]);
19615    operands[3] = gen_lowpart (SImode, operands[3]);")
19616                         
19617 \f
19618 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19619 ;; transform a complex memory operation into two memory to register operations.
19620
19621 ;; Don't push memory operands
19622 (define_peephole2
19623   [(set (match_operand:SI 0 "push_operand" "")
19624         (match_operand:SI 1 "memory_operand" ""))
19625    (match_scratch:SI 2 "r")]
19626   "!optimize_size && !TARGET_PUSH_MEMORY
19627    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19628   [(set (match_dup 2) (match_dup 1))
19629    (set (match_dup 0) (match_dup 2))]
19630   "")
19631
19632 (define_peephole2
19633   [(set (match_operand:DI 0 "push_operand" "")
19634         (match_operand:DI 1 "memory_operand" ""))
19635    (match_scratch:DI 2 "r")]
19636   "!optimize_size && !TARGET_PUSH_MEMORY
19637    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19638   [(set (match_dup 2) (match_dup 1))
19639    (set (match_dup 0) (match_dup 2))]
19640   "")
19641
19642 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19643 ;; SImode pushes.
19644 (define_peephole2
19645   [(set (match_operand:SF 0 "push_operand" "")
19646         (match_operand:SF 1 "memory_operand" ""))
19647    (match_scratch:SF 2 "r")]
19648   "!optimize_size && !TARGET_PUSH_MEMORY
19649    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19650   [(set (match_dup 2) (match_dup 1))
19651    (set (match_dup 0) (match_dup 2))]
19652   "")
19653
19654 (define_peephole2
19655   [(set (match_operand:HI 0 "push_operand" "")
19656         (match_operand:HI 1 "memory_operand" ""))
19657    (match_scratch:HI 2 "r")]
19658   "!optimize_size && !TARGET_PUSH_MEMORY
19659    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19660   [(set (match_dup 2) (match_dup 1))
19661    (set (match_dup 0) (match_dup 2))]
19662   "")
19663
19664 (define_peephole2
19665   [(set (match_operand:QI 0 "push_operand" "")
19666         (match_operand:QI 1 "memory_operand" ""))
19667    (match_scratch:QI 2 "q")]
19668   "!optimize_size && !TARGET_PUSH_MEMORY
19669    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19670   [(set (match_dup 2) (match_dup 1))
19671    (set (match_dup 0) (match_dup 2))]
19672   "")
19673
19674 ;; Don't move an immediate directly to memory when the instruction
19675 ;; gets too big.
19676 (define_peephole2
19677   [(match_scratch:SI 1 "r")
19678    (set (match_operand:SI 0 "memory_operand" "")
19679         (const_int 0))]
19680   "! optimize_size
19681    && ! TARGET_USE_MOV0
19682    && TARGET_SPLIT_LONG_MOVES
19683    && get_attr_length (insn) >= ix86_cost->large_insn
19684    && peep2_regno_dead_p (0, FLAGS_REG)"
19685   [(parallel [(set (match_dup 1) (const_int 0))
19686               (clobber (reg:CC FLAGS_REG))])
19687    (set (match_dup 0) (match_dup 1))]
19688   "")
19689
19690 (define_peephole2
19691   [(match_scratch:HI 1 "r")
19692    (set (match_operand:HI 0 "memory_operand" "")
19693         (const_int 0))]
19694   "! optimize_size
19695    && ! TARGET_USE_MOV0
19696    && TARGET_SPLIT_LONG_MOVES
19697    && get_attr_length (insn) >= ix86_cost->large_insn
19698    && peep2_regno_dead_p (0, FLAGS_REG)"
19699   [(parallel [(set (match_dup 2) (const_int 0))
19700               (clobber (reg:CC FLAGS_REG))])
19701    (set (match_dup 0) (match_dup 1))]
19702   "operands[2] = gen_lowpart (SImode, operands[1]);")
19703
19704 (define_peephole2
19705   [(match_scratch:QI 1 "q")
19706    (set (match_operand:QI 0 "memory_operand" "")
19707         (const_int 0))]
19708   "! optimize_size
19709    && ! TARGET_USE_MOV0
19710    && TARGET_SPLIT_LONG_MOVES
19711    && get_attr_length (insn) >= ix86_cost->large_insn
19712    && peep2_regno_dead_p (0, FLAGS_REG)"
19713   [(parallel [(set (match_dup 2) (const_int 0))
19714               (clobber (reg:CC FLAGS_REG))])
19715    (set (match_dup 0) (match_dup 1))]
19716   "operands[2] = gen_lowpart (SImode, operands[1]);")
19717
19718 (define_peephole2
19719   [(match_scratch:SI 2 "r")
19720    (set (match_operand:SI 0 "memory_operand" "")
19721         (match_operand:SI 1 "immediate_operand" ""))]
19722   "! optimize_size
19723    && get_attr_length (insn) >= ix86_cost->large_insn
19724    && TARGET_SPLIT_LONG_MOVES"
19725   [(set (match_dup 2) (match_dup 1))
19726    (set (match_dup 0) (match_dup 2))]
19727   "")
19728
19729 (define_peephole2
19730   [(match_scratch:HI 2 "r")
19731    (set (match_operand:HI 0 "memory_operand" "")
19732         (match_operand:HI 1 "immediate_operand" ""))]
19733   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19734   && TARGET_SPLIT_LONG_MOVES"
19735   [(set (match_dup 2) (match_dup 1))
19736    (set (match_dup 0) (match_dup 2))]
19737   "")
19738
19739 (define_peephole2
19740   [(match_scratch:QI 2 "q")
19741    (set (match_operand:QI 0 "memory_operand" "")
19742         (match_operand:QI 1 "immediate_operand" ""))]
19743   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19744   && TARGET_SPLIT_LONG_MOVES"
19745   [(set (match_dup 2) (match_dup 1))
19746    (set (match_dup 0) (match_dup 2))]
19747   "")
19748
19749 ;; Don't compare memory with zero, load and use a test instead.
19750 (define_peephole2
19751   [(set (match_operand 0 "flags_reg_operand" "")
19752         (match_operator 1 "compare_operator"
19753           [(match_operand:SI 2 "memory_operand" "")
19754            (const_int 0)]))
19755    (match_scratch:SI 3 "r")]
19756   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19757   [(set (match_dup 3) (match_dup 2))
19758    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19759   "")
19760
19761 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19762 ;; Don't split NOTs with a displacement operand, because resulting XOR
19763 ;; will not be pairable anyway.
19764 ;;
19765 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19766 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19767 ;; so this split helps here as well.
19768 ;;
19769 ;; Note: Can't do this as a regular split because we can't get proper
19770 ;; lifetime information then.
19771
19772 (define_peephole2
19773   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19774         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19775   "!optimize_size
19776    && peep2_regno_dead_p (0, FLAGS_REG)
19777    && ((TARGET_PENTIUM 
19778         && (GET_CODE (operands[0]) != MEM
19779             || !memory_displacement_operand (operands[0], SImode)))
19780        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19781   [(parallel [(set (match_dup 0)
19782                    (xor:SI (match_dup 1) (const_int -1)))
19783               (clobber (reg:CC FLAGS_REG))])]
19784   "")
19785
19786 (define_peephole2
19787   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19788         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19789   "!optimize_size
19790    && peep2_regno_dead_p (0, FLAGS_REG)
19791    && ((TARGET_PENTIUM 
19792         && (GET_CODE (operands[0]) != MEM
19793             || !memory_displacement_operand (operands[0], HImode)))
19794        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19795   [(parallel [(set (match_dup 0)
19796                    (xor:HI (match_dup 1) (const_int -1)))
19797               (clobber (reg:CC FLAGS_REG))])]
19798   "")
19799
19800 (define_peephole2
19801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19802         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19803   "!optimize_size
19804    && peep2_regno_dead_p (0, FLAGS_REG)
19805    && ((TARGET_PENTIUM 
19806         && (GET_CODE (operands[0]) != MEM
19807             || !memory_displacement_operand (operands[0], QImode)))
19808        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19809   [(parallel [(set (match_dup 0)
19810                    (xor:QI (match_dup 1) (const_int -1)))
19811               (clobber (reg:CC FLAGS_REG))])]
19812   "")
19813
19814 ;; Non pairable "test imm, reg" instructions can be translated to
19815 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19816 ;; byte opcode instead of two, have a short form for byte operands),
19817 ;; so do it for other CPUs as well.  Given that the value was dead,
19818 ;; this should not create any new dependencies.  Pass on the sub-word
19819 ;; versions if we're concerned about partial register stalls.
19820
19821 (define_peephole2
19822   [(set (match_operand 0 "flags_reg_operand" "")
19823         (match_operator 1 "compare_operator"
19824           [(and:SI (match_operand:SI 2 "register_operand" "")
19825                    (match_operand:SI 3 "immediate_operand" ""))
19826            (const_int 0)]))]
19827   "ix86_match_ccmode (insn, CCNOmode)
19828    && (true_regnum (operands[2]) != 0
19829        || satisfies_constraint_K (operands[3]))
19830    && peep2_reg_dead_p (1, operands[2])"
19831   [(parallel
19832      [(set (match_dup 0)
19833            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19834                             (const_int 0)]))
19835       (set (match_dup 2)
19836            (and:SI (match_dup 2) (match_dup 3)))])]
19837   "")
19838
19839 ;; We don't need to handle HImode case, because it will be promoted to SImode
19840 ;; on ! TARGET_PARTIAL_REG_STALL
19841
19842 (define_peephole2
19843   [(set (match_operand 0 "flags_reg_operand" "")
19844         (match_operator 1 "compare_operator"
19845           [(and:QI (match_operand:QI 2 "register_operand" "")
19846                    (match_operand:QI 3 "immediate_operand" ""))
19847            (const_int 0)]))]
19848   "! TARGET_PARTIAL_REG_STALL
19849    && ix86_match_ccmode (insn, CCNOmode)
19850    && true_regnum (operands[2]) != 0
19851    && peep2_reg_dead_p (1, operands[2])"
19852   [(parallel
19853      [(set (match_dup 0)
19854            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19855                             (const_int 0)]))
19856       (set (match_dup 2)
19857            (and:QI (match_dup 2) (match_dup 3)))])]
19858   "")
19859
19860 (define_peephole2
19861   [(set (match_operand 0 "flags_reg_operand" "")
19862         (match_operator 1 "compare_operator"
19863           [(and:SI
19864              (zero_extract:SI
19865                (match_operand 2 "ext_register_operand" "")
19866                (const_int 8)
19867                (const_int 8))
19868              (match_operand 3 "const_int_operand" ""))
19869            (const_int 0)]))]
19870   "! TARGET_PARTIAL_REG_STALL
19871    && ix86_match_ccmode (insn, CCNOmode)
19872    && true_regnum (operands[2]) != 0
19873    && peep2_reg_dead_p (1, operands[2])"
19874   [(parallel [(set (match_dup 0)
19875                    (match_op_dup 1
19876                      [(and:SI
19877                         (zero_extract:SI
19878                           (match_dup 2)
19879                           (const_int 8)
19880                           (const_int 8))
19881                         (match_dup 3))
19882                       (const_int 0)]))
19883               (set (zero_extract:SI (match_dup 2)
19884                                     (const_int 8)
19885                                     (const_int 8))
19886                    (and:SI 
19887                      (zero_extract:SI
19888                        (match_dup 2)
19889                        (const_int 8)
19890                        (const_int 8))
19891                      (match_dup 3)))])]
19892   "")
19893
19894 ;; Don't do logical operations with memory inputs.
19895 (define_peephole2
19896   [(match_scratch:SI 2 "r")
19897    (parallel [(set (match_operand:SI 0 "register_operand" "")
19898                    (match_operator:SI 3 "arith_or_logical_operator"
19899                      [(match_dup 0)
19900                       (match_operand:SI 1 "memory_operand" "")]))
19901               (clobber (reg:CC FLAGS_REG))])]
19902   "! optimize_size && ! TARGET_READ_MODIFY"
19903   [(set (match_dup 2) (match_dup 1))
19904    (parallel [(set (match_dup 0)
19905                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19906               (clobber (reg:CC FLAGS_REG))])]
19907   "")
19908
19909 (define_peephole2
19910   [(match_scratch:SI 2 "r")
19911    (parallel [(set (match_operand:SI 0 "register_operand" "")
19912                    (match_operator:SI 3 "arith_or_logical_operator"
19913                      [(match_operand:SI 1 "memory_operand" "")
19914                       (match_dup 0)]))
19915               (clobber (reg:CC FLAGS_REG))])]
19916   "! optimize_size && ! TARGET_READ_MODIFY"
19917   [(set (match_dup 2) (match_dup 1))
19918    (parallel [(set (match_dup 0)
19919                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19920               (clobber (reg:CC FLAGS_REG))])]
19921   "")
19922
19923 ; Don't do logical operations with memory outputs
19924 ;
19925 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19926 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19927 ; the same decoder scheduling characteristics as the original.
19928
19929 (define_peephole2
19930   [(match_scratch:SI 2 "r")
19931    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19932                    (match_operator:SI 3 "arith_or_logical_operator"
19933                      [(match_dup 0)
19934                       (match_operand:SI 1 "nonmemory_operand" "")]))
19935               (clobber (reg:CC FLAGS_REG))])]
19936   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19937   [(set (match_dup 2) (match_dup 0))
19938    (parallel [(set (match_dup 2)
19939                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19940               (clobber (reg:CC FLAGS_REG))])
19941    (set (match_dup 0) (match_dup 2))]
19942   "")
19943
19944 (define_peephole2
19945   [(match_scratch:SI 2 "r")
19946    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19947                    (match_operator:SI 3 "arith_or_logical_operator"
19948                      [(match_operand:SI 1 "nonmemory_operand" "")
19949                       (match_dup 0)]))
19950               (clobber (reg:CC FLAGS_REG))])]
19951   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19952   [(set (match_dup 2) (match_dup 0))
19953    (parallel [(set (match_dup 2)
19954                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19955               (clobber (reg:CC FLAGS_REG))])
19956    (set (match_dup 0) (match_dup 2))]
19957   "")
19958
19959 ;; Attempt to always use XOR for zeroing registers.
19960 (define_peephole2
19961   [(set (match_operand 0 "register_operand" "")
19962         (match_operand 1 "const0_operand" ""))]
19963   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19964    && (! TARGET_USE_MOV0 || optimize_size)
19965    && GENERAL_REG_P (operands[0])
19966    && peep2_regno_dead_p (0, FLAGS_REG)"
19967   [(parallel [(set (match_dup 0) (const_int 0))
19968               (clobber (reg:CC FLAGS_REG))])]
19969 {
19970   operands[0] = gen_lowpart (word_mode, operands[0]);
19971 })
19972
19973 (define_peephole2
19974   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19975         (const_int 0))]
19976   "(GET_MODE (operands[0]) == QImode
19977     || GET_MODE (operands[0]) == HImode)
19978    && (! TARGET_USE_MOV0 || optimize_size)
19979    && peep2_regno_dead_p (0, FLAGS_REG)"
19980   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19981               (clobber (reg:CC FLAGS_REG))])])
19982
19983 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19984 (define_peephole2
19985   [(set (match_operand 0 "register_operand" "")
19986         (const_int -1))]
19987   "(GET_MODE (operands[0]) == HImode
19988     || GET_MODE (operands[0]) == SImode 
19989     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19990    && (optimize_size || TARGET_PENTIUM)
19991    && peep2_regno_dead_p (0, FLAGS_REG)"
19992   [(parallel [(set (match_dup 0) (const_int -1))
19993               (clobber (reg:CC FLAGS_REG))])]
19994   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19995                               operands[0]);")
19996
19997 ;; Attempt to convert simple leas to adds. These can be created by
19998 ;; move expanders.
19999 (define_peephole2
20000   [(set (match_operand:SI 0 "register_operand" "")
20001         (plus:SI (match_dup 0)
20002                  (match_operand:SI 1 "nonmemory_operand" "")))]
20003   "peep2_regno_dead_p (0, FLAGS_REG)"
20004   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20005               (clobber (reg:CC FLAGS_REG))])]
20006   "")
20007
20008 (define_peephole2
20009   [(set (match_operand:SI 0 "register_operand" "")
20010         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20011                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20012   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20013   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20014               (clobber (reg:CC FLAGS_REG))])]
20015   "operands[2] = gen_lowpart (SImode, operands[2]);")
20016
20017 (define_peephole2
20018   [(set (match_operand:DI 0 "register_operand" "")
20019         (plus:DI (match_dup 0)
20020                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20021   "peep2_regno_dead_p (0, FLAGS_REG)"
20022   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20023               (clobber (reg:CC FLAGS_REG))])]
20024   "")
20025
20026 (define_peephole2
20027   [(set (match_operand:SI 0 "register_operand" "")
20028         (mult:SI (match_dup 0)
20029                  (match_operand:SI 1 "const_int_operand" "")))]
20030   "exact_log2 (INTVAL (operands[1])) >= 0
20031    && peep2_regno_dead_p (0, FLAGS_REG)"
20032   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20033               (clobber (reg:CC FLAGS_REG))])]
20034   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20035
20036 (define_peephole2
20037   [(set (match_operand:DI 0 "register_operand" "")
20038         (mult:DI (match_dup 0)
20039                  (match_operand:DI 1 "const_int_operand" "")))]
20040   "exact_log2 (INTVAL (operands[1])) >= 0
20041    && peep2_regno_dead_p (0, FLAGS_REG)"
20042   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20043               (clobber (reg:CC FLAGS_REG))])]
20044   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20045
20046 (define_peephole2
20047   [(set (match_operand:SI 0 "register_operand" "")
20048         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20049                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20050   "exact_log2 (INTVAL (operands[2])) >= 0
20051    && REGNO (operands[0]) == REGNO (operands[1])
20052    && peep2_regno_dead_p (0, FLAGS_REG)"
20053   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20054               (clobber (reg:CC FLAGS_REG))])]
20055   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20056
20057 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20058 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20059 ;; many CPUs it is also faster, since special hardware to avoid esp
20060 ;; dependencies is present.
20061
20062 ;; While some of these conversions may be done using splitters, we use peepholes
20063 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20064
20065 ;; Convert prologue esp subtractions to push.
20066 ;; We need register to push.  In order to keep verify_flow_info happy we have
20067 ;; two choices
20068 ;; - use scratch and clobber it in order to avoid dependencies
20069 ;; - use already live register
20070 ;; We can't use the second way right now, since there is no reliable way how to
20071 ;; verify that given register is live.  First choice will also most likely in
20072 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20073 ;; call clobbered registers are dead.  We may want to use base pointer as an
20074 ;; alternative when no register is available later.
20075
20076 (define_peephole2
20077   [(match_scratch:SI 0 "r")
20078    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20079               (clobber (reg:CC FLAGS_REG))
20080               (clobber (mem:BLK (scratch)))])]
20081   "optimize_size || !TARGET_SUB_ESP_4"
20082   [(clobber (match_dup 0))
20083    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20084               (clobber (mem:BLK (scratch)))])])
20085
20086 (define_peephole2
20087   [(match_scratch:SI 0 "r")
20088    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20089               (clobber (reg:CC FLAGS_REG))
20090               (clobber (mem:BLK (scratch)))])]
20091   "optimize_size || !TARGET_SUB_ESP_8"
20092   [(clobber (match_dup 0))
20093    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20094    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095               (clobber (mem:BLK (scratch)))])])
20096
20097 ;; Convert esp subtractions to push.
20098 (define_peephole2
20099   [(match_scratch:SI 0 "r")
20100    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20101               (clobber (reg:CC FLAGS_REG))])]
20102   "optimize_size || !TARGET_SUB_ESP_4"
20103   [(clobber (match_dup 0))
20104    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20105
20106 (define_peephole2
20107   [(match_scratch:SI 0 "r")
20108    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20109               (clobber (reg:CC FLAGS_REG))])]
20110   "optimize_size || !TARGET_SUB_ESP_8"
20111   [(clobber (match_dup 0))
20112    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20113    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20114
20115 ;; Convert epilogue deallocator to pop.
20116 (define_peephole2
20117   [(match_scratch:SI 0 "r")
20118    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20119               (clobber (reg:CC FLAGS_REG))
20120               (clobber (mem:BLK (scratch)))])]
20121   "optimize_size || !TARGET_ADD_ESP_4"
20122   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20123               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20124               (clobber (mem:BLK (scratch)))])]
20125   "")
20126
20127 ;; Two pops case is tricky, since pop causes dependency on destination register.
20128 ;; We use two registers if available.
20129 (define_peephole2
20130   [(match_scratch:SI 0 "r")
20131    (match_scratch:SI 1 "r")
20132    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20133               (clobber (reg:CC FLAGS_REG))
20134               (clobber (mem:BLK (scratch)))])]
20135   "optimize_size || !TARGET_ADD_ESP_8"
20136   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20137               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20138               (clobber (mem:BLK (scratch)))])
20139    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20140               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20141   "")
20142
20143 (define_peephole2
20144   [(match_scratch:SI 0 "r")
20145    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20146               (clobber (reg:CC FLAGS_REG))
20147               (clobber (mem:BLK (scratch)))])]
20148   "optimize_size"
20149   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20150               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20151               (clobber (mem:BLK (scratch)))])
20152    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20153               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20154   "")
20155
20156 ;; Convert esp additions to pop.
20157 (define_peephole2
20158   [(match_scratch:SI 0 "r")
20159    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20160               (clobber (reg:CC FLAGS_REG))])]
20161   ""
20162   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20163               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20164   "")
20165
20166 ;; Two pops case is tricky, since pop causes dependency on destination register.
20167 ;; We use two registers if available.
20168 (define_peephole2
20169   [(match_scratch:SI 0 "r")
20170    (match_scratch:SI 1 "r")
20171    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20172               (clobber (reg:CC FLAGS_REG))])]
20173   ""
20174   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20175               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20176    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20177               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20178   "")
20179
20180 (define_peephole2
20181   [(match_scratch:SI 0 "r")
20182    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20183               (clobber (reg:CC FLAGS_REG))])]
20184   "optimize_size"
20185   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20186               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20187    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20189   "")
20190 \f
20191 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20192 ;; required and register dies.  Similarly for 128 to plus -128.
20193 (define_peephole2
20194   [(set (match_operand 0 "flags_reg_operand" "")
20195         (match_operator 1 "compare_operator"
20196           [(match_operand 2 "register_operand" "")
20197            (match_operand 3 "const_int_operand" "")]))]
20198   "(INTVAL (operands[3]) == -1
20199     || INTVAL (operands[3]) == 1
20200     || INTVAL (operands[3]) == 128)
20201    && ix86_match_ccmode (insn, CCGCmode)
20202    && peep2_reg_dead_p (1, operands[2])"
20203   [(parallel [(set (match_dup 0)
20204                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20205               (clobber (match_dup 2))])]
20206   "")
20207 \f
20208 (define_peephole2
20209   [(match_scratch:DI 0 "r")
20210    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20211               (clobber (reg:CC FLAGS_REG))
20212               (clobber (mem:BLK (scratch)))])]
20213   "optimize_size || !TARGET_SUB_ESP_4"
20214   [(clobber (match_dup 0))
20215    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20216               (clobber (mem:BLK (scratch)))])])
20217
20218 (define_peephole2
20219   [(match_scratch:DI 0 "r")
20220    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20221               (clobber (reg:CC FLAGS_REG))
20222               (clobber (mem:BLK (scratch)))])]
20223   "optimize_size || !TARGET_SUB_ESP_8"
20224   [(clobber (match_dup 0))
20225    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20226    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227               (clobber (mem:BLK (scratch)))])])
20228
20229 ;; Convert esp subtractions to push.
20230 (define_peephole2
20231   [(match_scratch:DI 0 "r")
20232    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20233               (clobber (reg:CC FLAGS_REG))])]
20234   "optimize_size || !TARGET_SUB_ESP_4"
20235   [(clobber (match_dup 0))
20236    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20237
20238 (define_peephole2
20239   [(match_scratch:DI 0 "r")
20240    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20241               (clobber (reg:CC FLAGS_REG))])]
20242   "optimize_size || !TARGET_SUB_ESP_8"
20243   [(clobber (match_dup 0))
20244    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20245    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20246
20247 ;; Convert epilogue deallocator to pop.
20248 (define_peephole2
20249   [(match_scratch:DI 0 "r")
20250    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20251               (clobber (reg:CC FLAGS_REG))
20252               (clobber (mem:BLK (scratch)))])]
20253   "optimize_size || !TARGET_ADD_ESP_4"
20254   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20255               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20256               (clobber (mem:BLK (scratch)))])]
20257   "")
20258
20259 ;; Two pops case is tricky, since pop causes dependency on destination register.
20260 ;; We use two registers if available.
20261 (define_peephole2
20262   [(match_scratch:DI 0 "r")
20263    (match_scratch:DI 1 "r")
20264    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20265               (clobber (reg:CC FLAGS_REG))
20266               (clobber (mem:BLK (scratch)))])]
20267   "optimize_size || !TARGET_ADD_ESP_8"
20268   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20269               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20270               (clobber (mem:BLK (scratch)))])
20271    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20272               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20273   "")
20274
20275 (define_peephole2
20276   [(match_scratch:DI 0 "r")
20277    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20278               (clobber (reg:CC FLAGS_REG))
20279               (clobber (mem:BLK (scratch)))])]
20280   "optimize_size"
20281   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20282               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20283               (clobber (mem:BLK (scratch)))])
20284    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20285               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20286   "")
20287
20288 ;; Convert esp additions to pop.
20289 (define_peephole2
20290   [(match_scratch:DI 0 "r")
20291    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20292               (clobber (reg:CC FLAGS_REG))])]
20293   ""
20294   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20295               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20296   "")
20297
20298 ;; Two pops case is tricky, since pop causes dependency on destination register.
20299 ;; We use two registers if available.
20300 (define_peephole2
20301   [(match_scratch:DI 0 "r")
20302    (match_scratch:DI 1 "r")
20303    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20304               (clobber (reg:CC FLAGS_REG))])]
20305   ""
20306   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20307               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20308    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20309               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20310   "")
20311
20312 (define_peephole2
20313   [(match_scratch:DI 0 "r")
20314    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20315               (clobber (reg:CC FLAGS_REG))])]
20316   "optimize_size"
20317   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20318               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20319    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20321   "")
20322 \f
20323 ;; Convert imul by three, five and nine into lea
20324 (define_peephole2
20325   [(parallel
20326     [(set (match_operand:SI 0 "register_operand" "")
20327           (mult:SI (match_operand:SI 1 "register_operand" "")
20328                    (match_operand:SI 2 "const_int_operand" "")))
20329      (clobber (reg:CC FLAGS_REG))])]
20330   "INTVAL (operands[2]) == 3
20331    || INTVAL (operands[2]) == 5
20332    || INTVAL (operands[2]) == 9"
20333   [(set (match_dup 0)
20334         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20335                  (match_dup 1)))]
20336   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20337
20338 (define_peephole2
20339   [(parallel
20340     [(set (match_operand:SI 0 "register_operand" "")
20341           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20342                    (match_operand:SI 2 "const_int_operand" "")))
20343      (clobber (reg:CC FLAGS_REG))])]
20344   "!optimize_size 
20345    && (INTVAL (operands[2]) == 3
20346        || INTVAL (operands[2]) == 5
20347        || INTVAL (operands[2]) == 9)"
20348   [(set (match_dup 0) (match_dup 1))
20349    (set (match_dup 0)
20350         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20351                  (match_dup 0)))]
20352   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20353
20354 (define_peephole2
20355   [(parallel
20356     [(set (match_operand:DI 0 "register_operand" "")
20357           (mult:DI (match_operand:DI 1 "register_operand" "")
20358                    (match_operand:DI 2 "const_int_operand" "")))
20359      (clobber (reg:CC FLAGS_REG))])]
20360   "TARGET_64BIT
20361    && (INTVAL (operands[2]) == 3
20362        || INTVAL (operands[2]) == 5
20363        || INTVAL (operands[2]) == 9)"
20364   [(set (match_dup 0)
20365         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20366                  (match_dup 1)))]
20367   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20368
20369 (define_peephole2
20370   [(parallel
20371     [(set (match_operand:DI 0 "register_operand" "")
20372           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373                    (match_operand:DI 2 "const_int_operand" "")))
20374      (clobber (reg:CC FLAGS_REG))])]
20375   "TARGET_64BIT
20376    && !optimize_size 
20377    && (INTVAL (operands[2]) == 3
20378        || INTVAL (operands[2]) == 5
20379        || INTVAL (operands[2]) == 9)"
20380   [(set (match_dup 0) (match_dup 1))
20381    (set (match_dup 0)
20382         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20383                  (match_dup 0)))]
20384   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20385
20386 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20387 ;; imul $32bit_imm, reg, reg is direct decoded.
20388 (define_peephole2
20389   [(match_scratch:DI 3 "r")
20390    (parallel [(set (match_operand:DI 0 "register_operand" "")
20391                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20392                             (match_operand:DI 2 "immediate_operand" "")))
20393               (clobber (reg:CC FLAGS_REG))])]
20394   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20395    && !satisfies_constraint_K (operands[2])"
20396   [(set (match_dup 3) (match_dup 1))
20397    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399 "")
20400
20401 (define_peephole2
20402   [(match_scratch:SI 3 "r")
20403    (parallel [(set (match_operand:SI 0 "register_operand" "")
20404                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20405                             (match_operand:SI 2 "immediate_operand" "")))
20406               (clobber (reg:CC FLAGS_REG))])]
20407   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20408    && !satisfies_constraint_K (operands[2])"
20409   [(set (match_dup 3) (match_dup 1))
20410    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20411               (clobber (reg:CC FLAGS_REG))])]
20412 "")
20413
20414 (define_peephole2
20415   [(match_scratch:SI 3 "r")
20416    (parallel [(set (match_operand:DI 0 "register_operand" "")
20417                    (zero_extend:DI
20418                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20419                               (match_operand:SI 2 "immediate_operand" ""))))
20420               (clobber (reg:CC FLAGS_REG))])]
20421   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20422    && !satisfies_constraint_K (operands[2])"
20423   [(set (match_dup 3) (match_dup 1))
20424    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20425               (clobber (reg:CC FLAGS_REG))])]
20426 "")
20427
20428 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20429 ;; Convert it into imul reg, reg
20430 ;; It would be better to force assembler to encode instruction using long
20431 ;; immediate, but there is apparently no way to do so.
20432 (define_peephole2
20433   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20434                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20435                             (match_operand:DI 2 "const_int_operand" "")))
20436               (clobber (reg:CC FLAGS_REG))])
20437    (match_scratch:DI 3 "r")]
20438   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20439    && satisfies_constraint_K (operands[2])"
20440   [(set (match_dup 3) (match_dup 2))
20441    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20442               (clobber (reg:CC FLAGS_REG))])]
20443 {
20444   if (!rtx_equal_p (operands[0], operands[1]))
20445     emit_move_insn (operands[0], operands[1]);
20446 })
20447
20448 (define_peephole2
20449   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20450                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20451                             (match_operand:SI 2 "const_int_operand" "")))
20452               (clobber (reg:CC FLAGS_REG))])
20453    (match_scratch:SI 3 "r")]
20454   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20455    && satisfies_constraint_K (operands[2])"
20456   [(set (match_dup 3) (match_dup 2))
20457    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20458               (clobber (reg:CC FLAGS_REG))])]
20459 {
20460   if (!rtx_equal_p (operands[0], operands[1]))
20461     emit_move_insn (operands[0], operands[1]);
20462 })
20463
20464 (define_peephole2
20465   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20466                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20467                             (match_operand:HI 2 "immediate_operand" "")))
20468               (clobber (reg:CC FLAGS_REG))])
20469    (match_scratch:HI 3 "r")]
20470   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20471   [(set (match_dup 3) (match_dup 2))
20472    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20473               (clobber (reg:CC FLAGS_REG))])]
20474 {
20475   if (!rtx_equal_p (operands[0], operands[1]))
20476     emit_move_insn (operands[0], operands[1]);
20477 })
20478
20479 ;; After splitting up read-modify operations, array accesses with memory
20480 ;; operands might end up in form:
20481 ;;  sall    $2, %eax
20482 ;;  movl    4(%esp), %edx
20483 ;;  addl    %edx, %eax
20484 ;; instead of pre-splitting:
20485 ;;  sall    $2, %eax
20486 ;;  addl    4(%esp), %eax
20487 ;; Turn it into:
20488 ;;  movl    4(%esp), %edx
20489 ;;  leal    (%edx,%eax,4), %eax
20490
20491 (define_peephole2
20492   [(parallel [(set (match_operand 0 "register_operand" "")
20493                    (ashift (match_operand 1 "register_operand" "")
20494                            (match_operand 2 "const_int_operand" "")))
20495                (clobber (reg:CC FLAGS_REG))])
20496    (set (match_operand 3 "register_operand")
20497         (match_operand 4 "x86_64_general_operand" ""))
20498    (parallel [(set (match_operand 5 "register_operand" "")
20499                    (plus (match_operand 6 "register_operand" "")
20500                          (match_operand 7 "register_operand" "")))
20501                    (clobber (reg:CC FLAGS_REG))])]
20502   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20503    /* Validate MODE for lea.  */
20504    && ((!TARGET_PARTIAL_REG_STALL
20505         && (GET_MODE (operands[0]) == QImode
20506             || GET_MODE (operands[0]) == HImode))
20507        || GET_MODE (operands[0]) == SImode 
20508        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20509    /* We reorder load and the shift.  */
20510    && !rtx_equal_p (operands[1], operands[3])
20511    && !reg_overlap_mentioned_p (operands[0], operands[4])
20512    /* Last PLUS must consist of operand 0 and 3.  */
20513    && !rtx_equal_p (operands[0], operands[3])
20514    && (rtx_equal_p (operands[3], operands[6])
20515        || rtx_equal_p (operands[3], operands[7]))
20516    && (rtx_equal_p (operands[0], operands[6])
20517        || rtx_equal_p (operands[0], operands[7]))
20518    /* The intermediate operand 0 must die or be same as output.  */
20519    && (rtx_equal_p (operands[0], operands[5])
20520        || peep2_reg_dead_p (3, operands[0]))"
20521   [(set (match_dup 3) (match_dup 4))
20522    (set (match_dup 0) (match_dup 1))]
20523 {
20524   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20525   int scale = 1 << INTVAL (operands[2]);
20526   rtx index = gen_lowpart (Pmode, operands[1]);
20527   rtx base = gen_lowpart (Pmode, operands[3]);
20528   rtx dest = gen_lowpart (mode, operands[5]);
20529
20530   operands[1] = gen_rtx_PLUS (Pmode, base,
20531                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20532   if (mode != Pmode)
20533     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20534   operands[0] = dest;
20535 })
20536 \f
20537 ;; Call-value patterns last so that the wildcard operand does not
20538 ;; disrupt insn-recog's switch tables.
20539
20540 (define_insn "*call_value_pop_0"
20541   [(set (match_operand 0 "" "")
20542         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20543               (match_operand:SI 2 "" "")))
20544    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20545                             (match_operand:SI 3 "immediate_operand" "")))]
20546   "!TARGET_64BIT"
20547 {
20548   if (SIBLING_CALL_P (insn))
20549     return "jmp\t%P1";
20550   else
20551     return "call\t%P1";
20552 }
20553   [(set_attr "type" "callv")])
20554
20555 (define_insn "*call_value_pop_1"
20556   [(set (match_operand 0 "" "")
20557         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20558               (match_operand:SI 2 "" "")))
20559    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20560                             (match_operand:SI 3 "immediate_operand" "i")))]
20561   "!TARGET_64BIT"
20562 {
20563   if (constant_call_address_operand (operands[1], Pmode))
20564     {
20565       if (SIBLING_CALL_P (insn))
20566         return "jmp\t%P1";
20567       else
20568         return "call\t%P1";
20569     }
20570   if (SIBLING_CALL_P (insn))
20571     return "jmp\t%A1";
20572   else
20573     return "call\t%A1";
20574 }
20575   [(set_attr "type" "callv")])
20576
20577 (define_insn "*call_value_0"
20578   [(set (match_operand 0 "" "")
20579         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20580               (match_operand:SI 2 "" "")))]
20581   "!TARGET_64BIT"
20582 {
20583   if (SIBLING_CALL_P (insn))
20584     return "jmp\t%P1";
20585   else
20586     return "call\t%P1";
20587 }
20588   [(set_attr "type" "callv")])
20589
20590 (define_insn "*call_value_0_rex64"
20591   [(set (match_operand 0 "" "")
20592         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20593               (match_operand:DI 2 "const_int_operand" "")))]
20594   "TARGET_64BIT"
20595 {
20596   if (SIBLING_CALL_P (insn))
20597     return "jmp\t%P1";
20598   else
20599     return "call\t%P1";
20600 }
20601   [(set_attr "type" "callv")])
20602
20603 (define_insn "*call_value_1"
20604   [(set (match_operand 0 "" "")
20605         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20606               (match_operand:SI 2 "" "")))]
20607   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20608 {
20609   if (constant_call_address_operand (operands[1], Pmode))
20610     return "call\t%P1";
20611   return "call\t%A1";
20612 }
20613   [(set_attr "type" "callv")])
20614
20615 (define_insn "*sibcall_value_1"
20616   [(set (match_operand 0 "" "")
20617         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20618               (match_operand:SI 2 "" "")))]
20619   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20620 {
20621   if (constant_call_address_operand (operands[1], Pmode))
20622     return "jmp\t%P1";
20623   return "jmp\t%A1";
20624 }
20625   [(set_attr "type" "callv")])
20626
20627 (define_insn "*call_value_1_rex64"
20628   [(set (match_operand 0 "" "")
20629         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20630               (match_operand:DI 2 "" "")))]
20631   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20632 {
20633   if (constant_call_address_operand (operands[1], Pmode))
20634     return "call\t%P1";
20635   return "call\t%A1";
20636 }
20637   [(set_attr "type" "callv")])
20638
20639 (define_insn "*sibcall_value_1_rex64"
20640   [(set (match_operand 0 "" "")
20641         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20642               (match_operand:DI 2 "" "")))]
20643   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20644   "jmp\t%P1"
20645   [(set_attr "type" "callv")])
20646
20647 (define_insn "*sibcall_value_1_rex64_v"
20648   [(set (match_operand 0 "" "")
20649         (call (mem:QI (reg:DI 40))
20650               (match_operand:DI 1 "" "")))]
20651   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20652   "jmp\t*%%r11"
20653   [(set_attr "type" "callv")])
20654 \f
20655 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20656 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20657 ;; caught for use by garbage collectors and the like.  Using an insn that
20658 ;; maps to SIGILL makes it more likely the program will rightfully die.
20659 ;; Keeping with tradition, "6" is in honor of #UD.
20660 (define_insn "trap"
20661   [(trap_if (const_int 1) (const_int 6))]
20662   ""
20663   { return ASM_SHORT "0x0b0f"; }
20664   [(set_attr "length" "2")])
20665
20666 (define_expand "sse_prologue_save"
20667   [(parallel [(set (match_operand:BLK 0 "" "")
20668                    (unspec:BLK [(reg:DI 21)
20669                                 (reg:DI 22)
20670                                 (reg:DI 23)
20671                                 (reg:DI 24)
20672                                 (reg:DI 25)
20673                                 (reg:DI 26)
20674                                 (reg:DI 27)
20675                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20676               (use (match_operand:DI 1 "register_operand" ""))
20677               (use (match_operand:DI 2 "immediate_operand" ""))
20678               (use (label_ref:DI (match_operand 3 "" "")))])]
20679   "TARGET_64BIT"
20680   "")
20681
20682 (define_insn "*sse_prologue_save_insn"
20683   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20684                           (match_operand:DI 4 "const_int_operand" "n")))
20685         (unspec:BLK [(reg:DI 21)
20686                      (reg:DI 22)
20687                      (reg:DI 23)
20688                      (reg:DI 24)
20689                      (reg:DI 25)
20690                      (reg:DI 26)
20691                      (reg:DI 27)
20692                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20693    (use (match_operand:DI 1 "register_operand" "r"))
20694    (use (match_operand:DI 2 "const_int_operand" "i"))
20695    (use (label_ref:DI (match_operand 3 "" "X")))]
20696   "TARGET_64BIT
20697    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20698    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20699   "*
20700 {
20701   int i;
20702   operands[0] = gen_rtx_MEM (Pmode,
20703                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20704   output_asm_insn (\"jmp\\t%A1\", operands);
20705   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20706     {
20707       operands[4] = adjust_address (operands[0], DImode, i*16);
20708       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20709       PUT_MODE (operands[4], TImode);
20710       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20711         output_asm_insn (\"rex\", operands);
20712       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20713     }
20714   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20715                              CODE_LABEL_NUMBER (operands[3]));
20716   RET;
20717 }
20718   "
20719   [(set_attr "type" "other")
20720    (set_attr "length_immediate" "0")
20721    (set_attr "length_address" "0")
20722    (set_attr "length" "135")
20723    (set_attr "memory" "store")
20724    (set_attr "modrm" "0")
20725    (set_attr "mode" "DI")])
20726
20727 (define_expand "prefetch"
20728   [(prefetch (match_operand 0 "address_operand" "")
20729              (match_operand:SI 1 "const_int_operand" "")
20730              (match_operand:SI 2 "const_int_operand" ""))]
20731   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20732 {
20733   int rw = INTVAL (operands[1]);
20734   int locality = INTVAL (operands[2]);
20735
20736   gcc_assert (rw == 0 || rw == 1);
20737   gcc_assert (locality >= 0 && locality <= 3);
20738   gcc_assert (GET_MODE (operands[0]) == Pmode
20739               || GET_MODE (operands[0]) == VOIDmode);
20740
20741   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20742      supported by SSE counterpart or the SSE prefetch is not available
20743      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20744      of locality.  */
20745   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20746     operands[2] = GEN_INT (3);
20747   else
20748     operands[1] = const0_rtx;
20749 })
20750
20751 (define_insn "*prefetch_sse"
20752   [(prefetch (match_operand:SI 0 "address_operand" "p")
20753              (const_int 0)
20754              (match_operand:SI 1 "const_int_operand" ""))]
20755   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20756 {
20757   static const char * const patterns[4] = {
20758    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20759   };
20760
20761   int locality = INTVAL (operands[1]);
20762   gcc_assert (locality >= 0 && locality <= 3);
20763
20764   return patterns[locality];  
20765 }
20766   [(set_attr "type" "sse")
20767    (set_attr "memory" "none")])
20768
20769 (define_insn "*prefetch_sse_rex"
20770   [(prefetch (match_operand:DI 0 "address_operand" "p")
20771              (const_int 0)
20772              (match_operand:SI 1 "const_int_operand" ""))]
20773   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20774 {
20775   static const char * const patterns[4] = {
20776    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20777   };
20778
20779   int locality = INTVAL (operands[1]);
20780   gcc_assert (locality >= 0 && locality <= 3);
20781
20782   return patterns[locality];  
20783 }
20784   [(set_attr "type" "sse")
20785    (set_attr "memory" "none")])
20786
20787 (define_insn "*prefetch_3dnow"
20788   [(prefetch (match_operand:SI 0 "address_operand" "p")
20789              (match_operand:SI 1 "const_int_operand" "n")
20790              (const_int 3))]
20791   "TARGET_3DNOW && !TARGET_64BIT"
20792 {
20793   if (INTVAL (operands[1]) == 0)
20794     return "prefetch\t%a0";
20795   else
20796     return "prefetchw\t%a0";
20797 }
20798   [(set_attr "type" "mmx")
20799    (set_attr "memory" "none")])
20800
20801 (define_insn "*prefetch_3dnow_rex"
20802   [(prefetch (match_operand:DI 0 "address_operand" "p")
20803              (match_operand:SI 1 "const_int_operand" "n")
20804              (const_int 3))]
20805   "TARGET_3DNOW && TARGET_64BIT"
20806 {
20807   if (INTVAL (operands[1]) == 0)
20808     return "prefetch\t%a0";
20809   else
20810     return "prefetchw\t%a0";
20811 }
20812   [(set_attr "type" "mmx")
20813    (set_attr "memory" "none")])
20814
20815 (define_expand "stack_protect_set"
20816   [(match_operand 0 "memory_operand" "")
20817    (match_operand 1 "memory_operand" "")]
20818   ""
20819 {
20820 #ifdef TARGET_THREAD_SSP_OFFSET
20821   if (TARGET_64BIT)
20822     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20823                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20824   else
20825     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20826                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20827 #else
20828   if (TARGET_64BIT)
20829     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20830   else
20831     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20832 #endif
20833   DONE;
20834 })
20835
20836 (define_insn "stack_protect_set_si"
20837   [(set (match_operand:SI 0 "memory_operand" "=m")
20838         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20839    (set (match_scratch:SI 2 "=&r") (const_int 0))
20840    (clobber (reg:CC FLAGS_REG))]
20841   ""
20842   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20843   [(set_attr "type" "multi")])
20844
20845 (define_insn "stack_protect_set_di"
20846   [(set (match_operand:DI 0 "memory_operand" "=m")
20847         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20848    (set (match_scratch:DI 2 "=&r") (const_int 0))
20849    (clobber (reg:CC FLAGS_REG))]
20850   "TARGET_64BIT"
20851   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20852   [(set_attr "type" "multi")])
20853
20854 (define_insn "stack_tls_protect_set_si"
20855   [(set (match_operand:SI 0 "memory_operand" "=m")
20856         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20857    (set (match_scratch:SI 2 "=&r") (const_int 0))
20858    (clobber (reg:CC FLAGS_REG))]
20859   ""
20860   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20861   [(set_attr "type" "multi")])
20862
20863 (define_insn "stack_tls_protect_set_di"
20864   [(set (match_operand:DI 0 "memory_operand" "=m")
20865         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20866    (set (match_scratch:DI 2 "=&r") (const_int 0))
20867    (clobber (reg:CC FLAGS_REG))]
20868   "TARGET_64BIT"
20869   {
20870      /* The kernel uses a different segment register for performance reasons; a
20871         system call would not have to trash the userspace segment register,
20872         which would be expensive */
20873      if (ix86_cmodel != CM_KERNEL)
20874         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20875      else
20876         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20877   }
20878   [(set_attr "type" "multi")])
20879
20880 (define_expand "stack_protect_test"
20881   [(match_operand 0 "memory_operand" "")
20882    (match_operand 1 "memory_operand" "")
20883    (match_operand 2 "" "")]
20884   ""
20885 {
20886   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20887   ix86_compare_op0 = operands[0];
20888   ix86_compare_op1 = operands[1];
20889   ix86_compare_emitted = flags;
20890
20891 #ifdef TARGET_THREAD_SSP_OFFSET
20892   if (TARGET_64BIT)
20893     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20894                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20895   else
20896     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20897                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20898 #else
20899   if (TARGET_64BIT)
20900     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20901   else
20902     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20903 #endif
20904   emit_jump_insn (gen_beq (operands[2]));
20905   DONE;
20906 })
20907
20908 (define_insn "stack_protect_test_si"
20909   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20910         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20911                      (match_operand:SI 2 "memory_operand" "m")]
20912                     UNSPEC_SP_TEST))
20913    (clobber (match_scratch:SI 3 "=&r"))]
20914   ""
20915   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20916   [(set_attr "type" "multi")])
20917
20918 (define_insn "stack_protect_test_di"
20919   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20920         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20921                      (match_operand:DI 2 "memory_operand" "m")]
20922                     UNSPEC_SP_TEST))
20923    (clobber (match_scratch:DI 3 "=&r"))]
20924   "TARGET_64BIT"
20925   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20926   [(set_attr "type" "multi")])
20927
20928 (define_insn "stack_tls_protect_test_si"
20929   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20930         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20931                      (match_operand:SI 2 "const_int_operand" "i")]
20932                     UNSPEC_SP_TLS_TEST))
20933    (clobber (match_scratch:SI 3 "=r"))]
20934   ""
20935   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20936   [(set_attr "type" "multi")])
20937
20938 (define_insn "stack_tls_protect_test_di"
20939   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20940         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20941                      (match_operand:DI 2 "const_int_operand" "i")]
20942                     UNSPEC_SP_TLS_TEST))
20943    (clobber (match_scratch:DI 3 "=r"))]
20944   "TARGET_64BIT"
20945   {
20946      /* The kernel uses a different segment register for performance reasons; a
20947         system call would not have to trash the userspace segment register,
20948         which would be expensive */
20949      if (ix86_cmodel != CM_KERNEL)
20950         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20951      else
20952         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20953   }
20954   [(set_attr "type" "multi")])
20955
20956 (include "mmx.md")
20957 (include "sse.md")
20958 (include "sync.md")