OSDN Git Service

Introduce TLS descriptors for i386 and x86_64.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 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
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
169
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
191   (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456  
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465  
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates
479
480 (include "predicates.md")
481
482 \f
483 ;; Compare instructions.
484
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
488
489 (define_expand "cmpti"
490   [(set (reg:CC FLAGS_REG)
491         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492                     (match_operand:TI 1 "x86_64_general_operand" "")))]
493   "TARGET_64BIT"
494 {
495   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496     operands[0] = force_reg (TImode, operands[0]);
497   ix86_compare_op0 = operands[0];
498   ix86_compare_op1 = operands[1];
499   DONE;
500 })
501
502 (define_expand "cmpdi"
503   [(set (reg:CC FLAGS_REG)
504         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505                     (match_operand:DI 1 "x86_64_general_operand" "")))]
506   ""
507 {
508   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509     operands[0] = force_reg (DImode, operands[0]);
510   ix86_compare_op0 = operands[0];
511   ix86_compare_op1 = operands[1];
512   DONE;
513 })
514
515 (define_expand "cmpsi"
516   [(set (reg:CC FLAGS_REG)
517         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518                     (match_operand:SI 1 "general_operand" "")))]
519   ""
520 {
521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522     operands[0] = force_reg (SImode, operands[0]);
523   ix86_compare_op0 = operands[0];
524   ix86_compare_op1 = operands[1];
525   DONE;
526 })
527
528 (define_expand "cmphi"
529   [(set (reg:CC FLAGS_REG)
530         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531                     (match_operand:HI 1 "general_operand" "")))]
532   ""
533 {
534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535     operands[0] = force_reg (HImode, operands[0]);
536   ix86_compare_op0 = operands[0];
537   ix86_compare_op1 = operands[1];
538   DONE;
539 })
540
541 (define_expand "cmpqi"
542   [(set (reg:CC FLAGS_REG)
543         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544                     (match_operand:QI 1 "general_operand" "")))]
545   "TARGET_QIMODE_MATH"
546 {
547   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548     operands[0] = force_reg (QImode, operands[0]);
549   ix86_compare_op0 = operands[0];
550   ix86_compare_op1 = operands[1];
551   DONE;
552 })
553
554 (define_insn "cmpdi_ccno_1_rex64"
555   [(set (reg FLAGS_REG)
556         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557                  (match_operand:DI 1 "const0_operand" "n,n")))]
558   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559   "@
560    test{q}\t{%0, %0|%0, %0}
561    cmp{q}\t{%1, %0|%0, %1}"
562   [(set_attr "type" "test,icmp")
563    (set_attr "length_immediate" "0,1")
564    (set_attr "mode" "DI")])
565
566 (define_insn "*cmpdi_minus_1_rex64"
567   [(set (reg FLAGS_REG)
568         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570                  (const_int 0)))]
571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572   "cmp{q}\t{%1, %0|%0, %1}"
573   [(set_attr "type" "icmp")
574    (set_attr "mode" "DI")])
575
576 (define_expand "cmpdi_1_rex64"
577   [(set (reg:CC FLAGS_REG)
578         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579                     (match_operand:DI 1 "general_operand" "")))]
580   "TARGET_64BIT"
581   "")
582
583 (define_insn "cmpdi_1_insn_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
591
592
593 (define_insn "*cmpsi_ccno_1"
594   [(set (reg FLAGS_REG)
595         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596                  (match_operand:SI 1 "const0_operand" "n,n")))]
597   "ix86_match_ccmode (insn, CCNOmode)"
598   "@
599    test{l}\t{%0, %0|%0, %0}
600    cmp{l}\t{%1, %0|%0, %1}"
601   [(set_attr "type" "test,icmp")
602    (set_attr "length_immediate" "0,1")
603    (set_attr "mode" "SI")])
604
605 (define_insn "*cmpsi_minus_1"
606   [(set (reg FLAGS_REG)
607         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608                            (match_operand:SI 1 "general_operand" "ri,mr"))
609                  (const_int 0)))]
610   "ix86_match_ccmode (insn, CCGOCmode)"
611   "cmp{l}\t{%1, %0|%0, %1}"
612   [(set_attr "type" "icmp")
613    (set_attr "mode" "SI")])
614
615 (define_expand "cmpsi_1"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618                     (match_operand:SI 1 "general_operand" "ri,mr")))]
619   ""
620   "")
621
622 (define_insn "*cmpsi_1_insn"
623   [(set (reg FLAGS_REG)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                  (match_operand:SI 1 "general_operand" "ri,mr")))]
626   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627     && ix86_match_ccmode (insn, CCmode)"
628   "cmp{l}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "SI")])
631
632 (define_insn "*cmphi_ccno_1"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635                  (match_operand:HI 1 "const0_operand" "n,n")))]
636   "ix86_match_ccmode (insn, CCNOmode)"
637   "@
638    test{w}\t{%0, %0|%0, %0}
639    cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "test,icmp")
641    (set_attr "length_immediate" "0,1")
642    (set_attr "mode" "HI")])
643
644 (define_insn "*cmphi_minus_1"
645   [(set (reg FLAGS_REG)
646         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647                            (match_operand:HI 1 "general_operand" "ri,mr"))
648                  (const_int 0)))]
649   "ix86_match_ccmode (insn, CCGOCmode)"
650   "cmp{w}\t{%1, %0|%0, %1}"
651   [(set_attr "type" "icmp")
652    (set_attr "mode" "HI")])
653
654 (define_insn "*cmphi_1"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657                  (match_operand:HI 1 "general_operand" "ri,mr")))]
658   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659    && ix86_match_ccmode (insn, CCmode)"
660   "cmp{w}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "HI")])
663
664 (define_insn "*cmpqi_ccno_1"
665   [(set (reg FLAGS_REG)
666         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667                  (match_operand:QI 1 "const0_operand" "n,n")))]
668   "ix86_match_ccmode (insn, CCNOmode)"
669   "@
670    test{b}\t{%0, %0|%0, %0}
671    cmp{b}\t{$0, %0|%0, 0}"
672   [(set_attr "type" "test,icmp")
673    (set_attr "length_immediate" "0,1")
674    (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_1"
677   [(set (reg FLAGS_REG)
678         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679                  (match_operand:QI 1 "general_operand" "qi,mq")))]
680   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681     && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%1, %0|%0, %1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_minus_1"
687   [(set (reg FLAGS_REG)
688         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689                            (match_operand:QI 1 "general_operand" "qi,mq"))
690                  (const_int 0)))]
691   "ix86_match_ccmode (insn, CCGOCmode)"
692   "cmp{b}\t{%1, %0|%0, %1}"
693   [(set_attr "type" "icmp")
694    (set_attr "mode" "QI")])
695
696 (define_insn "*cmpqi_ext_1"
697   [(set (reg FLAGS_REG)
698         (compare
699           (match_operand:QI 0 "general_operand" "Qm")
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %0|%0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_ext_1_rex64"
711   [(set (reg FLAGS_REG)
712         (compare
713           (match_operand:QI 0 "register_operand" "Q")
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 1 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)))]
719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%h1, %0|%0, %h1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_ext_2"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "const0_operand" "n")))]
733   "ix86_match_ccmode (insn, CCNOmode)"
734   "test{b}\t%h0, %h0"
735   [(set_attr "type" "test")
736    (set_attr "length_immediate" "0")
737    (set_attr "mode" "QI")])
738
739 (define_expand "cmpqi_ext_3"
740   [(set (reg:CC FLAGS_REG)
741         (compare:CC
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "general_operand" "")))]
748   ""
749   "")
750
751 (define_insn "cmpqi_ext_3_insn"
752   [(set (reg FLAGS_REG)
753         (compare
754           (subreg:QI
755             (zero_extract:SI
756               (match_operand 0 "ext_register_operand" "Q")
757               (const_int 8)
758               (const_int 8)) 0)
759           (match_operand:QI 1 "general_operand" "Qmn")))]
760   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761   "cmp{b}\t{%1, %h0|%h0, %1}"
762   [(set_attr "type" "icmp")
763    (set_attr "mode" "QI")])
764
765 (define_insn "cmpqi_ext_3_insn_rex64"
766   [(set (reg FLAGS_REG)
767         (compare
768           (subreg:QI
769             (zero_extract:SI
770               (match_operand 0 "ext_register_operand" "Q")
771               (const_int 8)
772               (const_int 8)) 0)
773           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775   "cmp{b}\t{%1, %h0|%h0, %1}"
776   [(set_attr "type" "icmp")
777    (set_attr "mode" "QI")])
778
779 (define_insn "*cmpqi_ext_4"
780   [(set (reg FLAGS_REG)
781         (compare
782           (subreg:QI
783             (zero_extract:SI
784               (match_operand 0 "ext_register_operand" "Q")
785               (const_int 8)
786               (const_int 8)) 0)
787           (subreg:QI
788             (zero_extract:SI
789               (match_operand 1 "ext_register_operand" "Q")
790               (const_int 8)
791               (const_int 8)) 0)))]
792   "ix86_match_ccmode (insn, CCmode)"
793   "cmp{b}\t{%h1, %h0|%h0, %h1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "QI")])
796
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares.  Which is what
800 ;; the old patterns did, but with many more of them.
801
802 (define_expand "cmpxf"
803   [(set (reg:CC FLAGS_REG)
804         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805                     (match_operand:XF 1 "nonmemory_operand" "")))]
806   "TARGET_80387"
807 {
808   ix86_compare_op0 = operands[0];
809   ix86_compare_op1 = operands[1];
810   DONE;
811 })
812
813 (define_expand "cmpdf"
814   [(set (reg:CC FLAGS_REG)
815         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818 {
819   ix86_compare_op0 = operands[0];
820   ix86_compare_op1 = operands[1];
821   DONE;
822 })
823
824 (define_expand "cmpsf"
825   [(set (reg:CC FLAGS_REG)
826         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828   "TARGET_80387 || TARGET_SSE_MATH"
829 {
830   ix86_compare_op0 = operands[0];
831   ix86_compare_op1 = operands[1];
832   DONE;
833 })
834
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
837 ;;
838 ;; CCFPmode     compare with exceptions
839 ;; CCFPUmode    compare with no exceptions
840
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
843
844 (define_insn "*cmpfp_0"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand 1 "register_operand" "f")
849              (match_operand 2 "const0_operand" "X"))]
850         UNSPEC_FNSTSW))]
851   "TARGET_80387
852    && FLOAT_MODE_P (GET_MODE (operands[1]))
853    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854   "* return output_fp_compare (insn, operands, 0, 0);"
855   [(set_attr "type" "multi")
856    (set_attr "unit" "i387")
857    (set (attr "mode")
858      (cond [(match_operand:SF 1 "" "")
859               (const_string "SF")
860             (match_operand:DF 1 "" "")
861               (const_string "DF")
862            ]
863            (const_string "XF")))])
864
865 (define_insn "*cmpfp_sf"
866   [(set (match_operand:HI 0 "register_operand" "=a")
867         (unspec:HI
868           [(compare:CCFP
869              (match_operand:SF 1 "register_operand" "f")
870              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871           UNSPEC_FNSTSW))]
872   "TARGET_80387"
873   "* return output_fp_compare (insn, operands, 0, 0);"
874   [(set_attr "type" "multi")
875    (set_attr "unit" "i387")
876    (set_attr "mode" "SF")])
877
878 (define_insn "*cmpfp_df"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFP
882              (match_operand:DF 1 "register_operand" "f")
883              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387"
886   "* return output_fp_compare (insn, operands, 0, 0);"
887   [(set_attr "type" "multi")
888    (set_attr "unit" "i387")
889    (set_attr "mode" "DF")])
890
891 (define_insn "*cmpfp_xf"
892   [(set (match_operand:HI 0 "register_operand" "=a")
893         (unspec:HI
894           [(compare:CCFP
895              (match_operand:XF 1 "register_operand" "f")
896              (match_operand:XF 2 "register_operand" "f"))]
897           UNSPEC_FNSTSW))]
898   "TARGET_80387"
899   "* return output_fp_compare (insn, operands, 0, 0);"
900   [(set_attr "type" "multi")
901    (set_attr "unit" "i387")
902    (set_attr "mode" "XF")])
903
904 (define_insn "*cmpfp_u"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFPU
908              (match_operand 1 "register_operand" "f")
909              (match_operand 2 "register_operand" "f"))]
910           UNSPEC_FNSTSW))]
911   "TARGET_80387
912    && FLOAT_MODE_P (GET_MODE (operands[1]))
913    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914   "* return output_fp_compare (insn, operands, 0, 1);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set (attr "mode")
918      (cond [(match_operand:SF 1 "" "")
919               (const_string "SF")
920             (match_operand:DF 1 "" "")
921               (const_string "DF")
922            ]
923            (const_string "XF")))])
924
925 (define_insn "*cmpfp_<mode>"
926   [(set (match_operand:HI 0 "register_operand" "=a")
927         (unspec:HI
928           [(compare:CCFP
929              (match_operand 1 "register_operand" "f")
930              (match_operator 3 "float_operator"
931                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932           UNSPEC_FNSTSW))]
933   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934    && FLOAT_MODE_P (GET_MODE (operands[1]))
935    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936   "* return output_fp_compare (insn, operands, 0, 0);"
937   [(set_attr "type" "multi")
938    (set_attr "unit" "i387")
939    (set_attr "fp_int_src" "true")
940    (set_attr "mode" "<MODE>")])
941
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
944
945 (define_insn "x86_fnstsw_1"
946   [(set (match_operand:HI 0 "register_operand" "=a")
947         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948   "TARGET_80387"
949   "fnstsw\t%0"
950   [(set_attr "length" "2")
951    (set_attr "mode" "SI")
952    (set_attr "unit" "i387")])
953
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
956
957 (define_insn "x86_sahf_1"
958   [(set (reg:CC FLAGS_REG)
959         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960   "!TARGET_64BIT"
961   "sahf"
962   [(set_attr "length" "1")
963    (set_attr "athlon_decode" "vector")
964    (set_attr "mode" "SI")])
965
966 ;; Pentium Pro can do steps 1 through 3 in one go.
967
968 (define_insn "*cmpfp_i_mixed"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
972   "TARGET_MIX_SSE_I387
973    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975   "* return output_fp_compare (insn, operands, 1, 0);"
976   [(set_attr "type" "fcmp,ssecomi")
977    (set (attr "mode")
978      (if_then_else (match_operand:SF 1 "" "")
979         (const_string "SF")
980         (const_string "DF")))
981    (set_attr "athlon_decode" "vector")])
982
983 (define_insn "*cmpfp_i_sse"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "x")
986                       (match_operand 1 "nonimmediate_operand" "xm")))]
987   "TARGET_SSE_MATH
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_i387"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "f")
1001                       (match_operand 1 "register_operand" "f")))]
1002   "TARGET_80387 && TARGET_CMOVE
1003    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004    && FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "fcmp")
1008    (set (attr "mode")
1009      (cond [(match_operand:SF 1 "" "")
1010               (const_string "SF")
1011             (match_operand:DF 1 "" "")
1012               (const_string "DF")
1013            ]
1014            (const_string "XF")))
1015    (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_mixed"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021   "TARGET_MIX_SSE_I387
1022    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 1);"
1025   [(set_attr "type" "fcmp,ssecomi")
1026    (set (attr "mode")
1027      (if_then_else (match_operand:SF 1 "" "")
1028         (const_string "SF")
1029         (const_string "DF")))
1030    (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_sse"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "x")
1035                        (match_operand 1 "nonimmediate_operand" "xm")))]
1036   "TARGET_SSE_MATH
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_387"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "f")
1050                        (match_operand 1 "register_operand" "f")))]
1051   "TARGET_80387 && TARGET_CMOVE
1052    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053    && FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "fcmp")
1057    (set (attr "mode")
1058      (cond [(match_operand:SF 1 "" "")
1059               (const_string "SF")
1060             (match_operand:DF 1 "" "")
1061               (const_string "DF")
1062            ]
1063            (const_string "XF")))
1064    (set_attr "athlon_decode" "vector")])
1065 \f
1066 ;; Move instructions.
1067
1068 ;; General case of fullword move.
1069
1070 (define_expand "movsi"
1071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072         (match_operand:SI 1 "general_operand" ""))]
1073   ""
1074   "ix86_expand_move (SImode, operands); DONE;")
1075
1076 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1077 ;; general_operand.
1078 ;;
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1084
1085 (define_insn "*pushsi2"
1086   [(set (match_operand:SI 0 "push_operand" "=<")
1087         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088   "!TARGET_64BIT"
1089   "push{l}\t%1"
1090   [(set_attr "type" "push")
1091    (set_attr "mode" "SI")])
1092
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095   [(set (match_operand:SI 0 "push_operand" "=X")
1096         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097   "TARGET_64BIT"
1098   "push{q}\t%q1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1101
1102 (define_insn "*pushsi2_prologue"
1103   [(set (match_operand:SI 0 "push_operand" "=<")
1104         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105    (clobber (mem:BLK (scratch)))]
1106   "!TARGET_64BIT"
1107   "push{l}\t%1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*popsi1_epilogue"
1112   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113         (mem:SI (reg:SI SP_REG)))
1114    (set (reg:SI SP_REG)
1115         (plus:SI (reg:SI SP_REG) (const_int 4)))
1116    (clobber (mem:BLK (scratch)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "popsi1"
1123   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124         (mem:SI (reg:SI SP_REG)))
1125    (set (reg:SI SP_REG)
1126         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127   "!TARGET_64BIT"
1128   "pop{l}\t%0"
1129   [(set_attr "type" "pop")
1130    (set_attr "mode" "SI")])
1131
1132 (define_insn "*movsi_xor"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "const0_operand" "i"))
1135    (clobber (reg:CC FLAGS_REG))]
1136   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137   "xor{l}\t{%0, %0|%0, %0}"
1138   [(set_attr "type" "alu1")
1139    (set_attr "mode" "SI")
1140    (set_attr "length_immediate" "0")])
1141  
1142 (define_insn "*movsi_or"
1143   [(set (match_operand:SI 0 "register_operand" "=r")
1144         (match_operand:SI 1 "immediate_operand" "i"))
1145    (clobber (reg:CC FLAGS_REG))]
1146   "reload_completed
1147    && operands[1] == constm1_rtx
1148    && (TARGET_PENTIUM || optimize_size)"
1149 {
1150   operands[1] = constm1_rtx;
1151   return "or{l}\t{%1, %0|%0, %1}";
1152 }
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "1")])
1156
1157 (define_insn "*movsi_1"
1158   [(set (match_operand:SI 0 "nonimmediate_operand"
1159                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160         (match_operand:SI 1 "general_operand"
1161                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1162   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163 {
1164   switch (get_attr_type (insn))
1165     {
1166     case TYPE_SSELOG1:
1167       if (get_attr_mode (insn) == MODE_TI)
1168         return "pxor\t%0, %0";
1169       return "xorps\t%0, %0";
1170
1171     case TYPE_SSEMOV:
1172       switch (get_attr_mode (insn))
1173         {
1174         case MODE_TI:
1175           return "movdqa\t{%1, %0|%0, %1}";
1176         case MODE_V4SF:
1177           return "movaps\t{%1, %0|%0, %1}";
1178         case MODE_SI:
1179           return "movd\t{%1, %0|%0, %1}";
1180         case MODE_SF:
1181           return "movss\t{%1, %0|%0, %1}";
1182         default:
1183           gcc_unreachable ();
1184         }
1185
1186     case TYPE_MMXADD:
1187       return "pxor\t%0, %0";
1188
1189     case TYPE_MMXMOV:
1190       if (get_attr_mode (insn) == MODE_DI)
1191         return "movq\t{%1, %0|%0, %1}";
1192       return "movd\t{%1, %0|%0, %1}";
1193
1194     case TYPE_LEA:
1195       return "lea{l}\t{%1, %0|%0, %1}";
1196
1197     default:
1198       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199       return "mov{l}\t{%1, %0|%0, %1}";
1200     }
1201 }
1202   [(set (attr "type")
1203      (cond [(eq_attr "alternative" "2")
1204               (const_string "mmxadd")
1205             (eq_attr "alternative" "3,4,5")
1206               (const_string "mmxmov")
1207             (eq_attr "alternative" "6")
1208               (const_string "sselog1")
1209             (eq_attr "alternative" "7,8,9,10,11")
1210               (const_string "ssemov")
1211             (match_operand:DI 1 "pic_32bit_operand" "")
1212               (const_string "lea")
1213            ]
1214            (const_string "imov")))
1215    (set (attr "mode")
1216      (cond [(eq_attr "alternative" "2,3")
1217               (const_string "DI")
1218             (eq_attr "alternative" "6,7")
1219               (if_then_else
1220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221                 (const_string "V4SF")
1222                 (const_string "TI"))
1223             (and (eq_attr "alternative" "8,9,10,11")
1224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225               (const_string "SF")
1226            ]
1227            (const_string "SI")))])
1228
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236   "@
1237    movabs{l}\t{%1, %P0|%P0, %1}
1238    mov{l}\t{%1, %a0|%a0, %1}"
1239   [(set_attr "type" "imov")
1240    (set_attr "modrm" "0,*")
1241    (set_attr "length_address" "8,0")
1242    (set_attr "length_immediate" "0,*")
1243    (set_attr "memory" "store")
1244    (set_attr "mode" "SI")])
1245
1246 (define_insn "*movabssi_2_rex64"
1247   [(set (match_operand:SI 0 "register_operand" "=a,r")
1248         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250   "@
1251    movabs{l}\t{%P1, %0|%0, %P1}
1252    mov{l}\t{%a1, %0|%0, %a1}"
1253   [(set_attr "type" "imov")
1254    (set_attr "modrm" "0,*")
1255    (set_attr "length_address" "8,0")
1256    (set_attr "length_immediate" "0")
1257    (set_attr "memory" "load")
1258    (set_attr "mode" "SI")])
1259
1260 (define_insn "*swapsi"
1261   [(set (match_operand:SI 0 "register_operand" "+r")
1262         (match_operand:SI 1 "register_operand" "+r"))
1263    (set (match_dup 1)
1264         (match_dup 0))]
1265   ""
1266   "xchg{l}\t%1, %0"
1267   [(set_attr "type" "imov")
1268    (set_attr "mode" "SI")
1269    (set_attr "pent_pair" "np")
1270    (set_attr "athlon_decode" "vector")])
1271
1272 (define_expand "movhi"
1273   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274         (match_operand:HI 1 "general_operand" ""))]
1275   ""
1276   "ix86_expand_move (HImode, operands); DONE;")
1277
1278 (define_insn "*pushhi2"
1279   [(set (match_operand:HI 0 "push_operand" "=X")
1280         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281   "!TARGET_64BIT"
1282   "push{l}\t%k1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "SI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "DI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444   "!TARGET_64BIT"
1445   "push{l}\t%k1"
1446   [(set_attr "type" "push")
1447    (set_attr "mode" "SI")])
1448
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453   "TARGET_64BIT"
1454   "push{q}\t%q1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "DI")])
1457
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; instruction).
1464 ;;
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there.  Then we use movzx.
1468 (define_insn "*movqi_1"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1471   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472 {
1473   switch (get_attr_type (insn))
1474     {
1475     case TYPE_IMOVX:
1476       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478     default:
1479       if (get_attr_mode (insn) == MODE_SI)
1480         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481       else
1482         return "mov{b}\t{%1, %0|%0, %1}";
1483     }
1484 }
1485   [(set (attr "type")
1486      (cond [(and (eq_attr "alternative" "5")
1487                  (not (match_operand:QI 1 "aligned_operand" "")))
1488               (const_string "imovx")
1489             (ne (symbol_ref "optimize_size") (const_int 0))
1490               (const_string "imov")
1491             (and (eq_attr "alternative" "3")
1492                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493                           (const_int 0))
1494                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1495                           (const_int 0))))
1496               (const_string "imov")
1497             (eq_attr "alternative" "3,5")
1498               (const_string "imovx")
1499             (and (ne (symbol_ref "TARGET_MOVX")
1500                      (const_int 0))
1501                  (eq_attr "alternative" "2"))
1502               (const_string "imovx")
1503            ]
1504            (const_string "imov")))
1505    (set (attr "mode")
1506       (cond [(eq_attr "alternative" "3,4,5")
1507                (const_string "SI")
1508              (eq_attr "alternative" "6")
1509                (const_string "QI")
1510              (eq_attr "type" "imovx")
1511                (const_string "SI")
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515                            (const_int 0))))
1516                (const_string "SI")
1517              ;; Avoid partial register stalls when not using QImode arithmetic
1518              (and (eq_attr "type" "imov")
1519                   (and (eq_attr "alternative" "0,1")
1520                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1521                                 (const_int 0))
1522                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1523                                 (const_int 0)))))
1524                (const_string "SI")
1525            ]
1526            (const_string "QI")))])
1527
1528 (define_expand "reload_outqi"
1529   [(parallel [(match_operand:QI 0 "" "=m")
1530               (match_operand:QI 1 "register_operand" "r")
1531               (match_operand:QI 2 "register_operand" "=&q")])]
1532   ""
1533 {
1534   rtx op0, op1, op2;
1535   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1536
1537   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1538   if (! q_regs_operand (op1, QImode))
1539     {
1540       emit_insn (gen_movqi (op2, op1));
1541       op1 = op2;
1542     }
1543   emit_insn (gen_movqi (op0, op1));
1544   DONE;
1545 })
1546
1547 (define_insn "*swapqi_1"
1548   [(set (match_operand:QI 0 "register_operand" "+r")
1549         (match_operand:QI 1 "register_operand" "+r"))
1550    (set (match_dup 1)
1551         (match_dup 0))]
1552   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1553   "xchg{l}\t%k1, %k0"
1554   [(set_attr "type" "imov")
1555    (set_attr "mode" "SI")
1556    (set_attr "pent_pair" "np")
1557    (set_attr "athlon_decode" "vector")])
1558
1559 (define_insn "*swapqi_2"
1560   [(set (match_operand:QI 0 "register_operand" "+q")
1561         (match_operand:QI 1 "register_operand" "+q"))
1562    (set (match_dup 1)
1563         (match_dup 0))]
1564   "TARGET_PARTIAL_REG_STALL"
1565   "xchg{b}\t%1, %0"
1566   [(set_attr "type" "imov")
1567    (set_attr "mode" "QI")
1568    (set_attr "pent_pair" "np")
1569    (set_attr "athlon_decode" "vector")])
1570
1571 (define_expand "movstrictqi"
1572   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1573         (match_operand:QI 1 "general_operand" ""))]
1574   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1575 {
1576   /* Don't generate memory->memory moves, go through a register.  */
1577   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1578     operands[1] = force_reg (QImode, operands[1]);
1579 })
1580
1581 (define_insn "*movstrictqi_1"
1582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1583         (match_operand:QI 1 "general_operand" "*qn,m"))]
1584   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1585    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1586   "mov{b}\t{%1, %0|%0, %1}"
1587   [(set_attr "type" "imov")
1588    (set_attr "mode" "QI")])
1589
1590 (define_insn "*movstrictqi_xor"
1591   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1592         (match_operand:QI 1 "const0_operand" "i"))
1593    (clobber (reg:CC FLAGS_REG))]
1594   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1595   "xor{b}\t{%0, %0|%0, %0}"
1596   [(set_attr "type" "alu1")
1597    (set_attr "mode" "QI")
1598    (set_attr "length_immediate" "0")])
1599
1600 (define_insn "*movsi_extv_1"
1601   [(set (match_operand:SI 0 "register_operand" "=R")
1602         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   ""
1606   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1607   [(set_attr "type" "imovx")
1608    (set_attr "mode" "SI")])
1609
1610 (define_insn "*movhi_extv_1"
1611   [(set (match_operand:HI 0 "register_operand" "=R")
1612         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1613                          (const_int 8)
1614                          (const_int 8)))]
1615   ""
1616   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1617   [(set_attr "type" "imovx")
1618    (set_attr "mode" "SI")])
1619
1620 (define_insn "*movqi_extv_1"
1621   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1622         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1623                          (const_int 8)
1624                          (const_int 8)))]
1625   "!TARGET_64BIT"
1626 {
1627   switch (get_attr_type (insn))
1628     {
1629     case TYPE_IMOVX:
1630       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1631     default:
1632       return "mov{b}\t{%h1, %0|%0, %h1}";
1633     }
1634 }
1635   [(set (attr "type")
1636      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1637                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1638                              (ne (symbol_ref "TARGET_MOVX")
1639                                  (const_int 0))))
1640         (const_string "imovx")
1641         (const_string "imov")))
1642    (set (attr "mode")
1643      (if_then_else (eq_attr "type" "imovx")
1644         (const_string "SI")
1645         (const_string "QI")))])
1646
1647 (define_insn "*movqi_extv_1_rex64"
1648   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1649         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1650                          (const_int 8)
1651                          (const_int 8)))]
1652   "TARGET_64BIT"
1653 {
1654   switch (get_attr_type (insn))
1655     {
1656     case TYPE_IMOVX:
1657       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1658     default:
1659       return "mov{b}\t{%h1, %0|%0, %h1}";
1660     }
1661 }
1662   [(set (attr "type")
1663      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1664                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1665                              (ne (symbol_ref "TARGET_MOVX")
1666                                  (const_int 0))))
1667         (const_string "imovx")
1668         (const_string "imov")))
1669    (set (attr "mode")
1670      (if_then_else (eq_attr "type" "imovx")
1671         (const_string "SI")
1672         (const_string "QI")))])
1673
1674 ;; Stores and loads of ax to arbitrary constant address.
1675 ;; We fake an second form of instruction to force reload to load address
1676 ;; into register when rax is not available
1677 (define_insn "*movabsqi_1_rex64"
1678   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1681   "@
1682    movabs{b}\t{%1, %P0|%P0, %1}
1683    mov{b}\t{%1, %a0|%a0, %1}"
1684   [(set_attr "type" "imov")
1685    (set_attr "modrm" "0,*")
1686    (set_attr "length_address" "8,0")
1687    (set_attr "length_immediate" "0,*")
1688    (set_attr "memory" "store")
1689    (set_attr "mode" "QI")])
1690
1691 (define_insn "*movabsqi_2_rex64"
1692   [(set (match_operand:QI 0 "register_operand" "=a,r")
1693         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1695   "@
1696    movabs{b}\t{%P1, %0|%0, %P1}
1697    mov{b}\t{%a1, %0|%0, %a1}"
1698   [(set_attr "type" "imov")
1699    (set_attr "modrm" "0,*")
1700    (set_attr "length_address" "8,0")
1701    (set_attr "length_immediate" "0")
1702    (set_attr "memory" "load")
1703    (set_attr "mode" "QI")])
1704
1705 (define_insn "*movdi_extzv_1"
1706   [(set (match_operand:DI 0 "register_operand" "=R")
1707         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1708                          (const_int 8)
1709                          (const_int 8)))]
1710   "TARGET_64BIT"
1711   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1712   [(set_attr "type" "imovx")
1713    (set_attr "mode" "DI")])
1714
1715 (define_insn "*movsi_extzv_1"
1716   [(set (match_operand:SI 0 "register_operand" "=R")
1717         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1718                          (const_int 8)
1719                          (const_int 8)))]
1720   ""
1721   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1722   [(set_attr "type" "imovx")
1723    (set_attr "mode" "SI")])
1724
1725 (define_insn "*movqi_extzv_2"
1726   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1727         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728                                     (const_int 8)
1729                                     (const_int 8)) 0))]
1730   "!TARGET_64BIT"
1731 {
1732   switch (get_attr_type (insn))
1733     {
1734     case TYPE_IMOVX:
1735       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1736     default:
1737       return "mov{b}\t{%h1, %0|%0, %h1}";
1738     }
1739 }
1740   [(set (attr "type")
1741      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1742                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1743                              (ne (symbol_ref "TARGET_MOVX")
1744                                  (const_int 0))))
1745         (const_string "imovx")
1746         (const_string "imov")))
1747    (set (attr "mode")
1748      (if_then_else (eq_attr "type" "imovx")
1749         (const_string "SI")
1750         (const_string "QI")))])
1751
1752 (define_insn "*movqi_extzv_2_rex64"
1753   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1754         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1755                                     (const_int 8)
1756                                     (const_int 8)) 0))]
1757   "TARGET_64BIT"
1758 {
1759   switch (get_attr_type (insn))
1760     {
1761     case TYPE_IMOVX:
1762       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1763     default:
1764       return "mov{b}\t{%h1, %0|%0, %h1}";
1765     }
1766 }
1767   [(set (attr "type")
1768      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1769                         (ne (symbol_ref "TARGET_MOVX")
1770                             (const_int 0)))
1771         (const_string "imovx")
1772         (const_string "imov")))
1773    (set (attr "mode")
1774      (if_then_else (eq_attr "type" "imovx")
1775         (const_string "SI")
1776         (const_string "QI")))])
1777
1778 (define_insn "movsi_insv_1"
1779   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1780                          (const_int 8)
1781                          (const_int 8))
1782         (match_operand:SI 1 "general_operand" "Qmn"))]
1783   "!TARGET_64BIT"
1784   "mov{b}\t{%b1, %h0|%h0, %b1}"
1785   [(set_attr "type" "imov")
1786    (set_attr "mode" "QI")])
1787
1788 (define_insn "movdi_insv_1_rex64"
1789   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1790                          (const_int 8)
1791                          (const_int 8))
1792         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1793   "TARGET_64BIT"
1794   "mov{b}\t{%b1, %h0|%h0, %b1}"
1795   [(set_attr "type" "imov")
1796    (set_attr "mode" "QI")])
1797
1798 (define_insn "*movqi_insv_2"
1799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800                          (const_int 8)
1801                          (const_int 8))
1802         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1803                      (const_int 8)))]
1804   ""
1805   "mov{b}\t{%h1, %h0|%h0, %h1}"
1806   [(set_attr "type" "imov")
1807    (set_attr "mode" "QI")])
1808
1809 (define_expand "movdi"
1810   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1811         (match_operand:DI 1 "general_operand" ""))]
1812   ""
1813   "ix86_expand_move (DImode, operands); DONE;")
1814
1815 (define_insn "*pushdi"
1816   [(set (match_operand:DI 0 "push_operand" "=<")
1817         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1818   "!TARGET_64BIT"
1819   "#")
1820
1821 (define_insn "*pushdi2_rex64"
1822   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1823         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1824   "TARGET_64BIT"
1825   "@
1826    push{q}\t%1
1827    #"
1828   [(set_attr "type" "push,multi")
1829    (set_attr "mode" "DI")])
1830
1831 ;; Convert impossible pushes of immediate to existing instructions.
1832 ;; First try to get scratch register and go through it.  In case this
1833 ;; fails, push sign extended lower part first and then overwrite
1834 ;; upper part by 32bit move.
1835 (define_peephole2
1836   [(match_scratch:DI 2 "r")
1837    (set (match_operand:DI 0 "push_operand" "")
1838         (match_operand:DI 1 "immediate_operand" ""))]
1839   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1840    && !x86_64_immediate_operand (operands[1], DImode)"
1841   [(set (match_dup 2) (match_dup 1))
1842    (set (match_dup 0) (match_dup 2))]
1843   "")
1844
1845 ;; We need to define this as both peepholer and splitter for case
1846 ;; peephole2 pass is not run.
1847 ;; "&& 1" is needed to keep it from matching the previous pattern.
1848 (define_peephole2
1849   [(set (match_operand:DI 0 "push_operand" "")
1850         (match_operand:DI 1 "immediate_operand" ""))]
1851   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1853   [(set (match_dup 0) (match_dup 1))
1854    (set (match_dup 2) (match_dup 3))]
1855   "split_di (operands + 1, 1, operands + 2, operands + 3);
1856    operands[1] = gen_lowpart (DImode, operands[2]);
1857    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1858                                                     GEN_INT (4)));
1859   ")
1860
1861 (define_split
1862   [(set (match_operand:DI 0 "push_operand" "")
1863         (match_operand:DI 1 "immediate_operand" ""))]
1864   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1865                     ? flow2_completed : reload_completed)
1866    && !symbolic_operand (operands[1], DImode)
1867    && !x86_64_immediate_operand (operands[1], DImode)"
1868   [(set (match_dup 0) (match_dup 1))
1869    (set (match_dup 2) (match_dup 3))]
1870   "split_di (operands + 1, 1, operands + 2, operands + 3);
1871    operands[1] = gen_lowpart (DImode, operands[2]);
1872    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1873                                                     GEN_INT (4)));
1874   ")
1875
1876 (define_insn "*pushdi2_prologue_rex64"
1877   [(set (match_operand:DI 0 "push_operand" "=<")
1878         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1879    (clobber (mem:BLK (scratch)))]
1880   "TARGET_64BIT"
1881   "push{q}\t%1"
1882   [(set_attr "type" "push")
1883    (set_attr "mode" "DI")])
1884
1885 (define_insn "*popdi1_epilogue_rex64"
1886   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1887         (mem:DI (reg:DI SP_REG)))
1888    (set (reg:DI SP_REG)
1889         (plus:DI (reg:DI SP_REG) (const_int 8)))
1890    (clobber (mem:BLK (scratch)))]
1891   "TARGET_64BIT"
1892   "pop{q}\t%0"
1893   [(set_attr "type" "pop")
1894    (set_attr "mode" "DI")])
1895
1896 (define_insn "popdi1"
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   "TARGET_64BIT"
1902   "pop{q}\t%0"
1903   [(set_attr "type" "pop")
1904    (set_attr "mode" "DI")])
1905
1906 (define_insn "*movdi_xor_rex64"
1907   [(set (match_operand:DI 0 "register_operand" "=r")
1908         (match_operand:DI 1 "const0_operand" "i"))
1909    (clobber (reg:CC FLAGS_REG))]
1910   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1911    && reload_completed"
1912   "xor{l}\t{%k0, %k0|%k0, %k0}"
1913   [(set_attr "type" "alu1")
1914    (set_attr "mode" "SI")
1915    (set_attr "length_immediate" "0")])
1916
1917 (define_insn "*movdi_or_rex64"
1918   [(set (match_operand:DI 0 "register_operand" "=r")
1919         (match_operand:DI 1 "const_int_operand" "i"))
1920    (clobber (reg:CC FLAGS_REG))]
1921   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1922    && reload_completed
1923    && operands[1] == constm1_rtx"
1924 {
1925   operands[1] = constm1_rtx;
1926   return "or{q}\t{%1, %0|%0, %1}";
1927 }
1928   [(set_attr "type" "alu1")
1929    (set_attr "mode" "DI")
1930    (set_attr "length_immediate" "1")])
1931
1932 (define_insn "*movdi_2"
1933   [(set (match_operand:DI 0 "nonimmediate_operand"
1934                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1935         (match_operand:DI 1 "general_operand"
1936                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1937   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1938   "@
1939    #
1940    #
1941    pxor\t%0, %0
1942    movq\t{%1, %0|%0, %1}
1943    movq\t{%1, %0|%0, %1}
1944    pxor\t%0, %0
1945    movq\t{%1, %0|%0, %1}
1946    movdqa\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    xorps\t%0, %0
1949    movlps\t{%1, %0|%0, %1}
1950    movaps\t{%1, %0|%0, %1}
1951    movlps\t{%1, %0|%0, %1}"
1952   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1953    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1954
1955 (define_split
1956   [(set (match_operand:DI 0 "push_operand" "")
1957         (match_operand:DI 1 "general_operand" ""))]
1958   "!TARGET_64BIT && reload_completed
1959    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1960   [(const_int 0)]
1961   "ix86_split_long_move (operands); DONE;")
1962
1963 ;; %%% This multiword shite has got to go.
1964 (define_split
1965   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1966         (match_operand:DI 1 "general_operand" ""))]
1967   "!TARGET_64BIT && reload_completed
1968    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1969    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970   [(const_int 0)]
1971   "ix86_split_long_move (operands); DONE;")
1972
1973 (define_insn "*movdi_1_rex64"
1974   [(set (match_operand:DI 0 "nonimmediate_operand"
1975                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1976         (match_operand:DI 1 "general_operand"
1977                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1978   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1979 {
1980   switch (get_attr_type (insn))
1981     {
1982     case TYPE_SSECVT:
1983       if (which_alternative == 13)
1984         return "movq2dq\t{%1, %0|%0, %1}";
1985       else
1986         return "movdq2q\t{%1, %0|%0, %1}";
1987     case TYPE_SSEMOV:
1988       if (get_attr_mode (insn) == MODE_TI)
1989           return "movdqa\t{%1, %0|%0, %1}";
1990       /* FALLTHRU */
1991     case TYPE_MMXMOV:
1992       /* Moves from and into integer register is done using movd opcode with
1993          REX prefix.  */
1994       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995           return "movd\t{%1, %0|%0, %1}";
1996       return "movq\t{%1, %0|%0, %1}";
1997     case TYPE_SSELOG1:
1998     case TYPE_MMXADD:
1999       return "pxor\t%0, %0";
2000     case TYPE_MULTI:
2001       return "#";
2002     case TYPE_LEA:
2003       return "lea{q}\t{%a1, %0|%0, %a1}";
2004     default:
2005       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2006       if (get_attr_mode (insn) == MODE_SI)
2007         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2008       else if (which_alternative == 2)
2009         return "movabs{q}\t{%1, %0|%0, %1}";
2010       else
2011         return "mov{q}\t{%1, %0|%0, %1}";
2012     }
2013 }
2014   [(set (attr "type")
2015      (cond [(eq_attr "alternative" "5")
2016               (const_string "mmxadd")
2017             (eq_attr "alternative" "6,7,8")
2018               (const_string "mmxmov")
2019             (eq_attr "alternative" "9")
2020               (const_string "sselog1")
2021             (eq_attr "alternative" "10,11,12")
2022               (const_string "ssemov")
2023             (eq_attr "alternative" "13,14")
2024               (const_string "ssecvt")
2025             (eq_attr "alternative" "4")
2026               (const_string "multi")
2027             (match_operand:DI 1 "pic_32bit_operand" "")
2028               (const_string "lea")
2029            ]
2030            (const_string "imov")))
2031    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2032    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2033    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2034
2035 ;; Stores and loads of ax to arbitrary constant address.
2036 ;; We fake an second form of instruction to force reload to load address
2037 ;; into register when rax is not available
2038 (define_insn "*movabsdi_1_rex64"
2039   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2040         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2041   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2042   "@
2043    movabs{q}\t{%1, %P0|%P0, %1}
2044    mov{q}\t{%1, %a0|%a0, %1}"
2045   [(set_attr "type" "imov")
2046    (set_attr "modrm" "0,*")
2047    (set_attr "length_address" "8,0")
2048    (set_attr "length_immediate" "0,*")
2049    (set_attr "memory" "store")
2050    (set_attr "mode" "DI")])
2051
2052 (define_insn "*movabsdi_2_rex64"
2053   [(set (match_operand:DI 0 "register_operand" "=a,r")
2054         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2055   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2056   "@
2057    movabs{q}\t{%P1, %0|%0, %P1}
2058    mov{q}\t{%a1, %0|%0, %a1}"
2059   [(set_attr "type" "imov")
2060    (set_attr "modrm" "0,*")
2061    (set_attr "length_address" "8,0")
2062    (set_attr "length_immediate" "0")
2063    (set_attr "memory" "load")
2064    (set_attr "mode" "DI")])
2065
2066 ;; Convert impossible stores of immediate to existing instructions.
2067 ;; First try to get scratch register and go through it.  In case this
2068 ;; fails, move by 32bit parts.
2069 (define_peephole2
2070   [(match_scratch:DI 2 "r")
2071    (set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode)"
2075   [(set (match_dup 2) (match_dup 1))
2076    (set (match_dup 0) (match_dup 2))]
2077   "")
2078
2079 ;; We need to define this as both peepholer and splitter for case
2080 ;; peephole2 pass is not run.
2081 ;; "&& 1" is needed to keep it from matching the previous pattern.
2082 (define_peephole2
2083   [(set (match_operand:DI 0 "memory_operand" "")
2084         (match_operand:DI 1 "immediate_operand" ""))]
2085   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2087   [(set (match_dup 2) (match_dup 3))
2088    (set (match_dup 4) (match_dup 5))]
2089   "split_di (operands, 2, operands + 2, operands + 4);")
2090
2091 (define_split
2092   [(set (match_operand:DI 0 "memory_operand" "")
2093         (match_operand:DI 1 "immediate_operand" ""))]
2094   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2095                     ? flow2_completed : reload_completed)
2096    && !symbolic_operand (operands[1], DImode)
2097    && !x86_64_immediate_operand (operands[1], DImode)"
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_insn "*swapdi_rex64"
2103   [(set (match_operand:DI 0 "register_operand" "+r")
2104         (match_operand:DI 1 "register_operand" "+r"))
2105    (set (match_dup 1)
2106         (match_dup 0))]
2107   "TARGET_64BIT"
2108   "xchg{q}\t%1, %0"
2109   [(set_attr "type" "imov")
2110    (set_attr "mode" "DI")
2111    (set_attr "pent_pair" "np")
2112    (set_attr "athlon_decode" "vector")])
2113
2114 (define_expand "movti"
2115   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2116         (match_operand:TI 1 "nonimmediate_operand" ""))]
2117   "TARGET_SSE || TARGET_64BIT"
2118 {
2119   if (TARGET_64BIT)
2120     ix86_expand_move (TImode, operands);
2121   else
2122     ix86_expand_vector_move (TImode, operands);
2123   DONE;
2124 })
2125
2126 (define_insn "*movti_internal"
2127   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2128         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2129   "TARGET_SSE && !TARGET_64BIT
2130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2131 {
2132   switch (which_alternative)
2133     {
2134     case 0:
2135       if (get_attr_mode (insn) == MODE_V4SF)
2136         return "xorps\t%0, %0";
2137       else
2138         return "pxor\t%0, %0";
2139     case 1:
2140     case 2:
2141       if (get_attr_mode (insn) == MODE_V4SF)
2142         return "movaps\t{%1, %0|%0, %1}";
2143       else
2144         return "movdqa\t{%1, %0|%0, %1}";
2145     default:
2146       gcc_unreachable ();
2147     }
2148 }
2149   [(set_attr "type" "sselog1,ssemov,ssemov")
2150    (set (attr "mode")
2151         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2152                     (ne (symbol_ref "optimize_size") (const_int 0)))
2153                  (const_string "V4SF")
2154                (and (eq_attr "alternative" "2")
2155                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2156                         (const_int 0)))
2157                  (const_string "V4SF")]
2158               (const_string "TI")))])
2159
2160 (define_insn "*movti_rex64"
2161   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2162         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2163   "TARGET_64BIT
2164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2165 {
2166   switch (which_alternative)
2167     {
2168     case 0:
2169     case 1:
2170       return "#";
2171     case 2:
2172       if (get_attr_mode (insn) == MODE_V4SF)
2173         return "xorps\t%0, %0";
2174       else
2175         return "pxor\t%0, %0";
2176     case 3:
2177     case 4:
2178       if (get_attr_mode (insn) == MODE_V4SF)
2179         return "movaps\t{%1, %0|%0, %1}";
2180       else
2181         return "movdqa\t{%1, %0|%0, %1}";
2182     default:
2183       gcc_unreachable ();
2184     }
2185 }
2186   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2187    (set (attr "mode")
2188         (cond [(eq_attr "alternative" "2,3")
2189                  (if_then_else
2190                    (ne (symbol_ref "optimize_size")
2191                        (const_int 0))
2192                    (const_string "V4SF")
2193                    (const_string "TI"))
2194                (eq_attr "alternative" "4")
2195                  (if_then_else
2196                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2197                             (const_int 0))
2198                         (ne (symbol_ref "optimize_size")
2199                             (const_int 0)))
2200                    (const_string "V4SF")
2201                    (const_string "TI"))]
2202                (const_string "DI")))])
2203
2204 (define_split
2205   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2206         (match_operand:TI 1 "general_operand" ""))]
2207   "reload_completed && !SSE_REG_P (operands[0])
2208    && !SSE_REG_P (operands[1])"
2209   [(const_int 0)]
2210   "ix86_split_long_move (operands); DONE;")
2211
2212 (define_expand "movsf"
2213   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2214         (match_operand:SF 1 "general_operand" ""))]
2215   ""
2216   "ix86_expand_move (SFmode, operands); DONE;")
2217
2218 (define_insn "*pushsf"
2219   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2220         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2221   "!TARGET_64BIT"
2222 {
2223   /* Anything else should be already split before reg-stack.  */
2224   gcc_assert (which_alternative == 1);
2225   return "push{l}\t%1";
2226 }
2227   [(set_attr "type" "multi,push,multi")
2228    (set_attr "unit" "i387,*,*")
2229    (set_attr "mode" "SF,SI,SF")])
2230
2231 (define_insn "*pushsf_rex64"
2232   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2233         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2234   "TARGET_64BIT"
2235 {
2236   /* Anything else should be already split before reg-stack.  */
2237   gcc_assert (which_alternative == 1);
2238   return "push{q}\t%q1";
2239 }
2240   [(set_attr "type" "multi,push,multi")
2241    (set_attr "unit" "i387,*,*")
2242    (set_attr "mode" "SF,DI,SF")])
2243
2244 (define_split
2245   [(set (match_operand:SF 0 "push_operand" "")
2246         (match_operand:SF 1 "memory_operand" ""))]
2247   "reload_completed
2248    && GET_CODE (operands[1]) == MEM
2249    && constant_pool_reference_p (operands[1])"
2250   [(set (match_dup 0)
2251         (match_dup 1))]
2252   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2253
2254
2255 ;; %%% Kill this when call knows how to work this out.
2256 (define_split
2257   [(set (match_operand:SF 0 "push_operand" "")
2258         (match_operand:SF 1 "any_fp_register_operand" ""))]
2259   "!TARGET_64BIT"
2260   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2261    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2262
2263 (define_split
2264   [(set (match_operand:SF 0 "push_operand" "")
2265         (match_operand:SF 1 "any_fp_register_operand" ""))]
2266   "TARGET_64BIT"
2267   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2268    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2269
2270 (define_insn "*movsf_1"
2271   [(set (match_operand:SF 0 "nonimmediate_operand"
2272           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2273         (match_operand:SF 1 "general_operand"
2274           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2275   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2276    && (reload_in_progress || reload_completed
2277        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2278        || GET_CODE (operands[1]) != CONST_DOUBLE
2279        || memory_operand (operands[0], SFmode))" 
2280 {
2281   switch (which_alternative)
2282     {
2283     case 0:
2284       return output_387_reg_move (insn, operands);
2285
2286     case 1:
2287       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2288         return "fstp%z0\t%y0";
2289       else
2290         return "fst%z0\t%y0";
2291
2292     case 2:
2293       return standard_80387_constant_opcode (operands[1]);
2294
2295     case 3:
2296     case 4:
2297       return "mov{l}\t{%1, %0|%0, %1}";
2298     case 5:
2299       if (get_attr_mode (insn) == MODE_TI)
2300         return "pxor\t%0, %0";
2301       else
2302         return "xorps\t%0, %0";
2303     case 6:
2304       if (get_attr_mode (insn) == MODE_V4SF)
2305         return "movaps\t{%1, %0|%0, %1}";
2306       else
2307         return "movss\t{%1, %0|%0, %1}";
2308     case 7:
2309     case 8:
2310       return "movss\t{%1, %0|%0, %1}";
2311
2312     case 9:
2313     case 10:
2314       return "movd\t{%1, %0|%0, %1}";
2315
2316     case 11:
2317       return "movq\t{%1, %0|%0, %1}";
2318
2319     default:
2320       gcc_unreachable ();
2321     }
2322 }
2323   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2324    (set (attr "mode")
2325         (cond [(eq_attr "alternative" "3,4,9,10")
2326                  (const_string "SI")
2327                (eq_attr "alternative" "5")
2328                  (if_then_else
2329                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2330                                  (const_int 0))
2331                              (ne (symbol_ref "TARGET_SSE2")
2332                                  (const_int 0)))
2333                         (eq (symbol_ref "optimize_size")
2334                             (const_int 0)))
2335                    (const_string "TI")
2336                    (const_string "V4SF"))
2337                /* For architectures resolving dependencies on
2338                   whole SSE registers use APS move to break dependency
2339                   chains, otherwise use short move to avoid extra work. 
2340
2341                   Do the same for architectures resolving dependencies on
2342                   the parts.  While in DF mode it is better to always handle
2343                   just register parts, the SF mode is different due to lack
2344                   of instructions to load just part of the register.  It is
2345                   better to maintain the whole registers in single format
2346                   to avoid problems on using packed logical operations.  */
2347                (eq_attr "alternative" "6")
2348                  (if_then_else
2349                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2350                             (const_int 0))
2351                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2352                             (const_int 0)))
2353                    (const_string "V4SF")
2354                    (const_string "SF"))
2355                (eq_attr "alternative" "11")
2356                  (const_string "DI")]
2357                (const_string "SF")))])
2358
2359 (define_insn "*swapsf"
2360   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2361         (match_operand:SF 1 "fp_register_operand" "+f"))
2362    (set (match_dup 1)
2363         (match_dup 0))]
2364   "reload_completed || TARGET_80387"
2365 {
2366   if (STACK_TOP_P (operands[0]))
2367     return "fxch\t%1";
2368   else
2369     return "fxch\t%0";
2370 }
2371   [(set_attr "type" "fxch")
2372    (set_attr "mode" "SF")])
2373
2374 (define_expand "movdf"
2375   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2376         (match_operand:DF 1 "general_operand" ""))]
2377   ""
2378   "ix86_expand_move (DFmode, operands); DONE;")
2379
2380 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2381 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2382 ;; On the average, pushdf using integers can be still shorter.  Allow this
2383 ;; pattern for optimize_size too.
2384
2385 (define_insn "*pushdf_nointeger"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2388   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   gcc_unreachable ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "unit" "i387,*,*,*")
2395    (set_attr "mode" "DF,SI,SI,DF")])
2396
2397 (define_insn "*pushdf_integer"
2398   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2399         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2400   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2401 {
2402   /* This insn should be already split before reg-stack.  */
2403   gcc_unreachable ();
2404 }
2405   [(set_attr "type" "multi")
2406    (set_attr "unit" "i387,*,*")
2407    (set_attr "mode" "DF,SI,DF")])
2408
2409 ;; %%% Kill this when call knows how to work this out.
2410 (define_split
2411   [(set (match_operand:DF 0 "push_operand" "")
2412         (match_operand:DF 1 "any_fp_register_operand" ""))]
2413   "!TARGET_64BIT && reload_completed"
2414   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2415    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2416   "")
2417
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "TARGET_64BIT && reload_completed"
2422   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2424   "")
2425
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "general_operand" ""))]
2429   "reload_completed"
2430   [(const_int 0)]
2431   "ix86_split_long_move (operands); DONE;")
2432
2433 ;; Moving is usually shorter when only FP registers are used. This separate
2434 ;; movdf pattern avoids the use of integer registers for FP operations
2435 ;; when optimizing for size.
2436
2437 (define_insn "*movdf_nointeger"
2438   [(set (match_operand:DF 0 "nonimmediate_operand"
2439                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2440         (match_operand:DF 1 "general_operand"
2441                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2442   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2443    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2444    && (reload_in_progress || reload_completed
2445        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2446        || GET_CODE (operands[1]) != CONST_DOUBLE
2447        || memory_operand (operands[0], DFmode))" 
2448 {
2449   switch (which_alternative)
2450     {
2451     case 0:
2452       return output_387_reg_move (insn, operands);
2453
2454     case 1:
2455       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2456         return "fstp%z0\t%y0";
2457       else
2458         return "fst%z0\t%y0";
2459
2460     case 2:
2461       return standard_80387_constant_opcode (operands[1]);
2462
2463     case 3:
2464     case 4:
2465       return "#";
2466     case 5:
2467       switch (get_attr_mode (insn))
2468         {
2469         case MODE_V4SF:
2470           return "xorps\t%0, %0";
2471         case MODE_V2DF:
2472           return "xorpd\t%0, %0";
2473         case MODE_TI:
2474           return "pxor\t%0, %0";
2475         default:
2476           gcc_unreachable ();
2477         }
2478     case 6:
2479     case 7:
2480     case 8:
2481       switch (get_attr_mode (insn))
2482         {
2483         case MODE_V4SF:
2484           return "movaps\t{%1, %0|%0, %1}";
2485         case MODE_V2DF:
2486           return "movapd\t{%1, %0|%0, %1}";
2487         case MODE_TI:
2488           return "movdqa\t{%1, %0|%0, %1}";
2489         case MODE_DI:
2490           return "movq\t{%1, %0|%0, %1}";
2491         case MODE_DF:
2492           return "movsd\t{%1, %0|%0, %1}";
2493         case MODE_V1DF:
2494           return "movlpd\t{%1, %0|%0, %1}";
2495         case MODE_V2SF:
2496           return "movlps\t{%1, %0|%0, %1}";
2497         default:
2498           gcc_unreachable ();
2499         }
2500
2501     default:
2502       gcc_unreachable ();
2503     }
2504 }
2505   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2506    (set (attr "mode")
2507         (cond [(eq_attr "alternative" "0,1,2")
2508                  (const_string "DF")
2509                (eq_attr "alternative" "3,4")
2510                  (const_string "SI")
2511
2512                /* For SSE1, we have many fewer alternatives.  */
2513                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2514                  (cond [(eq_attr "alternative" "5,6")
2515                           (const_string "V4SF")
2516                        ]
2517                    (const_string "V2SF"))
2518
2519                /* xorps is one byte shorter.  */
2520                (eq_attr "alternative" "5")
2521                  (cond [(ne (symbol_ref "optimize_size")
2522                             (const_int 0))
2523                           (const_string "V4SF")
2524                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2525                             (const_int 0))
2526                           (const_string "TI")
2527                        ]
2528                        (const_string "V2DF"))
2529
2530                /* For architectures resolving dependencies on
2531                   whole SSE registers use APD move to break dependency
2532                   chains, otherwise use short move to avoid extra work.
2533
2534                   movaps encodes one byte shorter.  */
2535                (eq_attr "alternative" "6")
2536                  (cond
2537                    [(ne (symbol_ref "optimize_size")
2538                         (const_int 0))
2539                       (const_string "V4SF")
2540                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2541                         (const_int 0))
2542                       (const_string "V2DF")
2543                    ]
2544                    (const_string "DF"))
2545                /* For architectures resolving dependencies on register
2546                   parts we may avoid extra work to zero out upper part
2547                   of register.  */
2548                (eq_attr "alternative" "7")
2549                  (if_then_else
2550                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2551                        (const_int 0))
2552                    (const_string "V1DF")
2553                    (const_string "DF"))
2554               ]
2555               (const_string "DF")))])
2556
2557 (define_insn "*movdf_integer"
2558   [(set (match_operand:DF 0 "nonimmediate_operand"
2559                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2560         (match_operand:DF 1 "general_operand"
2561                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2562   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2563    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2564    && (reload_in_progress || reload_completed
2565        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2566        || GET_CODE (operands[1]) != CONST_DOUBLE
2567        || memory_operand (operands[0], DFmode))" 
2568 {
2569   switch (which_alternative)
2570     {
2571     case 0:
2572       return output_387_reg_move (insn, operands);
2573
2574     case 1:
2575       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2576         return "fstp%z0\t%y0";
2577       else
2578         return "fst%z0\t%y0";
2579
2580     case 2:
2581       return standard_80387_constant_opcode (operands[1]);
2582
2583     case 3:
2584     case 4:
2585       return "#";
2586
2587     case 5:
2588       switch (get_attr_mode (insn))
2589         {
2590         case MODE_V4SF:
2591           return "xorps\t%0, %0";
2592         case MODE_V2DF:
2593           return "xorpd\t%0, %0";
2594         case MODE_TI:
2595           return "pxor\t%0, %0";
2596         default:
2597           gcc_unreachable ();
2598         }
2599     case 6:
2600     case 7:
2601     case 8:
2602       switch (get_attr_mode (insn))
2603         {
2604         case MODE_V4SF:
2605           return "movaps\t{%1, %0|%0, %1}";
2606         case MODE_V2DF:
2607           return "movapd\t{%1, %0|%0, %1}";
2608         case MODE_TI:
2609           return "movdqa\t{%1, %0|%0, %1}";
2610         case MODE_DI:
2611           return "movq\t{%1, %0|%0, %1}";
2612         case MODE_DF:
2613           return "movsd\t{%1, %0|%0, %1}";
2614         case MODE_V1DF:
2615           return "movlpd\t{%1, %0|%0, %1}";
2616         case MODE_V2SF:
2617           return "movlps\t{%1, %0|%0, %1}";
2618         default:
2619           gcc_unreachable ();
2620         }
2621
2622     default:
2623       gcc_unreachable();
2624     }
2625 }
2626   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2627    (set (attr "mode")
2628         (cond [(eq_attr "alternative" "0,1,2")
2629                  (const_string "DF")
2630                (eq_attr "alternative" "3,4")
2631                  (const_string "SI")
2632
2633                /* For SSE1, we have many fewer alternatives.  */
2634                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2635                  (cond [(eq_attr "alternative" "5,6")
2636                           (const_string "V4SF")
2637                        ]
2638                    (const_string "V2SF"))
2639
2640                /* xorps is one byte shorter.  */
2641                (eq_attr "alternative" "5")
2642                  (cond [(ne (symbol_ref "optimize_size")
2643                             (const_int 0))
2644                           (const_string "V4SF")
2645                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2646                             (const_int 0))
2647                           (const_string "TI")
2648                        ]
2649                        (const_string "V2DF"))
2650
2651                /* For architectures resolving dependencies on
2652                   whole SSE registers use APD move to break dependency
2653                   chains, otherwise use short move to avoid extra work.
2654
2655                   movaps encodes one byte shorter.  */
2656                (eq_attr "alternative" "6")
2657                  (cond
2658                    [(ne (symbol_ref "optimize_size")
2659                         (const_int 0))
2660                       (const_string "V4SF")
2661                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2662                         (const_int 0))
2663                       (const_string "V2DF")
2664                    ]
2665                    (const_string "DF"))
2666                /* For architectures resolving dependencies on register
2667                   parts we may avoid extra work to zero out upper part
2668                   of register.  */
2669                (eq_attr "alternative" "7")
2670                  (if_then_else
2671                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2672                        (const_int 0))
2673                    (const_string "V1DF")
2674                    (const_string "DF"))
2675               ]
2676               (const_string "DF")))])
2677
2678 (define_split
2679   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2680         (match_operand:DF 1 "general_operand" ""))]
2681   "reload_completed
2682    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683    && ! (ANY_FP_REG_P (operands[0]) || 
2684          (GET_CODE (operands[0]) == SUBREG
2685           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2686    && ! (ANY_FP_REG_P (operands[1]) || 
2687          (GET_CODE (operands[1]) == SUBREG
2688           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2689   [(const_int 0)]
2690   "ix86_split_long_move (operands); DONE;")
2691
2692 (define_insn "*swapdf"
2693   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2694         (match_operand:DF 1 "fp_register_operand" "+f"))
2695    (set (match_dup 1)
2696         (match_dup 0))]
2697   "reload_completed || TARGET_80387"
2698 {
2699   if (STACK_TOP_P (operands[0]))
2700     return "fxch\t%1";
2701   else
2702     return "fxch\t%0";
2703 }
2704   [(set_attr "type" "fxch")
2705    (set_attr "mode" "DF")])
2706
2707 (define_expand "movxf"
2708   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2709         (match_operand:XF 1 "general_operand" ""))]
2710   ""
2711   "ix86_expand_move (XFmode, operands); DONE;")
2712
2713 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2714 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2715 ;; Pushing using integer instructions is longer except for constants
2716 ;; and direct memory references.
2717 ;; (assuming that any given constant is pushed only once, but this ought to be
2718 ;;  handled elsewhere).
2719
2720 (define_insn "*pushxf_nointeger"
2721   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2722         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2723   "optimize_size"
2724 {
2725   /* This insn should be already split before reg-stack.  */
2726   gcc_unreachable ();
2727 }
2728   [(set_attr "type" "multi")
2729    (set_attr "unit" "i387,*,*")
2730    (set_attr "mode" "XF,SI,SI")])
2731
2732 (define_insn "*pushxf_integer"
2733   [(set (match_operand:XF 0 "push_operand" "=<,<")
2734         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2735   "!optimize_size"
2736 {
2737   /* This insn should be already split before reg-stack.  */
2738   gcc_unreachable ();
2739 }
2740   [(set_attr "type" "multi")
2741    (set_attr "unit" "i387,*")
2742    (set_attr "mode" "XF,SI")])
2743
2744 (define_split
2745   [(set (match_operand 0 "push_operand" "")
2746         (match_operand 1 "general_operand" ""))]
2747   "reload_completed
2748    && (GET_MODE (operands[0]) == XFmode
2749        || GET_MODE (operands[0]) == DFmode)
2750    && !ANY_FP_REG_P (operands[1])"
2751   [(const_int 0)]
2752   "ix86_split_long_move (operands); DONE;")
2753
2754 (define_split
2755   [(set (match_operand:XF 0 "push_operand" "")
2756         (match_operand:XF 1 "any_fp_register_operand" ""))]
2757   "!TARGET_64BIT"
2758   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2759    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2760   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2761
2762 (define_split
2763   [(set (match_operand:XF 0 "push_operand" "")
2764         (match_operand:XF 1 "any_fp_register_operand" ""))]
2765   "TARGET_64BIT"
2766   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2767    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2768   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2769
2770 ;; Do not use integer registers when optimizing for size
2771 (define_insn "*movxf_nointeger"
2772   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2773         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2774   "optimize_size
2775    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2776    && (reload_in_progress || reload_completed
2777        || GET_CODE (operands[1]) != CONST_DOUBLE
2778        || memory_operand (operands[0], XFmode))" 
2779 {
2780   switch (which_alternative)
2781     {
2782     case 0:
2783       return output_387_reg_move (insn, operands);
2784
2785     case 1:
2786       /* There is no non-popping store to memory for XFmode.  So if
2787          we need one, follow the store with a load.  */
2788       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2789         return "fstp%z0\t%y0\;fld%z0\t%y0";
2790       else
2791         return "fstp%z0\t%y0";
2792
2793     case 2:
2794       return standard_80387_constant_opcode (operands[1]);
2795
2796     case 3: case 4:
2797       return "#";
2798     default:
2799       gcc_unreachable ();
2800     }
2801 }
2802   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2803    (set_attr "mode" "XF,XF,XF,SI,SI")])
2804
2805 (define_insn "*movxf_integer"
2806   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2807         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2808   "!optimize_size
2809    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2810    && (reload_in_progress || reload_completed
2811        || GET_CODE (operands[1]) != CONST_DOUBLE
2812        || memory_operand (operands[0], XFmode))" 
2813 {
2814   switch (which_alternative)
2815     {
2816     case 0:
2817       return output_387_reg_move (insn, operands);
2818
2819     case 1:
2820       /* There is no non-popping store to memory for XFmode.  So if
2821          we need one, follow the store with a load.  */
2822       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2823         return "fstp%z0\t%y0\;fld%z0\t%y0";
2824       else
2825         return "fstp%z0\t%y0";
2826
2827     case 2:
2828       return standard_80387_constant_opcode (operands[1]);
2829
2830     case 3: case 4:
2831       return "#";
2832
2833     default:
2834       gcc_unreachable ();
2835     }
2836 }
2837   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2838    (set_attr "mode" "XF,XF,XF,SI,SI")])
2839
2840 (define_split
2841   [(set (match_operand 0 "nonimmediate_operand" "")
2842         (match_operand 1 "general_operand" ""))]
2843   "reload_completed
2844    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845    && GET_MODE (operands[0]) == XFmode
2846    && ! (ANY_FP_REG_P (operands[0]) || 
2847          (GET_CODE (operands[0]) == SUBREG
2848           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2849    && ! (ANY_FP_REG_P (operands[1]) || 
2850          (GET_CODE (operands[1]) == SUBREG
2851           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2852   [(const_int 0)]
2853   "ix86_split_long_move (operands); DONE;")
2854
2855 (define_split
2856   [(set (match_operand 0 "register_operand" "")
2857         (match_operand 1 "memory_operand" ""))]
2858   "reload_completed
2859    && GET_CODE (operands[1]) == MEM
2860    && (GET_MODE (operands[0]) == XFmode
2861        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2862    && constant_pool_reference_p (operands[1])"
2863   [(set (match_dup 0) (match_dup 1))]
2864 {
2865   rtx c = avoid_constant_pool_reference (operands[1]);
2866   rtx r = operands[0];
2867
2868   if (GET_CODE (r) == SUBREG)
2869     r = SUBREG_REG (r);
2870
2871   if (SSE_REG_P (r))
2872     {
2873       if (!standard_sse_constant_p (c))
2874         FAIL;
2875     }
2876   else if (FP_REG_P (r))
2877     {
2878       if (!standard_80387_constant_p (c))
2879         FAIL;
2880     }
2881   else if (MMX_REG_P (r))
2882     FAIL;
2883
2884   operands[1] = c;
2885 })
2886
2887 (define_insn "swapxf"
2888   [(set (match_operand:XF 0 "register_operand" "+f")
2889         (match_operand:XF 1 "register_operand" "+f"))
2890    (set (match_dup 1)
2891         (match_dup 0))]
2892   "TARGET_80387"
2893 {
2894   if (STACK_TOP_P (operands[0]))
2895     return "fxch\t%1";
2896   else
2897     return "fxch\t%0";
2898 }
2899   [(set_attr "type" "fxch")
2900    (set_attr "mode" "XF")])
2901
2902 (define_expand "movtf"
2903   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2904         (match_operand:TF 1 "nonimmediate_operand" ""))]
2905   "TARGET_64BIT"
2906 {
2907   ix86_expand_move (TFmode, operands);
2908   DONE;
2909 })
2910
2911 (define_insn "*movtf_internal"
2912   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2913         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2914   "TARGET_64BIT
2915    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2916 {
2917   switch (which_alternative)
2918     {
2919     case 0:
2920     case 1:
2921       return "#";
2922     case 2:
2923       if (get_attr_mode (insn) == MODE_V4SF)
2924         return "xorps\t%0, %0";
2925       else
2926         return "pxor\t%0, %0";
2927     case 3:
2928     case 4:
2929       if (get_attr_mode (insn) == MODE_V4SF)
2930         return "movaps\t{%1, %0|%0, %1}";
2931       else
2932         return "movdqa\t{%1, %0|%0, %1}";
2933     default:
2934       gcc_unreachable ();
2935     }
2936 }
2937   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2938    (set (attr "mode")
2939         (cond [(eq_attr "alternative" "2,3")
2940                  (if_then_else
2941                    (ne (symbol_ref "optimize_size")
2942                        (const_int 0))
2943                    (const_string "V4SF")
2944                    (const_string "TI"))
2945                (eq_attr "alternative" "4")
2946                  (if_then_else
2947                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2948                             (const_int 0))
2949                         (ne (symbol_ref "optimize_size")
2950                             (const_int 0)))
2951                    (const_string "V4SF")
2952                    (const_string "TI"))]
2953                (const_string "DI")))])
2954
2955 (define_split
2956   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2957         (match_operand:TF 1 "general_operand" ""))]
2958   "reload_completed && !SSE_REG_P (operands[0])
2959    && !SSE_REG_P (operands[1])"
2960   [(const_int 0)]
2961   "ix86_split_long_move (operands); DONE;")
2962 \f
2963 ;; Zero extension instructions
2964
2965 (define_expand "zero_extendhisi2"
2966   [(set (match_operand:SI 0 "register_operand" "")
2967      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2968   ""
2969 {
2970   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2971     {
2972       operands[1] = force_reg (HImode, operands[1]);
2973       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2974       DONE;
2975     }
2976 })
2977
2978 (define_insn "zero_extendhisi2_and"
2979   [(set (match_operand:SI 0 "register_operand" "=r")
2980      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2981    (clobber (reg:CC FLAGS_REG))]
2982   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2983   "#"
2984   [(set_attr "type" "alu1")
2985    (set_attr "mode" "SI")])
2986
2987 (define_split
2988   [(set (match_operand:SI 0 "register_operand" "")
2989         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2990    (clobber (reg:CC FLAGS_REG))]
2991   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2993               (clobber (reg:CC FLAGS_REG))])]
2994   "")
2995
2996 (define_insn "*zero_extendhisi2_movzwl"
2997   [(set (match_operand:SI 0 "register_operand" "=r")
2998      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2999   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3000   "movz{wl|x}\t{%1, %0|%0, %1}"
3001   [(set_attr "type" "imovx")
3002    (set_attr "mode" "SI")])
3003
3004 (define_expand "zero_extendqihi2"
3005   [(parallel
3006     [(set (match_operand:HI 0 "register_operand" "")
3007        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3008      (clobber (reg:CC FLAGS_REG))])]
3009   ""
3010   "")
3011
3012 (define_insn "*zero_extendqihi2_and"
3013   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3014      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3015    (clobber (reg:CC FLAGS_REG))]
3016   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3017   "#"
3018   [(set_attr "type" "alu1")
3019    (set_attr "mode" "HI")])
3020
3021 (define_insn "*zero_extendqihi2_movzbw_and"
3022   [(set (match_operand:HI 0 "register_operand" "=r,r")
3023      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3024    (clobber (reg:CC FLAGS_REG))]
3025   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3026   "#"
3027   [(set_attr "type" "imovx,alu1")
3028    (set_attr "mode" "HI")])
3029
3030 ; zero extend to SImode here to avoid partial register stalls
3031 (define_insn "*zero_extendqihi2_movzbl"
3032   [(set (match_operand:HI 0 "register_operand" "=r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3035   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3036   [(set_attr "type" "imovx")
3037    (set_attr "mode" "SI")])
3038
3039 ;; For the movzbw case strip only the clobber
3040 (define_split
3041   [(set (match_operand:HI 0 "register_operand" "")
3042         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "reload_completed 
3045    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3046    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3049
3050 ;; When source and destination does not overlap, clear destination
3051 ;; first and then do the movb
3052 (define_split
3053   [(set (match_operand:HI 0 "register_operand" "")
3054         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3055    (clobber (reg:CC FLAGS_REG))]
3056   "reload_completed
3057    && ANY_QI_REG_P (operands[0])
3058    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3059    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3060   [(set (match_dup 0) (const_int 0))
3061    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3062   "operands[2] = gen_lowpart (QImode, operands[0]);")
3063
3064 ;; Rest is handled by single and.
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && true_regnum (operands[0]) == true_regnum (operands[1])"
3071   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3072               (clobber (reg:CC FLAGS_REG))])]
3073   "")
3074
3075 (define_expand "zero_extendqisi2"
3076   [(parallel
3077     [(set (match_operand:SI 0 "register_operand" "")
3078        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3079      (clobber (reg:CC FLAGS_REG))])]
3080   ""
3081   "")
3082
3083 (define_insn "*zero_extendqisi2_and"
3084   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3088   "#"
3089   [(set_attr "type" "alu1")
3090    (set_attr "mode" "SI")])
3091
3092 (define_insn "*zero_extendqisi2_movzbw_and"
3093   [(set (match_operand:SI 0 "register_operand" "=r,r")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3097   "#"
3098   [(set_attr "type" "imovx,alu1")
3099    (set_attr "mode" "SI")])
3100
3101 (define_insn "*zero_extendqisi2_movzbw"
3102   [(set (match_operand:SI 0 "register_operand" "=r")
3103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3104   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3105   "movz{bl|x}\t{%1, %0|%0, %1}"
3106   [(set_attr "type" "imovx")
3107    (set_attr "mode" "SI")])
3108
3109 ;; For the movzbl case strip only the clobber
3110 (define_split
3111   [(set (match_operand:SI 0 "register_operand" "")
3112         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113    (clobber (reg:CC FLAGS_REG))]
3114   "reload_completed 
3115    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3116    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3117   [(set (match_dup 0)
3118         (zero_extend:SI (match_dup 1)))])
3119
3120 ;; When source and destination does not overlap, clear destination
3121 ;; first and then do the movb
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && ANY_QI_REG_P (operands[0])
3128    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3129    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3130    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3131   [(set (match_dup 0) (const_int 0))
3132    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3133   "operands[2] = gen_lowpart (QImode, operands[0]);")
3134
3135 ;; Rest is handled by single and.
3136 (define_split
3137   [(set (match_operand:SI 0 "register_operand" "")
3138         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3139    (clobber (reg:CC FLAGS_REG))]
3140   "reload_completed
3141    && true_regnum (operands[0]) == true_regnum (operands[1])"
3142   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3143               (clobber (reg:CC FLAGS_REG))])]
3144   "")
3145
3146 ;; %%% Kill me once multi-word ops are sane.
3147 (define_expand "zero_extendsidi2"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3150   ""
3151   "if (!TARGET_64BIT)
3152      {
3153        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3154        DONE;
3155      }
3156   ")
3157
3158 (define_insn "zero_extendsidi2_32"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3160         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3161    (clobber (reg:CC FLAGS_REG))]
3162   "!TARGET_64BIT"
3163   "@
3164    #
3165    #
3166    #
3167    movd\t{%1, %0|%0, %1}
3168    movd\t{%1, %0|%0, %1}"
3169   [(set_attr "mode" "SI,SI,SI,DI,TI")
3170    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3171
3172 (define_insn "zero_extendsidi2_rex64"
3173   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3174      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3175   "TARGET_64BIT"
3176   "@
3177    mov\t{%k1, %k0|%k0, %k1}
3178    #
3179    movd\t{%1, %0|%0, %1}
3180    movd\t{%1, %0|%0, %1}"
3181   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3182    (set_attr "mode" "SI,DI,SI,SI")])
3183
3184 (define_split
3185   [(set (match_operand:DI 0 "memory_operand" "")
3186      (zero_extend:DI (match_dup 0)))]
3187   "TARGET_64BIT"
3188   [(set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_split 
3192   [(set (match_operand:DI 0 "register_operand" "")
3193         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3194    (clobber (reg:CC FLAGS_REG))]
3195   "!TARGET_64BIT && reload_completed
3196    && true_regnum (operands[0]) == true_regnum (operands[1])"
3197   [(set (match_dup 4) (const_int 0))]
3198   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3199
3200 (define_split 
3201   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3202         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT && reload_completed
3205    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3206   [(set (match_dup 3) (match_dup 1))
3207    (set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_insn "zero_extendhidi2"
3211   [(set (match_operand:DI 0 "register_operand" "=r")
3212      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3213   "TARGET_64BIT"
3214   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "DI")])
3217
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3221   "TARGET_64BIT"
3222   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "DI")])
3225 \f
3226 ;; Sign extension instructions
3227
3228 (define_expand "extendsidi2"
3229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231               (clobber (reg:CC FLAGS_REG))
3232               (clobber (match_scratch:SI 2 ""))])]
3233   ""
3234 {
3235   if (TARGET_64BIT)
3236     {
3237       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3238       DONE;
3239     }
3240 })
3241
3242 (define_insn "*extendsidi2_1"
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245    (clobber (reg:CC FLAGS_REG))
3246    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3247   "!TARGET_64BIT"
3248   "#")
3249
3250 (define_insn "extendsidi2_rex64"
3251   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3253   "TARGET_64BIT"
3254   "@
3255    {cltq|cdqe}
3256    movs{lq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")
3259    (set_attr "prefix_0f" "0")
3260    (set_attr "modrm" "0,1")])
3261
3262 (define_insn "extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "TARGET_64BIT"
3266   "movs{wq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")])
3269
3270 (define_insn "extendqidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3273   "TARGET_64BIT"
3274   "movs{bq|x}\t{%1,%0|%0, %1}"
3275    [(set_attr "type" "imovx")
3276     (set_attr "mode" "DI")])
3277
3278 ;; Extend to memory case when source register does die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "(reload_completed
3285     && dead_or_set_p (insn, operands[1])
3286     && !reg_mentioned_p (operands[1], operands[0]))"
3287   [(set (match_dup 3) (match_dup 1))
3288    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289               (clobber (reg:CC FLAGS_REG))])
3290    (set (match_dup 4) (match_dup 1))]
3291   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292
3293 ;; Extend to memory case when source register does not die.
3294 (define_split 
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_operand:SI 2 "register_operand" ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   emit_move_insn (operands[3], operands[1]);
3305
3306   /* Generate a cltd if possible and doing so it profitable.  */
3307   if (true_regnum (operands[1]) == 0
3308       && true_regnum (operands[2]) == 1
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3312     }
3313   else
3314     {
3315       emit_move_insn (operands[2], operands[1]);
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3317     }
3318   emit_move_insn (operands[4], operands[2]);
3319   DONE;
3320 })
3321
3322 ;; Extend to register case.  Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3324 (define_split 
3325   [(set (match_operand:DI 0 "register_operand" "")
3326         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327    (clobber (reg:CC FLAGS_REG))
3328    (clobber (match_scratch:SI 2 ""))]
3329   "reload_completed"
3330   [(const_int 0)]
3331 {
3332   split_di (&operands[0], 1, &operands[3], &operands[4]);
3333
3334   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[3], operands[1]);
3336
3337   /* Generate a cltd if possible and doing so it profitable.  */
3338   if (true_regnum (operands[3]) == 0
3339       && (optimize_size || TARGET_USE_CLTD))
3340     {
3341       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3342       DONE;
3343     }
3344
3345   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[4], operands[1]);
3347
3348   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3349   DONE;
3350 })
3351
3352 (define_insn "extendhisi2"
3353   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355   ""
3356 {
3357   switch (get_attr_prefix_0f (insn))
3358     {
3359     case 0:
3360       return "{cwtl|cwde}";
3361     default:
3362       return "movs{wl|x}\t{%1,%0|%0, %1}";
3363     }
3364 }
3365   [(set_attr "type" "imovx")
3366    (set_attr "mode" "SI")
3367    (set (attr "prefix_0f")
3368      ;; movsx is short decodable while cwtl is vector decoded.
3369      (if_then_else (and (eq_attr "cpu" "!k6")
3370                         (eq_attr "alternative" "0"))
3371         (const_string "0")
3372         (const_string "1")))
3373    (set (attr "modrm")
3374      (if_then_else (eq_attr "prefix_0f" "0")
3375         (const_string "0")
3376         (const_string "1")))])
3377
3378 (define_insn "*extendhisi2_zext"
3379   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3380         (zero_extend:DI
3381           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382   "TARGET_64BIT"
3383 {
3384   switch (get_attr_prefix_0f (insn))
3385     {
3386     case 0:
3387       return "{cwtl|cwde}";
3388     default:
3389       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390     }
3391 }
3392   [(set_attr "type" "imovx")
3393    (set_attr "mode" "SI")
3394    (set (attr "prefix_0f")
3395      ;; movsx is short decodable while cwtl is vector decoded.
3396      (if_then_else (and (eq_attr "cpu" "!k6")
3397                         (eq_attr "alternative" "0"))
3398         (const_string "0")
3399         (const_string "1")))
3400    (set (attr "modrm")
3401      (if_then_else (eq_attr "prefix_0f" "0")
3402         (const_string "0")
3403         (const_string "1")))])
3404
3405 (define_insn "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408   ""
3409 {
3410   switch (get_attr_prefix_0f (insn))
3411     {
3412     case 0:
3413       return "{cbtw|cbw}";
3414     default:
3415       return "movs{bw|x}\t{%1,%0|%0, %1}";
3416     }
3417 }
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "HI")
3420    (set (attr "prefix_0f")
3421      ;; movsx is short decodable while cwtl is vector decoded.
3422      (if_then_else (and (eq_attr "cpu" "!k6")
3423                         (eq_attr "alternative" "0"))
3424         (const_string "0")
3425         (const_string "1")))
3426    (set (attr "modrm")
3427      (if_then_else (eq_attr "prefix_0f" "0")
3428         (const_string "0")
3429         (const_string "1")))])
3430
3431 (define_insn "extendqisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=r")
3433         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3434   ""
3435   "movs{bl|x}\t{%1,%0|%0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3438
3439 (define_insn "*extendqisi2_zext"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (zero_extend:DI
3442           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3443   "TARGET_64BIT"
3444   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3447 \f
3448 ;; Conversions between float and double.
3449
3450 ;; These are all no-ops in the model used for the 80387.  So just
3451 ;; emit moves.
3452
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3454 (define_insn "*dummy_extendsfdf2"
3455   [(set (match_operand:DF 0 "push_operand" "=<")
3456         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3457   "0"
3458   "#")
3459
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "!TARGET_64BIT"
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_split
3468   [(set (match_operand:DF 0 "push_operand" "")
3469         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3473
3474 (define_insn "*dummy_extendsfxf2"
3475   [(set (match_operand:XF 0 "push_operand" "=<")
3476         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3477   "0"
3478   "#")
3479
3480 (define_split
3481   [(set (match_operand:XF 0 "push_operand" "")
3482         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3483   ""
3484   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   "TARGET_64BIT"
3492   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3499   ""
3500   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   "TARGET_64BIT"
3508   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511
3512 (define_expand "extendsfdf2"
3513   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3516 {
3517   /* ??? Needed for compress_float_constant since all fp constants
3518      are LEGITIMATE_CONSTANT_P.  */
3519   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522     operands[1] = force_reg (SFmode, operands[1]);
3523 })
3524
3525 (define_insn "*extendsfdf2_mixed"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3530 {
3531   switch (which_alternative)
3532     {
3533     case 0:
3534       return output_387_reg_move (insn, operands);
3535
3536     case 1:
3537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538         return "fstp%z0\t%y0";
3539       else
3540         return "fst%z0\t%y0";
3541
3542     case 2:
3543       return "cvtss2sd\t{%1, %0|%0, %1}";
3544
3545     default:
3546       gcc_unreachable ();
3547     }
3548 }
3549   [(set_attr "type" "fmov,fmov,ssecvt")
3550    (set_attr "mode" "SF,XF,DF")])
3551
3552 (define_insn "*extendsfdf2_sse"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555   "TARGET_SSE2 && TARGET_SSE_MATH
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   "cvtss2sd\t{%1, %0|%0, %1}"
3558   [(set_attr "type" "ssecvt")
3559    (set_attr "mode" "DF")])
3560
3561 (define_insn "*extendsfdf2_i387"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3564   "TARGET_80387
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566 {
3567   switch (which_alternative)
3568     {
3569     case 0:
3570       return output_387_reg_move (insn, operands);
3571
3572     case 1:
3573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574         return "fstp%z0\t%y0";
3575       else
3576         return "fst%z0\t%y0";
3577
3578     default:
3579       gcc_unreachable ();
3580     }
3581 }
3582   [(set_attr "type" "fmov")
3583    (set_attr "mode" "SF,XF")])
3584
3585 (define_expand "extendsfxf2"
3586   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588   "TARGET_80387"
3589 {
3590   /* ??? Needed for compress_float_constant since all fp constants
3591      are LEGITIMATE_CONSTANT_P.  */
3592   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595     operands[1] = force_reg (SFmode, operands[1]);
3596 })
3597
3598 (define_insn "*extendsfxf2_i387"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3601   "TARGET_80387
3602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3603 {
3604   switch (which_alternative)
3605     {
3606     case 0:
3607       return output_387_reg_move (insn, operands);
3608
3609     case 1:
3610       /* There is no non-popping store to memory for XFmode.  So if
3611          we need one, follow the store with a load.  */
3612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613         return "fstp%z0\t%y0";
3614       else
3615         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3616
3617     default:
3618       gcc_unreachable ();
3619     }
3620 }
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF,XF")])
3623
3624 (define_expand "extenddfxf2"
3625   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627   "TARGET_80387"
3628 {
3629   /* ??? Needed for compress_float_constant since all fp constants
3630      are LEGITIMATE_CONSTANT_P.  */
3631   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_reg (DFmode, operands[1]);
3635 })
3636
3637 (define_insn "*extenddfxf2_i387"
3638   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3640   "TARGET_80387
3641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       return output_387_reg_move (insn, operands);
3647
3648     case 1:
3649       /* There is no non-popping store to memory for XFmode.  So if
3650          we need one, follow the store with a load.  */
3651       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653       else
3654         return "fstp%z0\t%y0";
3655
3656     default:
3657       gcc_unreachable ();
3658     }
3659 }
3660   [(set_attr "type" "fmov")
3661    (set_attr "mode" "DF,XF")])
3662
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case.  Otherwise this is just like a simple move
3666 ;; insn.  So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3668
3669 ;; Conversion from DFmode to SFmode.
3670
3671 (define_expand "truncdfsf2"
3672   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3673         (float_truncate:SF
3674           (match_operand:DF 1 "nonimmediate_operand" "")))]
3675   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3676 {
3677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678     operands[1] = force_reg (DFmode, operands[1]);
3679
3680   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3681     ;
3682   else if (flag_unsafe_math_optimizations)
3683     ;
3684   else
3685     {
3686       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3687       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3688       DONE;
3689     }
3690 })
3691
3692 (define_expand "truncdfsf2_with_temp"
3693   [(parallel [(set (match_operand:SF 0 "" "")
3694                    (float_truncate:SF (match_operand:DF 1 "" "")))
3695               (clobber (match_operand:SF 2 "" ""))])]
3696   "")
3697
3698 (define_insn "*truncdfsf_fast_mixed"
3699   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3700         (float_truncate:SF
3701           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3703 {
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708         return "fstp%z0\t%y0";
3709       else
3710         return "fst%z0\t%y0";
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713     case 2:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     default:
3716       gcc_unreachable ();
3717     }
3718 }
3719   [(set_attr "type" "fmov,fmov,ssecvt")
3720    (set_attr "mode" "SF")])
3721
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728   "TARGET_SSE2 && TARGET_SSE_MATH"
3729   "cvtsd2ss\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "ssecvt")
3731    (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_fast_i387"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737   "TARGET_80387 && flag_unsafe_math_optimizations"
3738   "* return output_387_reg_move (insn, operands);"
3739   [(set_attr "type" "fmov")
3740    (set_attr "mode" "SF")])
3741
3742 (define_insn "*truncdfsf_mixed"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3746    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3747   "TARGET_MIX_SSE_I387"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     case 1:
3757       return "#";
3758     case 2:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     default:
3761       gcc_unreachable ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,multi,ssecvt")
3765    (set_attr "unit" "*,i387,*")
3766    (set_attr "mode" "SF")])
3767
3768 (define_insn "*truncdfsf_i387"
3769   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3770         (float_truncate:SF
3771           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3772    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3773   "TARGET_80387"
3774 {
3775   switch (which_alternative)
3776     {
3777     case 0:
3778       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779         return "fstp%z0\t%y0";
3780       else
3781         return "fst%z0\t%y0";
3782     case 1:
3783       return "#";
3784     default:
3785       gcc_unreachable ();
3786     }
3787 }
3788   [(set_attr "type" "fmov,multi")
3789    (set_attr "unit" "*,i387")
3790    (set_attr "mode" "SF")])
3791
3792 (define_insn "*truncdfsf2_i387_1"
3793   [(set (match_operand:SF 0 "memory_operand" "=m")
3794         (float_truncate:SF
3795           (match_operand:DF 1 "register_operand" "f")))]
3796   "TARGET_80387
3797    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3798    && !TARGET_MIX_SSE_I387"
3799 {
3800   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801     return "fstp%z0\t%y0";
3802   else
3803     return "fst%z0\t%y0";
3804 }
3805   [(set_attr "type" "fmov")
3806    (set_attr "mode" "SF")])
3807
3808 (define_split
3809   [(set (match_operand:SF 0 "register_operand" "")
3810         (float_truncate:SF
3811          (match_operand:DF 1 "fp_register_operand" "")))
3812    (clobber (match_operand 2 "" ""))]
3813   "reload_completed"
3814   [(set (match_dup 2) (match_dup 1))
3815    (set (match_dup 0) (match_dup 2))]
3816 {
3817   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3818 })
3819
3820 ;; Conversion from XFmode to SFmode.
3821
3822 (define_expand "truncxfsf2"
3823   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3824                    (float_truncate:SF
3825                     (match_operand:XF 1 "register_operand" "")))
3826               (clobber (match_dup 2))])]
3827   "TARGET_80387"
3828 {
3829   if (flag_unsafe_math_optimizations)
3830     {
3831       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3832       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3833       if (reg != operands[0])
3834         emit_move_insn (operands[0], reg);
3835       DONE;
3836     }
3837   else
3838     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3839 })
3840
3841 (define_insn "*truncxfsf2_mixed"
3842   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3843         (float_truncate:SF
3844          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3845    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3846   "TARGET_MIX_SSE_I387"
3847 {
3848   gcc_assert (!which_alternative);
3849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850     return "fstp%z0\t%y0";
3851   else
3852     return "fst%z0\t%y0";
3853 }
3854   [(set_attr "type" "fmov,multi,multi,multi")
3855    (set_attr "unit" "*,i387,i387,i387")
3856    (set_attr "mode" "SF")])
3857
3858 (define_insn "truncxfsf2_i387_noop"
3859   [(set (match_operand:SF 0 "register_operand" "=f")
3860         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3861   "TARGET_80387 && flag_unsafe_math_optimizations"
3862 {
3863   return output_387_reg_move (insn, operands);
3864 }
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3867
3868 (define_insn "*truncxfsf2_i387"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3873   "TARGET_80387"
3874 {
3875   gcc_assert (!which_alternative);
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878    else
3879      return "fst%z0\t%y0";
3880 }
3881   [(set_attr "type" "fmov,multi,multi")
3882    (set_attr "unit" "*,i387,i387")
3883    (set_attr "mode" "SF")])
3884
3885 (define_insn "*truncxfsf2_i387_1"
3886   [(set (match_operand:SF 0 "memory_operand" "=m")
3887         (float_truncate:SF
3888          (match_operand:XF 1 "register_operand" "f")))]
3889   "TARGET_80387"
3890 {
3891   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3892     return "fstp%z0\t%y0";
3893   else
3894     return "fst%z0\t%y0";
3895 }
3896   [(set_attr "type" "fmov")
3897    (set_attr "mode" "SF")])
3898
3899 (define_split
3900   [(set (match_operand:SF 0 "register_operand" "")
3901         (float_truncate:SF
3902          (match_operand:XF 1 "register_operand" "")))
3903    (clobber (match_operand:SF 2 "memory_operand" ""))]
3904   "TARGET_80387 && reload_completed"
3905   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3906    (set (match_dup 0) (match_dup 2))]
3907   "")
3908
3909 (define_split
3910   [(set (match_operand:SF 0 "memory_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387"
3915   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3916   "")
3917
3918 ;; Conversion from XFmode to DFmode.
3919
3920 (define_expand "truncxfdf2"
3921   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3922                    (float_truncate:DF
3923                     (match_operand:XF 1 "register_operand" "")))
3924               (clobber (match_dup 2))])]
3925   "TARGET_80387"
3926 {
3927   if (flag_unsafe_math_optimizations)
3928     {
3929       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3930       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3931       if (reg != operands[0])
3932         emit_move_insn (operands[0], reg);
3933       DONE;
3934     }
3935   else
3936     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3937 })
3938
3939 (define_insn "*truncxfdf2_mixed"
3940   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3941         (float_truncate:DF
3942          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3943    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3944   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 {
3946   gcc_assert (!which_alternative);
3947   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948     return "fstp%z0\t%y0";
3949   else
3950     return "fst%z0\t%y0";
3951 }
3952   [(set_attr "type" "fmov,multi,multi,multi")
3953    (set_attr "unit" "*,i387,i387,i387")
3954    (set_attr "mode" "DF")])
3955
3956 (define_insn "truncxfdf2_i387_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3960 {
3961   return output_387_reg_move (insn, operands);
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "*truncxfdf2_i387"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3971   "TARGET_80387"
3972 {
3973   gcc_assert (!which_alternative);
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3978 }
3979   [(set_attr "type" "fmov,multi,multi")
3980    (set_attr "unit" "*,i387,i387")
3981    (set_attr "mode" "DF")])
3982
3983 (define_insn "*truncxfdf2_i387_1"
3984   [(set (match_operand:DF 0 "memory_operand" "=m")
3985         (float_truncate:DF
3986           (match_operand:XF 1 "register_operand" "f")))]
3987   "TARGET_80387"
3988 {
3989   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3990     return "fstp%z0\t%y0";
3991   else
3992     return "fst%z0\t%y0";
3993 }
3994   [(set_attr "type" "fmov")
3995    (set_attr "mode" "DF")])
3996
3997 (define_split
3998   [(set (match_operand:DF 0 "register_operand" "")
3999         (float_truncate:DF
4000          (match_operand:XF 1 "register_operand" "")))
4001    (clobber (match_operand:DF 2 "memory_operand" ""))]
4002   "TARGET_80387 && reload_completed"
4003   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4004    (set (match_dup 0) (match_dup 2))]
4005   "")
4006
4007 (define_split
4008   [(set (match_operand:DF 0 "memory_operand" "")
4009         (float_truncate:DF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:DF 2 "memory_operand" ""))]
4012   "TARGET_80387"
4013   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4014   "")
4015 \f
4016 ;; Signed conversion to DImode.
4017
4018 (define_expand "fix_truncxfdi2"
4019   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4021               (clobber (reg:CC FLAGS_REG))])]
4022   "TARGET_80387"
4023 {
4024   if (TARGET_FISTTP)
4025    {
4026      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4027      DONE;
4028    }
4029 })
4030
4031 (define_expand "fix_trunc<mode>di2"
4032   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4034               (clobber (reg:CC FLAGS_REG))])]
4035   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4036 {
4037   if (TARGET_FISTTP
4038       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4039    {
4040      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4041      DONE;
4042    }
4043   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4044    {
4045      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4046      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4047      if (out != operands[0])
4048         emit_move_insn (operands[0], out);
4049      DONE;
4050    }
4051 })
4052
4053 ;; Signed conversion to SImode.
4054
4055 (define_expand "fix_truncxfsi2"
4056   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4057                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4058               (clobber (reg:CC FLAGS_REG))])]
4059   "TARGET_80387"
4060 {
4061   if (TARGET_FISTTP)
4062    {
4063      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4064      DONE;
4065    }
4066 })
4067
4068 (define_expand "fix_trunc<mode>si2"
4069   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))])]
4072   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4073 {
4074   if (TARGET_FISTTP
4075       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4076    {
4077      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4078      DONE;
4079    }
4080   if (SSE_FLOAT_MODE_P (<MODE>mode))
4081    {
4082      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4083      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4084      if (out != operands[0])
4085         emit_move_insn (operands[0], out);
4086      DONE;
4087    }
4088 })
4089
4090 ;; Signed conversion to HImode.
4091
4092 (define_expand "fix_trunc<mode>hi2"
4093   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4094                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4095               (clobber (reg:CC FLAGS_REG))])]
4096   "TARGET_80387
4097    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4098 {
4099   if (TARGET_FISTTP)
4100    {
4101      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4102      DONE;
4103    }
4104 })
4105
4106 ;; When SSE is available, it is always faster to use it!
4107 (define_insn "fix_truncsfdi_sse"
4108   [(set (match_operand:DI 0 "register_operand" "=r,r")
4109         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4110   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111   "cvttss2si{q}\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "sseicvt")
4113    (set_attr "mode" "SF")
4114    (set_attr "athlon_decode" "double,vector")])
4115
4116 (define_insn "fix_truncdfdi_sse"
4117   [(set (match_operand:DI 0 "register_operand" "=r,r")
4118         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4119   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "DF")
4123    (set_attr "athlon_decode" "double,vector")])
4124
4125 (define_insn "fix_truncsfsi_sse"
4126   [(set (match_operand:SI 0 "register_operand" "=r,r")
4127         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4128   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttss2si\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4133
4134 (define_insn "fix_truncdfsi_sse"
4135   [(set (match_operand:SI 0 "register_operand" "=r,r")
4136         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4137   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttsd2si\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "DF")
4141    (set_attr "athlon_decode" "double,vector")])
4142
4143 ;; Avoid vector decoded forms of the instruction.
4144 (define_peephole2
4145   [(match_scratch:DF 2 "Y")
4146    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4148   "TARGET_K8 && !optimize_size"
4149   [(set (match_dup 2) (match_dup 1))
4150    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151   "")
4152
4153 (define_peephole2
4154   [(match_scratch:SF 2 "x")
4155    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160   "")
4161
4162 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4163   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4164         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4165   "TARGET_FISTTP
4166    && FLOAT_MODE_P (GET_MODE (operands[1]))
4167    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4168          && (TARGET_64BIT || <MODE>mode != DImode))
4169         && TARGET_SSE_MATH)
4170    && !(reload_completed || reload_in_progress)"
4171   "#"
4172   "&& 1"
4173   [(const_int 0)]
4174 {
4175   if (memory_operand (operands[0], VOIDmode))
4176     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4177   else
4178     {
4179       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4180       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4181                                                             operands[1],
4182                                                             operands[2]));
4183     }
4184   DONE;
4185 }
4186   [(set_attr "type" "fisttp")
4187    (set_attr "mode" "<MODE>")])
4188
4189 (define_insn "fix_trunc<mode>_i387_fisttp"
4190   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4191         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4192    (clobber (match_scratch:XF 2 "=&1f"))]
4193   "TARGET_FISTTP
4194    && FLOAT_MODE_P (GET_MODE (operands[1]))
4195    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4196          && (TARGET_64BIT || <MODE>mode != DImode))
4197         && TARGET_SSE_MATH)"
4198   "* return output_fix_trunc (insn, operands, 1);"
4199   [(set_attr "type" "fisttp")
4200    (set_attr "mode" "<MODE>")])
4201
4202 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4205    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4206    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4207   "TARGET_FISTTP
4208    && FLOAT_MODE_P (GET_MODE (operands[1]))
4209    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4210         && (TARGET_64BIT || <MODE>mode != DImode))
4211         && TARGET_SSE_MATH)"
4212   "#"
4213   [(set_attr "type" "fisttp")
4214    (set_attr "mode" "<MODE>")])
4215
4216 (define_split
4217   [(set (match_operand:X87MODEI 0 "register_operand" "")
4218         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4219    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4220    (clobber (match_scratch 3 ""))]
4221   "reload_completed"
4222   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4223               (clobber (match_dup 3))])
4224    (set (match_dup 0) (match_dup 2))]
4225   "")
4226
4227 (define_split
4228   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4230    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4231    (clobber (match_scratch 3 ""))]
4232   "reload_completed"
4233   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4234               (clobber (match_dup 3))])]
4235   "")
4236
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (reg:CC FLAGS_REG))]
4246   "TARGET_80387 && !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    && !(reload_completed || reload_in_progress)"
4251   "#"
4252   "&& 1"
4253   [(const_int 0)]
4254 {
4255   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4256
4257   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259   if (memory_operand (operands[0], VOIDmode))
4260     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261                                          operands[2], operands[3]));
4262   else
4263     {
4264       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266                                                      operands[2], operands[3],
4267                                                      operands[4]));
4268     }
4269   DONE;
4270 }
4271   [(set_attr "type" "fistp")
4272    (set_attr "i387_cw" "trunc")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_truncdi_i387"
4276   [(set (match_operand:DI 0 "memory_operand" "=m")
4277         (fix:DI (match_operand 1 "register_operand" "f")))
4278    (use (match_operand:HI 2 "memory_operand" "m"))
4279    (use (match_operand:HI 3 "memory_operand" "m"))
4280    (clobber (match_scratch:XF 4 "=&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "* return output_fix_trunc (insn, operands, 0);"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4288
4289 (define_insn "fix_truncdi_i387_with_temp"
4290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:DI (match_operand 1 "register_operand" "f,f")))
4292    (use (match_operand:HI 2 "memory_operand" "m,m"))
4293    (use (match_operand:HI 3 "memory_operand" "m,m"))
4294    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296   "TARGET_80387 && !TARGET_FISTTP
4297    && FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299   "#"
4300   [(set_attr "type" "fistp")
4301    (set_attr "i387_cw" "trunc")
4302    (set_attr "mode" "DI")])
4303
4304 (define_split 
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])
4316    (set (match_dup 0) (match_dup 4))]
4317   "")
4318
4319 (define_split 
4320   [(set (match_operand:DI 0 "memory_operand" "")
4321         (fix:DI (match_operand 1 "register_operand" "")))
4322    (use (match_operand:HI 2 "memory_operand" ""))
4323    (use (match_operand:HI 3 "memory_operand" ""))
4324    (clobber (match_operand:DI 4 "memory_operand" ""))
4325    (clobber (match_scratch 5 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328               (use (match_dup 2))
4329               (use (match_dup 3))
4330               (clobber (match_dup 5))])]
4331   "")
4332
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "TARGET_80387 && !TARGET_FISTTP
4339    && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, 0);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4345
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4359
4360 (define_split 
4361   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363    (use (match_operand:HI 2 "memory_operand" ""))
4364    (use (match_operand:HI 3 "memory_operand" ""))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))]
4371   "")
4372
4373 (define_split 
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376    (use (match_operand:HI 2 "memory_operand" ""))
4377    (use (match_operand:HI 3 "memory_operand" ""))
4378    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4379   "reload_completed"
4380   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4381               (use (match_dup 2))
4382               (use (match_dup 3))])]
4383   "")
4384
4385 (define_insn "x86_fnstcw_1"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388   "TARGET_80387"
4389   "fnstcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")])
4393
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPSR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")
4402    (set_attr "athlon_decode" "vector")])
4403 \f
4404 ;; Conversion between fixed point and floating point.
4405
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4408
4409 (define_expand "floathisf2"
4410   [(set (match_operand:SF 0 "register_operand" "")
4411         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412   "TARGET_80387 || TARGET_SSE_MATH"
4413 {
4414   if (TARGET_SSE_MATH)
4415     {
4416       emit_insn (gen_floatsisf2 (operands[0],
4417                                  convert_to_mode (SImode, operands[1], 0)));
4418       DONE;
4419     }
4420 })
4421
4422 (define_insn "*floathisf2_i387"
4423   [(set (match_operand:SF 0 "register_operand" "=f,f")
4424         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4426   "@
4427    fild%z1\t%1
4428    #"
4429   [(set_attr "type" "fmov,multi")
4430    (set_attr "mode" "SF")
4431    (set_attr "unit" "*,i387")
4432    (set_attr "fp_int_src" "true")])
4433
4434 (define_expand "floatsisf2"
4435   [(set (match_operand:SF 0 "register_operand" "")
4436         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4437   "TARGET_80387 || TARGET_SSE_MATH"
4438   "")
4439
4440 (define_insn "*floatsisf2_mixed"
4441   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4443   "TARGET_MIX_SSE_I387"
4444   "@
4445    fild%z1\t%1
4446    #
4447    cvtsi2ss\t{%1, %0|%0, %1}
4448    cvtsi2ss\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4450    (set_attr "mode" "SF")
4451    (set_attr "unit" "*,i387,*,*")
4452    (set_attr "athlon_decode" "*,*,vector,double")
4453    (set_attr "fp_int_src" "true")])
4454
4455 (define_insn "*floatsisf2_sse"
4456   [(set (match_operand:SF 0 "register_operand" "=x,x")
4457         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4458   "TARGET_SSE_MATH"
4459   "cvtsi2ss\t{%1, %0|%0, %1}"
4460   [(set_attr "type" "sseicvt")
4461    (set_attr "mode" "SF")
4462    (set_attr "athlon_decode" "vector,double")
4463    (set_attr "fp_int_src" "true")])
4464
4465 (define_insn "*floatsisf2_i387"
4466   [(set (match_operand:SF 0 "register_operand" "=f,f")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4468   "TARGET_80387"
4469   "@
4470    fild%z1\t%1
4471    #"
4472   [(set_attr "type" "fmov,multi")
4473    (set_attr "mode" "SF")
4474    (set_attr "unit" "*,i387")
4475    (set_attr "fp_int_src" "true")])
4476
4477 (define_expand "floatdisf2"
4478   [(set (match_operand:SF 0 "register_operand" "")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4480   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4481   "")
4482
4483 (define_insn "*floatdisf2_mixed"
4484   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4487   "@
4488    fild%z1\t%1
4489    #
4490    cvtsi2ss{q}\t{%1, %0|%0, %1}
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "unit" "*,i387,*,*")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatdisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_64BIT && TARGET_SSE_MATH"
4502   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "unit" "*,i387")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_expand "floathidf2"
4521   [(set (match_operand:DF 0 "register_operand" "")
4522         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4523   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524 {
4525   if (TARGET_SSE2 && TARGET_SSE_MATH)
4526     {
4527       emit_insn (gen_floatsidf2 (operands[0],
4528                                  convert_to_mode (SImode, operands[1], 0)));
4529       DONE;
4530     }
4531 })
4532
4533 (define_insn "*floathidf2_i387"
4534   [(set (match_operand:DF 0 "register_operand" "=f,f")
4535         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4536   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4537   "@
4538    fild%z1\t%1
4539    #"
4540   [(set_attr "type" "fmov,multi")
4541    (set_attr "mode" "DF")
4542    (set_attr "unit" "*,i387")
4543    (set_attr "fp_int_src" "true")])
4544
4545 (define_expand "floatsidf2"
4546   [(set (match_operand:DF 0 "register_operand" "")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549   "")
4550
4551 (define_insn "*floatsidf2_mixed"
4552   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4555   "@
4556    fild%z1\t%1
4557    #
4558    cvtsi2sd\t{%1, %0|%0, %1}
4559    cvtsi2sd\t{%1, %0|%0, %1}"
4560   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561    (set_attr "mode" "DF")
4562    (set_attr "unit" "*,i387,*,*")
4563    (set_attr "athlon_decode" "*,*,double,direct")
4564    (set_attr "fp_int_src" "true")])
4565
4566 (define_insn "*floatsidf2_sse"
4567   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4568         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_SSE2 && TARGET_SSE_MATH"
4570   "cvtsi2sd\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "DF")
4573    (set_attr "athlon_decode" "double,direct")
4574    (set_attr "fp_int_src" "true")])
4575
4576 (define_insn "*floatsidf2_i387"
4577   [(set (match_operand:DF 0 "register_operand" "=f,f")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4579   "TARGET_80387"
4580   "@
4581    fild%z1\t%1
4582    #"
4583   [(set_attr "type" "fmov,multi")
4584    (set_attr "mode" "DF")
4585    (set_attr "unit" "*,i387")
4586    (set_attr "fp_int_src" "true")])
4587
4588 (define_expand "floatdidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4593
4594 (define_insn "*floatdidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd{q}\t{%1, %0|%0, %1}
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "unit" "*,i387,*,*")
4606    (set_attr "athlon_decode" "*,*,double,direct")
4607    (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatdidf2_sse"
4610   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4611         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4612   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4613   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4614   [(set_attr "type" "sseicvt")
4615    (set_attr "mode" "DF")
4616    (set_attr "athlon_decode" "double,direct")
4617    (set_attr "fp_int_src" "true")])
4618
4619 (define_insn "*floatdidf2_i387"
4620   [(set (match_operand:DF 0 "register_operand" "=f,f")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4622   "TARGET_80387"
4623   "@
4624    fild%z1\t%1
4625    #"
4626   [(set_attr "type" "fmov,multi")
4627    (set_attr "mode" "DF")
4628    (set_attr "unit" "*,i387")
4629    (set_attr "fp_int_src" "true")])
4630
4631 (define_insn "floathixf2"
4632   [(set (match_operand:XF 0 "register_operand" "=f,f")
4633         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4634   "TARGET_80387"
4635   "@
4636    fild%z1\t%1
4637    #"
4638   [(set_attr "type" "fmov,multi")
4639    (set_attr "mode" "XF")
4640    (set_attr "unit" "*,i387")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "floatsixf2"
4644   [(set (match_operand:XF 0 "register_operand" "=f,f")
4645         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "XF")
4652    (set_attr "unit" "*,i387")
4653    (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "floatdixf2"
4656   [(set (match_operand:XF 0 "register_operand" "=f,f")
4657         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658   "TARGET_80387"
4659   "@
4660    fild%z1\t%1
4661    #"
4662   [(set_attr "type" "fmov,multi")
4663    (set_attr "mode" "XF")
4664    (set_attr "unit" "*,i387")
4665    (set_attr "fp_int_src" "true")])
4666
4667 ;; %%% Kill these when reload knows how to do it.
4668 (define_split
4669   [(set (match_operand 0 "fp_register_operand" "")
4670         (float (match_operand 1 "register_operand" "")))]
4671   "reload_completed
4672    && TARGET_80387
4673    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4674   [(const_int 0)]
4675 {
4676   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4677   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4678   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4679   ix86_free_from_memory (GET_MODE (operands[1]));
4680   DONE;
4681 })
4682
4683 (define_expand "floatunssisf2"
4684   [(use (match_operand:SF 0 "register_operand" ""))
4685    (use (match_operand:SI 1 "register_operand" ""))]
4686   "!TARGET_64BIT && TARGET_SSE_MATH"
4687   "x86_emit_floatuns (operands); DONE;")
4688
4689 (define_expand "floatunsdisf2"
4690   [(use (match_operand:SF 0 "register_operand" ""))
4691    (use (match_operand:DI 1 "register_operand" ""))]
4692   "TARGET_64BIT && TARGET_SSE_MATH"
4693   "x86_emit_floatuns (operands); DONE;")
4694
4695 (define_expand "floatunsdidf2"
4696   [(use (match_operand:DF 0 "register_operand" ""))
4697    (use (match_operand:DI 1 "register_operand" ""))]
4698   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699   "x86_emit_floatuns (operands); DONE;")
4700 \f
4701 ;; SSE extract/set expanders
4702
4703 \f
4704 ;; Add instructions
4705
4706 ;; %%% splits for addditi3
4707
4708 (define_expand "addti3"
4709   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4711                  (match_operand:TI 2 "x86_64_general_operand" "")))
4712    (clobber (reg:CC FLAGS_REG))]
4713   "TARGET_64BIT"
4714   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4715
4716 (define_insn "*addti3_1"
4717   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4719                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4720    (clobber (reg:CC FLAGS_REG))]
4721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4722   "#")
4723
4724 (define_split
4725   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4727                  (match_operand:TI 2 "general_operand" "")))
4728    (clobber (reg:CC FLAGS_REG))]
4729   "TARGET_64BIT && reload_completed"
4730   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4731                                           UNSPEC_ADD_CARRY))
4732               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4733    (parallel [(set (match_dup 3)
4734                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4735                                      (match_dup 4))
4736                             (match_dup 5)))
4737               (clobber (reg:CC FLAGS_REG))])]
4738   "split_ti (operands+0, 1, operands+0, operands+3);
4739    split_ti (operands+1, 1, operands+1, operands+4);
4740    split_ti (operands+2, 1, operands+2, operands+5);")
4741
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4746
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4754
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4762
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "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:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4780
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4792
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4804
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4816
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4828
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4840
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4853
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4877
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4885
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4893
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4910
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4918
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4921
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4937 {
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4949 }
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4952
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4966 {
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4970 }
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4973
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4988 {
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
4999 }
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5002
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5016 {
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5019 }
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5037 {
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5072 {
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076 }
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5079
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5086 {
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5092
5093     case TYPE_INCDEC:
5094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5095       if (operands[2] == const1_rtx)
5096         return "inc{q}\t%0";
5097       else
5098         {
5099           gcc_assert (operands[2] == constm1_rtx);
5100           return "dec{q}\t%0";
5101         }
5102
5103     default:
5104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5105
5106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5108       if (GET_CODE (operands[2]) == CONST_INT
5109           /* Avoid overflows.  */
5110           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5111           && (INTVAL (operands[2]) == 128
5112               || (INTVAL (operands[2]) < 0
5113                   && INTVAL (operands[2]) != -128)))
5114         {
5115           operands[2] = GEN_INT (-INTVAL (operands[2]));
5116           return "sub{q}\t{%2, %0|%0, %2}";
5117         }
5118       return "add{q}\t{%2, %0|%0, %2}";
5119     }
5120 }
5121   [(set (attr "type")
5122      (cond [(eq_attr "alternative" "2")
5123               (const_string "lea")
5124             ; Current assemblers are broken and do not allow @GOTOFF in
5125             ; ought but a memory context.
5126             (match_operand:DI 2 "pic_symbolic_operand" "")
5127               (const_string "lea")
5128             (match_operand:DI 2 "incdec_operand" "")
5129               (const_string "incdec")
5130            ]
5131            (const_string "alu")))
5132    (set_attr "mode" "DI")])
5133
5134 ;; Convert lea to the lea pattern to avoid flags dependency.
5135 (define_split
5136   [(set (match_operand:DI 0 "register_operand" "")
5137         (plus:DI (match_operand:DI 1 "register_operand" "")
5138                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5139    (clobber (reg:CC FLAGS_REG))]
5140   "TARGET_64BIT && reload_completed
5141    && true_regnum (operands[0]) != true_regnum (operands[1])"
5142   [(set (match_dup 0)
5143         (plus:DI (match_dup 1)
5144                  (match_dup 2)))]
5145   "")
5146
5147 (define_insn "*adddi_2_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare
5150           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5151                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5152           (const_int 0)))                       
5153    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5154         (plus:DI (match_dup 1) (match_dup 2)))]
5155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5156    && ix86_binary_operator_ok (PLUS, DImode, operands)
5157    /* Current assemblers are broken and do not allow @GOTOFF in
5158       ought but a memory context.  */
5159    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5160 {
5161   switch (get_attr_type (insn))
5162     {
5163     case TYPE_INCDEC:
5164       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else
5168         {
5169           gcc_assert (operands[2] == constm1_rtx);
5170           return "dec{q}\t%0";
5171         }
5172
5173     default:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175       /* ???? We ought to handle there the 32bit case too
5176          - do we need new constraint?  */
5177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5179       if (GET_CODE (operands[2]) == CONST_INT
5180           /* Avoid overflows.  */
5181           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182           && (INTVAL (operands[2]) == 128
5183               || (INTVAL (operands[2]) < 0
5184                   && INTVAL (operands[2]) != -128)))
5185         {
5186           operands[2] = GEN_INT (-INTVAL (operands[2]));
5187           return "sub{q}\t{%2, %0|%0, %2}";
5188         }
5189       return "add{q}\t{%2, %0|%0, %2}";
5190     }
5191 }
5192   [(set (attr "type")
5193      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194         (const_string "incdec")
5195         (const_string "alu")))
5196    (set_attr "mode" "DI")])
5197
5198 (define_insn "*adddi_3_rex64"
5199   [(set (reg FLAGS_REG)
5200         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5201                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5202    (clobber (match_scratch:DI 0 "=r"))]
5203   "TARGET_64BIT
5204    && ix86_match_ccmode (insn, CCZmode)
5205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5206    /* Current assemblers are broken and do not allow @GOTOFF in
5207       ought but a memory context.  */
5208    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5209 {
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_INCDEC:
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       if (operands[2] == const1_rtx)
5215         return "inc{q}\t%0";
5216       else
5217         {
5218           gcc_assert (operands[2] == constm1_rtx);
5219           return "dec{q}\t%0";
5220         }
5221
5222     default:
5223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224       /* ???? We ought to handle there the 32bit case too
5225          - do we need new constraint?  */
5226       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5227          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5228       if (GET_CODE (operands[2]) == CONST_INT
5229           /* Avoid overflows.  */
5230           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5231           && (INTVAL (operands[2]) == 128
5232               || (INTVAL (operands[2]) < 0
5233                   && INTVAL (operands[2]) != -128)))
5234         {
5235           operands[2] = GEN_INT (-INTVAL (operands[2]));
5236           return "sub{q}\t{%2, %0|%0, %2}";
5237         }
5238       return "add{q}\t{%2, %0|%0, %2}";
5239     }
5240 }
5241   [(set (attr "type")
5242      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5243         (const_string "incdec")
5244         (const_string "alu")))
5245    (set_attr "mode" "DI")])
5246
5247 ; For comparisons against 1, -1 and 128, we may generate better code
5248 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5249 ; is matched then.  We can't accept general immediate, because for
5250 ; case of overflows,  the result is messed up.
5251 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5252 ; when negated.
5253 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5254 ; only for comparisons not depending on it.
5255 (define_insn "*adddi_4_rex64"
5256   [(set (reg FLAGS_REG)
5257         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5258                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5259    (clobber (match_scratch:DI 0 "=rm"))]
5260   "TARGET_64BIT
5261    &&  ix86_match_ccmode (insn, CCGCmode)"
5262 {
5263   switch (get_attr_type (insn))
5264     {
5265     case TYPE_INCDEC:
5266       if (operands[2] == constm1_rtx)
5267         return "inc{q}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == const1_rtx);
5271           return "dec{q}\t%0";
5272         }
5273
5274     default:
5275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5278       if ((INTVAL (operands[2]) == -128
5279            || (INTVAL (operands[2]) > 0
5280                && INTVAL (operands[2]) != 128))
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5283         return "sub{q}\t{%2, %0|%0, %2}";
5284       operands[2] = GEN_INT (-INTVAL (operands[2]));
5285       return "add{q}\t{%2, %0|%0, %2}";
5286     }
5287 }
5288   [(set (attr "type")
5289      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290         (const_string "incdec")
5291         (const_string "alu")))
5292    (set_attr "mode" "DI")])
5293
5294 (define_insn "*adddi_5_rex64"
5295   [(set (reg FLAGS_REG)
5296         (compare
5297           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5298                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5299           (const_int 0)))                       
5300    (clobber (match_scratch:DI 0 "=r"))]
5301   "TARGET_64BIT
5302    && ix86_match_ccmode (insn, CCGOCmode)
5303    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5304    /* Current assemblers are broken and do not allow @GOTOFF in
5305       ought but a memory context.  */
5306    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5307 {
5308   switch (get_attr_type (insn))
5309     {
5310     case TYPE_INCDEC:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else
5315         {
5316           gcc_assert (operands[2] == constm1_rtx);
5317           return "dec{q}\t%0";
5318         }
5319
5320     default:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5324       if (GET_CODE (operands[2]) == CONST_INT
5325           /* Avoid overflows.  */
5326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327           && (INTVAL (operands[2]) == 128
5328               || (INTVAL (operands[2]) < 0
5329                   && INTVAL (operands[2]) != -128)))
5330         {
5331           operands[2] = GEN_INT (-INTVAL (operands[2]));
5332           return "sub{q}\t{%2, %0|%0, %2}";
5333         }
5334       return "add{q}\t{%2, %0|%0, %2}";
5335     }
5336 }
5337   [(set (attr "type")
5338      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339         (const_string "incdec")
5340         (const_string "alu")))
5341    (set_attr "mode" "DI")])
5342
5343
5344 (define_insn "*addsi_1"
5345   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %0|%0, %a2}";
5356
5357     case TYPE_INCDEC:
5358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359       if (operands[2] == const1_rtx)
5360         return "inc{l}\t%0";
5361       else
5362         {
5363           gcc_assert (operands[2] == constm1_rtx);
5364           return "dec{l}\t%0";
5365         }
5366
5367     default:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           && (INTVAL (operands[2]) == 128
5374               || (INTVAL (operands[2]) < 0
5375                   && INTVAL (operands[2]) != -128)))
5376         {
5377           operands[2] = GEN_INT (-INTVAL (operands[2]));
5378           return "sub{l}\t{%2, %0|%0, %2}";
5379         }
5380       return "add{l}\t{%2, %0|%0, %2}";
5381     }
5382 }
5383   [(set (attr "type")
5384      (cond [(eq_attr "alternative" "2")
5385               (const_string "lea")
5386             ; Current assemblers are broken and do not allow @GOTOFF in
5387             ; ought but a memory context.
5388             (match_operand:SI 2 "pic_symbolic_operand" "")
5389               (const_string "lea")
5390             (match_operand:SI 2 "incdec_operand" "")
5391               (const_string "incdec")
5392            ]
5393            (const_string "alu")))
5394    (set_attr "mode" "SI")])
5395
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5397 (define_split
5398   [(set (match_operand 0 "register_operand" "")
5399         (plus (match_operand 1 "register_operand" "")
5400               (match_operand 2 "nonmemory_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "reload_completed
5403    && true_regnum (operands[0]) != true_regnum (operands[1])"
5404   [(const_int 0)]
5405 {
5406   rtx pat;
5407   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5408      may confuse gen_lowpart.  */
5409   if (GET_MODE (operands[0]) != Pmode)
5410     {
5411       operands[1] = gen_lowpart (Pmode, operands[1]);
5412       operands[2] = gen_lowpart (Pmode, operands[2]);
5413     }
5414   operands[0] = gen_lowpart (SImode, operands[0]);
5415   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5416   if (Pmode != SImode)
5417     pat = gen_rtx_SUBREG (SImode, pat, 0);
5418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5419   DONE;
5420 })
5421
5422 ;; It may seem that nonimmediate operand is proper one for operand 1.
5423 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5424 ;; we take care in ix86_binary_operator_ok to not allow two memory
5425 ;; operands so proper swapping will be done in reload.  This allow
5426 ;; patterns constructed from addsi_1 to match.
5427 (define_insn "addsi_1_zext"
5428   [(set (match_operand:DI 0 "register_operand" "=r,r")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5431                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5434 {
5435   switch (get_attr_type (insn))
5436     {
5437     case TYPE_LEA:
5438       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5439       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5440
5441     case TYPE_INCDEC:
5442       if (operands[2] == const1_rtx)
5443         return "inc{l}\t%k0";
5444       else
5445         {
5446           gcc_assert (operands[2] == constm1_rtx);
5447           return "dec{l}\t%k0";
5448         }
5449
5450     default:
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if (GET_CODE (operands[2]) == CONST_INT
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{l}\t{%2, %k0|%k0, %2}";
5460         }
5461       return "add{l}\t{%2, %k0|%k0, %2}";
5462     }
5463 }
5464   [(set (attr "type")
5465      (cond [(eq_attr "alternative" "1")
5466               (const_string "lea")
5467             ; Current assemblers are broken and do not allow @GOTOFF in
5468             ; ought but a memory context.
5469             (match_operand:SI 2 "pic_symbolic_operand" "")
5470               (const_string "lea")
5471             (match_operand:SI 2 "incdec_operand" "")
5472               (const_string "incdec")
5473            ]
5474            (const_string "alu")))
5475    (set_attr "mode" "SI")])
5476
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479   [(set (match_operand:DI 0 "register_operand" "")
5480         (zero_extend:DI
5481           (plus:SI (match_operand:SI 1 "register_operand" "")
5482                    (match_operand:SI 2 "nonmemory_operand" ""))))
5483    (clobber (reg:CC FLAGS_REG))]
5484   "TARGET_64BIT && reload_completed
5485    && true_regnum (operands[0]) != true_regnum (operands[1])"
5486   [(set (match_dup 0)
5487         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5488 {
5489   operands[1] = gen_lowpart (Pmode, operands[1]);
5490   operands[2] = gen_lowpart (Pmode, operands[2]);
5491 })
5492
5493 (define_insn "*addsi_2"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5498           (const_int 0)))                       
5499    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:SI (match_dup 1) (match_dup 2)))]
5501   "ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, SImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{l}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{l}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5523       if (GET_CODE (operands[2]) == CONST_INT
5524           && (INTVAL (operands[2]) == 128
5525               || (INTVAL (operands[2]) < 0
5526                   && INTVAL (operands[2]) != -128)))
5527         {
5528           operands[2] = GEN_INT (-INTVAL (operands[2]));
5529           return "sub{l}\t{%2, %0|%0, %2}";
5530         }
5531       return "add{l}\t{%2, %0|%0, %2}";
5532     }
5533 }
5534   [(set (attr "type")
5535      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5536         (const_string "incdec")
5537         (const_string "alu")))
5538    (set_attr "mode" "SI")])
5539
5540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5541 (define_insn "*addsi_2_zext"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:SI 2 "general_operand" "rmni"))
5546           (const_int 0)))                       
5547    (set (match_operand:DI 0 "register_operand" "=r")
5548         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (operands[2] == const1_rtx)
5559         return "inc{l}\t%k0";
5560       else
5561         {
5562           gcc_assert (operands[2] == constm1_rtx);
5563           return "dec{l}\t%k0";
5564         }
5565
5566     default:
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %k0|%k0, %2}";
5576         }
5577       return "add{l}\t{%2, %k0|%k0, %2}";
5578     }
5579 }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5585
5586 (define_insn "*addsi_3"
5587   [(set (reg FLAGS_REG)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (clobber (match_scratch:SI 0 "=r"))]
5591   "ix86_match_ccmode (insn, CCZmode)
5592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593    /* Current assemblers are broken and do not allow @GOTOFF in
5594       ought but a memory context.  */
5595    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 {
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_INCDEC:
5600       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5601       if (operands[2] == const1_rtx)
5602         return "inc{l}\t%0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{l}\t%0";
5607         }
5608
5609     default:
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %0|%0, %2}";
5620         }
5621       return "add{l}\t{%2, %0|%0, %2}";
5622     }
5623 }
5624   [(set (attr "type")
5625      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5626         (const_string "incdec")
5627         (const_string "alu")))
5628    (set_attr "mode" "SI")])
5629
5630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5631 (define_insn "*addsi_3_zext"
5632   [(set (reg FLAGS_REG)
5633         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 {
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5653
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5676 ; is matched then.  We can't accept general immediate, because for
5677 ; case of overflows,  the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683   [(set (reg FLAGS_REG)
5684         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685                  (match_operand:SI 2 "const_int_operand" "n")))
5686    (clobber (match_scratch:SI 0 "=rm"))]
5687   "ix86_match_ccmode (insn, CCGCmode)
5688    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5689 {
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == constm1_rtx)
5694         return "inc{l}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == const1_rtx);
5698           return "dec{l}\t%0";
5699         }
5700
5701     default:
5702       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if ((INTVAL (operands[2]) == -128
5706            || (INTVAL (operands[2]) > 0
5707                && INTVAL (operands[2]) != 128)))
5708         return "sub{l}\t{%2, %0|%0, %2}";
5709       operands[2] = GEN_INT (-INTVAL (operands[2]));
5710       return "add{l}\t{%2, %0|%0, %2}";
5711     }
5712 }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715         (const_string "incdec")
5716         (const_string "alu")))
5717    (set_attr "mode" "SI")])
5718
5719 (define_insn "*addsi_5"
5720   [(set (reg FLAGS_REG)
5721         (compare
5722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723                    (match_operand:SI 2 "general_operand" "rmni"))
5724           (const_int 0)))                       
5725    (clobber (match_scratch:SI 0 "=r"))]
5726   "ix86_match_ccmode (insn, CCGOCmode)
5727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else
5739         {
5740           gcc_assert (operands[2] == constm1_rtx);
5741           return "dec{l}\t%0";
5742         }
5743
5744     default:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5758 }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5764
5765 (define_expand "addhi3"
5766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5767                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5768                             (match_operand:HI 2 "general_operand" "")))
5769               (clobber (reg:CC FLAGS_REG))])]
5770   "TARGET_HIMODE_MATH"
5771   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5772
5773 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5774 ;; type optimizations enabled by define-splits.  This is not important
5775 ;; for PII, and in fact harmful because of partial register stalls.
5776
5777 (define_insn "*addhi_1_lea"
5778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5779         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5780                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "!TARGET_PARTIAL_REG_STALL
5783    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5784 {
5785   switch (get_attr_type (insn))
5786     {
5787     case TYPE_LEA:
5788       return "#";
5789     case TYPE_INCDEC:
5790       if (operands[2] == const1_rtx)
5791         return "inc{w}\t%0";
5792       else
5793         {
5794           gcc_assert (operands[2] == constm1_rtx);
5795           return "dec{w}\t%0";
5796         }
5797
5798     default:
5799       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5800          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5801       if (GET_CODE (operands[2]) == CONST_INT
5802           && (INTVAL (operands[2]) == 128
5803               || (INTVAL (operands[2]) < 0
5804                   && INTVAL (operands[2]) != -128)))
5805         {
5806           operands[2] = GEN_INT (-INTVAL (operands[2]));
5807           return "sub{w}\t{%2, %0|%0, %2}";
5808         }
5809       return "add{w}\t{%2, %0|%0, %2}";
5810     }
5811 }
5812   [(set (attr "type")
5813      (if_then_else (eq_attr "alternative" "2")
5814         (const_string "lea")
5815         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5816            (const_string "incdec")
5817            (const_string "alu"))))
5818    (set_attr "mode" "HI,HI,SI")])
5819
5820 (define_insn "*addhi_1"
5821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5822         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5823                  (match_operand:HI 2 "general_operand" "ri,rm")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "TARGET_PARTIAL_REG_STALL
5826    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5827 {
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_INCDEC:
5831       if (operands[2] == const1_rtx)
5832         return "inc{w}\t%0";
5833       else
5834         {
5835           gcc_assert (operands[2] == constm1_rtx);
5836           return "dec{w}\t%0";
5837         }
5838
5839     default:
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (GET_CODE (operands[2]) == CONST_INT
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{w}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{w}\t{%2, %0|%0, %2}";
5851     }
5852 }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "HI")])
5858
5859 (define_insn "*addhi_2"
5860   [(set (reg FLAGS_REG)
5861         (compare
5862           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5864           (const_int 0)))                       
5865    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5866         (plus:HI (match_dup 1) (match_dup 2)))]
5867   "ix86_match_ccmode (insn, CCGOCmode)
5868    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5869 {
5870   switch (get_attr_type (insn))
5871     {
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{w}\t%0";
5875       else
5876         {
5877           gcc_assert (operands[2] == constm1_rtx);
5878           return "dec{w}\t%0";
5879         }
5880
5881     default:
5882       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5883          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5884       if (GET_CODE (operands[2]) == CONST_INT
5885           && (INTVAL (operands[2]) == 128
5886               || (INTVAL (operands[2]) < 0
5887                   && INTVAL (operands[2]) != -128)))
5888         {
5889           operands[2] = GEN_INT (-INTVAL (operands[2]));
5890           return "sub{w}\t{%2, %0|%0, %2}";
5891         }
5892       return "add{w}\t{%2, %0|%0, %2}";
5893     }
5894 }
5895   [(set (attr "type")
5896      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5897         (const_string "incdec")
5898         (const_string "alu")))
5899    (set_attr "mode" "HI")])
5900
5901 (define_insn "*addhi_3"
5902   [(set (reg FLAGS_REG)
5903         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5904                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5905    (clobber (match_scratch:HI 0 "=r"))]
5906   "ix86_match_ccmode (insn, CCZmode)
5907    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
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 ; See comments above addsi_4 for details.
5941 (define_insn "*addhi_4"
5942   [(set (reg FLAGS_REG)
5943         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5944                  (match_operand:HI 2 "const_int_operand" "n")))
5945    (clobber (match_scratch:HI 0 "=rm"))]
5946   "ix86_match_ccmode (insn, CCGCmode)
5947    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5948 {
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == constm1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == const1_rtx);
5957           return "dec{w}\t%0";
5958         }
5959
5960     default:
5961       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5963          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5964       if ((INTVAL (operands[2]) == -128
5965            || (INTVAL (operands[2]) > 0
5966                && INTVAL (operands[2]) != 128)))
5967         return "sub{w}\t{%2, %0|%0, %2}";
5968       operands[2] = GEN_INT (-INTVAL (operands[2]));
5969       return "add{w}\t{%2, %0|%0, %2}";
5970     }
5971 }
5972   [(set (attr "type")
5973      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974         (const_string "incdec")
5975         (const_string "alu")))
5976    (set_attr "mode" "SI")])
5977
5978
5979 (define_insn "*addhi_5"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5983                    (match_operand:HI 2 "general_operand" "rmni"))
5984           (const_int 0)))                       
5985    (clobber (match_scratch:HI 0 "=r"))]
5986   "ix86_match_ccmode (insn, CCGOCmode)
5987    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{w}\t%0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{w}\t{%2, %0|%0, %2}";
6010         }
6011       return "add{w}\t{%2, %0|%0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "HI")])
6019
6020 (define_expand "addqi3"
6021   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6022                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6023                             (match_operand:QI 2 "general_operand" "")))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "TARGET_QIMODE_MATH"
6026   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6027
6028 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6029 (define_insn "*addqi_1_lea"
6030   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033    (clobber (reg:CC FLAGS_REG))]
6034   "!TARGET_PARTIAL_REG_STALL
6035    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6036 {
6037   int widen = (which_alternative == 2);
6038   switch (get_attr_type (insn))
6039     {
6040     case TYPE_LEA:
6041       return "#";
6042     case TYPE_INCDEC:
6043       if (operands[2] == const1_rtx)
6044         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045       else
6046         {
6047           gcc_assert (operands[2] == constm1_rtx);
6048           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6049         }
6050
6051     default:
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if (GET_CODE (operands[2]) == CONST_INT
6055           && (INTVAL (operands[2]) == 128
6056               || (INTVAL (operands[2]) < 0
6057                   && INTVAL (operands[2]) != -128)))
6058         {
6059           operands[2] = GEN_INT (-INTVAL (operands[2]));
6060           if (widen)
6061             return "sub{l}\t{%2, %k0|%k0, %2}";
6062           else
6063             return "sub{b}\t{%2, %0|%0, %2}";
6064         }
6065       if (widen)
6066         return "add{l}\t{%k2, %k0|%k0, %k2}";
6067       else
6068         return "add{b}\t{%2, %0|%0, %2}";
6069     }
6070 }
6071   [(set (attr "type")
6072      (if_then_else (eq_attr "alternative" "3")
6073         (const_string "lea")
6074         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6075            (const_string "incdec")
6076            (const_string "alu"))))
6077    (set_attr "mode" "QI,QI,SI,SI")])
6078
6079 (define_insn "*addqi_1"
6080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6083    (clobber (reg:CC FLAGS_REG))]
6084   "TARGET_PARTIAL_REG_STALL
6085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6086 {
6087   int widen = (which_alternative == 2);
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6118 }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "QI,QI,SI")])
6124
6125 (define_insn "*addqi_1_slp"
6126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127         (plus:QI (match_dup 0)
6128                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6129    (clobber (reg:CC FLAGS_REG))]
6130   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6132 {
6133   switch (get_attr_type (insn))
6134     {
6135     case TYPE_INCDEC:
6136       if (operands[1] == const1_rtx)
6137         return "inc{b}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[1] == constm1_rtx);
6141           return "dec{b}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6146       if (GET_CODE (operands[1]) == CONST_INT
6147           && INTVAL (operands[1]) < 0)
6148         {
6149           operands[1] = GEN_INT (-INTVAL (operands[1]));
6150           return "sub{b}\t{%1, %0|%0, %1}";
6151         }
6152       return "add{b}\t{%1, %0|%0, %1}";
6153     }
6154 }
6155   [(set (attr "type")
6156      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6157         (const_string "incdec")
6158         (const_string "alu1")))
6159    (set (attr "memory")
6160      (if_then_else (match_operand 1 "memory_operand" "")
6161         (const_string "load")
6162         (const_string "none")))
6163    (set_attr "mode" "QI")])
6164
6165 (define_insn "*addqi_2"
6166   [(set (reg FLAGS_REG)
6167         (compare
6168           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6169                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6170           (const_int 0)))
6171    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6172         (plus:QI (match_dup 1) (match_dup 2)))]
6173   "ix86_match_ccmode (insn, CCGOCmode)
6174    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175 {
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx
6184                       || (GET_CODE (operands[2]) == CONST_INT
6185                           && INTVAL (operands[2]) == 255));
6186           return "dec{b}\t%0";
6187         }
6188
6189     default:
6190       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6191       if (GET_CODE (operands[2]) == CONST_INT
6192           && INTVAL (operands[2]) < 0)
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{b}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{b}\t{%2, %0|%0, %2}";
6198     }
6199 }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "QI")])
6205
6206 (define_insn "*addqi_3"
6207   [(set (reg FLAGS_REG)
6208         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6209                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6210    (clobber (match_scratch:QI 0 "=q"))]
6211   "ix86_match_ccmode (insn, CCZmode)
6212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6213 {
6214   switch (get_attr_type (insn))
6215     {
6216     case TYPE_INCDEC:
6217       if (operands[2] == const1_rtx)
6218         return "inc{b}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx
6222                       || (GET_CODE (operands[2]) == CONST_INT
6223                           && INTVAL (operands[2]) == 255));
6224           return "dec{b}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && INTVAL (operands[2]) < 0)
6231         {
6232           operands[2] = GEN_INT (-INTVAL (operands[2]));
6233           return "sub{b}\t{%2, %0|%0, %2}";
6234         }
6235       return "add{b}\t{%2, %0|%0, %2}";
6236     }
6237 }
6238   [(set (attr "type")
6239      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240         (const_string "incdec")
6241         (const_string "alu")))
6242    (set_attr "mode" "QI")])
6243
6244 ; See comments above addsi_4 for details.
6245 (define_insn "*addqi_4"
6246   [(set (reg FLAGS_REG)
6247         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6248                  (match_operand:QI 2 "const_int_operand" "n")))
6249    (clobber (match_scratch:QI 0 "=qm"))]
6250   "ix86_match_ccmode (insn, CCGCmode)
6251    && (INTVAL (operands[2]) & 0xff) != 0x80"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx
6257           || (GET_CODE (operands[2]) == CONST_INT
6258               && INTVAL (operands[2]) == 255))
6259         return "inc{b}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == const1_rtx);
6263           return "dec{b}\t%0";
6264         }
6265
6266     default:
6267       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6268       if (INTVAL (operands[2]) < 0)
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "add{b}\t{%2, %0|%0, %2}";
6272         }
6273       return "sub{b}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "QI")])
6281
6282
6283 (define_insn "*addqi_5"
6284   [(set (reg FLAGS_REG)
6285         (compare
6286           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6287                    (match_operand:QI 2 "general_operand" "qmni"))
6288           (const_int 0)))
6289    (clobber (match_scratch:QI 0 "=q"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{b}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx
6301                       || (GET_CODE (operands[2]) == CONST_INT
6302                           && INTVAL (operands[2]) == 255));
6303           return "dec{b}\t%0";
6304         }
6305
6306     default:
6307       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6308       if (GET_CODE (operands[2]) == CONST_INT
6309           && INTVAL (operands[2]) < 0)
6310         {
6311           operands[2] = GEN_INT (-INTVAL (operands[2]));
6312           return "sub{b}\t{%2, %0|%0, %2}";
6313         }
6314       return "add{b}\t{%2, %0|%0, %2}";
6315     }
6316 }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set_attr "mode" "QI")])
6322
6323
6324 (define_insn "addqi_ext_1"
6325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6326                          (const_int 8)
6327                          (const_int 8))
6328         (plus:SI
6329           (zero_extract:SI
6330             (match_operand 1 "ext_register_operand" "0")
6331             (const_int 8)
6332             (const_int 8))
6333           (match_operand:QI 2 "general_operand" "Qmn")))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "!TARGET_64BIT"
6336 {
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       if (operands[2] == const1_rtx)
6341         return "inc{b}\t%h0";
6342       else
6343         {
6344           gcc_assert (operands[2] == constm1_rtx
6345                       || (GET_CODE (operands[2]) == CONST_INT
6346                           && INTVAL (operands[2]) == 255));
6347           return "dec{b}\t%h0";
6348         }
6349
6350     default:
6351       return "add{b}\t{%2, %h0|%h0, %2}";
6352     }
6353 }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI")])
6359
6360 (define_insn "*addqi_ext_1_rex64"
6361   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6362                          (const_int 8)
6363                          (const_int 8))
6364         (plus:SI
6365           (zero_extract:SI
6366             (match_operand 1 "ext_register_operand" "0")
6367             (const_int 8)
6368             (const_int 8))
6369           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "TARGET_64BIT"
6372 {
6373   switch (get_attr_type (insn))
6374     {
6375     case TYPE_INCDEC:
6376       if (operands[2] == const1_rtx)
6377         return "inc{b}\t%h0";
6378       else
6379         {
6380           gcc_assert (operands[2] == constm1_rtx
6381                       || (GET_CODE (operands[2]) == CONST_INT
6382                           && INTVAL (operands[2]) == 255));
6383           return "dec{b}\t%h0";
6384         }
6385
6386     default:
6387       return "add{b}\t{%2, %h0|%h0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396 (define_insn "*addqi_ext_2"
6397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398                          (const_int 8)
6399                          (const_int 8))
6400         (plus:SI
6401           (zero_extract:SI
6402             (match_operand 1 "ext_register_operand" "%0")
6403             (const_int 8)
6404             (const_int 8))
6405           (zero_extract:SI
6406             (match_operand 2 "ext_register_operand" "Q")
6407             (const_int 8)
6408             (const_int 8))))
6409    (clobber (reg:CC FLAGS_REG))]
6410   ""
6411   "add{b}\t{%h2, %h0|%h0, %h2}"
6412   [(set_attr "type" "alu")
6413    (set_attr "mode" "QI")])
6414
6415 ;; The patterns that match these are at the end of this file.
6416
6417 (define_expand "addxf3"
6418   [(set (match_operand:XF 0 "register_operand" "")
6419         (plus:XF (match_operand:XF 1 "register_operand" "")
6420                  (match_operand:XF 2 "register_operand" "")))]
6421   "TARGET_80387"
6422   "")
6423
6424 (define_expand "adddf3"
6425   [(set (match_operand:DF 0 "register_operand" "")
6426         (plus:DF (match_operand:DF 1 "register_operand" "")
6427                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6428   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6429   "")
6430
6431 (define_expand "addsf3"
6432   [(set (match_operand:SF 0 "register_operand" "")
6433         (plus:SF (match_operand:SF 1 "register_operand" "")
6434                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6435   "TARGET_80387 || TARGET_SSE_MATH"
6436   "")
6437 \f
6438 ;; Subtract instructions
6439
6440 ;; %%% splits for subditi3
6441
6442 (define_expand "subti3"
6443   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6444                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6445                              (match_operand:TI 2 "x86_64_general_operand" "")))
6446               (clobber (reg:CC FLAGS_REG))])]
6447   "TARGET_64BIT"
6448   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6449
6450 (define_insn "*subti3_1"
6451   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6452         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6453                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6454    (clobber (reg:CC FLAGS_REG))]
6455   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6456   "#")
6457
6458 (define_split
6459   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6460         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6461                   (match_operand:TI 2 "general_operand" "")))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && reload_completed"
6464   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6465               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6466    (parallel [(set (match_dup 3)
6467                    (minus:DI (match_dup 4)
6468                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6469                                       (match_dup 5))))
6470               (clobber (reg:CC FLAGS_REG))])]
6471   "split_ti (operands+0, 1, operands+0, operands+3);
6472    split_ti (operands+1, 1, operands+1, operands+4);
6473    split_ti (operands+2, 1, operands+2, operands+5);")
6474
6475 ;; %%% splits for subsidi3
6476
6477 (define_expand "subdi3"
6478   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6479                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6480                              (match_operand:DI 2 "x86_64_general_operand" "")))
6481               (clobber (reg:CC FLAGS_REG))])]
6482   ""
6483   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6484
6485 (define_insn "*subdi3_1"
6486   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6487         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6488                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6491   "#")
6492
6493 (define_split
6494   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6495         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6496                   (match_operand:DI 2 "general_operand" "")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!TARGET_64BIT && reload_completed"
6499   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6500               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6501    (parallel [(set (match_dup 3)
6502                    (minus:SI (match_dup 4)
6503                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6504                                       (match_dup 5))))
6505               (clobber (reg:CC FLAGS_REG))])]
6506   "split_di (operands+0, 1, operands+0, operands+3);
6507    split_di (operands+1, 1, operands+1, operands+4);
6508    split_di (operands+2, 1, operands+2, operands+5);")
6509
6510 (define_insn "subdi3_carry_rex64"
6511   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6512           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6513             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6514                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6517   "sbb{q}\t{%2, %0|%0, %2}"
6518   [(set_attr "type" "alu")
6519    (set_attr "pent_pair" "pu")
6520    (set_attr "mode" "DI")])
6521
6522 (define_insn "*subdi_1_rex64"
6523   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6524         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6525                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6526    (clobber (reg:CC FLAGS_REG))]
6527   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6528   "sub{q}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "mode" "DI")])
6531
6532 (define_insn "*subdi_2_rex64"
6533   [(set (reg FLAGS_REG)
6534         (compare
6535           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6537           (const_int 0)))
6538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6539         (minus:DI (match_dup 1) (match_dup 2)))]
6540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6541    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542   "sub{q}\t{%2, %0|%0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "DI")])
6545
6546 (define_insn "*subdi_3_rex63"
6547   [(set (reg FLAGS_REG)
6548         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6549                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6550    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551         (minus:DI (match_dup 1) (match_dup 2)))]
6552   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{q}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "DI")])
6557
6558 (define_insn "subqi3_carry"
6559   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6560           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6561             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:QI 2 "general_operand" "qi,qm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6565   "sbb{b}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "QI")])
6569
6570 (define_insn "subhi3_carry"
6571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6573             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6574                (match_operand:HI 2 "general_operand" "ri,rm"))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6577   "sbb{w}\t{%2, %0|%0, %2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "pent_pair" "pu")
6580    (set_attr "mode" "HI")])
6581
6582 (define_insn "subsi3_carry"
6583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6585             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6586                (match_operand:SI 2 "general_operand" "ri,rm"))))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6589   "sbb{l}\t{%2, %0|%0, %2}"
6590   [(set_attr "type" "alu")
6591    (set_attr "pent_pair" "pu")
6592    (set_attr "mode" "SI")])
6593
6594 (define_insn "subsi3_carry_zext"
6595   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6596           (zero_extend:DI
6597             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6598               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6599                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sbb{l}\t{%2, %k0|%k0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "SI")])
6606
6607 (define_expand "subsi3"
6608   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6609                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6610                              (match_operand:SI 2 "general_operand" "")))
6611               (clobber (reg:CC FLAGS_REG))])]
6612   ""
6613   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6614
6615 (define_insn "*subsi_1"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618                   (match_operand:SI 2 "general_operand" "ri,rm")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sub{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "SI")])
6624
6625 (define_insn "*subsi_1_zext"
6626   [(set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_operand:SI 1 "register_operand" "0")
6629                     (match_operand:SI 2 "general_operand" "rim"))))
6630    (clobber (reg:CC FLAGS_REG))]
6631   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{l}\t{%2, %k0|%k0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "SI")])
6635
6636 (define_insn "*subsi_2"
6637   [(set (reg FLAGS_REG)
6638         (compare
6639           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6640                     (match_operand:SI 2 "general_operand" "ri,rm"))
6641           (const_int 0)))
6642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:SI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCGOCmode)
6645    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6646   "sub{l}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "SI")])
6649
6650 (define_insn "*subsi_2_zext"
6651   [(set (reg FLAGS_REG)
6652         (compare
6653           (minus:SI (match_operand:SI 1 "register_operand" "0")
6654                     (match_operand:SI 2 "general_operand" "rim"))
6655           (const_int 0)))
6656    (set (match_operand:DI 0 "register_operand" "=r")
6657         (zero_extend:DI
6658           (minus:SI (match_dup 1)
6659                     (match_dup 2))))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sub{l}\t{%2, %k0|%k0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "SI")])
6665
6666 (define_insn "*subsi_3"
6667   [(set (reg FLAGS_REG)
6668         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6669                  (match_operand:SI 2 "general_operand" "ri,rm")))
6670    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671         (minus:SI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCmode)
6673    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sub{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "SI")])
6677
6678 (define_insn "*subsi_3_zext"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:SI 1 "register_operand" "0")
6681                  (match_operand:SI 2 "general_operand" "rim")))
6682    (set (match_operand:DI 0 "register_operand" "=r")
6683         (zero_extend:DI
6684           (minus:SI (match_dup 1)
6685                     (match_dup 2))))]
6686   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6687    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6691
6692 (define_expand "subhi3"
6693   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6694                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6695                              (match_operand:HI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_HIMODE_MATH"
6698   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6699
6700 (define_insn "*subhi_1"
6701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:HI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6706   "sub{w}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "HI")])
6709
6710 (define_insn "*subhi_2"
6711   [(set (reg FLAGS_REG)
6712         (compare
6713           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6714                     (match_operand:HI 2 "general_operand" "ri,rm"))
6715           (const_int 0)))
6716    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6717         (minus:HI (match_dup 1) (match_dup 2)))]
6718   "ix86_match_ccmode (insn, CCGOCmode)
6719    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6720   "sub{w}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "HI")])
6723
6724 (define_insn "*subhi_3"
6725   [(set (reg FLAGS_REG)
6726         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6727                  (match_operand:HI 2 "general_operand" "ri,rm")))
6728    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6729         (minus:HI (match_dup 1) (match_dup 2)))]
6730   "ix86_match_ccmode (insn, CCmode)
6731    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6732   "sub{w}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "HI")])
6735
6736 (define_expand "subqi3"
6737   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6738                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6739                              (match_operand:QI 2 "general_operand" "")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_QIMODE_MATH"
6742   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6743
6744 (define_insn "*subqi_1"
6745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6746         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6747                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6750   "sub{b}\t{%2, %0|%0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "QI")])
6753
6754 (define_insn "*subqi_1_slp"
6755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6756         (minus:QI (match_dup 0)
6757                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6761   "sub{b}\t{%1, %0|%0, %1}"
6762   [(set_attr "type" "alu1")
6763    (set_attr "mode" "QI")])
6764
6765 (define_insn "*subqi_2"
6766   [(set (reg FLAGS_REG)
6767         (compare
6768           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6769                     (match_operand:QI 2 "general_operand" "qi,qm"))
6770           (const_int 0)))
6771    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6772         (minus:HI (match_dup 1) (match_dup 2)))]
6773   "ix86_match_ccmode (insn, CCGOCmode)
6774    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6775   "sub{b}\t{%2, %0|%0, %2}"
6776   [(set_attr "type" "alu")
6777    (set_attr "mode" "QI")])
6778
6779 (define_insn "*subqi_3"
6780   [(set (reg FLAGS_REG)
6781         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6782                  (match_operand:QI 2 "general_operand" "qi,qm")))
6783    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6784         (minus:HI (match_dup 1) (match_dup 2)))]
6785   "ix86_match_ccmode (insn, CCmode)
6786    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6787   "sub{b}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "QI")])
6790
6791 ;; The patterns that match these are at the end of this file.
6792
6793 (define_expand "subxf3"
6794   [(set (match_operand:XF 0 "register_operand" "")
6795         (minus:XF (match_operand:XF 1 "register_operand" "")
6796                   (match_operand:XF 2 "register_operand" "")))]
6797   "TARGET_80387"
6798   "")
6799
6800 (define_expand "subdf3"
6801   [(set (match_operand:DF 0 "register_operand" "")
6802         (minus:DF (match_operand:DF 1 "register_operand" "")
6803                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6804   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6805   "")
6806
6807 (define_expand "subsf3"
6808   [(set (match_operand:SF 0 "register_operand" "")
6809         (minus:SF (match_operand:SF 1 "register_operand" "")
6810                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6811   "TARGET_80387 || TARGET_SSE_MATH"
6812   "")
6813 \f
6814 ;; Multiply instructions
6815
6816 (define_expand "muldi3"
6817   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6818                    (mult:DI (match_operand:DI 1 "register_operand" "")
6819                             (match_operand:DI 2 "x86_64_general_operand" "")))
6820               (clobber (reg:CC FLAGS_REG))])]
6821   "TARGET_64BIT"
6822   "")
6823
6824 (define_insn "*muldi3_1_rex64"
6825   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6826         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6827                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{q}\t{%2, %1, %0|%0, %1, %2}
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "DI")])
6847
6848 (define_expand "mulsi3"
6849   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6850                    (mult:SI (match_operand:SI 1 "register_operand" "")
6851                             (match_operand:SI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   ""
6854   "")
6855
6856 (define_insn "*mulsi3_1"
6857   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6858         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{l}\t{%2, %1, %0|%0, %1, %2}
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1")
6872                   (const_string "vector")
6873                (and (eq_attr "alternative" "2")
6874                     (match_operand 1 "memory_operand" ""))
6875                   (const_string "vector")]
6876               (const_string "direct")))
6877    (set_attr "mode" "SI")])
6878
6879 (define_insn "*mulsi3_1_zext"
6880   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881         (zero_extend:DI
6882           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6883                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_64BIT
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "@
6888    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %k0|%k0, %2}"
6891   [(set_attr "type" "imul")
6892    (set_attr "prefix_0f" "0,0,1")
6893    (set (attr "athlon_decode")
6894         (cond [(eq_attr "cpu" "athlon")
6895                   (const_string "vector")
6896                (eq_attr "alternative" "1")
6897                   (const_string "vector")
6898                (and (eq_attr "alternative" "2")
6899                     (match_operand 1 "memory_operand" ""))
6900                   (const_string "vector")]
6901               (const_string "direct")))
6902    (set_attr "mode" "SI")])
6903
6904 (define_expand "mulhi3"
6905   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6906                    (mult:HI (match_operand:HI 1 "register_operand" "")
6907                             (match_operand:HI 2 "general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_HIMODE_MATH"
6910   "")
6911
6912 (define_insn "*mulhi3_1"
6913   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6914         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6918   "@
6919    imul{w}\t{%2, %1, %0|%0, %1, %2}
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %0|%0, %2}"
6922   [(set_attr "type" "imul")
6923    (set_attr "prefix_0f" "0,0,1")
6924    (set (attr "athlon_decode")
6925         (cond [(eq_attr "cpu" "athlon")
6926                   (const_string "vector")
6927                (eq_attr "alternative" "1,2")
6928                   (const_string "vector")]
6929               (const_string "direct")))
6930    (set_attr "mode" "HI")])
6931
6932 (define_expand "mulqi3"
6933   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6934                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6935                             (match_operand:QI 2 "register_operand" "")))
6936               (clobber (reg:CC FLAGS_REG))])]
6937   "TARGET_QIMODE_MATH"
6938   "")
6939
6940 (define_insn "*mulqi3_1"
6941   [(set (match_operand:QI 0 "register_operand" "=a")
6942         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6943                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6944    (clobber (reg:CC FLAGS_REG))]
6945   "TARGET_QIMODE_MATH
6946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6947   "mul{b}\t%2"
6948   [(set_attr "type" "imul")
6949    (set_attr "length_immediate" "0")
6950    (set (attr "athlon_decode")
6951      (if_then_else (eq_attr "cpu" "athlon")
6952         (const_string "vector")
6953         (const_string "direct")))
6954    (set_attr "mode" "QI")])
6955
6956 (define_expand "umulqihi3"
6957   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6958                    (mult:HI (zero_extend:HI
6959                               (match_operand:QI 1 "nonimmediate_operand" ""))
6960                             (zero_extend:HI
6961                               (match_operand:QI 2 "register_operand" ""))))
6962               (clobber (reg:CC FLAGS_REG))])]
6963   "TARGET_QIMODE_MATH"
6964   "")
6965
6966 (define_insn "*umulqihi3_1"
6967   [(set (match_operand:HI 0 "register_operand" "=a")
6968         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970    (clobber (reg:CC FLAGS_REG))]
6971   "TARGET_QIMODE_MATH
6972    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6973   "mul{b}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "direct")))
6980    (set_attr "mode" "QI")])
6981
6982 (define_expand "mulqihi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6985                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "TARGET_QIMODE_MATH"
6988   "")
6989
6990 (define_insn "*mulqihi3_insn"
6991   [(set (match_operand:HI 0 "register_operand" "=a")
6992         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6993                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_QIMODE_MATH
6996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997   "imul{b}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "direct")))
7004    (set_attr "mode" "QI")])
7005
7006 (define_expand "umulditi3"
7007   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7008                    (mult:TI (zero_extend:TI
7009                               (match_operand:DI 1 "nonimmediate_operand" ""))
7010                             (zero_extend:TI
7011                               (match_operand:DI 2 "register_operand" ""))))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_64BIT"
7014   "")
7015
7016 (define_insn "*umulditi3_insn"
7017   [(set (match_operand:TI 0 "register_operand" "=A")
7018         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7019                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "TARGET_64BIT
7022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7023   "mul{q}\t%2"
7024   [(set_attr "type" "imul")
7025    (set_attr "length_immediate" "0")
7026    (set (attr "athlon_decode")
7027      (if_then_else (eq_attr "cpu" "athlon")
7028         (const_string "vector")
7029         (const_string "double")))
7030    (set_attr "mode" "DI")])
7031
7032 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7033 (define_expand "umulsidi3"
7034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035                    (mult:DI (zero_extend:DI
7036                               (match_operand:SI 1 "nonimmediate_operand" ""))
7037                             (zero_extend:DI
7038                               (match_operand:SI 2 "register_operand" ""))))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "!TARGET_64BIT"
7041   "")
7042
7043 (define_insn "*umulsidi3_insn"
7044   [(set (match_operand:DI 0 "register_operand" "=A")
7045         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7046                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "!TARGET_64BIT
7049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7050   "mul{l}\t%2"
7051   [(set_attr "type" "imul")
7052    (set_attr "length_immediate" "0")
7053    (set (attr "athlon_decode")
7054      (if_then_else (eq_attr "cpu" "athlon")
7055         (const_string "vector")
7056         (const_string "double")))
7057    (set_attr "mode" "SI")])
7058
7059 (define_expand "mulditi3"
7060   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7061                    (mult:TI (sign_extend:TI
7062                               (match_operand:DI 1 "nonimmediate_operand" ""))
7063                             (sign_extend:TI
7064                               (match_operand:DI 2 "register_operand" ""))))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7068
7069 (define_insn "*mulditi3_insn"
7070   [(set (match_operand:TI 0 "register_operand" "=A")
7071         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7072                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "TARGET_64BIT
7075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7076   "imul{q}\t%2"
7077   [(set_attr "type" "imul")
7078    (set_attr "length_immediate" "0")
7079    (set (attr "athlon_decode")
7080      (if_then_else (eq_attr "cpu" "athlon")
7081         (const_string "vector")
7082         (const_string "double")))
7083    (set_attr "mode" "DI")])
7084
7085 (define_expand "mulsidi3"
7086   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7087                    (mult:DI (sign_extend:DI
7088                               (match_operand:SI 1 "nonimmediate_operand" ""))
7089                             (sign_extend:DI
7090                               (match_operand:SI 2 "register_operand" ""))))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "!TARGET_64BIT"
7093   "")
7094
7095 (define_insn "*mulsidi3_insn"
7096   [(set (match_operand:DI 0 "register_operand" "=A")
7097         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7098                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "!TARGET_64BIT
7101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7102   "imul{l}\t%2"
7103   [(set_attr "type" "imul")
7104    (set_attr "length_immediate" "0")
7105    (set (attr "athlon_decode")
7106      (if_then_else (eq_attr "cpu" "athlon")
7107         (const_string "vector")
7108         (const_string "double")))
7109    (set_attr "mode" "SI")])
7110
7111 (define_expand "umuldi3_highpart"
7112   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7113                    (truncate:DI
7114                      (lshiftrt:TI
7115                        (mult:TI (zero_extend:TI
7116                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7117                                 (zero_extend:TI
7118                                   (match_operand:DI 2 "register_operand" "")))
7119                        (const_int 64))))
7120               (clobber (match_scratch:DI 3 ""))
7121               (clobber (reg:CC FLAGS_REG))])]
7122   "TARGET_64BIT"
7123   "")
7124
7125 (define_insn "*umuldi3_highpart_rex64"
7126   [(set (match_operand:DI 0 "register_operand" "=d")
7127         (truncate:DI
7128           (lshiftrt:TI
7129             (mult:TI (zero_extend:TI
7130                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7131                      (zero_extend:TI
7132                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7133             (const_int 64))))
7134    (clobber (match_scratch:DI 3 "=1"))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "TARGET_64BIT
7137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138   "mul{q}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "DI")])
7146
7147 (define_expand "umulsi3_highpart"
7148   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149                    (truncate:SI
7150                      (lshiftrt:DI
7151                        (mult:DI (zero_extend:DI
7152                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7153                                 (zero_extend:DI
7154                                   (match_operand:SI 2 "register_operand" "")))
7155                        (const_int 32))))
7156               (clobber (match_scratch:SI 3 ""))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "")
7160
7161 (define_insn "*umulsi3_highpart_insn"
7162   [(set (match_operand:SI 0 "register_operand" "=d")
7163         (truncate:SI
7164           (lshiftrt:DI
7165             (mult:DI (zero_extend:DI
7166                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7167                      (zero_extend:DI
7168                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7169             (const_int 32))))
7170    (clobber (match_scratch:SI 3 "=1"))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "mode" "SI")])
7181
7182 (define_insn "*umulsi3_highpart_zext"
7183   [(set (match_operand:DI 0 "register_operand" "=d")
7184         (zero_extend:DI (truncate:SI
7185           (lshiftrt:DI
7186             (mult:DI (zero_extend:DI
7187                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188                      (zero_extend:DI
7189                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190             (const_int 32)))))
7191    (clobber (match_scratch:SI 3 "=1"))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "mul{l}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "mode" "SI")])
7203
7204 (define_expand "smuldi3_highpart"
7205   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7206                    (truncate:DI
7207                      (lshiftrt:TI
7208                        (mult:TI (sign_extend:TI
7209                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7210                                 (sign_extend:TI
7211                                   (match_operand:DI 2 "register_operand" "")))
7212                        (const_int 64))))
7213               (clobber (match_scratch:DI 3 ""))
7214               (clobber (reg:CC FLAGS_REG))])]
7215   "TARGET_64BIT"
7216   "")
7217
7218 (define_insn "*smuldi3_highpart_rex64"
7219   [(set (match_operand:DI 0 "register_operand" "=d")
7220         (truncate:DI
7221           (lshiftrt:TI
7222             (mult:TI (sign_extend:TI
7223                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7224                      (sign_extend:TI
7225                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7226             (const_int 64))))
7227    (clobber (match_scratch:DI 3 "=1"))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_64BIT
7230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7231   "imul{q}\t%2"
7232   [(set_attr "type" "imul")
7233    (set (attr "athlon_decode")
7234      (if_then_else (eq_attr "cpu" "athlon")
7235         (const_string "vector")
7236         (const_string "double")))
7237    (set_attr "mode" "DI")])
7238
7239 (define_expand "smulsi3_highpart"
7240   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7241                    (truncate:SI
7242                      (lshiftrt:DI
7243                        (mult:DI (sign_extend:DI
7244                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7245                                 (sign_extend:DI
7246                                   (match_operand:SI 2 "register_operand" "")))
7247                        (const_int 32))))
7248               (clobber (match_scratch:SI 3 ""))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   ""
7251   "")
7252
7253 (define_insn "*smulsi3_highpart_insn"
7254   [(set (match_operand:SI 0 "register_operand" "=d")
7255         (truncate:SI
7256           (lshiftrt:DI
7257             (mult:DI (sign_extend:DI
7258                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7259                      (sign_extend:DI
7260                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7261             (const_int 32))))
7262    (clobber (match_scratch:SI 3 "=1"))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7265   "imul{l}\t%2"
7266   [(set_attr "type" "imul")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "mode" "SI")])
7272
7273 (define_insn "*smulsi3_highpart_zext"
7274   [(set (match_operand:DI 0 "register_operand" "=d")
7275         (zero_extend:DI (truncate:SI
7276           (lshiftrt:DI
7277             (mult:DI (sign_extend:DI
7278                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7279                      (sign_extend:DI
7280                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7281             (const_int 32)))))
7282    (clobber (match_scratch:SI 3 "=1"))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set (attr "athlon_decode")
7289      (if_then_else (eq_attr "cpu" "athlon")
7290         (const_string "vector")
7291         (const_string "double")))
7292    (set_attr "mode" "SI")])
7293
7294 ;; The patterns that match these are at the end of this file.
7295
7296 (define_expand "mulxf3"
7297   [(set (match_operand:XF 0 "register_operand" "")
7298         (mult:XF (match_operand:XF 1 "register_operand" "")
7299                  (match_operand:XF 2 "register_operand" "")))]
7300   "TARGET_80387"
7301   "")
7302
7303 (define_expand "muldf3"
7304   [(set (match_operand:DF 0 "register_operand" "")
7305         (mult:DF (match_operand:DF 1 "register_operand" "")
7306                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7307   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7308   "")
7309
7310 (define_expand "mulsf3"
7311   [(set (match_operand:SF 0 "register_operand" "")
7312         (mult:SF (match_operand:SF 1 "register_operand" "")
7313                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7314   "TARGET_80387 || TARGET_SSE_MATH"
7315   "")
7316 \f
7317 ;; Divide instructions
7318
7319 (define_insn "divqi3"
7320   [(set (match_operand:QI 0 "register_operand" "=a")
7321         (div:QI (match_operand:HI 1 "register_operand" "0")
7322                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_QIMODE_MATH"
7325   "idiv{b}\t%2"
7326   [(set_attr "type" "idiv")
7327    (set_attr "mode" "QI")])
7328
7329 (define_insn "udivqi3"
7330   [(set (match_operand:QI 0 "register_operand" "=a")
7331         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7332                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_QIMODE_MATH"
7335   "div{b}\t%2"
7336   [(set_attr "type" "idiv")
7337    (set_attr "mode" "QI")])
7338
7339 ;; The patterns that match these are at the end of this file.
7340
7341 (define_expand "divxf3"
7342   [(set (match_operand:XF 0 "register_operand" "")
7343         (div:XF (match_operand:XF 1 "register_operand" "")
7344                 (match_operand:XF 2 "register_operand" "")))]
7345   "TARGET_80387"
7346   "")
7347
7348 (define_expand "divdf3"
7349   [(set (match_operand:DF 0 "register_operand" "")
7350         (div:DF (match_operand:DF 1 "register_operand" "")
7351                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353    "")
7354  
7355 (define_expand "divsf3"
7356   [(set (match_operand:SF 0 "register_operand" "")
7357         (div:SF (match_operand:SF 1 "register_operand" "")
7358                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359   "TARGET_80387 || TARGET_SSE_MATH"
7360   "")
7361 \f
7362 ;; Remainder instructions.
7363
7364 (define_expand "divmoddi4"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7366                    (div:DI (match_operand:DI 1 "register_operand" "")
7367                            (match_operand:DI 2 "nonimmediate_operand" "")))
7368               (set (match_operand:DI 3 "register_operand" "")
7369                    (mod:DI (match_dup 1) (match_dup 2)))
7370               (clobber (reg:CC FLAGS_REG))])]
7371   "TARGET_64BIT"
7372   "")
7373
7374 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7375 ;; Penalize eax case slightly because it results in worse scheduling
7376 ;; of code.
7377 (define_insn "*divmoddi4_nocltd_rex64"
7378   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7379         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7380                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7381    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7382         (mod:DI (match_dup 2) (match_dup 3)))
7383    (clobber (reg:CC FLAGS_REG))]
7384   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7385   "#"
7386   [(set_attr "type" "multi")])
7387
7388 (define_insn "*divmoddi4_cltd_rex64"
7389   [(set (match_operand:DI 0 "register_operand" "=a")
7390         (div:DI (match_operand:DI 2 "register_operand" "a")
7391                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7392    (set (match_operand:DI 1 "register_operand" "=&d")
7393         (mod:DI (match_dup 2) (match_dup 3)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7396   "#"
7397   [(set_attr "type" "multi")])
7398
7399 (define_insn "*divmoddi_noext_rex64"
7400   [(set (match_operand:DI 0 "register_operand" "=a")
7401         (div:DI (match_operand:DI 1 "register_operand" "0")
7402                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403    (set (match_operand:DI 3 "register_operand" "=d")
7404         (mod:DI (match_dup 1) (match_dup 2)))
7405    (use (match_operand:DI 4 "register_operand" "3"))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_64BIT"
7408   "idiv{q}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "DI")])
7411
7412 (define_split
7413   [(set (match_operand:DI 0 "register_operand" "")
7414         (div:DI (match_operand:DI 1 "register_operand" "")
7415                 (match_operand:DI 2 "nonimmediate_operand" "")))
7416    (set (match_operand:DI 3 "register_operand" "")
7417         (mod:DI (match_dup 1) (match_dup 2)))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_64BIT && reload_completed"
7420   [(parallel [(set (match_dup 3)
7421                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7422               (clobber (reg:CC FLAGS_REG))])
7423    (parallel [(set (match_dup 0)
7424                    (div:DI (reg:DI 0) (match_dup 2)))
7425               (set (match_dup 3)
7426                    (mod:DI (reg:DI 0) (match_dup 2)))
7427               (use (match_dup 3))
7428               (clobber (reg:CC FLAGS_REG))])]
7429 {
7430   /* Avoid use of cltd in favor of a mov+shift.  */
7431   if (!TARGET_USE_CLTD && !optimize_size)
7432     {
7433       if (true_regnum (operands[1]))
7434         emit_move_insn (operands[0], operands[1]);
7435       else
7436         emit_move_insn (operands[3], operands[1]);
7437       operands[4] = operands[3];
7438     }
7439   else
7440     {
7441       gcc_assert (!true_regnum (operands[1]));
7442       operands[4] = operands[1];
7443     }
7444 })
7445
7446
7447 (define_expand "divmodsi4"
7448   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7449                    (div:SI (match_operand:SI 1 "register_operand" "")
7450                            (match_operand:SI 2 "nonimmediate_operand" "")))
7451               (set (match_operand:SI 3 "register_operand" "")
7452                    (mod:SI (match_dup 1) (match_dup 2)))
7453               (clobber (reg:CC FLAGS_REG))])]
7454   ""
7455   "")
7456
7457 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7458 ;; Penalize eax case slightly because it results in worse scheduling
7459 ;; of code.
7460 (define_insn "*divmodsi4_nocltd"
7461   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7462         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7463                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7464    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7465         (mod:SI (match_dup 2) (match_dup 3)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "!optimize_size && !TARGET_USE_CLTD"
7468   "#"
7469   [(set_attr "type" "multi")])
7470
7471 (define_insn "*divmodsi4_cltd"
7472   [(set (match_operand:SI 0 "register_operand" "=a")
7473         (div:SI (match_operand:SI 2 "register_operand" "a")
7474                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7475    (set (match_operand:SI 1 "register_operand" "=&d")
7476         (mod:SI (match_dup 2) (match_dup 3)))
7477    (clobber (reg:CC FLAGS_REG))]
7478   "optimize_size || TARGET_USE_CLTD"
7479   "#"
7480   [(set_attr "type" "multi")])
7481
7482 (define_insn "*divmodsi_noext"
7483   [(set (match_operand:SI 0 "register_operand" "=a")
7484         (div:SI (match_operand:SI 1 "register_operand" "0")
7485                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486    (set (match_operand:SI 3 "register_operand" "=d")
7487         (mod:SI (match_dup 1) (match_dup 2)))
7488    (use (match_operand:SI 4 "register_operand" "3"))
7489    (clobber (reg:CC FLAGS_REG))]
7490   ""
7491   "idiv{l}\t%2"
7492   [(set_attr "type" "idiv")
7493    (set_attr "mode" "SI")])
7494
7495 (define_split
7496   [(set (match_operand:SI 0 "register_operand" "")
7497         (div:SI (match_operand:SI 1 "register_operand" "")
7498                 (match_operand:SI 2 "nonimmediate_operand" "")))
7499    (set (match_operand:SI 3 "register_operand" "")
7500         (mod:SI (match_dup 1) (match_dup 2)))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "reload_completed"
7503   [(parallel [(set (match_dup 3)
7504                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7505               (clobber (reg:CC FLAGS_REG))])
7506    (parallel [(set (match_dup 0)
7507                    (div:SI (reg:SI 0) (match_dup 2)))
7508               (set (match_dup 3)
7509                    (mod:SI (reg:SI 0) (match_dup 2)))
7510               (use (match_dup 3))
7511               (clobber (reg:CC FLAGS_REG))])]
7512 {
7513   /* Avoid use of cltd in favor of a mov+shift.  */
7514   if (!TARGET_USE_CLTD && !optimize_size)
7515     {
7516       if (true_regnum (operands[1]))
7517         emit_move_insn (operands[0], operands[1]);
7518       else
7519         emit_move_insn (operands[3], operands[1]);
7520       operands[4] = operands[3];
7521     }
7522   else
7523     {
7524       gcc_assert (!true_regnum (operands[1]));
7525       operands[4] = operands[1];
7526     }
7527 })
7528 ;; %%% Split me.
7529 (define_insn "divmodhi4"
7530   [(set (match_operand:HI 0 "register_operand" "=a")
7531         (div:HI (match_operand:HI 1 "register_operand" "0")
7532                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7533    (set (match_operand:HI 3 "register_operand" "=&d")
7534         (mod:HI (match_dup 1) (match_dup 2)))
7535    (clobber (reg:CC FLAGS_REG))]
7536   "TARGET_HIMODE_MATH"
7537   "cwtd\;idiv{w}\t%2"
7538   [(set_attr "type" "multi")
7539    (set_attr "length_immediate" "0")
7540    (set_attr "mode" "SI")])
7541
7542 (define_insn "udivmoddi4"
7543   [(set (match_operand:DI 0 "register_operand" "=a")
7544         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7545                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546    (set (match_operand:DI 3 "register_operand" "=&d")
7547         (umod:DI (match_dup 1) (match_dup 2)))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT"
7550   "xor{q}\t%3, %3\;div{q}\t%2"
7551   [(set_attr "type" "multi")
7552    (set_attr "length_immediate" "0")
7553    (set_attr "mode" "DI")])
7554
7555 (define_insn "*udivmoddi4_noext"
7556   [(set (match_operand:DI 0 "register_operand" "=a")
7557         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7558                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559    (set (match_operand:DI 3 "register_operand" "=d")
7560         (umod:DI (match_dup 1) (match_dup 2)))
7561    (use (match_dup 3))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "TARGET_64BIT"
7564   "div{q}\t%2"
7565   [(set_attr "type" "idiv")
7566    (set_attr "mode" "DI")])
7567
7568 (define_split
7569   [(set (match_operand:DI 0 "register_operand" "")
7570         (udiv:DI (match_operand:DI 1 "register_operand" "")
7571                  (match_operand:DI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:DI 3 "register_operand" "")
7573         (umod:DI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_64BIT && reload_completed"
7576   [(set (match_dup 3) (const_int 0))
7577    (parallel [(set (match_dup 0)
7578                    (udiv:DI (match_dup 1) (match_dup 2)))
7579               (set (match_dup 3)
7580                    (umod:DI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 3))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "")
7584
7585 (define_insn "udivmodsi4"
7586   [(set (match_operand:SI 0 "register_operand" "=a")
7587         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7588                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7589    (set (match_operand:SI 3 "register_operand" "=&d")
7590         (umod:SI (match_dup 1) (match_dup 2)))
7591    (clobber (reg:CC FLAGS_REG))]
7592   ""
7593   "xor{l}\t%3, %3\;div{l}\t%2"
7594   [(set_attr "type" "multi")
7595    (set_attr "length_immediate" "0")
7596    (set_attr "mode" "SI")])
7597
7598 (define_insn "*udivmodsi4_noext"
7599   [(set (match_operand:SI 0 "register_operand" "=a")
7600         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7601                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602    (set (match_operand:SI 3 "register_operand" "=d")
7603         (umod:SI (match_dup 1) (match_dup 2)))
7604    (use (match_dup 3))
7605    (clobber (reg:CC FLAGS_REG))]
7606   ""
7607   "div{l}\t%2"
7608   [(set_attr "type" "idiv")
7609    (set_attr "mode" "SI")])
7610
7611 (define_split
7612   [(set (match_operand:SI 0 "register_operand" "")
7613         (udiv:SI (match_operand:SI 1 "register_operand" "")
7614                  (match_operand:SI 2 "nonimmediate_operand" "")))
7615    (set (match_operand:SI 3 "register_operand" "")
7616         (umod:SI (match_dup 1) (match_dup 2)))
7617    (clobber (reg:CC FLAGS_REG))]
7618   "reload_completed"
7619   [(set (match_dup 3) (const_int 0))
7620    (parallel [(set (match_dup 0)
7621                    (udiv:SI (match_dup 1) (match_dup 2)))
7622               (set (match_dup 3)
7623                    (umod:SI (match_dup 1) (match_dup 2)))
7624               (use (match_dup 3))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   "")
7627
7628 (define_expand "udivmodhi4"
7629   [(set (match_dup 4) (const_int 0))
7630    (parallel [(set (match_operand:HI 0 "register_operand" "")
7631                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7632                             (match_operand:HI 2 "nonimmediate_operand" "")))
7633               (set (match_operand:HI 3 "register_operand" "")
7634                    (umod:HI (match_dup 1) (match_dup 2)))
7635               (use (match_dup 4))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_HIMODE_MATH"
7638   "operands[4] = gen_reg_rtx (HImode);")
7639
7640 (define_insn "*udivmodhi_noext"
7641   [(set (match_operand:HI 0 "register_operand" "=a")
7642         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7643                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:HI 3 "register_operand" "=d")
7645         (umod:HI (match_dup 1) (match_dup 2)))
7646    (use (match_operand:HI 4 "register_operand" "3"))
7647    (clobber (reg:CC FLAGS_REG))]
7648   ""
7649   "div{w}\t%2"
7650   [(set_attr "type" "idiv")
7651    (set_attr "mode" "HI")])
7652
7653 ;; We cannot use div/idiv for double division, because it causes
7654 ;; "division by zero" on the overflow and that's not what we expect
7655 ;; from truncate.  Because true (non truncating) double division is
7656 ;; never generated, we can't create this insn anyway.
7657 ;
7658 ;(define_insn ""
7659 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7660 ;       (truncate:SI
7661 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7662 ;                  (zero_extend:DI
7663 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7664 ;   (set (match_operand:SI 3 "register_operand" "=d")
7665 ;       (truncate:SI
7666 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7667 ;   (clobber (reg:CC FLAGS_REG))]
7668 ;  ""
7669 ;  "div{l}\t{%2, %0|%0, %2}"
7670 ;  [(set_attr "type" "idiv")])
7671 \f
7672 ;;- Logical AND instructions
7673
7674 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7675 ;; Note that this excludes ah.
7676
7677 (define_insn "*testdi_1_rex64"
7678   [(set (reg FLAGS_REG)
7679         (compare
7680           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7681                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7682           (const_int 0)))]
7683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685   "@
7686    test{l}\t{%k1, %k0|%k0, %k1}
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{q}\t{%1, %0|%0, %1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}"
7691   [(set_attr "type" "test")
7692    (set_attr "modrm" "0,1,0,1,1")
7693    (set_attr "mode" "SI,SI,DI,DI,DI")
7694    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7695
7696 (define_insn "testsi_1"
7697   [(set (reg FLAGS_REG)
7698         (compare
7699           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7700                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7701           (const_int 0)))]
7702   "ix86_match_ccmode (insn, CCNOmode)
7703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704   "test{l}\t{%1, %0|%0, %1}"
7705   [(set_attr "type" "test")
7706    (set_attr "modrm" "0,1,1")
7707    (set_attr "mode" "SI")
7708    (set_attr "pent_pair" "uv,np,uv")])
7709
7710 (define_expand "testsi_ccno_1"
7711   [(set (reg:CCNO FLAGS_REG)
7712         (compare:CCNO
7713           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7714                   (match_operand:SI 1 "nonmemory_operand" ""))
7715           (const_int 0)))]
7716   ""
7717   "")
7718
7719 (define_insn "*testhi_1"
7720   [(set (reg FLAGS_REG)
7721         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7722                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7723                  (const_int 0)))]
7724   "ix86_match_ccmode (insn, CCNOmode)
7725    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7726   "test{w}\t{%1, %0|%0, %1}"
7727   [(set_attr "type" "test")
7728    (set_attr "modrm" "0,1,1")
7729    (set_attr "mode" "HI")
7730    (set_attr "pent_pair" "uv,np,uv")])
7731
7732 (define_expand "testqi_ccz_1"
7733   [(set (reg:CCZ FLAGS_REG)
7734         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7735                              (match_operand:QI 1 "nonmemory_operand" ""))
7736                  (const_int 0)))]
7737   ""
7738   "")
7739
7740 (define_insn "*testqi_1_maybe_si"
7741   [(set (reg FLAGS_REG)
7742         (compare
7743           (and:QI
7744             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7745             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7746           (const_int 0)))]
7747    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7748     && ix86_match_ccmode (insn,
7749                          GET_CODE (operands[1]) == CONST_INT
7750                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7751 {
7752   if (which_alternative == 3)
7753     {
7754       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7755         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7756       return "test{l}\t{%1, %k0|%k0, %1}";
7757     }
7758   return "test{b}\t{%1, %0|%0, %1}";
7759 }
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1,1")
7762    (set_attr "mode" "QI,QI,QI,SI")
7763    (set_attr "pent_pair" "uv,np,uv,np")])
7764
7765 (define_insn "*testqi_1"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:QI
7769             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7770             (match_operand:QI 1 "general_operand" "n,n,qn"))
7771           (const_int 0)))]
7772   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7773    && ix86_match_ccmode (insn, CCNOmode)"
7774   "test{b}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "QI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testqi_ext_ccno_0"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI
7784             (zero_extract:SI
7785               (match_operand 0 "ext_register_operand" "")
7786               (const_int 8)
7787               (const_int 8))
7788             (match_operand 1 "const_int_operand" ""))
7789           (const_int 0)))]
7790   ""
7791   "")
7792
7793 (define_insn "*testqi_ext_0"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI
7797             (zero_extract:SI
7798               (match_operand 0 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8))
7801             (match_operand 1 "const_int_operand" "n"))
7802           (const_int 0)))]
7803   "ix86_match_ccmode (insn, CCNOmode)"
7804   "test{b}\t{%1, %h0|%h0, %1}"
7805   [(set_attr "type" "test")
7806    (set_attr "mode" "QI")
7807    (set_attr "length_immediate" "1")
7808    (set_attr "pent_pair" "np")])
7809
7810 (define_insn "*testqi_ext_1"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:SI
7814             (zero_extract:SI
7815               (match_operand 0 "ext_register_operand" "Q")
7816               (const_int 8)
7817               (const_int 8))
7818             (zero_extend:SI
7819               (match_operand:QI 1 "general_operand" "Qm")))
7820           (const_int 0)))]
7821   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")])
7826
7827 (define_insn "*testqi_ext_1_rex64"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:SI
7831             (zero_extract:SI
7832               (match_operand 0 "ext_register_operand" "Q")
7833               (const_int 8)
7834               (const_int 8))
7835             (zero_extend:SI
7836               (match_operand:QI 1 "register_operand" "Q")))
7837           (const_int 0)))]
7838   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7839   "test{b}\t{%1, %h0|%h0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "mode" "QI")])
7842
7843 (define_insn "*testqi_ext_2"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extract:SI
7852               (match_operand 1 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8)))
7855           (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)"
7857   "test{b}\t{%h1, %h0|%h0, %h1}"
7858   [(set_attr "type" "test")
7859    (set_attr "mode" "QI")])
7860
7861 ;; Combine likes to form bit extractions for some tests.  Humor it.
7862 (define_insn "*testqi_ext_3"
7863   [(set (reg FLAGS_REG)
7864         (compare (zero_extract:SI
7865                    (match_operand 0 "nonimmediate_operand" "rm")
7866                    (match_operand:SI 1 "const_int_operand" "")
7867                    (match_operand:SI 2 "const_int_operand" ""))
7868                  (const_int 0)))]
7869   "ix86_match_ccmode (insn, CCNOmode)
7870    && INTVAL (operands[1]) > 0
7871    && INTVAL (operands[2]) >= 0
7872    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7873    && (GET_MODE (operands[0]) == SImode
7874        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7875        || GET_MODE (operands[0]) == HImode
7876        || GET_MODE (operands[0]) == QImode)"
7877   "#")
7878
7879 (define_insn "*testqi_ext_3_rex64"
7880   [(set (reg FLAGS_REG)
7881         (compare (zero_extract:DI
7882                    (match_operand 0 "nonimmediate_operand" "rm")
7883                    (match_operand:DI 1 "const_int_operand" "")
7884                    (match_operand:DI 2 "const_int_operand" ""))
7885                  (const_int 0)))]
7886   "TARGET_64BIT
7887    && ix86_match_ccmode (insn, CCNOmode)
7888    && INTVAL (operands[1]) > 0
7889    && INTVAL (operands[2]) >= 0
7890    /* Ensure that resulting mask is zero or sign extended operand.  */
7891    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7892        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7893            && INTVAL (operands[1]) > 32))
7894    && (GET_MODE (operands[0]) == SImode
7895        || GET_MODE (operands[0]) == DImode
7896        || GET_MODE (operands[0]) == HImode
7897        || GET_MODE (operands[0]) == QImode)"
7898   "#")
7899
7900 (define_split
7901   [(set (match_operand 0 "flags_reg_operand" "")
7902         (match_operator 1 "compare_operator"
7903           [(zero_extract
7904              (match_operand 2 "nonimmediate_operand" "")
7905              (match_operand 3 "const_int_operand" "")
7906              (match_operand 4 "const_int_operand" ""))
7907            (const_int 0)]))]
7908   "ix86_match_ccmode (insn, CCNOmode)"
7909   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7910 {
7911   rtx val = operands[2];
7912   HOST_WIDE_INT len = INTVAL (operands[3]);
7913   HOST_WIDE_INT pos = INTVAL (operands[4]);
7914   HOST_WIDE_INT mask;
7915   enum machine_mode mode, submode;
7916
7917   mode = GET_MODE (val);
7918   if (GET_CODE (val) == MEM)
7919     {
7920       /* ??? Combine likes to put non-volatile mem extractions in QImode
7921          no matter the size of the test.  So find a mode that works.  */
7922       if (! MEM_VOLATILE_P (val))
7923         {
7924           mode = smallest_mode_for_size (pos + len, MODE_INT);
7925           val = adjust_address (val, mode, 0);
7926         }
7927     }
7928   else if (GET_CODE (val) == SUBREG
7929            && (submode = GET_MODE (SUBREG_REG (val)),
7930                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7931            && pos + len <= GET_MODE_BITSIZE (submode))
7932     {
7933       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7934       mode = submode;
7935       val = SUBREG_REG (val);
7936     }
7937   else if (mode == HImode && pos + len <= 8)
7938     {
7939       /* Small HImode tests can be converted to QImode.  */
7940       mode = QImode;
7941       val = gen_lowpart (QImode, val);
7942     }
7943
7944   if (len == HOST_BITS_PER_WIDE_INT)
7945     mask = -1;
7946   else
7947     mask = ((HOST_WIDE_INT)1 << len) - 1;
7948   mask <<= pos;
7949
7950   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7951 })
7952
7953 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7954 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7955 ;; this is relatively important trick.
7956 ;; Do the conversion only post-reload to avoid limiting of the register class
7957 ;; to QI regs.
7958 (define_split
7959   [(set (match_operand 0 "flags_reg_operand" "")
7960         (match_operator 1 "compare_operator"
7961           [(and (match_operand 2 "register_operand" "")
7962                 (match_operand 3 "const_int_operand" ""))
7963            (const_int 0)]))]
7964    "reload_completed
7965     && QI_REG_P (operands[2])
7966     && GET_MODE (operands[2]) != QImode
7967     && ((ix86_match_ccmode (insn, CCZmode)
7968          && !(INTVAL (operands[3]) & ~(255 << 8)))
7969         || (ix86_match_ccmode (insn, CCNOmode)
7970             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7971   [(set (match_dup 0)
7972         (match_op_dup 1
7973           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7974                    (match_dup 3))
7975            (const_int 0)]))]
7976   "operands[2] = gen_lowpart (SImode, operands[2]);
7977    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7978
7979 (define_split
7980   [(set (match_operand 0 "flags_reg_operand" "")
7981         (match_operator 1 "compare_operator"
7982           [(and (match_operand 2 "nonimmediate_operand" "")
7983                 (match_operand 3 "const_int_operand" ""))
7984            (const_int 0)]))]
7985    "reload_completed
7986     && GET_MODE (operands[2]) != QImode
7987     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7988     && ((ix86_match_ccmode (insn, CCZmode)
7989          && !(INTVAL (operands[3]) & ~255))
7990         || (ix86_match_ccmode (insn, CCNOmode)
7991             && !(INTVAL (operands[3]) & ~127)))"
7992   [(set (match_dup 0)
7993         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7994                          (const_int 0)]))]
7995   "operands[2] = gen_lowpart (QImode, operands[2]);
7996    operands[3] = gen_lowpart (QImode, operands[3]);")
7997
7998
7999 ;; %%% This used to optimize known byte-wide and operations to memory,
8000 ;; and sometimes to QImode registers.  If this is considered useful,
8001 ;; it should be done with splitters.
8002
8003 (define_expand "anddi3"
8004   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8005         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8006                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8007    (clobber (reg:CC FLAGS_REG))]
8008   "TARGET_64BIT"
8009   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8010
8011 (define_insn "*anddi_1_rex64"
8012   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8013         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8014                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8015    (clobber (reg:CC FLAGS_REG))]
8016   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8017 {
8018   switch (get_attr_type (insn))
8019     {
8020     case TYPE_IMOVX:
8021       {
8022         enum machine_mode mode;
8023
8024         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8025         if (INTVAL (operands[2]) == 0xff)
8026           mode = QImode;
8027         else
8028           {
8029             gcc_assert (INTVAL (operands[2]) == 0xffff);
8030             mode = HImode;
8031           }
8032         
8033         operands[1] = gen_lowpart (mode, operands[1]);
8034         if (mode == QImode)
8035           return "movz{bq|x}\t{%1,%0|%0, %1}";
8036         else
8037           return "movz{wq|x}\t{%1,%0|%0, %1}";
8038       }
8039
8040     default:
8041       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8042       if (get_attr_mode (insn) == MODE_SI)
8043         return "and{l}\t{%k2, %k0|%k0, %k2}";
8044       else
8045         return "and{q}\t{%2, %0|%0, %2}";
8046     }
8047 }
8048   [(set_attr "type" "alu,alu,alu,imovx")
8049    (set_attr "length_immediate" "*,*,*,0")
8050    (set_attr "mode" "SI,DI,DI,DI")])
8051
8052 (define_insn "*anddi_2"
8053   [(set (reg FLAGS_REG)
8054         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8055                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8056                  (const_int 0)))
8057    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8058         (and:DI (match_dup 1) (match_dup 2)))]
8059   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8060    && ix86_binary_operator_ok (AND, DImode, operands)"
8061   "@
8062    and{l}\t{%k2, %k0|%k0, %k2}
8063    and{q}\t{%2, %0|%0, %2}
8064    and{q}\t{%2, %0|%0, %2}"
8065   [(set_attr "type" "alu")
8066    (set_attr "mode" "SI,DI,DI")])
8067
8068 (define_expand "andsi3"
8069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8070         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8071                 (match_operand:SI 2 "general_operand" "")))
8072    (clobber (reg:CC FLAGS_REG))]
8073   ""
8074   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8075
8076 (define_insn "*andsi_1"
8077   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8078         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8079                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8080    (clobber (reg:CC FLAGS_REG))]
8081   "ix86_binary_operator_ok (AND, SImode, operands)"
8082 {
8083   switch (get_attr_type (insn))
8084     {
8085     case TYPE_IMOVX:
8086       {
8087         enum machine_mode mode;
8088
8089         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8090         if (INTVAL (operands[2]) == 0xff)
8091           mode = QImode;
8092         else
8093           {
8094             gcc_assert (INTVAL (operands[2]) == 0xffff);
8095             mode = HImode;
8096           }
8097         
8098         operands[1] = gen_lowpart (mode, operands[1]);
8099         if (mode == QImode)
8100           return "movz{bl|x}\t{%1,%0|%0, %1}";
8101         else
8102           return "movz{wl|x}\t{%1,%0|%0, %1}";
8103       }
8104
8105     default:
8106       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8107       return "and{l}\t{%2, %0|%0, %2}";
8108     }
8109 }
8110   [(set_attr "type" "alu,alu,imovx")
8111    (set_attr "length_immediate" "*,*,0")
8112    (set_attr "mode" "SI")])
8113
8114 (define_split
8115   [(set (match_operand 0 "register_operand" "")
8116         (and (match_dup 0)
8117              (const_int -65536)))
8118    (clobber (reg:CC FLAGS_REG))]
8119   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8120   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8121   "operands[1] = gen_lowpart (HImode, operands[0]);")
8122
8123 (define_split
8124   [(set (match_operand 0 "ext_register_operand" "")
8125         (and (match_dup 0)
8126              (const_int -256)))
8127    (clobber (reg:CC FLAGS_REG))]
8128   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8129   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8130   "operands[1] = gen_lowpart (QImode, operands[0]);")
8131
8132 (define_split
8133   [(set (match_operand 0 "ext_register_operand" "")
8134         (and (match_dup 0)
8135              (const_int -65281)))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8138   [(parallel [(set (zero_extract:SI (match_dup 0)
8139                                     (const_int 8)
8140                                     (const_int 8))
8141                    (xor:SI 
8142                      (zero_extract:SI (match_dup 0)
8143                                       (const_int 8)
8144                                       (const_int 8))
8145                      (zero_extract:SI (match_dup 0)
8146                                       (const_int 8)
8147                                       (const_int 8))))
8148               (clobber (reg:CC FLAGS_REG))])]
8149   "operands[0] = gen_lowpart (SImode, operands[0]);")
8150
8151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8152 (define_insn "*andsi_1_zext"
8153   [(set (match_operand:DI 0 "register_operand" "=r")
8154         (zero_extend:DI
8155           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8156                   (match_operand:SI 2 "general_operand" "rim"))))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8159   "and{l}\t{%2, %k0|%k0, %2}"
8160   [(set_attr "type" "alu")
8161    (set_attr "mode" "SI")])
8162
8163 (define_insn "*andsi_2"
8164   [(set (reg FLAGS_REG)
8165         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8166                          (match_operand:SI 2 "general_operand" "rim,ri"))
8167                  (const_int 0)))
8168    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8169         (and:SI (match_dup 1) (match_dup 2)))]
8170   "ix86_match_ccmode (insn, CCNOmode)
8171    && ix86_binary_operator_ok (AND, SImode, operands)"
8172   "and{l}\t{%2, %0|%0, %2}"
8173   [(set_attr "type" "alu")
8174    (set_attr "mode" "SI")])
8175
8176 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8177 (define_insn "*andsi_2_zext"
8178   [(set (reg FLAGS_REG)
8179         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8180                          (match_operand:SI 2 "general_operand" "rim"))
8181                  (const_int 0)))
8182    (set (match_operand:DI 0 "register_operand" "=r")
8183         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8184   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8185    && ix86_binary_operator_ok (AND, SImode, operands)"
8186   "and{l}\t{%2, %k0|%k0, %2}"
8187   [(set_attr "type" "alu")
8188    (set_attr "mode" "SI")])
8189
8190 (define_expand "andhi3"
8191   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8192         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8193                 (match_operand:HI 2 "general_operand" "")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "TARGET_HIMODE_MATH"
8196   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8197
8198 (define_insn "*andhi_1"
8199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8200         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8201                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8202    (clobber (reg:CC FLAGS_REG))]
8203   "ix86_binary_operator_ok (AND, HImode, operands)"
8204 {
8205   switch (get_attr_type (insn))
8206     {
8207     case TYPE_IMOVX:
8208       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8209       gcc_assert (INTVAL (operands[2]) == 0xff);
8210       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8211
8212     default:
8213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8214
8215       return "and{w}\t{%2, %0|%0, %2}";
8216     }
8217 }
8218   [(set_attr "type" "alu,alu,imovx")
8219    (set_attr "length_immediate" "*,*,0")
8220    (set_attr "mode" "HI,HI,SI")])
8221
8222 (define_insn "*andhi_2"
8223   [(set (reg FLAGS_REG)
8224         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8225                          (match_operand:HI 2 "general_operand" "rim,ri"))
8226                  (const_int 0)))
8227    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8228         (and:HI (match_dup 1) (match_dup 2)))]
8229   "ix86_match_ccmode (insn, CCNOmode)
8230    && ix86_binary_operator_ok (AND, HImode, operands)"
8231   "and{w}\t{%2, %0|%0, %2}"
8232   [(set_attr "type" "alu")
8233    (set_attr "mode" "HI")])
8234
8235 (define_expand "andqi3"
8236   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8237         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8238                 (match_operand:QI 2 "general_operand" "")))
8239    (clobber (reg:CC FLAGS_REG))]
8240   "TARGET_QIMODE_MATH"
8241   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8242
8243 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8244 (define_insn "*andqi_1"
8245   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8246         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8247                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8248    (clobber (reg:CC FLAGS_REG))]
8249   "ix86_binary_operator_ok (AND, QImode, operands)"
8250   "@
8251    and{b}\t{%2, %0|%0, %2}
8252    and{b}\t{%2, %0|%0, %2}
8253    and{l}\t{%k2, %k0|%k0, %k2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "mode" "QI,QI,SI")])
8256
8257 (define_insn "*andqi_1_slp"
8258   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8259         (and:QI (match_dup 0)
8260                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8261    (clobber (reg:CC FLAGS_REG))]
8262   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8263    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8264   "and{b}\t{%1, %0|%0, %1}"
8265   [(set_attr "type" "alu1")
8266    (set_attr "mode" "QI")])
8267
8268 (define_insn "*andqi_2_maybe_si"
8269   [(set (reg FLAGS_REG)
8270         (compare (and:QI
8271                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8272                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8273                  (const_int 0)))
8274    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8275         (and:QI (match_dup 1) (match_dup 2)))]
8276   "ix86_binary_operator_ok (AND, QImode, operands)
8277    && ix86_match_ccmode (insn,
8278                          GET_CODE (operands[2]) == CONST_INT
8279                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8280 {
8281   if (which_alternative == 2)
8282     {
8283       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8284         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8285       return "and{l}\t{%2, %k0|%k0, %2}";
8286     }
8287   return "and{b}\t{%2, %0|%0, %2}";
8288 }
8289   [(set_attr "type" "alu")
8290    (set_attr "mode" "QI,QI,SI")])
8291
8292 (define_insn "*andqi_2"
8293   [(set (reg FLAGS_REG)
8294         (compare (and:QI
8295                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8296                    (match_operand:QI 2 "general_operand" "qim,qi"))
8297                  (const_int 0)))
8298    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8299         (and:QI (match_dup 1) (match_dup 2)))]
8300   "ix86_match_ccmode (insn, CCNOmode)
8301    && ix86_binary_operator_ok (AND, QImode, operands)"
8302   "and{b}\t{%2, %0|%0, %2}"
8303   [(set_attr "type" "alu")
8304    (set_attr "mode" "QI")])
8305
8306 (define_insn "*andqi_2_slp"
8307   [(set (reg FLAGS_REG)
8308         (compare (and:QI
8309                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8310                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8311                  (const_int 0)))
8312    (set (strict_low_part (match_dup 0))
8313         (and:QI (match_dup 0) (match_dup 1)))]
8314   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8315    && ix86_match_ccmode (insn, CCNOmode)
8316    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8317   "and{b}\t{%1, %0|%0, %1}"
8318   [(set_attr "type" "alu1")
8319    (set_attr "mode" "QI")])
8320
8321 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8322 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8323 ;; for a QImode operand, which of course failed.
8324
8325 (define_insn "andqi_ext_0"
8326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327                          (const_int 8)
8328                          (const_int 8))
8329         (and:SI 
8330           (zero_extract:SI
8331             (match_operand 1 "ext_register_operand" "0")
8332             (const_int 8)
8333             (const_int 8))
8334           (match_operand 2 "const_int_operand" "n")))
8335    (clobber (reg:CC FLAGS_REG))]
8336   ""
8337   "and{b}\t{%2, %h0|%h0, %2}"
8338   [(set_attr "type" "alu")
8339    (set_attr "length_immediate" "1")
8340    (set_attr "mode" "QI")])
8341
8342 ;; Generated by peephole translating test to and.  This shows up
8343 ;; often in fp comparisons.
8344
8345 (define_insn "*andqi_ext_0_cc"
8346   [(set (reg FLAGS_REG)
8347         (compare
8348           (and:SI
8349             (zero_extract:SI
8350               (match_operand 1 "ext_register_operand" "0")
8351               (const_int 8)
8352               (const_int 8))
8353             (match_operand 2 "const_int_operand" "n"))
8354           (const_int 0)))
8355    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8356                          (const_int 8)
8357                          (const_int 8))
8358         (and:SI 
8359           (zero_extract:SI
8360             (match_dup 1)
8361             (const_int 8)
8362             (const_int 8))
8363           (match_dup 2)))]
8364   "ix86_match_ccmode (insn, CCNOmode)"
8365   "and{b}\t{%2, %h0|%h0, %2}"
8366   [(set_attr "type" "alu")
8367    (set_attr "length_immediate" "1")
8368    (set_attr "mode" "QI")])
8369
8370 (define_insn "*andqi_ext_1"
8371   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8372                          (const_int 8)
8373                          (const_int 8))
8374         (and:SI 
8375           (zero_extract:SI
8376             (match_operand 1 "ext_register_operand" "0")
8377             (const_int 8)
8378             (const_int 8))
8379           (zero_extend:SI
8380             (match_operand:QI 2 "general_operand" "Qm"))))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "!TARGET_64BIT"
8383   "and{b}\t{%2, %h0|%h0, %2}"
8384   [(set_attr "type" "alu")
8385    (set_attr "length_immediate" "0")
8386    (set_attr "mode" "QI")])
8387
8388 (define_insn "*andqi_ext_1_rex64"
8389   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8390                          (const_int 8)
8391                          (const_int 8))
8392         (and:SI 
8393           (zero_extract:SI
8394             (match_operand 1 "ext_register_operand" "0")
8395             (const_int 8)
8396             (const_int 8))
8397           (zero_extend:SI
8398             (match_operand 2 "ext_register_operand" "Q"))))
8399    (clobber (reg:CC FLAGS_REG))]
8400   "TARGET_64BIT"
8401   "and{b}\t{%2, %h0|%h0, %2}"
8402   [(set_attr "type" "alu")
8403    (set_attr "length_immediate" "0")
8404    (set_attr "mode" "QI")])
8405
8406 (define_insn "*andqi_ext_2"
8407   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8408                          (const_int 8)
8409                          (const_int 8))
8410         (and:SI
8411           (zero_extract:SI
8412             (match_operand 1 "ext_register_operand" "%0")
8413             (const_int 8)
8414             (const_int 8))
8415           (zero_extract:SI
8416             (match_operand 2 "ext_register_operand" "Q")
8417             (const_int 8)
8418             (const_int 8))))
8419    (clobber (reg:CC FLAGS_REG))]
8420   ""
8421   "and{b}\t{%h2, %h0|%h0, %h2}"
8422   [(set_attr "type" "alu")
8423    (set_attr "length_immediate" "0")
8424    (set_attr "mode" "QI")])
8425
8426 ;; Convert wide AND instructions with immediate operand to shorter QImode
8427 ;; equivalents when possible.
8428 ;; Don't do the splitting with memory operands, since it introduces risk
8429 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8430 ;; for size, but that can (should?) be handled by generic code instead.
8431 (define_split
8432   [(set (match_operand 0 "register_operand" "")
8433         (and (match_operand 1 "register_operand" "")
8434              (match_operand 2 "const_int_operand" "")))
8435    (clobber (reg:CC FLAGS_REG))]
8436    "reload_completed
8437     && QI_REG_P (operands[0])
8438     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8439     && !(~INTVAL (operands[2]) & ~(255 << 8))
8440     && GET_MODE (operands[0]) != QImode"
8441   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8442                    (and:SI (zero_extract:SI (match_dup 1)
8443                                             (const_int 8) (const_int 8))
8444                            (match_dup 2)))
8445               (clobber (reg:CC FLAGS_REG))])]
8446   "operands[0] = gen_lowpart (SImode, operands[0]);
8447    operands[1] = gen_lowpart (SImode, operands[1]);
8448    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8449
8450 ;; Since AND can be encoded with sign extended immediate, this is only
8451 ;; profitable when 7th bit is not set.
8452 (define_split
8453   [(set (match_operand 0 "register_operand" "")
8454         (and (match_operand 1 "general_operand" "")
8455              (match_operand 2 "const_int_operand" "")))
8456    (clobber (reg:CC FLAGS_REG))]
8457    "reload_completed
8458     && ANY_QI_REG_P (operands[0])
8459     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8460     && !(~INTVAL (operands[2]) & ~255)
8461     && !(INTVAL (operands[2]) & 128)
8462     && GET_MODE (operands[0]) != QImode"
8463   [(parallel [(set (strict_low_part (match_dup 0))
8464                    (and:QI (match_dup 1)
8465                            (match_dup 2)))
8466               (clobber (reg:CC FLAGS_REG))])]
8467   "operands[0] = gen_lowpart (QImode, operands[0]);
8468    operands[1] = gen_lowpart (QImode, operands[1]);
8469    operands[2] = gen_lowpart (QImode, operands[2]);")
8470 \f
8471 ;; Logical inclusive OR instructions
8472
8473 ;; %%% This used to optimize known byte-wide and operations to memory.
8474 ;; If this is considered useful, it should be done with splitters.
8475
8476 (define_expand "iordi3"
8477   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8478         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8479                 (match_operand:DI 2 "x86_64_general_operand" "")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "TARGET_64BIT"
8482   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8483
8484 (define_insn "*iordi_1_rex64"
8485   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8486         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8487                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8488    (clobber (reg:CC FLAGS_REG))]
8489   "TARGET_64BIT
8490    && ix86_binary_operator_ok (IOR, DImode, operands)"
8491   "or{q}\t{%2, %0|%0, %2}"
8492   [(set_attr "type" "alu")
8493    (set_attr "mode" "DI")])
8494
8495 (define_insn "*iordi_2_rex64"
8496   [(set (reg FLAGS_REG)
8497         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8498                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8499                  (const_int 0)))
8500    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8501         (ior:DI (match_dup 1) (match_dup 2)))]
8502   "TARGET_64BIT
8503    && ix86_match_ccmode (insn, CCNOmode)
8504    && ix86_binary_operator_ok (IOR, DImode, operands)"
8505   "or{q}\t{%2, %0|%0, %2}"
8506   [(set_attr "type" "alu")
8507    (set_attr "mode" "DI")])
8508
8509 (define_insn "*iordi_3_rex64"
8510   [(set (reg FLAGS_REG)
8511         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8512                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8513                  (const_int 0)))
8514    (clobber (match_scratch:DI 0 "=r"))]
8515   "TARGET_64BIT
8516    && ix86_match_ccmode (insn, CCNOmode)
8517    && ix86_binary_operator_ok (IOR, DImode, operands)"
8518   "or{q}\t{%2, %0|%0, %2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "mode" "DI")])
8521
8522
8523 (define_expand "iorsi3"
8524   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8525         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8526                 (match_operand:SI 2 "general_operand" "")))
8527    (clobber (reg:CC FLAGS_REG))]
8528   ""
8529   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8530
8531 (define_insn "*iorsi_1"
8532   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8533         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8534                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "ix86_binary_operator_ok (IOR, SImode, operands)"
8537   "or{l}\t{%2, %0|%0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "SI")])
8540
8541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8542 (define_insn "*iorsi_1_zext"
8543   [(set (match_operand:DI 0 "register_operand" "=rm")
8544         (zero_extend:DI
8545           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8546                   (match_operand:SI 2 "general_operand" "rim"))))
8547    (clobber (reg:CC FLAGS_REG))]
8548   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8549   "or{l}\t{%2, %k0|%k0, %2}"
8550   [(set_attr "type" "alu")
8551    (set_attr "mode" "SI")])
8552
8553 (define_insn "*iorsi_1_zext_imm"
8554   [(set (match_operand:DI 0 "register_operand" "=rm")
8555         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8556                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "TARGET_64BIT"
8559   "or{l}\t{%2, %k0|%k0, %2}"
8560   [(set_attr "type" "alu")
8561    (set_attr "mode" "SI")])
8562
8563 (define_insn "*iorsi_2"
8564   [(set (reg FLAGS_REG)
8565         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8566                          (match_operand:SI 2 "general_operand" "rim,ri"))
8567                  (const_int 0)))
8568    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8569         (ior:SI (match_dup 1) (match_dup 2)))]
8570   "ix86_match_ccmode (insn, CCNOmode)
8571    && ix86_binary_operator_ok (IOR, SImode, operands)"
8572   "or{l}\t{%2, %0|%0, %2}"
8573   [(set_attr "type" "alu")
8574    (set_attr "mode" "SI")])
8575
8576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8577 ;; ??? Special case for immediate operand is missing - it is tricky.
8578 (define_insn "*iorsi_2_zext"
8579   [(set (reg FLAGS_REG)
8580         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8581                          (match_operand:SI 2 "general_operand" "rim"))
8582                  (const_int 0)))
8583    (set (match_operand:DI 0 "register_operand" "=r")
8584         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8585   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8586    && ix86_binary_operator_ok (IOR, SImode, operands)"
8587   "or{l}\t{%2, %k0|%k0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "SI")])
8590
8591 (define_insn "*iorsi_2_zext_imm"
8592   [(set (reg FLAGS_REG)
8593         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "register_operand" "=r")
8597         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599    && ix86_binary_operator_ok (IOR, SImode, operands)"
8600   "or{l}\t{%2, %k0|%k0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "SI")])
8603
8604 (define_insn "*iorsi_3"
8605   [(set (reg FLAGS_REG)
8606         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8607                          (match_operand:SI 2 "general_operand" "rim"))
8608                  (const_int 0)))
8609    (clobber (match_scratch:SI 0 "=r"))]
8610   "ix86_match_ccmode (insn, CCNOmode)
8611    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8612   "or{l}\t{%2, %0|%0, %2}"
8613   [(set_attr "type" "alu")
8614    (set_attr "mode" "SI")])
8615
8616 (define_expand "iorhi3"
8617   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8618         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8619                 (match_operand:HI 2 "general_operand" "")))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "TARGET_HIMODE_MATH"
8622   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8623
8624 (define_insn "*iorhi_1"
8625   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8626         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8627                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8628    (clobber (reg:CC FLAGS_REG))]
8629   "ix86_binary_operator_ok (IOR, HImode, operands)"
8630   "or{w}\t{%2, %0|%0, %2}"
8631   [(set_attr "type" "alu")
8632    (set_attr "mode" "HI")])
8633
8634 (define_insn "*iorhi_2"
8635   [(set (reg FLAGS_REG)
8636         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8637                          (match_operand:HI 2 "general_operand" "rim,ri"))
8638                  (const_int 0)))
8639    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8640         (ior:HI (match_dup 1) (match_dup 2)))]
8641   "ix86_match_ccmode (insn, CCNOmode)
8642    && ix86_binary_operator_ok (IOR, HImode, operands)"
8643   "or{w}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "HI")])
8646
8647 (define_insn "*iorhi_3"
8648   [(set (reg FLAGS_REG)
8649         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8650                          (match_operand:HI 2 "general_operand" "rim"))
8651                  (const_int 0)))
8652    (clobber (match_scratch:HI 0 "=r"))]
8653   "ix86_match_ccmode (insn, CCNOmode)
8654    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8655   "or{w}\t{%2, %0|%0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "mode" "HI")])
8658
8659 (define_expand "iorqi3"
8660   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8661         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8662                 (match_operand:QI 2 "general_operand" "")))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "TARGET_QIMODE_MATH"
8665   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8666
8667 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8668 (define_insn "*iorqi_1"
8669   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8670         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8671                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8672    (clobber (reg:CC FLAGS_REG))]
8673   "ix86_binary_operator_ok (IOR, QImode, operands)"
8674   "@
8675    or{b}\t{%2, %0|%0, %2}
8676    or{b}\t{%2, %0|%0, %2}
8677    or{l}\t{%k2, %k0|%k0, %k2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "mode" "QI,QI,SI")])
8680
8681 (define_insn "*iorqi_1_slp"
8682   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8683         (ior:QI (match_dup 0)
8684                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8685    (clobber (reg:CC FLAGS_REG))]
8686   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8688   "or{b}\t{%1, %0|%0, %1}"
8689   [(set_attr "type" "alu1")
8690    (set_attr "mode" "QI")])
8691
8692 (define_insn "*iorqi_2"
8693   [(set (reg FLAGS_REG)
8694         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8695                          (match_operand:QI 2 "general_operand" "qim,qi"))
8696                  (const_int 0)))
8697    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8698         (ior:QI (match_dup 1) (match_dup 2)))]
8699   "ix86_match_ccmode (insn, CCNOmode)
8700    && ix86_binary_operator_ok (IOR, QImode, operands)"
8701   "or{b}\t{%2, %0|%0, %2}"
8702   [(set_attr "type" "alu")
8703    (set_attr "mode" "QI")])
8704
8705 (define_insn "*iorqi_2_slp"
8706   [(set (reg FLAGS_REG)
8707         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8708                          (match_operand:QI 1 "general_operand" "qim,qi"))
8709                  (const_int 0)))
8710    (set (strict_low_part (match_dup 0))
8711         (ior:QI (match_dup 0) (match_dup 1)))]
8712   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8713    && ix86_match_ccmode (insn, CCNOmode)
8714    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8715   "or{b}\t{%1, %0|%0, %1}"
8716   [(set_attr "type" "alu1")
8717    (set_attr "mode" "QI")])
8718
8719 (define_insn "*iorqi_3"
8720   [(set (reg FLAGS_REG)
8721         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8722                          (match_operand:QI 2 "general_operand" "qim"))
8723                  (const_int 0)))
8724    (clobber (match_scratch:QI 0 "=q"))]
8725   "ix86_match_ccmode (insn, CCNOmode)
8726    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8727   "or{b}\t{%2, %0|%0, %2}"
8728   [(set_attr "type" "alu")
8729    (set_attr "mode" "QI")])
8730
8731 (define_insn "iorqi_ext_0"
8732   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8733                          (const_int 8)
8734                          (const_int 8))
8735         (ior:SI 
8736           (zero_extract:SI
8737             (match_operand 1 "ext_register_operand" "0")
8738             (const_int 8)
8739             (const_int 8))
8740           (match_operand 2 "const_int_operand" "n")))
8741    (clobber (reg:CC FLAGS_REG))]
8742   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8743   "or{b}\t{%2, %h0|%h0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "length_immediate" "1")
8746    (set_attr "mode" "QI")])
8747
8748 (define_insn "*iorqi_ext_1"
8749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8750                          (const_int 8)
8751                          (const_int 8))
8752         (ior:SI 
8753           (zero_extract:SI
8754             (match_operand 1 "ext_register_operand" "0")
8755             (const_int 8)
8756             (const_int 8))
8757           (zero_extend:SI
8758             (match_operand:QI 2 "general_operand" "Qm"))))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "!TARGET_64BIT
8761    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8762   "or{b}\t{%2, %h0|%h0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "length_immediate" "0")
8765    (set_attr "mode" "QI")])
8766
8767 (define_insn "*iorqi_ext_1_rex64"
8768   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8769                          (const_int 8)
8770                          (const_int 8))
8771         (ior:SI 
8772           (zero_extract:SI
8773             (match_operand 1 "ext_register_operand" "0")
8774             (const_int 8)
8775             (const_int 8))
8776           (zero_extend:SI
8777             (match_operand 2 "ext_register_operand" "Q"))))
8778    (clobber (reg:CC FLAGS_REG))]
8779   "TARGET_64BIT
8780    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8781   "or{b}\t{%2, %h0|%h0, %2}"
8782   [(set_attr "type" "alu")
8783    (set_attr "length_immediate" "0")
8784    (set_attr "mode" "QI")])
8785
8786 (define_insn "*iorqi_ext_2"
8787   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8788                          (const_int 8)
8789                          (const_int 8))
8790         (ior:SI 
8791           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8792                            (const_int 8)
8793                            (const_int 8))
8794           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8795                            (const_int 8)
8796                            (const_int 8))))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8799   "ior{b}\t{%h2, %h0|%h0, %h2}"
8800   [(set_attr "type" "alu")
8801    (set_attr "length_immediate" "0")
8802    (set_attr "mode" "QI")])
8803
8804 (define_split
8805   [(set (match_operand 0 "register_operand" "")
8806         (ior (match_operand 1 "register_operand" "")
8807              (match_operand 2 "const_int_operand" "")))
8808    (clobber (reg:CC FLAGS_REG))]
8809    "reload_completed
8810     && QI_REG_P (operands[0])
8811     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8812     && !(INTVAL (operands[2]) & ~(255 << 8))
8813     && GET_MODE (operands[0]) != QImode"
8814   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8815                    (ior:SI (zero_extract:SI (match_dup 1)
8816                                             (const_int 8) (const_int 8))
8817                            (match_dup 2)))
8818               (clobber (reg:CC FLAGS_REG))])]
8819   "operands[0] = gen_lowpart (SImode, operands[0]);
8820    operands[1] = gen_lowpart (SImode, operands[1]);
8821    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8822
8823 ;; Since OR can be encoded with sign extended immediate, this is only
8824 ;; profitable when 7th bit is set.
8825 (define_split
8826   [(set (match_operand 0 "register_operand" "")
8827         (ior (match_operand 1 "general_operand" "")
8828              (match_operand 2 "const_int_operand" "")))
8829    (clobber (reg:CC FLAGS_REG))]
8830    "reload_completed
8831     && ANY_QI_REG_P (operands[0])
8832     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8833     && !(INTVAL (operands[2]) & ~255)
8834     && (INTVAL (operands[2]) & 128)
8835     && GET_MODE (operands[0]) != QImode"
8836   [(parallel [(set (strict_low_part (match_dup 0))
8837                    (ior:QI (match_dup 1)
8838                            (match_dup 2)))
8839               (clobber (reg:CC FLAGS_REG))])]
8840   "operands[0] = gen_lowpart (QImode, operands[0]);
8841    operands[1] = gen_lowpart (QImode, operands[1]);
8842    operands[2] = gen_lowpart (QImode, operands[2]);")
8843 \f
8844 ;; Logical XOR instructions
8845
8846 ;; %%% This used to optimize known byte-wide and operations to memory.
8847 ;; If this is considered useful, it should be done with splitters.
8848
8849 (define_expand "xordi3"
8850   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8851         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8852                 (match_operand:DI 2 "x86_64_general_operand" "")))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT"
8855   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8856
8857 (define_insn "*xordi_1_rex64"
8858   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8859         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8860                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8861    (clobber (reg:CC FLAGS_REG))]
8862   "TARGET_64BIT
8863    && ix86_binary_operator_ok (XOR, DImode, operands)"
8864   "@
8865    xor{q}\t{%2, %0|%0, %2}
8866    xor{q}\t{%2, %0|%0, %2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "mode" "DI,DI")])
8869
8870 (define_insn "*xordi_2_rex64"
8871   [(set (reg FLAGS_REG)
8872         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8873                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8874                  (const_int 0)))
8875    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8876         (xor:DI (match_dup 1) (match_dup 2)))]
8877   "TARGET_64BIT
8878    && ix86_match_ccmode (insn, CCNOmode)
8879    && ix86_binary_operator_ok (XOR, DImode, operands)"
8880   "@
8881    xor{q}\t{%2, %0|%0, %2}
8882    xor{q}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "DI,DI")])
8885
8886 (define_insn "*xordi_3_rex64"
8887   [(set (reg FLAGS_REG)
8888         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8889                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8890                  (const_int 0)))
8891    (clobber (match_scratch:DI 0 "=r"))]
8892   "TARGET_64BIT
8893    && ix86_match_ccmode (insn, CCNOmode)
8894    && ix86_binary_operator_ok (XOR, DImode, operands)"
8895   "xor{q}\t{%2, %0|%0, %2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "mode" "DI")])
8898
8899 (define_expand "xorsi3"
8900   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8901         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8902                 (match_operand:SI 2 "general_operand" "")))
8903    (clobber (reg:CC FLAGS_REG))]
8904   ""
8905   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8906
8907 (define_insn "*xorsi_1"
8908   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8909         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8910                 (match_operand:SI 2 "general_operand" "ri,rm")))
8911    (clobber (reg:CC FLAGS_REG))]
8912   "ix86_binary_operator_ok (XOR, SImode, operands)"
8913   "xor{l}\t{%2, %0|%0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "mode" "SI")])
8916
8917 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8918 ;; Add speccase for immediates
8919 (define_insn "*xorsi_1_zext"
8920   [(set (match_operand:DI 0 "register_operand" "=r")
8921         (zero_extend:DI
8922           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8923                   (match_operand:SI 2 "general_operand" "rim"))))
8924    (clobber (reg:CC FLAGS_REG))]
8925   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8926   "xor{l}\t{%2, %k0|%k0, %2}"
8927   [(set_attr "type" "alu")
8928    (set_attr "mode" "SI")])
8929
8930 (define_insn "*xorsi_1_zext_imm"
8931   [(set (match_operand:DI 0 "register_operand" "=r")
8932         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8933                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8934    (clobber (reg:CC FLAGS_REG))]
8935   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8936   "xor{l}\t{%2, %k0|%k0, %2}"
8937   [(set_attr "type" "alu")
8938    (set_attr "mode" "SI")])
8939
8940 (define_insn "*xorsi_2"
8941   [(set (reg FLAGS_REG)
8942         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943                          (match_operand:SI 2 "general_operand" "rim,ri"))
8944                  (const_int 0)))
8945    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8946         (xor:SI (match_dup 1) (match_dup 2)))]
8947   "ix86_match_ccmode (insn, CCNOmode)
8948    && ix86_binary_operator_ok (XOR, SImode, operands)"
8949   "xor{l}\t{%2, %0|%0, %2}"
8950   [(set_attr "type" "alu")
8951    (set_attr "mode" "SI")])
8952
8953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8954 ;; ??? Special case for immediate operand is missing - it is tricky.
8955 (define_insn "*xorsi_2_zext"
8956   [(set (reg FLAGS_REG)
8957         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8958                          (match_operand:SI 2 "general_operand" "rim"))
8959                  (const_int 0)))
8960    (set (match_operand:DI 0 "register_operand" "=r")
8961         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8962   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8963    && ix86_binary_operator_ok (XOR, SImode, operands)"
8964   "xor{l}\t{%2, %k0|%k0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "SI")])
8967
8968 (define_insn "*xorsi_2_zext_imm"
8969   [(set (reg FLAGS_REG)
8970         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8972                  (const_int 0)))
8973    (set (match_operand:DI 0 "register_operand" "=r")
8974         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8975   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (XOR, SImode, operands)"
8977   "xor{l}\t{%2, %k0|%k0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "SI")])
8980
8981 (define_insn "*xorsi_3"
8982   [(set (reg FLAGS_REG)
8983         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8984                          (match_operand:SI 2 "general_operand" "rim"))
8985                  (const_int 0)))
8986    (clobber (match_scratch:SI 0 "=r"))]
8987   "ix86_match_ccmode (insn, CCNOmode)
8988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8989   "xor{l}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "SI")])
8992
8993 (define_expand "xorhi3"
8994   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8995         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8996                 (match_operand:HI 2 "general_operand" "")))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "TARGET_HIMODE_MATH"
8999   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9000
9001 (define_insn "*xorhi_1"
9002   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9003         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9004                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "ix86_binary_operator_ok (XOR, HImode, operands)"
9007   "xor{w}\t{%2, %0|%0, %2}"
9008   [(set_attr "type" "alu")
9009    (set_attr "mode" "HI")])
9010
9011 (define_insn "*xorhi_2"
9012   [(set (reg FLAGS_REG)
9013         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9014                          (match_operand:HI 2 "general_operand" "rim,ri"))
9015                  (const_int 0)))
9016    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9017         (xor:HI (match_dup 1) (match_dup 2)))]
9018   "ix86_match_ccmode (insn, CCNOmode)
9019    && ix86_binary_operator_ok (XOR, HImode, operands)"
9020   "xor{w}\t{%2, %0|%0, %2}"
9021   [(set_attr "type" "alu")
9022    (set_attr "mode" "HI")])
9023
9024 (define_insn "*xorhi_3"
9025   [(set (reg FLAGS_REG)
9026         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9027                          (match_operand:HI 2 "general_operand" "rim"))
9028                  (const_int 0)))
9029    (clobber (match_scratch:HI 0 "=r"))]
9030   "ix86_match_ccmode (insn, CCNOmode)
9031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9032   "xor{w}\t{%2, %0|%0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "HI")])
9035
9036 (define_expand "xorqi3"
9037   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9038         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9039                 (match_operand:QI 2 "general_operand" "")))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "TARGET_QIMODE_MATH"
9042   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9043
9044 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9045 (define_insn "*xorqi_1"
9046   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9047         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9048                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9049    (clobber (reg:CC FLAGS_REG))]
9050   "ix86_binary_operator_ok (XOR, QImode, operands)"
9051   "@
9052    xor{b}\t{%2, %0|%0, %2}
9053    xor{b}\t{%2, %0|%0, %2}
9054    xor{l}\t{%k2, %k0|%k0, %k2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "QI,QI,SI")])
9057
9058 (define_insn "*xorqi_1_slp"
9059   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9060         (xor:QI (match_dup 0)
9061                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9062    (clobber (reg:CC FLAGS_REG))]
9063   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9064    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9065   "xor{b}\t{%1, %0|%0, %1}"
9066   [(set_attr "type" "alu1")
9067    (set_attr "mode" "QI")])
9068
9069 (define_insn "xorqi_ext_0"
9070   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071                          (const_int 8)
9072                          (const_int 8))
9073         (xor:SI 
9074           (zero_extract:SI
9075             (match_operand 1 "ext_register_operand" "0")
9076             (const_int 8)
9077             (const_int 8))
9078           (match_operand 2 "const_int_operand" "n")))
9079    (clobber (reg:CC FLAGS_REG))]
9080   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9081   "xor{b}\t{%2, %h0|%h0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "length_immediate" "1")
9084    (set_attr "mode" "QI")])
9085
9086 (define_insn "*xorqi_ext_1"
9087   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9088                          (const_int 8)
9089                          (const_int 8))
9090         (xor:SI 
9091           (zero_extract:SI
9092             (match_operand 1 "ext_register_operand" "0")
9093             (const_int 8)
9094             (const_int 8))
9095           (zero_extend:SI
9096             (match_operand:QI 2 "general_operand" "Qm"))))
9097    (clobber (reg:CC FLAGS_REG))]
9098   "!TARGET_64BIT
9099    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100   "xor{b}\t{%2, %h0|%h0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "length_immediate" "0")
9103    (set_attr "mode" "QI")])
9104
9105 (define_insn "*xorqi_ext_1_rex64"
9106   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9107                          (const_int 8)
9108                          (const_int 8))
9109         (xor:SI 
9110           (zero_extract:SI
9111             (match_operand 1 "ext_register_operand" "0")
9112             (const_int 8)
9113             (const_int 8))
9114           (zero_extend:SI
9115             (match_operand 2 "ext_register_operand" "Q"))))
9116    (clobber (reg:CC FLAGS_REG))]
9117   "TARGET_64BIT
9118    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9119   "xor{b}\t{%2, %h0|%h0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "length_immediate" "0")
9122    (set_attr "mode" "QI")])
9123
9124 (define_insn "*xorqi_ext_2"
9125   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9126                          (const_int 8)
9127                          (const_int 8))
9128         (xor:SI 
9129           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9130                            (const_int 8)
9131                            (const_int 8))
9132           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9133                            (const_int 8)
9134                            (const_int 8))))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9137   "xor{b}\t{%h2, %h0|%h0, %h2}"
9138   [(set_attr "type" "alu")
9139    (set_attr "length_immediate" "0")
9140    (set_attr "mode" "QI")])
9141
9142 (define_insn "*xorqi_cc_1"
9143   [(set (reg FLAGS_REG)
9144         (compare
9145           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9146                   (match_operand:QI 2 "general_operand" "qim,qi"))
9147           (const_int 0)))
9148    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9149         (xor:QI (match_dup 1) (match_dup 2)))]
9150   "ix86_match_ccmode (insn, CCNOmode)
9151    && ix86_binary_operator_ok (XOR, QImode, operands)"
9152   "xor{b}\t{%2, %0|%0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "mode" "QI")])
9155
9156 (define_insn "*xorqi_2_slp"
9157   [(set (reg FLAGS_REG)
9158         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9159                          (match_operand:QI 1 "general_operand" "qim,qi"))
9160                  (const_int 0)))
9161    (set (strict_low_part (match_dup 0))
9162         (xor:QI (match_dup 0) (match_dup 1)))]
9163   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9164    && ix86_match_ccmode (insn, CCNOmode)
9165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9166   "xor{b}\t{%1, %0|%0, %1}"
9167   [(set_attr "type" "alu1")
9168    (set_attr "mode" "QI")])
9169
9170 (define_insn "*xorqi_cc_2"
9171   [(set (reg FLAGS_REG)
9172         (compare
9173           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9174                   (match_operand:QI 2 "general_operand" "qim"))
9175           (const_int 0)))
9176    (clobber (match_scratch:QI 0 "=q"))]
9177   "ix86_match_ccmode (insn, CCNOmode)
9178    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9179   "xor{b}\t{%2, %0|%0, %2}"
9180   [(set_attr "type" "alu")
9181    (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_cc_ext_1"
9184   [(set (reg FLAGS_REG)
9185         (compare
9186           (xor:SI
9187             (zero_extract:SI
9188               (match_operand 1 "ext_register_operand" "0")
9189               (const_int 8)
9190               (const_int 8))
9191             (match_operand:QI 2 "general_operand" "qmn"))
9192           (const_int 0)))
9193    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI 
9197           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9198           (match_dup 2)))]
9199   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9200   "xor{b}\t{%2, %h0|%h0, %2}"
9201   [(set_attr "type" "alu")
9202    (set_attr "mode" "QI")])
9203
9204 (define_insn "*xorqi_cc_ext_1_rex64"
9205   [(set (reg FLAGS_REG)
9206         (compare
9207           (xor:SI
9208             (zero_extract:SI
9209               (match_operand 1 "ext_register_operand" "0")
9210               (const_int 8)
9211               (const_int 8))
9212             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9213           (const_int 0)))
9214    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9215                          (const_int 8)
9216                          (const_int 8))
9217         (xor:SI 
9218           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9219           (match_dup 2)))]
9220   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9221   "xor{b}\t{%2, %h0|%h0, %2}"
9222   [(set_attr "type" "alu")
9223    (set_attr "mode" "QI")])
9224
9225 (define_expand "xorqi_cc_ext_1"
9226   [(parallel [
9227      (set (reg:CCNO FLAGS_REG)
9228           (compare:CCNO
9229             (xor:SI
9230               (zero_extract:SI
9231                 (match_operand 1 "ext_register_operand" "")
9232                 (const_int 8)
9233                 (const_int 8))
9234               (match_operand:QI 2 "general_operand" ""))
9235             (const_int 0)))
9236      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9237                            (const_int 8)
9238                            (const_int 8))
9239           (xor:SI 
9240             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9241             (match_dup 2)))])]
9242   ""
9243   "")
9244
9245 (define_split
9246   [(set (match_operand 0 "register_operand" "")
9247         (xor (match_operand 1 "register_operand" "")
9248              (match_operand 2 "const_int_operand" "")))
9249    (clobber (reg:CC FLAGS_REG))]
9250    "reload_completed
9251     && QI_REG_P (operands[0])
9252     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9253     && !(INTVAL (operands[2]) & ~(255 << 8))
9254     && GET_MODE (operands[0]) != QImode"
9255   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9256                    (xor:SI (zero_extract:SI (match_dup 1)
9257                                             (const_int 8) (const_int 8))
9258                            (match_dup 2)))
9259               (clobber (reg:CC FLAGS_REG))])]
9260   "operands[0] = gen_lowpart (SImode, operands[0]);
9261    operands[1] = gen_lowpart (SImode, operands[1]);
9262    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9263
9264 ;; Since XOR can be encoded with sign extended immediate, this is only
9265 ;; profitable when 7th bit is set.
9266 (define_split
9267   [(set (match_operand 0 "register_operand" "")
9268         (xor (match_operand 1 "general_operand" "")
9269              (match_operand 2 "const_int_operand" "")))
9270    (clobber (reg:CC FLAGS_REG))]
9271    "reload_completed
9272     && ANY_QI_REG_P (operands[0])
9273     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9274     && !(INTVAL (operands[2]) & ~255)
9275     && (INTVAL (operands[2]) & 128)
9276     && GET_MODE (operands[0]) != QImode"
9277   [(parallel [(set (strict_low_part (match_dup 0))
9278                    (xor:QI (match_dup 1)
9279                            (match_dup 2)))
9280               (clobber (reg:CC FLAGS_REG))])]
9281   "operands[0] = gen_lowpart (QImode, operands[0]);
9282    operands[1] = gen_lowpart (QImode, operands[1]);
9283    operands[2] = gen_lowpart (QImode, operands[2]);")
9284 \f
9285 ;; Negation instructions
9286
9287 (define_expand "negti2"
9288   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9289                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9290               (clobber (reg:CC FLAGS_REG))])]
9291   "TARGET_64BIT"
9292   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9293
9294 (define_insn "*negti2_1"
9295   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9296         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9297    (clobber (reg:CC FLAGS_REG))]
9298   "TARGET_64BIT
9299    && ix86_unary_operator_ok (NEG, TImode, operands)"
9300   "#")
9301
9302 (define_split
9303   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9304         (neg:TI (match_operand:TI 1 "general_operand" "")))
9305    (clobber (reg:CC FLAGS_REG))]
9306   "TARGET_64BIT && reload_completed"
9307   [(parallel
9308     [(set (reg:CCZ FLAGS_REG)
9309           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9310      (set (match_dup 0) (neg:DI (match_dup 2)))])
9311    (parallel
9312     [(set (match_dup 1)
9313           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9314                             (match_dup 3))
9315                    (const_int 0)))
9316      (clobber (reg:CC FLAGS_REG))])
9317    (parallel
9318     [(set (match_dup 1)
9319           (neg:DI (match_dup 1)))
9320      (clobber (reg:CC FLAGS_REG))])]
9321   "split_ti (operands+1, 1, operands+2, operands+3);
9322    split_ti (operands+0, 1, operands+0, operands+1);")
9323
9324 (define_expand "negdi2"
9325   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9326                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9327               (clobber (reg:CC FLAGS_REG))])]
9328   ""
9329   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9330
9331 (define_insn "*negdi2_1"
9332   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9333         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9334    (clobber (reg:CC FLAGS_REG))]
9335   "!TARGET_64BIT
9336    && ix86_unary_operator_ok (NEG, DImode, operands)"
9337   "#")
9338
9339 (define_split
9340   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9341         (neg:DI (match_operand:DI 1 "general_operand" "")))
9342    (clobber (reg:CC FLAGS_REG))]
9343   "!TARGET_64BIT && reload_completed"
9344   [(parallel
9345     [(set (reg:CCZ FLAGS_REG)
9346           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9347      (set (match_dup 0) (neg:SI (match_dup 2)))])
9348    (parallel
9349     [(set (match_dup 1)
9350           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9351                             (match_dup 3))
9352                    (const_int 0)))
9353      (clobber (reg:CC FLAGS_REG))])
9354    (parallel
9355     [(set (match_dup 1)
9356           (neg:SI (match_dup 1)))
9357      (clobber (reg:CC FLAGS_REG))])]
9358   "split_di (operands+1, 1, operands+2, operands+3);
9359    split_di (operands+0, 1, operands+0, operands+1);")
9360
9361 (define_insn "*negdi2_1_rex64"
9362   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9363         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9366   "neg{q}\t%0"
9367   [(set_attr "type" "negnot")
9368    (set_attr "mode" "DI")])
9369
9370 ;; The problem with neg is that it does not perform (compare x 0),
9371 ;; it really performs (compare 0 x), which leaves us with the zero
9372 ;; flag being the only useful item.
9373
9374 (define_insn "*negdi2_cmpz_rex64"
9375   [(set (reg:CCZ FLAGS_REG)
9376         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9377                      (const_int 0)))
9378    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9379         (neg:DI (match_dup 1)))]
9380   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9381   "neg{q}\t%0"
9382   [(set_attr "type" "negnot")
9383    (set_attr "mode" "DI")])
9384
9385
9386 (define_expand "negsi2"
9387   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9388                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9389               (clobber (reg:CC FLAGS_REG))])]
9390   ""
9391   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9392
9393 (define_insn "*negsi2_1"
9394   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9395         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "ix86_unary_operator_ok (NEG, SImode, operands)"
9398   "neg{l}\t%0"
9399   [(set_attr "type" "negnot")
9400    (set_attr "mode" "SI")])
9401
9402 ;; Combine is quite creative about this pattern.
9403 (define_insn "*negsi2_1_zext"
9404   [(set (match_operand:DI 0 "register_operand" "=r")
9405         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9406                                         (const_int 32)))
9407                      (const_int 32)))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9410   "neg{l}\t%k0"
9411   [(set_attr "type" "negnot")
9412    (set_attr "mode" "SI")])
9413
9414 ;; The problem with neg is that it does not perform (compare x 0),
9415 ;; it really performs (compare 0 x), which leaves us with the zero
9416 ;; flag being the only useful item.
9417
9418 (define_insn "*negsi2_cmpz"
9419   [(set (reg:CCZ FLAGS_REG)
9420         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9421                      (const_int 0)))
9422    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9423         (neg:SI (match_dup 1)))]
9424   "ix86_unary_operator_ok (NEG, SImode, operands)"
9425   "neg{l}\t%0"
9426   [(set_attr "type" "negnot")
9427    (set_attr "mode" "SI")])
9428
9429 (define_insn "*negsi2_cmpz_zext"
9430   [(set (reg:CCZ FLAGS_REG)
9431         (compare:CCZ (lshiftrt:DI
9432                        (neg:DI (ashift:DI
9433                                  (match_operand:DI 1 "register_operand" "0")
9434                                  (const_int 32)))
9435                        (const_int 32))
9436                      (const_int 0)))
9437    (set (match_operand:DI 0 "register_operand" "=r")
9438         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9439                                         (const_int 32)))
9440                      (const_int 32)))]
9441   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9442   "neg{l}\t%k0"
9443   [(set_attr "type" "negnot")
9444    (set_attr "mode" "SI")])
9445
9446 (define_expand "neghi2"
9447   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9448                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9449               (clobber (reg:CC FLAGS_REG))])]
9450   "TARGET_HIMODE_MATH"
9451   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9452
9453 (define_insn "*neghi2_1"
9454   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9455         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "ix86_unary_operator_ok (NEG, HImode, operands)"
9458   "neg{w}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "HI")])
9461
9462 (define_insn "*neghi2_cmpz"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9465                      (const_int 0)))
9466    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9467         (neg:HI (match_dup 1)))]
9468   "ix86_unary_operator_ok (NEG, HImode, operands)"
9469   "neg{w}\t%0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "HI")])
9472
9473 (define_expand "negqi2"
9474   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9475                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9476               (clobber (reg:CC FLAGS_REG))])]
9477   "TARGET_QIMODE_MATH"
9478   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9479
9480 (define_insn "*negqi2_1"
9481   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9482         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9483    (clobber (reg:CC FLAGS_REG))]
9484   "ix86_unary_operator_ok (NEG, QImode, operands)"
9485   "neg{b}\t%0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "QI")])
9488
9489 (define_insn "*negqi2_cmpz"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9492                      (const_int 0)))
9493    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9494         (neg:QI (match_dup 1)))]
9495   "ix86_unary_operator_ok (NEG, QImode, operands)"
9496   "neg{b}\t%0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "QI")])
9499
9500 ;; Changing of sign for FP values is doable using integer unit too.
9501
9502 (define_expand "negsf2"
9503   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9504         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9505   "TARGET_80387 || TARGET_SSE_MATH"
9506   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9507
9508 (define_expand "abssf2"
9509   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9510         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9511   "TARGET_80387 || TARGET_SSE_MATH"
9512   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9513
9514 (define_insn "*absnegsf2_mixed"
9515   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9516         (match_operator:SF 3 "absneg_operator"
9517           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9518    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9519    (clobber (reg:CC FLAGS_REG))]
9520   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9521    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9522   "#")
9523
9524 (define_insn "*absnegsf2_sse"
9525   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9526         (match_operator:SF 3 "absneg_operator"
9527           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9528    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9529    (clobber (reg:CC FLAGS_REG))]
9530   "TARGET_SSE_MATH
9531    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9532   "#")
9533
9534 (define_insn "*absnegsf2_i387"
9535   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9536         (match_operator:SF 3 "absneg_operator"
9537           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9538    (use (match_operand 2 "" ""))
9539    (clobber (reg:CC FLAGS_REG))]
9540   "TARGET_80387 && !TARGET_SSE_MATH
9541    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9542   "#")
9543
9544 (define_expand "copysignsf3"
9545   [(match_operand:SF 0 "register_operand" "")
9546    (match_operand:SF 1 "nonmemory_operand" "")
9547    (match_operand:SF 2 "register_operand" "")]
9548   "TARGET_SSE_MATH"
9549 {
9550   ix86_expand_copysign (operands);
9551   DONE;
9552 })
9553
9554 (define_insn_and_split "copysignsf3_const"
9555   [(set (match_operand:SF 0 "register_operand"          "=x")
9556         (unspec:SF
9557           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9558            (match_operand:SF 2 "register_operand"       "0")
9559            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9560           UNSPEC_COPYSIGN))]
9561   "TARGET_SSE_MATH"
9562   "#"
9563   "&& reload_completed"
9564   [(const_int 0)]
9565 {
9566   ix86_split_copysign_const (operands);
9567   DONE;
9568 })
9569
9570 (define_insn "copysignsf3_var"
9571   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9572         (unspec:SF
9573           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9574            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9575            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9576            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9577           UNSPEC_COPYSIGN))
9578    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9579   "TARGET_SSE_MATH"
9580   "#")
9581
9582 (define_split
9583   [(set (match_operand:SF 0 "register_operand" "")
9584         (unspec:SF
9585           [(match_operand:SF 2 "register_operand" "")
9586            (match_operand:SF 3 "register_operand" "")
9587            (match_operand:V4SF 4 "" "")
9588            (match_operand:V4SF 5 "" "")]
9589           UNSPEC_COPYSIGN))
9590    (clobber (match_scratch:V4SF 1 ""))]
9591   "TARGET_SSE_MATH && reload_completed"
9592   [(const_int 0)]
9593 {
9594   ix86_split_copysign_var (operands);
9595   DONE;
9596 })
9597
9598 (define_expand "negdf2"
9599   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9600         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9601   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9602   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9603
9604 (define_expand "absdf2"
9605   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9606         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9607   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9608   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9609
9610 (define_insn "*absnegdf2_mixed"
9611   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9612         (match_operator:DF 3 "absneg_operator"
9613           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9614    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9617    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9618   "#")
9619
9620 (define_insn "*absnegdf2_sse"
9621   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9622         (match_operator:DF 3 "absneg_operator"
9623           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9624    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "TARGET_SSE2 && TARGET_SSE_MATH
9627    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9628   "#")
9629
9630 (define_insn "*absnegdf2_i387"
9631   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9632         (match_operator:DF 3 "absneg_operator"
9633           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9634    (use (match_operand 2 "" ""))
9635    (clobber (reg:CC FLAGS_REG))]
9636   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9637    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9638   "#")
9639
9640 (define_expand "copysigndf3"
9641   [(match_operand:DF 0 "register_operand" "")
9642    (match_operand:DF 1 "nonmemory_operand" "")
9643    (match_operand:DF 2 "register_operand" "")]
9644   "TARGET_SSE2 && TARGET_SSE_MATH"
9645 {
9646   ix86_expand_copysign (operands);
9647   DONE;
9648 })
9649
9650 (define_insn_and_split "copysigndf3_const"
9651   [(set (match_operand:DF 0 "register_operand"          "=x")
9652         (unspec:DF
9653           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9654            (match_operand:DF 2 "register_operand"       "0")
9655            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9656           UNSPEC_COPYSIGN))]
9657   "TARGET_SSE2 && TARGET_SSE_MATH"
9658   "#"
9659   "&& reload_completed"
9660   [(const_int 0)]
9661 {
9662   ix86_split_copysign_const (operands);
9663   DONE;
9664 })
9665
9666 (define_insn "copysigndf3_var"
9667   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9668         (unspec:DF
9669           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9670            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9671            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9672            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9673           UNSPEC_COPYSIGN))
9674    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9675   "TARGET_SSE2 && TARGET_SSE_MATH"
9676   "#")
9677
9678 (define_split
9679   [(set (match_operand:DF 0 "register_operand" "")
9680         (unspec:DF
9681           [(match_operand:DF 2 "register_operand" "")
9682            (match_operand:DF 3 "register_operand" "")
9683            (match_operand:V2DF 4 "" "")
9684            (match_operand:V2DF 5 "" "")]
9685           UNSPEC_COPYSIGN))
9686    (clobber (match_scratch:V2DF 1 ""))]
9687   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9688   [(const_int 0)]
9689 {
9690   ix86_split_copysign_var (operands);
9691   DONE;
9692 })
9693
9694 (define_expand "negxf2"
9695   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9696         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9697   "TARGET_80387"
9698   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9699
9700 (define_expand "absxf2"
9701   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9702         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9703   "TARGET_80387"
9704   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9705
9706 (define_insn "*absnegxf2_i387"
9707   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9708         (match_operator:XF 3 "absneg_operator"
9709           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9710    (use (match_operand 2 "" ""))
9711    (clobber (reg:CC FLAGS_REG))]
9712   "TARGET_80387
9713    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9714   "#")
9715
9716 ;; Splitters for fp abs and neg.
9717
9718 (define_split
9719   [(set (match_operand 0 "fp_register_operand" "")
9720         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9721    (use (match_operand 2 "" ""))
9722    (clobber (reg:CC FLAGS_REG))]
9723   "reload_completed"
9724   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9725
9726 (define_split
9727   [(set (match_operand 0 "register_operand" "")
9728         (match_operator 3 "absneg_operator"
9729           [(match_operand 1 "register_operand" "")]))
9730    (use (match_operand 2 "nonimmediate_operand" ""))
9731    (clobber (reg:CC FLAGS_REG))]
9732   "reload_completed && SSE_REG_P (operands[0])"
9733   [(set (match_dup 0) (match_dup 3))]
9734 {
9735   enum machine_mode mode = GET_MODE (operands[0]);
9736   enum machine_mode vmode = GET_MODE (operands[2]);
9737   rtx tmp;
9738   
9739   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9740   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9741   if (operands_match_p (operands[0], operands[2]))
9742     {
9743       tmp = operands[1];
9744       operands[1] = operands[2];
9745       operands[2] = tmp;
9746     }
9747   if (GET_CODE (operands[3]) == ABS)
9748     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9749   else
9750     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9751   operands[3] = tmp;
9752 })
9753
9754 (define_split
9755   [(set (match_operand:SF 0 "register_operand" "")
9756         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9757    (use (match_operand:V4SF 2 "" ""))
9758    (clobber (reg:CC FLAGS_REG))]
9759   "reload_completed"
9760   [(parallel [(set (match_dup 0) (match_dup 1))
9761               (clobber (reg:CC FLAGS_REG))])]
9762
9763   rtx tmp;
9764   operands[0] = gen_lowpart (SImode, operands[0]);
9765   if (GET_CODE (operands[1]) == ABS)
9766     {
9767       tmp = gen_int_mode (0x7fffffff, SImode);
9768       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9769     }
9770   else
9771     {
9772       tmp = gen_int_mode (0x80000000, SImode);
9773       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9774     }
9775   operands[1] = tmp;
9776 })
9777
9778 (define_split
9779   [(set (match_operand:DF 0 "register_operand" "")
9780         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9781    (use (match_operand 2 "" ""))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "reload_completed"
9784   [(parallel [(set (match_dup 0) (match_dup 1))
9785               (clobber (reg:CC FLAGS_REG))])]
9786 {
9787   rtx tmp;
9788   if (TARGET_64BIT)
9789     {
9790       tmp = gen_lowpart (DImode, operands[0]);
9791       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9792       operands[0] = tmp;
9793
9794       if (GET_CODE (operands[1]) == ABS)
9795         tmp = const0_rtx;
9796       else
9797         tmp = gen_rtx_NOT (DImode, tmp);
9798     }
9799   else
9800     {
9801       operands[0] = gen_highpart (SImode, operands[0]);
9802       if (GET_CODE (operands[1]) == ABS)
9803         {
9804           tmp = gen_int_mode (0x7fffffff, SImode);
9805           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9806         }
9807       else
9808         {
9809           tmp = gen_int_mode (0x80000000, SImode);
9810           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9811         }
9812     }
9813   operands[1] = tmp;
9814 })
9815
9816 (define_split
9817   [(set (match_operand:XF 0 "register_operand" "")
9818         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9819    (use (match_operand 2 "" ""))
9820    (clobber (reg:CC FLAGS_REG))]
9821   "reload_completed"
9822   [(parallel [(set (match_dup 0) (match_dup 1))
9823               (clobber (reg:CC FLAGS_REG))])]
9824 {
9825   rtx tmp;
9826   operands[0] = gen_rtx_REG (SImode,
9827                              true_regnum (operands[0])
9828                              + (TARGET_64BIT ? 1 : 2));
9829   if (GET_CODE (operands[1]) == ABS)
9830     {
9831       tmp = GEN_INT (0x7fff);
9832       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9833     }
9834   else
9835     {
9836       tmp = GEN_INT (0x8000);
9837       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9838     }
9839   operands[1] = tmp;
9840 })
9841
9842 (define_split
9843   [(set (match_operand 0 "memory_operand" "")
9844         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9845    (use (match_operand 2 "" ""))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "reload_completed"
9848   [(parallel [(set (match_dup 0) (match_dup 1))
9849               (clobber (reg:CC FLAGS_REG))])]
9850 {
9851   enum machine_mode mode = GET_MODE (operands[0]);
9852   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9853   rtx tmp;
9854
9855   operands[0] = adjust_address (operands[0], QImode, size - 1);
9856   if (GET_CODE (operands[1]) == ABS)
9857     {
9858       tmp = gen_int_mode (0x7f, QImode);
9859       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9860     }
9861   else
9862     {
9863       tmp = gen_int_mode (0x80, QImode);
9864       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9865     }
9866   operands[1] = tmp;
9867 })
9868
9869 ;; Conditionalize these after reload. If they match before reload, we 
9870 ;; lose the clobber and ability to use integer instructions.
9871
9872 (define_insn "*negsf2_1"
9873   [(set (match_operand:SF 0 "register_operand" "=f")
9874         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9875   "TARGET_80387 && reload_completed"
9876   "fchs"
9877   [(set_attr "type" "fsgn")
9878    (set_attr "mode" "SF")])
9879
9880 (define_insn "*negdf2_1"
9881   [(set (match_operand:DF 0 "register_operand" "=f")
9882         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9883   "TARGET_80387 && reload_completed"
9884   "fchs"
9885   [(set_attr "type" "fsgn")
9886    (set_attr "mode" "DF")])
9887
9888 (define_insn "*negxf2_1"
9889   [(set (match_operand:XF 0 "register_operand" "=f")
9890         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9891   "TARGET_80387 && reload_completed"
9892   "fchs"
9893   [(set_attr "type" "fsgn")
9894    (set_attr "mode" "XF")])
9895
9896 (define_insn "*abssf2_1"
9897   [(set (match_operand:SF 0 "register_operand" "=f")
9898         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9899   "TARGET_80387 && reload_completed"
9900   "fabs"
9901   [(set_attr "type" "fsgn")
9902    (set_attr "mode" "SF")])
9903
9904 (define_insn "*absdf2_1"
9905   [(set (match_operand:DF 0 "register_operand" "=f")
9906         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9907   "TARGET_80387 && reload_completed"
9908   "fabs"
9909   [(set_attr "type" "fsgn")
9910    (set_attr "mode" "DF")])
9911
9912 (define_insn "*absxf2_1"
9913   [(set (match_operand:XF 0 "register_operand" "=f")
9914         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9915   "TARGET_80387 && reload_completed"
9916   "fabs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "DF")])
9919
9920 (define_insn "*negextendsfdf2"
9921   [(set (match_operand:DF 0 "register_operand" "=f")
9922         (neg:DF (float_extend:DF
9923                   (match_operand:SF 1 "register_operand" "0"))))]
9924   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9925   "fchs"
9926   [(set_attr "type" "fsgn")
9927    (set_attr "mode" "DF")])
9928
9929 (define_insn "*negextenddfxf2"
9930   [(set (match_operand:XF 0 "register_operand" "=f")
9931         (neg:XF (float_extend:XF
9932                   (match_operand:DF 1 "register_operand" "0"))))]
9933   "TARGET_80387"
9934   "fchs"
9935   [(set_attr "type" "fsgn")
9936    (set_attr "mode" "XF")])
9937
9938 (define_insn "*negextendsfxf2"
9939   [(set (match_operand:XF 0 "register_operand" "=f")
9940         (neg:XF (float_extend:XF
9941                   (match_operand:SF 1 "register_operand" "0"))))]
9942   "TARGET_80387"
9943   "fchs"
9944   [(set_attr "type" "fsgn")
9945    (set_attr "mode" "XF")])
9946
9947 (define_insn "*absextendsfdf2"
9948   [(set (match_operand:DF 0 "register_operand" "=f")
9949         (abs:DF (float_extend:DF
9950                   (match_operand:SF 1 "register_operand" "0"))))]
9951   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9952   "fabs"
9953   [(set_attr "type" "fsgn")
9954    (set_attr "mode" "DF")])
9955
9956 (define_insn "*absextenddfxf2"
9957   [(set (match_operand:XF 0 "register_operand" "=f")
9958         (abs:XF (float_extend:XF
9959           (match_operand:DF 1 "register_operand" "0"))))]
9960   "TARGET_80387"
9961   "fabs"
9962   [(set_attr "type" "fsgn")
9963    (set_attr "mode" "XF")])
9964
9965 (define_insn "*absextendsfxf2"
9966   [(set (match_operand:XF 0 "register_operand" "=f")
9967         (abs:XF (float_extend:XF
9968           (match_operand:SF 1 "register_operand" "0"))))]
9969   "TARGET_80387"
9970   "fabs"
9971   [(set_attr "type" "fsgn")
9972    (set_attr "mode" "XF")])
9973 \f
9974 ;; One complement instructions
9975
9976 (define_expand "one_cmpldi2"
9977   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9978         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9979   "TARGET_64BIT"
9980   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9981
9982 (define_insn "*one_cmpldi2_1_rex64"
9983   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9984         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9985   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9986   "not{q}\t%0"
9987   [(set_attr "type" "negnot")
9988    (set_attr "mode" "DI")])
9989
9990 (define_insn "*one_cmpldi2_2_rex64"
9991   [(set (reg FLAGS_REG)
9992         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9993                  (const_int 0)))
9994    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9995         (not:DI (match_dup 1)))]
9996   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9997    && ix86_unary_operator_ok (NOT, DImode, operands)"
9998   "#"
9999   [(set_attr "type" "alu1")
10000    (set_attr "mode" "DI")])
10001
10002 (define_split
10003   [(set (match_operand 0 "flags_reg_operand" "")
10004         (match_operator 2 "compare_operator"
10005           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10006            (const_int 0)]))
10007    (set (match_operand:DI 1 "nonimmediate_operand" "")
10008         (not:DI (match_dup 3)))]
10009   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10010   [(parallel [(set (match_dup 0)
10011                    (match_op_dup 2
10012                      [(xor:DI (match_dup 3) (const_int -1))
10013                       (const_int 0)]))
10014               (set (match_dup 1)
10015                    (xor:DI (match_dup 3) (const_int -1)))])]
10016   "")
10017
10018 (define_expand "one_cmplsi2"
10019   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10020         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10021   ""
10022   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10023
10024 (define_insn "*one_cmplsi2_1"
10025   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10026         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10027   "ix86_unary_operator_ok (NOT, SImode, operands)"
10028   "not{l}\t%0"
10029   [(set_attr "type" "negnot")
10030    (set_attr "mode" "SI")])
10031
10032 ;; ??? Currently never generated - xor is used instead.
10033 (define_insn "*one_cmplsi2_1_zext"
10034   [(set (match_operand:DI 0 "register_operand" "=r")
10035         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10036   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10037   "not{l}\t%k0"
10038   [(set_attr "type" "negnot")
10039    (set_attr "mode" "SI")])
10040
10041 (define_insn "*one_cmplsi2_2"
10042   [(set (reg FLAGS_REG)
10043         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10044                  (const_int 0)))
10045    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10046         (not:SI (match_dup 1)))]
10047   "ix86_match_ccmode (insn, CCNOmode)
10048    && ix86_unary_operator_ok (NOT, SImode, operands)"
10049   "#"
10050   [(set_attr "type" "alu1")
10051    (set_attr "mode" "SI")])
10052
10053 (define_split
10054   [(set (match_operand 0 "flags_reg_operand" "")
10055         (match_operator 2 "compare_operator"
10056           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10057            (const_int 0)]))
10058    (set (match_operand:SI 1 "nonimmediate_operand" "")
10059         (not:SI (match_dup 3)))]
10060   "ix86_match_ccmode (insn, CCNOmode)"
10061   [(parallel [(set (match_dup 0)
10062                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10063                                     (const_int 0)]))
10064               (set (match_dup 1)
10065                    (xor:SI (match_dup 3) (const_int -1)))])]
10066   "")
10067
10068 ;; ??? Currently never generated - xor is used instead.
10069 (define_insn "*one_cmplsi2_2_zext"
10070   [(set (reg FLAGS_REG)
10071         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10072                  (const_int 0)))
10073    (set (match_operand:DI 0 "register_operand" "=r")
10074         (zero_extend:DI (not:SI (match_dup 1))))]
10075   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10076    && ix86_unary_operator_ok (NOT, SImode, operands)"
10077   "#"
10078   [(set_attr "type" "alu1")
10079    (set_attr "mode" "SI")])
10080
10081 (define_split
10082   [(set (match_operand 0 "flags_reg_operand" "")
10083         (match_operator 2 "compare_operator"
10084           [(not:SI (match_operand:SI 3 "register_operand" ""))
10085            (const_int 0)]))
10086    (set (match_operand:DI 1 "register_operand" "")
10087         (zero_extend:DI (not:SI (match_dup 3))))]
10088   "ix86_match_ccmode (insn, CCNOmode)"
10089   [(parallel [(set (match_dup 0)
10090                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10091                                     (const_int 0)]))
10092               (set (match_dup 1)
10093                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10094   "")
10095
10096 (define_expand "one_cmplhi2"
10097   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10098         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10099   "TARGET_HIMODE_MATH"
10100   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10101
10102 (define_insn "*one_cmplhi2_1"
10103   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10104         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10105   "ix86_unary_operator_ok (NOT, HImode, operands)"
10106   "not{w}\t%0"
10107   [(set_attr "type" "negnot")
10108    (set_attr "mode" "HI")])
10109
10110 (define_insn "*one_cmplhi2_2"
10111   [(set (reg FLAGS_REG)
10112         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10113                  (const_int 0)))
10114    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10115         (not:HI (match_dup 1)))]
10116   "ix86_match_ccmode (insn, CCNOmode)
10117    && ix86_unary_operator_ok (NEG, HImode, operands)"
10118   "#"
10119   [(set_attr "type" "alu1")
10120    (set_attr "mode" "HI")])
10121
10122 (define_split
10123   [(set (match_operand 0 "flags_reg_operand" "")
10124         (match_operator 2 "compare_operator"
10125           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10126            (const_int 0)]))
10127    (set (match_operand:HI 1 "nonimmediate_operand" "")
10128         (not:HI (match_dup 3)))]
10129   "ix86_match_ccmode (insn, CCNOmode)"
10130   [(parallel [(set (match_dup 0)
10131                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10132                                     (const_int 0)]))
10133               (set (match_dup 1)
10134                    (xor:HI (match_dup 3) (const_int -1)))])]
10135   "")
10136
10137 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10138 (define_expand "one_cmplqi2"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10141   "TARGET_QIMODE_MATH"
10142   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10143
10144 (define_insn "*one_cmplqi2_1"
10145   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10146         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10147   "ix86_unary_operator_ok (NOT, QImode, operands)"
10148   "@
10149    not{b}\t%0
10150    not{l}\t%k0"
10151   [(set_attr "type" "negnot")
10152    (set_attr "mode" "QI,SI")])
10153
10154 (define_insn "*one_cmplqi2_2"
10155   [(set (reg FLAGS_REG)
10156         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10157                  (const_int 0)))
10158    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10159         (not:QI (match_dup 1)))]
10160   "ix86_match_ccmode (insn, CCNOmode)
10161    && ix86_unary_operator_ok (NOT, QImode, operands)"
10162   "#"
10163   [(set_attr "type" "alu1")
10164    (set_attr "mode" "QI")])
10165
10166 (define_split
10167   [(set (match_operand 0 "flags_reg_operand" "")
10168         (match_operator 2 "compare_operator"
10169           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10170            (const_int 0)]))
10171    (set (match_operand:QI 1 "nonimmediate_operand" "")
10172         (not:QI (match_dup 3)))]
10173   "ix86_match_ccmode (insn, CCNOmode)"
10174   [(parallel [(set (match_dup 0)
10175                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10176                                     (const_int 0)]))
10177               (set (match_dup 1)
10178                    (xor:QI (match_dup 3) (const_int -1)))])]
10179   "")
10180 \f
10181 ;; Arithmetic shift instructions
10182
10183 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10184 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10185 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10186 ;; from the assembler input.
10187 ;;
10188 ;; This instruction shifts the target reg/mem as usual, but instead of
10189 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10190 ;; is a left shift double, bits are taken from the high order bits of
10191 ;; reg, else if the insn is a shift right double, bits are taken from the
10192 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10193 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10194 ;;
10195 ;; Since sh[lr]d does not change the `reg' operand, that is done
10196 ;; separately, making all shifts emit pairs of shift double and normal
10197 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10198 ;; support a 63 bit shift, each shift where the count is in a reg expands
10199 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10200 ;;
10201 ;; If the shift count is a constant, we need never emit more than one
10202 ;; shift pair, instead using moves and sign extension for counts greater
10203 ;; than 31.
10204
10205 (define_expand "ashlti3"
10206   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10207                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10208                               (match_operand:QI 2 "nonmemory_operand" "")))
10209               (clobber (reg:CC FLAGS_REG))])]
10210   "TARGET_64BIT"
10211 {
10212   if (! immediate_operand (operands[2], QImode))
10213     {
10214       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10215       DONE;
10216     }
10217   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10218   DONE;
10219 })
10220
10221 (define_insn "ashlti3_1"
10222   [(set (match_operand:TI 0 "register_operand" "=r")
10223         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10224                    (match_operand:QI 2 "register_operand" "c")))
10225    (clobber (match_scratch:DI 3 "=&r"))
10226    (clobber (reg:CC FLAGS_REG))]
10227   "TARGET_64BIT"
10228   "#"
10229   [(set_attr "type" "multi")])
10230
10231 (define_insn "*ashlti3_2"
10232   [(set (match_operand:TI 0 "register_operand" "=r")
10233         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10234                    (match_operand:QI 2 "immediate_operand" "O")))
10235    (clobber (reg:CC FLAGS_REG))]
10236   "TARGET_64BIT"
10237   "#"
10238   [(set_attr "type" "multi")])
10239
10240 (define_split
10241   [(set (match_operand:TI 0 "register_operand" "")
10242         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10243                    (match_operand:QI 2 "register_operand" "")))
10244    (clobber (match_scratch:DI 3 ""))
10245    (clobber (reg:CC FLAGS_REG))]
10246   "TARGET_64BIT && reload_completed"
10247   [(const_int 0)]
10248   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10249
10250 (define_split
10251   [(set (match_operand:TI 0 "register_operand" "")
10252         (ashift:TI (match_operand:TI 1 "register_operand" "")
10253                    (match_operand:QI 2 "immediate_operand" "")))
10254    (clobber (reg:CC FLAGS_REG))]
10255   "TARGET_64BIT && reload_completed"
10256   [(const_int 0)]
10257   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10258
10259 (define_insn "x86_64_shld"
10260   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10261         (ior:DI (ashift:DI (match_dup 0)
10262                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10263                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10264                   (minus:QI (const_int 64) (match_dup 2)))))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "TARGET_64BIT"
10267   "@
10268    shld{q}\t{%2, %1, %0|%0, %1, %2}
10269    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10270   [(set_attr "type" "ishift")
10271    (set_attr "prefix_0f" "1")
10272    (set_attr "mode" "DI")
10273    (set_attr "athlon_decode" "vector")])
10274
10275 (define_expand "x86_64_shift_adj"
10276   [(set (reg:CCZ FLAGS_REG)
10277         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10278                              (const_int 64))
10279                      (const_int 0)))
10280    (set (match_operand:DI 0 "register_operand" "")
10281         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10282                          (match_operand:DI 1 "register_operand" "")
10283                          (match_dup 0)))
10284    (set (match_dup 1)
10285         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286                          (match_operand:DI 3 "register_operand" "r")
10287                          (match_dup 1)))]
10288   "TARGET_64BIT"
10289   "")
10290
10291 (define_expand "ashldi3"
10292   [(set (match_operand:DI 0 "shiftdi_operand" "")
10293         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10294                    (match_operand:QI 2 "nonmemory_operand" "")))]
10295   ""
10296   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10297
10298 (define_insn "*ashldi3_1_rex64"
10299   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10300         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10301                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10304 {
10305   switch (get_attr_type (insn))
10306     {
10307     case TYPE_ALU:
10308       gcc_assert (operands[2] == const1_rtx);
10309       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10310       return "add{q}\t{%0, %0|%0, %0}";
10311
10312     case TYPE_LEA:
10313       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10314       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10315       operands[1] = gen_rtx_MULT (DImode, operands[1],
10316                                   GEN_INT (1 << INTVAL (operands[2])));
10317       return "lea{q}\t{%a1, %0|%0, %a1}";
10318
10319     default:
10320       if (REG_P (operands[2]))
10321         return "sal{q}\t{%b2, %0|%0, %b2}";
10322       else if (operands[2] == const1_rtx
10323                && (TARGET_SHIFT1 || optimize_size))
10324         return "sal{q}\t%0";
10325       else
10326         return "sal{q}\t{%2, %0|%0, %2}";
10327     }
10328 }
10329   [(set (attr "type")
10330      (cond [(eq_attr "alternative" "1")
10331               (const_string "lea")
10332             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10333                           (const_int 0))
10334                       (match_operand 0 "register_operand" ""))
10335                  (match_operand 2 "const1_operand" ""))
10336               (const_string "alu")
10337            ]
10338            (const_string "ishift")))
10339    (set_attr "mode" "DI")])
10340
10341 ;; Convert lea to the lea pattern to avoid flags dependency.
10342 (define_split
10343   [(set (match_operand:DI 0 "register_operand" "")
10344         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10345                    (match_operand:QI 2 "immediate_operand" "")))
10346    (clobber (reg:CC FLAGS_REG))]
10347   "TARGET_64BIT && reload_completed
10348    && true_regnum (operands[0]) != true_regnum (operands[1])"
10349   [(set (match_dup 0)
10350         (mult:DI (match_dup 1)
10351                  (match_dup 2)))]
10352   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10353
10354 ;; This pattern can't accept a variable shift count, since shifts by
10355 ;; zero don't affect the flags.  We assume that shifts by constant
10356 ;; zero are optimized away.
10357 (define_insn "*ashldi3_cmp_rex64"
10358   [(set (reg FLAGS_REG)
10359         (compare
10360           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10361                      (match_operand:QI 2 "immediate_operand" "e"))
10362           (const_int 0)))
10363    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10364         (ashift:DI (match_dup 1) (match_dup 2)))]
10365   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10366    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10367 {
10368   switch (get_attr_type (insn))
10369     {
10370     case TYPE_ALU:
10371       gcc_assert (operands[2] == const1_rtx);
10372       return "add{q}\t{%0, %0|%0, %0}";
10373
10374     default:
10375       if (REG_P (operands[2]))
10376         return "sal{q}\t{%b2, %0|%0, %b2}";
10377       else if (operands[2] == const1_rtx
10378                && (TARGET_SHIFT1 || optimize_size))
10379         return "sal{q}\t%0";
10380       else
10381         return "sal{q}\t{%2, %0|%0, %2}";
10382     }
10383 }
10384   [(set (attr "type")
10385      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10386                           (const_int 0))
10387                       (match_operand 0 "register_operand" ""))
10388                  (match_operand 2 "const1_operand" ""))
10389               (const_string "alu")
10390            ]
10391            (const_string "ishift")))
10392    (set_attr "mode" "DI")])
10393
10394 (define_insn "*ashldi3_1"
10395   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10396         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10397                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "!TARGET_64BIT"
10400   "#"
10401   [(set_attr "type" "multi")])
10402
10403 ;; By default we don't ask for a scratch register, because when DImode
10404 ;; values are manipulated, registers are already at a premium.  But if
10405 ;; we have one handy, we won't turn it away.
10406 (define_peephole2
10407   [(match_scratch:SI 3 "r")
10408    (parallel [(set (match_operand:DI 0 "register_operand" "")
10409                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10410                               (match_operand:QI 2 "nonmemory_operand" "")))
10411               (clobber (reg:CC FLAGS_REG))])
10412    (match_dup 3)]
10413   "!TARGET_64BIT && TARGET_CMOVE"
10414   [(const_int 0)]
10415   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10416
10417 (define_split
10418   [(set (match_operand:DI 0 "register_operand" "")
10419         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10420                    (match_operand:QI 2 "nonmemory_operand" "")))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10423                      ? flow2_completed : reload_completed)"
10424   [(const_int 0)]
10425   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10426
10427 (define_insn "x86_shld_1"
10428   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10429         (ior:SI (ashift:SI (match_dup 0)
10430                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10431                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10432                   (minus:QI (const_int 32) (match_dup 2)))))
10433    (clobber (reg:CC FLAGS_REG))]
10434   ""
10435   "@
10436    shld{l}\t{%2, %1, %0|%0, %1, %2}
10437    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10438   [(set_attr "type" "ishift")
10439    (set_attr "prefix_0f" "1")
10440    (set_attr "mode" "SI")
10441    (set_attr "pent_pair" "np")
10442    (set_attr "athlon_decode" "vector")])
10443
10444 (define_expand "x86_shift_adj_1"
10445   [(set (reg:CCZ FLAGS_REG)
10446         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10447                              (const_int 32))
10448                      (const_int 0)))
10449    (set (match_operand:SI 0 "register_operand" "")
10450         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10451                          (match_operand:SI 1 "register_operand" "")
10452                          (match_dup 0)))
10453    (set (match_dup 1)
10454         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10455                          (match_operand:SI 3 "register_operand" "r")
10456                          (match_dup 1)))]
10457   "TARGET_CMOVE"
10458   "")
10459
10460 (define_expand "x86_shift_adj_2"
10461   [(use (match_operand:SI 0 "register_operand" ""))
10462    (use (match_operand:SI 1 "register_operand" ""))
10463    (use (match_operand:QI 2 "register_operand" ""))]
10464   ""
10465 {
10466   rtx label = gen_label_rtx ();
10467   rtx tmp;
10468
10469   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10470
10471   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10472   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10473   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10474                               gen_rtx_LABEL_REF (VOIDmode, label),
10475                               pc_rtx);
10476   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10477   JUMP_LABEL (tmp) = label;
10478
10479   emit_move_insn (operands[0], operands[1]);
10480   ix86_expand_clear (operands[1]);
10481
10482   emit_label (label);
10483   LABEL_NUSES (label) = 1;
10484
10485   DONE;
10486 })
10487
10488 (define_expand "ashlsi3"
10489   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10490         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10491                    (match_operand:QI 2 "nonmemory_operand" "")))
10492    (clobber (reg:CC FLAGS_REG))]
10493   ""
10494   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10495
10496 (define_insn "*ashlsi3_1"
10497   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10498         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10499                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10502 {
10503   switch (get_attr_type (insn))
10504     {
10505     case TYPE_ALU:
10506       gcc_assert (operands[2] == const1_rtx);
10507       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10508       return "add{l}\t{%0, %0|%0, %0}";
10509
10510     case TYPE_LEA:
10511       return "#";
10512
10513     default:
10514       if (REG_P (operands[2]))
10515         return "sal{l}\t{%b2, %0|%0, %b2}";
10516       else if (operands[2] == const1_rtx
10517                && (TARGET_SHIFT1 || optimize_size))
10518         return "sal{l}\t%0";
10519       else
10520         return "sal{l}\t{%2, %0|%0, %2}";
10521     }
10522 }
10523   [(set (attr "type")
10524      (cond [(eq_attr "alternative" "1")
10525               (const_string "lea")
10526             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10527                           (const_int 0))
10528                       (match_operand 0 "register_operand" ""))
10529                  (match_operand 2 "const1_operand" ""))
10530               (const_string "alu")
10531            ]
10532            (const_string "ishift")))
10533    (set_attr "mode" "SI")])
10534
10535 ;; Convert lea to the lea pattern to avoid flags dependency.
10536 (define_split
10537   [(set (match_operand 0 "register_operand" "")
10538         (ashift (match_operand 1 "index_register_operand" "")
10539                 (match_operand:QI 2 "const_int_operand" "")))
10540    (clobber (reg:CC FLAGS_REG))]
10541   "reload_completed
10542    && true_regnum (operands[0]) != true_regnum (operands[1])
10543    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10544   [(const_int 0)]
10545 {
10546   rtx pat;
10547   enum machine_mode mode = GET_MODE (operands[0]);
10548
10549   if (GET_MODE_SIZE (mode) < 4)
10550     operands[0] = gen_lowpart (SImode, operands[0]);
10551   if (mode != Pmode)
10552     operands[1] = gen_lowpart (Pmode, operands[1]);
10553   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10554
10555   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10556   if (Pmode != SImode)
10557     pat = gen_rtx_SUBREG (SImode, pat, 0);
10558   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10559   DONE;
10560 })
10561
10562 ;; Rare case of shifting RSP is handled by generating move and shift
10563 (define_split
10564   [(set (match_operand 0 "register_operand" "")
10565         (ashift (match_operand 1 "register_operand" "")
10566                 (match_operand:QI 2 "const_int_operand" "")))
10567    (clobber (reg:CC FLAGS_REG))]
10568   "reload_completed
10569    && true_regnum (operands[0]) != true_regnum (operands[1])"
10570   [(const_int 0)]
10571 {
10572   rtx pat, clob;
10573   emit_move_insn (operands[0], operands[1]);
10574   pat = gen_rtx_SET (VOIDmode, operands[0],
10575                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10576                                      operands[0], operands[2]));
10577   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10578   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10579   DONE;
10580 })
10581
10582 (define_insn "*ashlsi3_1_zext"
10583   [(set (match_operand:DI 0 "register_operand" "=r,r")
10584         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10585                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10588 {
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       gcc_assert (operands[2] == const1_rtx);
10593       return "add{l}\t{%k0, %k0|%k0, %k0}";
10594
10595     case TYPE_LEA:
10596       return "#";
10597
10598     default:
10599       if (REG_P (operands[2]))
10600         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10601       else if (operands[2] == const1_rtx
10602                && (TARGET_SHIFT1 || optimize_size))
10603         return "sal{l}\t%k0";
10604       else
10605         return "sal{l}\t{%2, %k0|%k0, %2}";
10606     }
10607 }
10608   [(set (attr "type")
10609      (cond [(eq_attr "alternative" "1")
10610               (const_string "lea")
10611             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10612                      (const_int 0))
10613                  (match_operand 2 "const1_operand" ""))
10614               (const_string "alu")
10615            ]
10616            (const_string "ishift")))
10617    (set_attr "mode" "SI")])
10618
10619 ;; Convert lea to the lea pattern to avoid flags dependency.
10620 (define_split
10621   [(set (match_operand:DI 0 "register_operand" "")
10622         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10623                                 (match_operand:QI 2 "const_int_operand" ""))))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "TARGET_64BIT && reload_completed
10626    && true_regnum (operands[0]) != true_regnum (operands[1])"
10627   [(set (match_dup 0) (zero_extend:DI
10628                         (subreg:SI (mult:SI (match_dup 1)
10629                                             (match_dup 2)) 0)))]
10630 {
10631   operands[1] = gen_lowpart (Pmode, operands[1]);
10632   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10633 })
10634
10635 ;; This pattern can't accept a variable shift count, since shifts by
10636 ;; zero don't affect the flags.  We assume that shifts by constant
10637 ;; zero are optimized away.
10638 (define_insn "*ashlsi3_cmp"
10639   [(set (reg FLAGS_REG)
10640         (compare
10641           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10642                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10643           (const_int 0)))
10644    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10645         (ashift:SI (match_dup 1) (match_dup 2)))]
10646   "ix86_match_ccmode (insn, CCGOCmode)
10647    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10648 {
10649   switch (get_attr_type (insn))
10650     {
10651     case TYPE_ALU:
10652       gcc_assert (operands[2] == const1_rtx);
10653       return "add{l}\t{%0, %0|%0, %0}";
10654
10655     default:
10656       if (REG_P (operands[2]))
10657         return "sal{l}\t{%b2, %0|%0, %b2}";
10658       else if (operands[2] == const1_rtx
10659                && (TARGET_SHIFT1 || optimize_size))
10660         return "sal{l}\t%0";
10661       else
10662         return "sal{l}\t{%2, %0|%0, %2}";
10663     }
10664 }
10665   [(set (attr "type")
10666      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10667                           (const_int 0))
10668                       (match_operand 0 "register_operand" ""))
10669                  (match_operand 2 "const1_operand" ""))
10670               (const_string "alu")
10671            ]
10672            (const_string "ishift")))
10673    (set_attr "mode" "SI")])
10674
10675 (define_insn "*ashlsi3_cmp_zext"
10676   [(set (reg FLAGS_REG)
10677         (compare
10678           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10679                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10680           (const_int 0)))
10681    (set (match_operand:DI 0 "register_operand" "=r")
10682         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10683   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10684    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10685 {
10686   switch (get_attr_type (insn))
10687     {
10688     case TYPE_ALU:
10689       gcc_assert (operands[2] == const1_rtx);
10690       return "add{l}\t{%k0, %k0|%k0, %k0}";
10691
10692     default:
10693       if (REG_P (operands[2]))
10694         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695       else if (operands[2] == const1_rtx
10696                && (TARGET_SHIFT1 || optimize_size))
10697         return "sal{l}\t%k0";
10698       else
10699         return "sal{l}\t{%2, %k0|%k0, %2}";
10700     }
10701 }
10702   [(set (attr "type")
10703      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10704                      (const_int 0))
10705                  (match_operand 2 "const1_operand" ""))
10706               (const_string "alu")
10707            ]
10708            (const_string "ishift")))
10709    (set_attr "mode" "SI")])
10710
10711 (define_expand "ashlhi3"
10712   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10713         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10714                    (match_operand:QI 2 "nonmemory_operand" "")))
10715    (clobber (reg:CC FLAGS_REG))]
10716   "TARGET_HIMODE_MATH"
10717   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10718
10719 (define_insn "*ashlhi3_1_lea"
10720   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10721         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10722                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "!TARGET_PARTIAL_REG_STALL
10725    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10726 {
10727   switch (get_attr_type (insn))
10728     {
10729     case TYPE_LEA:
10730       return "#";
10731     case TYPE_ALU:
10732       gcc_assert (operands[2] == const1_rtx);
10733       return "add{w}\t{%0, %0|%0, %0}";
10734
10735     default:
10736       if (REG_P (operands[2]))
10737         return "sal{w}\t{%b2, %0|%0, %b2}";
10738       else if (operands[2] == const1_rtx
10739                && (TARGET_SHIFT1 || optimize_size))
10740         return "sal{w}\t%0";
10741       else
10742         return "sal{w}\t{%2, %0|%0, %2}";
10743     }
10744 }
10745   [(set (attr "type")
10746      (cond [(eq_attr "alternative" "1")
10747               (const_string "lea")
10748             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10749                           (const_int 0))
10750                       (match_operand 0 "register_operand" ""))
10751                  (match_operand 2 "const1_operand" ""))
10752               (const_string "alu")
10753            ]
10754            (const_string "ishift")))
10755    (set_attr "mode" "HI,SI")])
10756
10757 (define_insn "*ashlhi3_1"
10758   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10759         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10760                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10761    (clobber (reg:CC FLAGS_REG))]
10762   "TARGET_PARTIAL_REG_STALL
10763    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10764 {
10765   switch (get_attr_type (insn))
10766     {
10767     case TYPE_ALU:
10768       gcc_assert (operands[2] == const1_rtx);
10769       return "add{w}\t{%0, %0|%0, %0}";
10770
10771     default:
10772       if (REG_P (operands[2]))
10773         return "sal{w}\t{%b2, %0|%0, %b2}";
10774       else if (operands[2] == const1_rtx
10775                && (TARGET_SHIFT1 || optimize_size))
10776         return "sal{w}\t%0";
10777       else
10778         return "sal{w}\t{%2, %0|%0, %2}";
10779     }
10780 }
10781   [(set (attr "type")
10782      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10783                           (const_int 0))
10784                       (match_operand 0 "register_operand" ""))
10785                  (match_operand 2 "const1_operand" ""))
10786               (const_string "alu")
10787            ]
10788            (const_string "ishift")))
10789    (set_attr "mode" "HI")])
10790
10791 ;; This pattern can't accept a variable shift count, since shifts by
10792 ;; zero don't affect the flags.  We assume that shifts by constant
10793 ;; zero are optimized away.
10794 (define_insn "*ashlhi3_cmp"
10795   [(set (reg FLAGS_REG)
10796         (compare
10797           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10798                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10799           (const_int 0)))
10800    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10801         (ashift:HI (match_dup 1) (match_dup 2)))]
10802   "ix86_match_ccmode (insn, CCGOCmode)
10803    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10804 {
10805   switch (get_attr_type (insn))
10806     {
10807     case TYPE_ALU:
10808       gcc_assert (operands[2] == const1_rtx);
10809       return "add{w}\t{%0, %0|%0, %0}";
10810
10811     default:
10812       if (REG_P (operands[2]))
10813         return "sal{w}\t{%b2, %0|%0, %b2}";
10814       else if (operands[2] == const1_rtx
10815                && (TARGET_SHIFT1 || optimize_size))
10816         return "sal{w}\t%0";
10817       else
10818         return "sal{w}\t{%2, %0|%0, %2}";
10819     }
10820 }
10821   [(set (attr "type")
10822      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10823                           (const_int 0))
10824                       (match_operand 0 "register_operand" ""))
10825                  (match_operand 2 "const1_operand" ""))
10826               (const_string "alu")
10827            ]
10828            (const_string "ishift")))
10829    (set_attr "mode" "HI")])
10830
10831 (define_expand "ashlqi3"
10832   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10833         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10834                    (match_operand:QI 2 "nonmemory_operand" "")))
10835    (clobber (reg:CC FLAGS_REG))]
10836   "TARGET_QIMODE_MATH"
10837   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10838
10839 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10840
10841 (define_insn "*ashlqi3_1_lea"
10842   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10843         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10844                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "!TARGET_PARTIAL_REG_STALL
10847    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10848 {
10849   switch (get_attr_type (insn))
10850     {
10851     case TYPE_LEA:
10852       return "#";
10853     case TYPE_ALU:
10854       gcc_assert (operands[2] == const1_rtx);
10855       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10856         return "add{l}\t{%k0, %k0|%k0, %k0}";
10857       else
10858         return "add{b}\t{%0, %0|%0, %0}";
10859
10860     default:
10861       if (REG_P (operands[2]))
10862         {
10863           if (get_attr_mode (insn) == MODE_SI)
10864             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10865           else
10866             return "sal{b}\t{%b2, %0|%0, %b2}";
10867         }
10868       else if (operands[2] == const1_rtx
10869                && (TARGET_SHIFT1 || optimize_size))
10870         {
10871           if (get_attr_mode (insn) == MODE_SI)
10872             return "sal{l}\t%0";
10873           else
10874             return "sal{b}\t%0";
10875         }
10876       else
10877         {
10878           if (get_attr_mode (insn) == MODE_SI)
10879             return "sal{l}\t{%2, %k0|%k0, %2}";
10880           else
10881             return "sal{b}\t{%2, %0|%0, %2}";
10882         }
10883     }
10884 }
10885   [(set (attr "type")
10886      (cond [(eq_attr "alternative" "2")
10887               (const_string "lea")
10888             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889                           (const_int 0))
10890                       (match_operand 0 "register_operand" ""))
10891                  (match_operand 2 "const1_operand" ""))
10892               (const_string "alu")
10893            ]
10894            (const_string "ishift")))
10895    (set_attr "mode" "QI,SI,SI")])
10896
10897 (define_insn "*ashlqi3_1"
10898   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10899         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10900                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10901    (clobber (reg:CC FLAGS_REG))]
10902   "TARGET_PARTIAL_REG_STALL
10903    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10904 {
10905   switch (get_attr_type (insn))
10906     {
10907     case TYPE_ALU:
10908       gcc_assert (operands[2] == const1_rtx);
10909       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10910         return "add{l}\t{%k0, %k0|%k0, %k0}";
10911       else
10912         return "add{b}\t{%0, %0|%0, %0}";
10913
10914     default:
10915       if (REG_P (operands[2]))
10916         {
10917           if (get_attr_mode (insn) == MODE_SI)
10918             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10919           else
10920             return "sal{b}\t{%b2, %0|%0, %b2}";
10921         }
10922       else if (operands[2] == const1_rtx
10923                && (TARGET_SHIFT1 || optimize_size))
10924         {
10925           if (get_attr_mode (insn) == MODE_SI)
10926             return "sal{l}\t%0";
10927           else
10928             return "sal{b}\t%0";
10929         }
10930       else
10931         {
10932           if (get_attr_mode (insn) == MODE_SI)
10933             return "sal{l}\t{%2, %k0|%k0, %2}";
10934           else
10935             return "sal{b}\t{%2, %0|%0, %2}";
10936         }
10937     }
10938 }
10939   [(set (attr "type")
10940      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10941                           (const_int 0))
10942                       (match_operand 0 "register_operand" ""))
10943                  (match_operand 2 "const1_operand" ""))
10944               (const_string "alu")
10945            ]
10946            (const_string "ishift")))
10947    (set_attr "mode" "QI,SI")])
10948
10949 ;; This pattern can't accept a variable shift count, since shifts by
10950 ;; zero don't affect the flags.  We assume that shifts by constant
10951 ;; zero are optimized away.
10952 (define_insn "*ashlqi3_cmp"
10953   [(set (reg FLAGS_REG)
10954         (compare
10955           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10956                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10957           (const_int 0)))
10958    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10959         (ashift:QI (match_dup 1) (match_dup 2)))]
10960   "ix86_match_ccmode (insn, CCGOCmode)
10961    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10962 {
10963   switch (get_attr_type (insn))
10964     {
10965     case TYPE_ALU:
10966       gcc_assert (operands[2] == const1_rtx);
10967       return "add{b}\t{%0, %0|%0, %0}";
10968
10969     default:
10970       if (REG_P (operands[2]))
10971         return "sal{b}\t{%b2, %0|%0, %b2}";
10972       else if (operands[2] == const1_rtx
10973                && (TARGET_SHIFT1 || optimize_size))
10974         return "sal{b}\t%0";
10975       else
10976         return "sal{b}\t{%2, %0|%0, %2}";
10977     }
10978 }
10979   [(set (attr "type")
10980      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10981                           (const_int 0))
10982                       (match_operand 0 "register_operand" ""))
10983                  (match_operand 2 "const1_operand" ""))
10984               (const_string "alu")
10985            ]
10986            (const_string "ishift")))
10987    (set_attr "mode" "QI")])
10988
10989 ;; See comment above `ashldi3' about how this works.
10990
10991 (define_expand "ashrti3"
10992   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10993                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10994                                 (match_operand:QI 2 "nonmemory_operand" "")))
10995               (clobber (reg:CC FLAGS_REG))])]
10996   "TARGET_64BIT"
10997 {
10998   if (! immediate_operand (operands[2], QImode))
10999     {
11000       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11001       DONE;
11002     }
11003   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11004   DONE;
11005 })
11006
11007 (define_insn "ashrti3_1"
11008   [(set (match_operand:TI 0 "register_operand" "=r")
11009         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11010                      (match_operand:QI 2 "register_operand" "c")))
11011    (clobber (match_scratch:DI 3 "=&r"))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "TARGET_64BIT"
11014   "#"
11015   [(set_attr "type" "multi")])
11016
11017 (define_insn "*ashrti3_2"
11018   [(set (match_operand:TI 0 "register_operand" "=r")
11019         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11020                      (match_operand:QI 2 "immediate_operand" "O")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "TARGET_64BIT"
11023   "#"
11024   [(set_attr "type" "multi")])
11025
11026 (define_split
11027   [(set (match_operand:TI 0 "register_operand" "")
11028         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11029                      (match_operand:QI 2 "register_operand" "")))
11030    (clobber (match_scratch:DI 3 ""))
11031    (clobber (reg:CC FLAGS_REG))]
11032   "TARGET_64BIT && reload_completed"
11033   [(const_int 0)]
11034   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11035
11036 (define_split
11037   [(set (match_operand:TI 0 "register_operand" "")
11038         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11039                      (match_operand:QI 2 "immediate_operand" "")))
11040    (clobber (reg:CC FLAGS_REG))]
11041   "TARGET_64BIT && reload_completed"
11042   [(const_int 0)]
11043   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11044
11045 (define_insn "x86_64_shrd"
11046   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11047         (ior:DI (ashiftrt:DI (match_dup 0)
11048                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11049                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11050                   (minus:QI (const_int 64) (match_dup 2)))))
11051    (clobber (reg:CC FLAGS_REG))]
11052   "TARGET_64BIT"
11053   "@
11054    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11055    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11056   [(set_attr "type" "ishift")
11057    (set_attr "prefix_0f" "1")
11058    (set_attr "mode" "DI")
11059    (set_attr "athlon_decode" "vector")])
11060
11061 (define_expand "ashrdi3"
11062   [(set (match_operand:DI 0 "shiftdi_operand" "")
11063         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11064                      (match_operand:QI 2 "nonmemory_operand" "")))]
11065   ""
11066   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11067
11068 (define_insn "*ashrdi3_63_rex64"
11069   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11070         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11071                      (match_operand:DI 2 "const_int_operand" "i,i")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   "TARGET_64BIT && INTVAL (operands[2]) == 63
11074    && (TARGET_USE_CLTD || optimize_size)
11075    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11076   "@
11077    {cqto|cqo}
11078    sar{q}\t{%2, %0|%0, %2}"
11079   [(set_attr "type" "imovx,ishift")
11080    (set_attr "prefix_0f" "0,*")
11081    (set_attr "length_immediate" "0,*")
11082    (set_attr "modrm" "0,1")
11083    (set_attr "mode" "DI")])
11084
11085 (define_insn "*ashrdi3_1_one_bit_rex64"
11086   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11087         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11088                      (match_operand:QI 2 "const1_operand" "")))
11089    (clobber (reg:CC FLAGS_REG))]
11090   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11091    && (TARGET_SHIFT1 || optimize_size)"
11092   "sar{q}\t%0"
11093   [(set_attr "type" "ishift")
11094    (set (attr "length") 
11095      (if_then_else (match_operand:DI 0 "register_operand" "") 
11096         (const_string "2")
11097         (const_string "*")))])
11098
11099 (define_insn "*ashrdi3_1_rex64"
11100   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11101         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11102                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11103    (clobber (reg:CC FLAGS_REG))]
11104   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11105   "@
11106    sar{q}\t{%2, %0|%0, %2}
11107    sar{q}\t{%b2, %0|%0, %b2}"
11108   [(set_attr "type" "ishift")
11109    (set_attr "mode" "DI")])
11110
11111 ;; This pattern can't accept a variable shift count, since shifts by
11112 ;; zero don't affect the flags.  We assume that shifts by constant
11113 ;; zero are optimized away.
11114 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11115   [(set (reg FLAGS_REG)
11116         (compare
11117           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11118                        (match_operand:QI 2 "const1_operand" ""))
11119           (const_int 0)))
11120    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11121         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11122   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11123    && (TARGET_SHIFT1 || optimize_size)
11124    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11125   "sar{q}\t%0"
11126   [(set_attr "type" "ishift")
11127    (set (attr "length") 
11128      (if_then_else (match_operand:DI 0 "register_operand" "") 
11129         (const_string "2")
11130         (const_string "*")))])
11131
11132 ;; This pattern can't accept a variable shift count, since shifts by
11133 ;; zero don't affect the flags.  We assume that shifts by constant
11134 ;; zero are optimized away.
11135 (define_insn "*ashrdi3_cmp_rex64"
11136   [(set (reg FLAGS_REG)
11137         (compare
11138           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11139                        (match_operand:QI 2 "const_int_operand" "n"))
11140           (const_int 0)))
11141    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11142         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11143   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11144    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11145   "sar{q}\t{%2, %0|%0, %2}"
11146   [(set_attr "type" "ishift")
11147    (set_attr "mode" "DI")])
11148
11149 (define_insn "*ashrdi3_1"
11150   [(set (match_operand:DI 0 "register_operand" "=r")
11151         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11152                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "!TARGET_64BIT"
11155   "#"
11156   [(set_attr "type" "multi")])
11157
11158 ;; By default we don't ask for a scratch register, because when DImode
11159 ;; values are manipulated, registers are already at a premium.  But if
11160 ;; we have one handy, we won't turn it away.
11161 (define_peephole2
11162   [(match_scratch:SI 3 "r")
11163    (parallel [(set (match_operand:DI 0 "register_operand" "")
11164                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11165                                 (match_operand:QI 2 "nonmemory_operand" "")))
11166               (clobber (reg:CC FLAGS_REG))])
11167    (match_dup 3)]
11168   "!TARGET_64BIT && TARGET_CMOVE"
11169   [(const_int 0)]
11170   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11171
11172 (define_split
11173   [(set (match_operand:DI 0 "register_operand" "")
11174         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11175                      (match_operand:QI 2 "nonmemory_operand" "")))
11176    (clobber (reg:CC FLAGS_REG))]
11177   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11178                      ? flow2_completed : reload_completed)"
11179   [(const_int 0)]
11180   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11181
11182 (define_insn "x86_shrd_1"
11183   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11184         (ior:SI (ashiftrt:SI (match_dup 0)
11185                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11186                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11187                   (minus:QI (const_int 32) (match_dup 2)))))
11188    (clobber (reg:CC FLAGS_REG))]
11189   ""
11190   "@
11191    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11192    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11193   [(set_attr "type" "ishift")
11194    (set_attr "prefix_0f" "1")
11195    (set_attr "pent_pair" "np")
11196    (set_attr "mode" "SI")])
11197
11198 (define_expand "x86_shift_adj_3"
11199   [(use (match_operand:SI 0 "register_operand" ""))
11200    (use (match_operand:SI 1 "register_operand" ""))
11201    (use (match_operand:QI 2 "register_operand" ""))]
11202   ""
11203 {
11204   rtx label = gen_label_rtx ();
11205   rtx tmp;
11206
11207   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11208
11209   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11210   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11211   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11212                               gen_rtx_LABEL_REF (VOIDmode, label),
11213                               pc_rtx);
11214   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11215   JUMP_LABEL (tmp) = label;
11216
11217   emit_move_insn (operands[0], operands[1]);
11218   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11219
11220   emit_label (label);
11221   LABEL_NUSES (label) = 1;
11222
11223   DONE;
11224 })
11225
11226 (define_insn "ashrsi3_31"
11227   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11228         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11229                      (match_operand:SI 2 "const_int_operand" "i,i")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11232    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11233   "@
11234    {cltd|cdq}
11235    sar{l}\t{%2, %0|%0, %2}"
11236   [(set_attr "type" "imovx,ishift")
11237    (set_attr "prefix_0f" "0,*")
11238    (set_attr "length_immediate" "0,*")
11239    (set_attr "modrm" "0,1")
11240    (set_attr "mode" "SI")])
11241
11242 (define_insn "*ashrsi3_31_zext"
11243   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11244         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11245                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11246    (clobber (reg:CC FLAGS_REG))]
11247   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11248    && INTVAL (operands[2]) == 31
11249    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11250   "@
11251    {cltd|cdq}
11252    sar{l}\t{%2, %k0|%k0, %2}"
11253   [(set_attr "type" "imovx,ishift")
11254    (set_attr "prefix_0f" "0,*")
11255    (set_attr "length_immediate" "0,*")
11256    (set_attr "modrm" "0,1")
11257    (set_attr "mode" "SI")])
11258
11259 (define_expand "ashrsi3"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11262                      (match_operand:QI 2 "nonmemory_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   ""
11265   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11266
11267 (define_insn "*ashrsi3_1_one_bit"
11268   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11269         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11270                      (match_operand:QI 2 "const1_operand" "")))
11271    (clobber (reg:CC FLAGS_REG))]
11272   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11273    && (TARGET_SHIFT1 || optimize_size)"
11274   "sar{l}\t%0"
11275   [(set_attr "type" "ishift")
11276    (set (attr "length") 
11277      (if_then_else (match_operand:SI 0 "register_operand" "") 
11278         (const_string "2")
11279         (const_string "*")))])
11280
11281 (define_insn "*ashrsi3_1_one_bit_zext"
11282   [(set (match_operand:DI 0 "register_operand" "=r")
11283         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11284                                      (match_operand:QI 2 "const1_operand" ""))))
11285    (clobber (reg:CC FLAGS_REG))]
11286   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11287    && (TARGET_SHIFT1 || optimize_size)"
11288   "sar{l}\t%k0"
11289   [(set_attr "type" "ishift")
11290    (set_attr "length" "2")])
11291
11292 (define_insn "*ashrsi3_1"
11293   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11294         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11295                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11298   "@
11299    sar{l}\t{%2, %0|%0, %2}
11300    sar{l}\t{%b2, %0|%0, %b2}"
11301   [(set_attr "type" "ishift")
11302    (set_attr "mode" "SI")])
11303
11304 (define_insn "*ashrsi3_1_zext"
11305   [(set (match_operand:DI 0 "register_operand" "=r,r")
11306         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11307                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11308    (clobber (reg:CC FLAGS_REG))]
11309   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11310   "@
11311    sar{l}\t{%2, %k0|%k0, %2}
11312    sar{l}\t{%b2, %k0|%k0, %b2}"
11313   [(set_attr "type" "ishift")
11314    (set_attr "mode" "SI")])
11315
11316 ;; This pattern can't accept a variable shift count, since shifts by
11317 ;; zero don't affect the flags.  We assume that shifts by constant
11318 ;; zero are optimized away.
11319 (define_insn "*ashrsi3_one_bit_cmp"
11320   [(set (reg FLAGS_REG)
11321         (compare
11322           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11323                        (match_operand:QI 2 "const1_operand" ""))
11324           (const_int 0)))
11325    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11326         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11327   "ix86_match_ccmode (insn, CCGOCmode)
11328    && (TARGET_SHIFT1 || optimize_size)
11329    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11330   "sar{l}\t%0"
11331   [(set_attr "type" "ishift")
11332    (set (attr "length") 
11333      (if_then_else (match_operand:SI 0 "register_operand" "") 
11334         (const_string "2")
11335         (const_string "*")))])
11336
11337 (define_insn "*ashrsi3_one_bit_cmp_zext"
11338   [(set (reg FLAGS_REG)
11339         (compare
11340           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11341                        (match_operand:QI 2 "const1_operand" ""))
11342           (const_int 0)))
11343    (set (match_operand:DI 0 "register_operand" "=r")
11344         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11345   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11346    && (TARGET_SHIFT1 || optimize_size)
11347    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11348   "sar{l}\t%k0"
11349   [(set_attr "type" "ishift")
11350    (set_attr "length" "2")])
11351
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags.  We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrsi3_cmp"
11356   [(set (reg FLAGS_REG)
11357         (compare
11358           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11359                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11360           (const_int 0)))
11361    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11362         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11363   "ix86_match_ccmode (insn, CCGOCmode)
11364    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11365   "sar{l}\t{%2, %0|%0, %2}"
11366   [(set_attr "type" "ishift")
11367    (set_attr "mode" "SI")])
11368
11369 (define_insn "*ashrsi3_cmp_zext"
11370   [(set (reg FLAGS_REG)
11371         (compare
11372           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11373                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11374           (const_int 0)))
11375    (set (match_operand:DI 0 "register_operand" "=r")
11376         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11377   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11378    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11379   "sar{l}\t{%2, %k0|%k0, %2}"
11380   [(set_attr "type" "ishift")
11381    (set_attr "mode" "SI")])
11382
11383 (define_expand "ashrhi3"
11384   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11385         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11386                      (match_operand:QI 2 "nonmemory_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "TARGET_HIMODE_MATH"
11389   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11390
11391 (define_insn "*ashrhi3_1_one_bit"
11392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11393         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11394                      (match_operand:QI 2 "const1_operand" "")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11397    && (TARGET_SHIFT1 || optimize_size)"
11398   "sar{w}\t%0"
11399   [(set_attr "type" "ishift")
11400    (set (attr "length") 
11401      (if_then_else (match_operand 0 "register_operand" "") 
11402         (const_string "2")
11403         (const_string "*")))])
11404
11405 (define_insn "*ashrhi3_1"
11406   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11407         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11408                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11409    (clobber (reg:CC FLAGS_REG))]
11410   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11411   "@
11412    sar{w}\t{%2, %0|%0, %2}
11413    sar{w}\t{%b2, %0|%0, %b2}"
11414   [(set_attr "type" "ishift")
11415    (set_attr "mode" "HI")])
11416
11417 ;; This pattern can't accept a variable shift count, since shifts by
11418 ;; zero don't affect the flags.  We assume that shifts by constant
11419 ;; zero are optimized away.
11420 (define_insn "*ashrhi3_one_bit_cmp"
11421   [(set (reg FLAGS_REG)
11422         (compare
11423           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11424                        (match_operand:QI 2 "const1_operand" ""))
11425           (const_int 0)))
11426    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11427         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11428   "ix86_match_ccmode (insn, CCGOCmode)
11429    && (TARGET_SHIFT1 || optimize_size)
11430    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11431   "sar{w}\t%0"
11432   [(set_attr "type" "ishift")
11433    (set (attr "length") 
11434      (if_then_else (match_operand 0 "register_operand" "") 
11435         (const_string "2")
11436         (const_string "*")))])
11437
11438 ;; This pattern can't accept a variable shift count, since shifts by
11439 ;; zero don't affect the flags.  We assume that shifts by constant
11440 ;; zero are optimized away.
11441 (define_insn "*ashrhi3_cmp"
11442   [(set (reg FLAGS_REG)
11443         (compare
11444           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11445                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11446           (const_int 0)))
11447    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11448         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11449   "ix86_match_ccmode (insn, CCGOCmode)
11450    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11451   "sar{w}\t{%2, %0|%0, %2}"
11452   [(set_attr "type" "ishift")
11453    (set_attr "mode" "HI")])
11454
11455 (define_expand "ashrqi3"
11456   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11457         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11458                      (match_operand:QI 2 "nonmemory_operand" "")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "TARGET_QIMODE_MATH"
11461   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11462
11463 (define_insn "*ashrqi3_1_one_bit"
11464   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11465         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11466                      (match_operand:QI 2 "const1_operand" "")))
11467    (clobber (reg:CC FLAGS_REG))]
11468   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11469    && (TARGET_SHIFT1 || optimize_size)"
11470   "sar{b}\t%0"
11471   [(set_attr "type" "ishift")
11472    (set (attr "length") 
11473      (if_then_else (match_operand 0 "register_operand" "") 
11474         (const_string "2")
11475         (const_string "*")))])
11476
11477 (define_insn "*ashrqi3_1_one_bit_slp"
11478   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11479         (ashiftrt:QI (match_dup 0)
11480                      (match_operand:QI 1 "const1_operand" "")))
11481    (clobber (reg:CC FLAGS_REG))]
11482   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11483    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11484    && (TARGET_SHIFT1 || optimize_size)"
11485   "sar{b}\t%0"
11486   [(set_attr "type" "ishift1")
11487    (set (attr "length") 
11488      (if_then_else (match_operand 0 "register_operand" "") 
11489         (const_string "2")
11490         (const_string "*")))])
11491
11492 (define_insn "*ashrqi3_1"
11493   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11494         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11495                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11496    (clobber (reg:CC FLAGS_REG))]
11497   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11498   "@
11499    sar{b}\t{%2, %0|%0, %2}
11500    sar{b}\t{%b2, %0|%0, %b2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "mode" "QI")])
11503
11504 (define_insn "*ashrqi3_1_slp"
11505   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11506         (ashiftrt:QI (match_dup 0)
11507                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11510    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11511   "@
11512    sar{b}\t{%1, %0|%0, %1}
11513    sar{b}\t{%b1, %0|%0, %b1}"
11514   [(set_attr "type" "ishift1")
11515    (set_attr "mode" "QI")])
11516
11517 ;; This pattern can't accept a variable shift count, since shifts by
11518 ;; zero don't affect the flags.  We assume that shifts by constant
11519 ;; zero are optimized away.
11520 (define_insn "*ashrqi3_one_bit_cmp"
11521   [(set (reg FLAGS_REG)
11522         (compare
11523           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11524                        (match_operand:QI 2 "const1_operand" "I"))
11525           (const_int 0)))
11526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11527         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11528   "ix86_match_ccmode (insn, CCGOCmode)
11529    && (TARGET_SHIFT1 || optimize_size)
11530    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11531   "sar{b}\t%0"
11532   [(set_attr "type" "ishift")
11533    (set (attr "length") 
11534      (if_then_else (match_operand 0 "register_operand" "") 
11535         (const_string "2")
11536         (const_string "*")))])
11537
11538 ;; This pattern can't accept a variable shift count, since shifts by
11539 ;; zero don't affect the flags.  We assume that shifts by constant
11540 ;; zero are optimized away.
11541 (define_insn "*ashrqi3_cmp"
11542   [(set (reg FLAGS_REG)
11543         (compare
11544           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11545                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546           (const_int 0)))
11547    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11548         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11549   "ix86_match_ccmode (insn, CCGOCmode)
11550    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11551   "sar{b}\t{%2, %0|%0, %2}"
11552   [(set_attr "type" "ishift")
11553    (set_attr "mode" "QI")])
11554 \f
11555 ;; Logical shift instructions
11556
11557 ;; See comment above `ashldi3' about how this works.
11558
11559 (define_expand "lshrti3"
11560   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11561                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11562                                 (match_operand:QI 2 "nonmemory_operand" "")))
11563               (clobber (reg:CC FLAGS_REG))])]
11564   "TARGET_64BIT"
11565 {
11566   if (! immediate_operand (operands[2], QImode))
11567     {
11568       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11569       DONE;
11570     }
11571   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11572   DONE;
11573 })
11574
11575 (define_insn "lshrti3_1"
11576   [(set (match_operand:TI 0 "register_operand" "=r")
11577         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11578                      (match_operand:QI 2 "register_operand" "c")))
11579    (clobber (match_scratch:DI 3 "=&r"))
11580    (clobber (reg:CC FLAGS_REG))]
11581   "TARGET_64BIT"
11582   "#"
11583   [(set_attr "type" "multi")])
11584
11585 (define_insn "*lshrti3_2"
11586   [(set (match_operand:TI 0 "register_operand" "=r")
11587         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11588                      (match_operand:QI 2 "immediate_operand" "O")))
11589    (clobber (reg:CC FLAGS_REG))]
11590   "TARGET_64BIT"
11591   "#"
11592   [(set_attr "type" "multi")])
11593
11594 (define_split 
11595   [(set (match_operand:TI 0 "register_operand" "")
11596         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11597                      (match_operand:QI 2 "register_operand" "")))
11598    (clobber (match_scratch:DI 3 ""))
11599    (clobber (reg:CC FLAGS_REG))]
11600   "TARGET_64BIT && reload_completed"
11601   [(const_int 0)]
11602   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11603
11604 (define_split 
11605   [(set (match_operand:TI 0 "register_operand" "")
11606         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11607                      (match_operand:QI 2 "immediate_operand" "")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_64BIT && reload_completed"
11610   [(const_int 0)]
11611   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11612
11613 (define_expand "lshrdi3"
11614   [(set (match_operand:DI 0 "shiftdi_operand" "")
11615         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11616                      (match_operand:QI 2 "nonmemory_operand" "")))]
11617   ""
11618   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11619
11620 (define_insn "*lshrdi3_1_one_bit_rex64"
11621   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11622         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11623                      (match_operand:QI 2 "const1_operand" "")))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11626    && (TARGET_SHIFT1 || optimize_size)"
11627   "shr{q}\t%0"
11628   [(set_attr "type" "ishift")
11629    (set (attr "length") 
11630      (if_then_else (match_operand:DI 0 "register_operand" "") 
11631         (const_string "2")
11632         (const_string "*")))])
11633
11634 (define_insn "*lshrdi3_1_rex64"
11635   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11636         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11637                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11638    (clobber (reg:CC FLAGS_REG))]
11639   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11640   "@
11641    shr{q}\t{%2, %0|%0, %2}
11642    shr{q}\t{%b2, %0|%0, %b2}"
11643   [(set_attr "type" "ishift")
11644    (set_attr "mode" "DI")])
11645
11646 ;; This pattern can't accept a variable shift count, since shifts by
11647 ;; zero don't affect the flags.  We assume that shifts by constant
11648 ;; zero are optimized away.
11649 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11650   [(set (reg FLAGS_REG)
11651         (compare
11652           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11653                        (match_operand:QI 2 "const1_operand" ""))
11654           (const_int 0)))
11655    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11656         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11657   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11658    && (TARGET_SHIFT1 || optimize_size)
11659    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11660   "shr{q}\t%0"
11661   [(set_attr "type" "ishift")
11662    (set (attr "length") 
11663      (if_then_else (match_operand:DI 0 "register_operand" "") 
11664         (const_string "2")
11665         (const_string "*")))])
11666
11667 ;; This pattern can't accept a variable shift count, since shifts by
11668 ;; zero don't affect the flags.  We assume that shifts by constant
11669 ;; zero are optimized away.
11670 (define_insn "*lshrdi3_cmp_rex64"
11671   [(set (reg FLAGS_REG)
11672         (compare
11673           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11674                        (match_operand:QI 2 "const_int_operand" "e"))
11675           (const_int 0)))
11676    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11677         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11679    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11680   "shr{q}\t{%2, %0|%0, %2}"
11681   [(set_attr "type" "ishift")
11682    (set_attr "mode" "DI")])
11683
11684 (define_insn "*lshrdi3_1"
11685   [(set (match_operand:DI 0 "register_operand" "=r")
11686         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11687                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "!TARGET_64BIT"
11690   "#"
11691   [(set_attr "type" "multi")])
11692
11693 ;; By default we don't ask for a scratch register, because when DImode
11694 ;; values are manipulated, registers are already at a premium.  But if
11695 ;; we have one handy, we won't turn it away.
11696 (define_peephole2
11697   [(match_scratch:SI 3 "r")
11698    (parallel [(set (match_operand:DI 0 "register_operand" "")
11699                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11700                                 (match_operand:QI 2 "nonmemory_operand" "")))
11701               (clobber (reg:CC FLAGS_REG))])
11702    (match_dup 3)]
11703   "!TARGET_64BIT && TARGET_CMOVE"
11704   [(const_int 0)]
11705   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11706
11707 (define_split 
11708   [(set (match_operand:DI 0 "register_operand" "")
11709         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11710                      (match_operand:QI 2 "nonmemory_operand" "")))
11711    (clobber (reg:CC FLAGS_REG))]
11712   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11713                      ? flow2_completed : reload_completed)"
11714   [(const_int 0)]
11715   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11716
11717 (define_expand "lshrsi3"
11718   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11719         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11720                      (match_operand:QI 2 "nonmemory_operand" "")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   ""
11723   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11724
11725 (define_insn "*lshrsi3_1_one_bit"
11726   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11727         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728                      (match_operand:QI 2 "const1_operand" "")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11731    && (TARGET_SHIFT1 || optimize_size)"
11732   "shr{l}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand:SI 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 (define_insn "*lshrsi3_1_one_bit_zext"
11740   [(set (match_operand:DI 0 "register_operand" "=r")
11741         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11742                      (match_operand:QI 2 "const1_operand" "")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11745    && (TARGET_SHIFT1 || optimize_size)"
11746   "shr{l}\t%k0"
11747   [(set_attr "type" "ishift")
11748    (set_attr "length" "2")])
11749
11750 (define_insn "*lshrsi3_1"
11751   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11752         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11753                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756   "@
11757    shr{l}\t{%2, %0|%0, %2}
11758    shr{l}\t{%b2, %0|%0, %b2}"
11759   [(set_attr "type" "ishift")
11760    (set_attr "mode" "SI")])
11761
11762 (define_insn "*lshrsi3_1_zext"
11763   [(set (match_operand:DI 0 "register_operand" "=r,r")
11764         (zero_extend:DI
11765           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11766                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11767    (clobber (reg:CC FLAGS_REG))]
11768   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11769   "@
11770    shr{l}\t{%2, %k0|%k0, %2}
11771    shr{l}\t{%b2, %k0|%k0, %b2}"
11772   [(set_attr "type" "ishift")
11773    (set_attr "mode" "SI")])
11774
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags.  We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*lshrsi3_one_bit_cmp"
11779   [(set (reg FLAGS_REG)
11780         (compare
11781           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11782                        (match_operand:QI 2 "const1_operand" ""))
11783           (const_int 0)))
11784    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11785         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && (TARGET_SHIFT1 || optimize_size)
11788    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789   "shr{l}\t%0"
11790   [(set_attr "type" "ishift")
11791    (set (attr "length") 
11792      (if_then_else (match_operand:SI 0 "register_operand" "") 
11793         (const_string "2")
11794         (const_string "*")))])
11795
11796 (define_insn "*lshrsi3_cmp_one_bit_zext"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11800                        (match_operand:QI 2 "const1_operand" ""))
11801           (const_int 0)))
11802    (set (match_operand:DI 0 "register_operand" "=r")
11803         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11804   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11805    && (TARGET_SHIFT1 || optimize_size)
11806    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11807   "shr{l}\t%k0"
11808   [(set_attr "type" "ishift")
11809    (set_attr "length" "2")])
11810
11811 ;; This pattern can't accept a variable shift count, since shifts by
11812 ;; zero don't affect the flags.  We assume that shifts by constant
11813 ;; zero are optimized away.
11814 (define_insn "*lshrsi3_cmp"
11815   [(set (reg FLAGS_REG)
11816         (compare
11817           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11818                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11819           (const_int 0)))
11820    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11821         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11822   "ix86_match_ccmode (insn, CCGOCmode)
11823    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11824   "shr{l}\t{%2, %0|%0, %2}"
11825   [(set_attr "type" "ishift")
11826    (set_attr "mode" "SI")])
11827
11828 (define_insn "*lshrsi3_cmp_zext"
11829   [(set (reg FLAGS_REG)
11830         (compare
11831           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11832                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11833           (const_int 0)))
11834    (set (match_operand:DI 0 "register_operand" "=r")
11835         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11837    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11838   "shr{l}\t{%2, %k0|%k0, %2}"
11839   [(set_attr "type" "ishift")
11840    (set_attr "mode" "SI")])
11841
11842 (define_expand "lshrhi3"
11843   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11844         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11845                      (match_operand:QI 2 "nonmemory_operand" "")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   "TARGET_HIMODE_MATH"
11848   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11849
11850 (define_insn "*lshrhi3_1_one_bit"
11851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11852         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11853                      (match_operand:QI 2 "const1_operand" "")))
11854    (clobber (reg:CC FLAGS_REG))]
11855   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11856    && (TARGET_SHIFT1 || optimize_size)"
11857   "shr{w}\t%0"
11858   [(set_attr "type" "ishift")
11859    (set (attr "length") 
11860      (if_then_else (match_operand 0 "register_operand" "") 
11861         (const_string "2")
11862         (const_string "*")))])
11863
11864 (define_insn "*lshrhi3_1"
11865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11866         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11867                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870   "@
11871    shr{w}\t{%2, %0|%0, %2}
11872    shr{w}\t{%b2, %0|%0, %b2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "HI")])
11875
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags.  We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*lshrhi3_one_bit_cmp"
11880   [(set (reg FLAGS_REG)
11881         (compare
11882           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11883                        (match_operand:QI 2 "const1_operand" ""))
11884           (const_int 0)))
11885    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11887   "ix86_match_ccmode (insn, CCGOCmode)
11888    && (TARGET_SHIFT1 || optimize_size)
11889    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11890   "shr{w}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set (attr "length") 
11893      (if_then_else (match_operand:SI 0 "register_operand" "") 
11894         (const_string "2")
11895         (const_string "*")))])
11896
11897 ;; This pattern can't accept a variable shift count, since shifts by
11898 ;; zero don't affect the flags.  We assume that shifts by constant
11899 ;; zero are optimized away.
11900 (define_insn "*lshrhi3_cmp"
11901   [(set (reg FLAGS_REG)
11902         (compare
11903           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11904                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11905           (const_int 0)))
11906    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11907         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11908   "ix86_match_ccmode (insn, CCGOCmode)
11909    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11910   "shr{w}\t{%2, %0|%0, %2}"
11911   [(set_attr "type" "ishift")
11912    (set_attr "mode" "HI")])
11913
11914 (define_expand "lshrqi3"
11915   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11916         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11917                      (match_operand:QI 2 "nonmemory_operand" "")))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "TARGET_QIMODE_MATH"
11920   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11921
11922 (define_insn "*lshrqi3_1_one_bit"
11923   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11924         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11925                      (match_operand:QI 2 "const1_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11928    && (TARGET_SHIFT1 || optimize_size)"
11929   "shr{b}\t%0"
11930   [(set_attr "type" "ishift")
11931    (set (attr "length") 
11932      (if_then_else (match_operand 0 "register_operand" "") 
11933         (const_string "2")
11934         (const_string "*")))])
11935
11936 (define_insn "*lshrqi3_1_one_bit_slp"
11937   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11938         (lshiftrt:QI (match_dup 0)
11939                      (match_operand:QI 1 "const1_operand" "")))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11942    && (TARGET_SHIFT1 || optimize_size)"
11943   "shr{b}\t%0"
11944   [(set_attr "type" "ishift1")
11945    (set (attr "length") 
11946      (if_then_else (match_operand 0 "register_operand" "") 
11947         (const_string "2")
11948         (const_string "*")))])
11949
11950 (define_insn "*lshrqi3_1"
11951   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11952         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11953                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11954    (clobber (reg:CC FLAGS_REG))]
11955   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11956   "@
11957    shr{b}\t{%2, %0|%0, %2}
11958    shr{b}\t{%b2, %0|%0, %b2}"
11959   [(set_attr "type" "ishift")
11960    (set_attr "mode" "QI")])
11961
11962 (define_insn "*lshrqi3_1_slp"
11963   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11964         (lshiftrt:QI (match_dup 0)
11965                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11968    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11969   "@
11970    shr{b}\t{%1, %0|%0, %1}
11971    shr{b}\t{%b1, %0|%0, %b1}"
11972   [(set_attr "type" "ishift1")
11973    (set_attr "mode" "QI")])
11974
11975 ;; This pattern can't accept a variable shift count, since shifts by
11976 ;; zero don't affect the flags.  We assume that shifts by constant
11977 ;; zero are optimized away.
11978 (define_insn "*lshrqi2_one_bit_cmp"
11979   [(set (reg FLAGS_REG)
11980         (compare
11981           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11982                        (match_operand:QI 2 "const1_operand" ""))
11983           (const_int 0)))
11984    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11985         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11986   "ix86_match_ccmode (insn, CCGOCmode)
11987    && (TARGET_SHIFT1 || optimize_size)
11988    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11989   "shr{b}\t%0"
11990   [(set_attr "type" "ishift")
11991    (set (attr "length") 
11992      (if_then_else (match_operand:SI 0 "register_operand" "") 
11993         (const_string "2")
11994         (const_string "*")))])
11995
11996 ;; This pattern can't accept a variable shift count, since shifts by
11997 ;; zero don't affect the flags.  We assume that shifts by constant
11998 ;; zero are optimized away.
11999 (define_insn "*lshrqi2_cmp"
12000   [(set (reg FLAGS_REG)
12001         (compare
12002           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12003                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12004           (const_int 0)))
12005    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12006         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12007   "ix86_match_ccmode (insn, CCGOCmode)
12008    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12009   "shr{b}\t{%2, %0|%0, %2}"
12010   [(set_attr "type" "ishift")
12011    (set_attr "mode" "QI")])
12012 \f
12013 ;; Rotate instructions
12014
12015 (define_expand "rotldi3"
12016   [(set (match_operand:DI 0 "shiftdi_operand" "")
12017         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12018                    (match_operand:QI 2 "nonmemory_operand" "")))
12019    (clobber (reg:CC FLAGS_REG))]
12020  ""
12021 {
12022   if (TARGET_64BIT)
12023     {
12024       ix86_expand_binary_operator (ROTATE, DImode, operands);
12025       DONE;
12026     }
12027   if (!const_1_to_31_operand (operands[2], VOIDmode))
12028     FAIL;
12029   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12030   DONE;
12031 })
12032
12033 ;; Implement rotation using two double-precision shift instructions
12034 ;; and a scratch register.   
12035 (define_insn_and_split "ix86_rotldi3"
12036  [(set (match_operand:DI 0 "register_operand" "=r")
12037        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12038                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12039   (clobber (reg:CC FLAGS_REG))
12040   (clobber (match_scratch:SI 3 "=&r"))]
12041  "!TARGET_64BIT"
12042  "" 
12043  "&& reload_completed"
12044  [(set (match_dup 3) (match_dup 4))
12045   (parallel
12046    [(set (match_dup 4)
12047          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12048                  (lshiftrt:SI (match_dup 5)
12049                               (minus:QI (const_int 32) (match_dup 2)))))
12050     (clobber (reg:CC FLAGS_REG))])
12051   (parallel
12052    [(set (match_dup 5)
12053          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12054                  (lshiftrt:SI (match_dup 3)
12055                               (minus:QI (const_int 32) (match_dup 2)))))
12056     (clobber (reg:CC FLAGS_REG))])]
12057  "split_di (operands, 1, operands + 4, operands + 5);")
12058  
12059 (define_insn "*rotlsi3_1_one_bit_rex64"
12060   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12061         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12062                    (match_operand:QI 2 "const1_operand" "")))
12063    (clobber (reg:CC FLAGS_REG))]
12064   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12065    && (TARGET_SHIFT1 || optimize_size)"
12066   "rol{q}\t%0"
12067   [(set_attr "type" "rotate")
12068    (set (attr "length") 
12069      (if_then_else (match_operand:DI 0 "register_operand" "") 
12070         (const_string "2")
12071         (const_string "*")))])
12072
12073 (define_insn "*rotldi3_1_rex64"
12074   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12075         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12076                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12079   "@
12080    rol{q}\t{%2, %0|%0, %2}
12081    rol{q}\t{%b2, %0|%0, %b2}"
12082   [(set_attr "type" "rotate")
12083    (set_attr "mode" "DI")])
12084
12085 (define_expand "rotlsi3"
12086   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12087         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12088                    (match_operand:QI 2 "nonmemory_operand" "")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   ""
12091   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12092
12093 (define_insn "*rotlsi3_1_one_bit"
12094   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12095         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12096                    (match_operand:QI 2 "const1_operand" "")))
12097    (clobber (reg:CC FLAGS_REG))]
12098   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12099    && (TARGET_SHIFT1 || optimize_size)"
12100   "rol{l}\t%0"
12101   [(set_attr "type" "rotate")
12102    (set (attr "length") 
12103      (if_then_else (match_operand:SI 0 "register_operand" "") 
12104         (const_string "2")
12105         (const_string "*")))])
12106
12107 (define_insn "*rotlsi3_1_one_bit_zext"
12108   [(set (match_operand:DI 0 "register_operand" "=r")
12109         (zero_extend:DI
12110           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12111                      (match_operand:QI 2 "const1_operand" ""))))
12112    (clobber (reg:CC FLAGS_REG))]
12113   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12114    && (TARGET_SHIFT1 || optimize_size)"
12115   "rol{l}\t%k0"
12116   [(set_attr "type" "rotate")
12117    (set_attr "length" "2")])
12118
12119 (define_insn "*rotlsi3_1"
12120   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12121         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12122                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12125   "@
12126    rol{l}\t{%2, %0|%0, %2}
12127    rol{l}\t{%b2, %0|%0, %b2}"
12128   [(set_attr "type" "rotate")
12129    (set_attr "mode" "SI")])
12130
12131 (define_insn "*rotlsi3_1_zext"
12132   [(set (match_operand:DI 0 "register_operand" "=r,r")
12133         (zero_extend:DI
12134           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12135                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12136    (clobber (reg:CC FLAGS_REG))]
12137   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12138   "@
12139    rol{l}\t{%2, %k0|%k0, %2}
12140    rol{l}\t{%b2, %k0|%k0, %b2}"
12141   [(set_attr "type" "rotate")
12142    (set_attr "mode" "SI")])
12143
12144 (define_expand "rotlhi3"
12145   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12146         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12147                    (match_operand:QI 2 "nonmemory_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "TARGET_HIMODE_MATH"
12150   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12151
12152 (define_insn "*rotlhi3_1_one_bit"
12153   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12154         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12155                    (match_operand:QI 2 "const1_operand" "")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12158    && (TARGET_SHIFT1 || optimize_size)"
12159   "rol{w}\t%0"
12160   [(set_attr "type" "rotate")
12161    (set (attr "length") 
12162      (if_then_else (match_operand 0 "register_operand" "") 
12163         (const_string "2")
12164         (const_string "*")))])
12165
12166 (define_insn "*rotlhi3_1"
12167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12168         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12169                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12172   "@
12173    rol{w}\t{%2, %0|%0, %2}
12174    rol{w}\t{%b2, %0|%0, %b2}"
12175   [(set_attr "type" "rotate")
12176    (set_attr "mode" "HI")])
12177
12178 (define_expand "rotlqi3"
12179   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12180         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12181                    (match_operand:QI 2 "nonmemory_operand" "")))
12182    (clobber (reg:CC FLAGS_REG))]
12183   "TARGET_QIMODE_MATH"
12184   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12185
12186 (define_insn "*rotlqi3_1_one_bit_slp"
12187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12188         (rotate:QI (match_dup 0)
12189                    (match_operand:QI 1 "const1_operand" "")))
12190    (clobber (reg:CC FLAGS_REG))]
12191   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12192    && (TARGET_SHIFT1 || optimize_size)"
12193   "rol{b}\t%0"
12194   [(set_attr "type" "rotate1")
12195    (set (attr "length") 
12196      (if_then_else (match_operand 0 "register_operand" "") 
12197         (const_string "2")
12198         (const_string "*")))])
12199
12200 (define_insn "*rotlqi3_1_one_bit"
12201   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12202         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12203                    (match_operand:QI 2 "const1_operand" "")))
12204    (clobber (reg:CC FLAGS_REG))]
12205   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12206    && (TARGET_SHIFT1 || optimize_size)"
12207   "rol{b}\t%0"
12208   [(set_attr "type" "rotate")
12209    (set (attr "length") 
12210      (if_then_else (match_operand 0 "register_operand" "") 
12211         (const_string "2")
12212         (const_string "*")))])
12213
12214 (define_insn "*rotlqi3_1_slp"
12215   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12216         (rotate:QI (match_dup 0)
12217                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12218    (clobber (reg:CC FLAGS_REG))]
12219   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12220    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12221   "@
12222    rol{b}\t{%1, %0|%0, %1}
12223    rol{b}\t{%b1, %0|%0, %b1}"
12224   [(set_attr "type" "rotate1")
12225    (set_attr "mode" "QI")])
12226
12227 (define_insn "*rotlqi3_1"
12228   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12229         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12230                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12231    (clobber (reg:CC FLAGS_REG))]
12232   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12233   "@
12234    rol{b}\t{%2, %0|%0, %2}
12235    rol{b}\t{%b2, %0|%0, %b2}"
12236   [(set_attr "type" "rotate")
12237    (set_attr "mode" "QI")])
12238
12239 (define_expand "rotrdi3"
12240   [(set (match_operand:DI 0 "shiftdi_operand" "")
12241         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12242                    (match_operand:QI 2 "nonmemory_operand" "")))
12243    (clobber (reg:CC FLAGS_REG))]
12244  ""
12245 {
12246   if (TARGET_64BIT)
12247     {
12248       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12249       DONE;
12250     }
12251   if (!const_1_to_31_operand (operands[2], VOIDmode))
12252     FAIL;
12253   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12254   DONE;
12255 })
12256   
12257 ;; Implement rotation using two double-precision shift instructions
12258 ;; and a scratch register.   
12259 (define_insn_and_split "ix86_rotrdi3"
12260  [(set (match_operand:DI 0 "register_operand" "=r")
12261        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12262                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12263   (clobber (reg:CC FLAGS_REG))
12264   (clobber (match_scratch:SI 3 "=&r"))]
12265  "!TARGET_64BIT"
12266  ""
12267  "&& reload_completed"
12268  [(set (match_dup 3) (match_dup 4))
12269   (parallel
12270    [(set (match_dup 4)
12271          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12272                  (ashift:SI (match_dup 5)
12273                             (minus:QI (const_int 32) (match_dup 2)))))
12274     (clobber (reg:CC FLAGS_REG))])
12275   (parallel
12276    [(set (match_dup 5)
12277          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12278                  (ashift:SI (match_dup 3)
12279                             (minus:QI (const_int 32) (match_dup 2)))))
12280     (clobber (reg:CC FLAGS_REG))])]
12281  "split_di (operands, 1, operands + 4, operands + 5);")
12282
12283 (define_insn "*rotrdi3_1_one_bit_rex64"
12284   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12285         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12286                      (match_operand:QI 2 "const1_operand" "")))
12287    (clobber (reg:CC FLAGS_REG))]
12288   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12289    && (TARGET_SHIFT1 || optimize_size)"
12290   "ror{q}\t%0"
12291   [(set_attr "type" "rotate")
12292    (set (attr "length") 
12293      (if_then_else (match_operand:DI 0 "register_operand" "") 
12294         (const_string "2")
12295         (const_string "*")))])
12296
12297 (define_insn "*rotrdi3_1_rex64"
12298   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12299         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12300                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12301    (clobber (reg:CC FLAGS_REG))]
12302   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12303   "@
12304    ror{q}\t{%2, %0|%0, %2}
12305    ror{q}\t{%b2, %0|%0, %b2}"
12306   [(set_attr "type" "rotate")
12307    (set_attr "mode" "DI")])
12308
12309 (define_expand "rotrsi3"
12310   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12311         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12312                      (match_operand:QI 2 "nonmemory_operand" "")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   ""
12315   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12316
12317 (define_insn "*rotrsi3_1_one_bit"
12318   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12319         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12320                      (match_operand:QI 2 "const1_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12323    && (TARGET_SHIFT1 || optimize_size)"
12324   "ror{l}\t%0"
12325   [(set_attr "type" "rotate")
12326    (set (attr "length") 
12327      (if_then_else (match_operand:SI 0 "register_operand" "") 
12328         (const_string "2")
12329         (const_string "*")))])
12330
12331 (define_insn "*rotrsi3_1_one_bit_zext"
12332   [(set (match_operand:DI 0 "register_operand" "=r")
12333         (zero_extend:DI
12334           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12335                        (match_operand:QI 2 "const1_operand" ""))))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12338    && (TARGET_SHIFT1 || optimize_size)"
12339   "ror{l}\t%k0"
12340   [(set_attr "type" "rotate")
12341    (set (attr "length") 
12342      (if_then_else (match_operand:SI 0 "register_operand" "") 
12343         (const_string "2")
12344         (const_string "*")))])
12345
12346 (define_insn "*rotrsi3_1"
12347   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12348         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12349                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12350    (clobber (reg:CC FLAGS_REG))]
12351   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12352   "@
12353    ror{l}\t{%2, %0|%0, %2}
12354    ror{l}\t{%b2, %0|%0, %b2}"
12355   [(set_attr "type" "rotate")
12356    (set_attr "mode" "SI")])
12357
12358 (define_insn "*rotrsi3_1_zext"
12359   [(set (match_operand:DI 0 "register_operand" "=r,r")
12360         (zero_extend:DI
12361           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12362                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12363    (clobber (reg:CC FLAGS_REG))]
12364   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12365   "@
12366    ror{l}\t{%2, %k0|%k0, %2}
12367    ror{l}\t{%b2, %k0|%k0, %b2}"
12368   [(set_attr "type" "rotate")
12369    (set_attr "mode" "SI")])
12370
12371 (define_expand "rotrhi3"
12372   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12373         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12374                      (match_operand:QI 2 "nonmemory_operand" "")))
12375    (clobber (reg:CC FLAGS_REG))]
12376   "TARGET_HIMODE_MATH"
12377   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12378
12379 (define_insn "*rotrhi3_one_bit"
12380   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12381         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12382                      (match_operand:QI 2 "const1_operand" "")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12385    && (TARGET_SHIFT1 || optimize_size)"
12386   "ror{w}\t%0"
12387   [(set_attr "type" "rotate")
12388    (set (attr "length") 
12389      (if_then_else (match_operand 0 "register_operand" "") 
12390         (const_string "2")
12391         (const_string "*")))])
12392
12393 (define_insn "*rotrhi3"
12394   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12395         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12396                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12397    (clobber (reg:CC FLAGS_REG))]
12398   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12399   "@
12400    ror{w}\t{%2, %0|%0, %2}
12401    ror{w}\t{%b2, %0|%0, %b2}"
12402   [(set_attr "type" "rotate")
12403    (set_attr "mode" "HI")])
12404
12405 (define_expand "rotrqi3"
12406   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12407         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12408                      (match_operand:QI 2 "nonmemory_operand" "")))
12409    (clobber (reg:CC FLAGS_REG))]
12410   "TARGET_QIMODE_MATH"
12411   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12412
12413 (define_insn "*rotrqi3_1_one_bit"
12414   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12415         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12416                      (match_operand:QI 2 "const1_operand" "")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12419    && (TARGET_SHIFT1 || optimize_size)"
12420   "ror{b}\t%0"
12421   [(set_attr "type" "rotate")
12422    (set (attr "length") 
12423      (if_then_else (match_operand 0 "register_operand" "") 
12424         (const_string "2")
12425         (const_string "*")))])
12426
12427 (define_insn "*rotrqi3_1_one_bit_slp"
12428   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12429         (rotatert:QI (match_dup 0)
12430                      (match_operand:QI 1 "const1_operand" "")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12433    && (TARGET_SHIFT1 || optimize_size)"
12434   "ror{b}\t%0"
12435   [(set_attr "type" "rotate1")
12436    (set (attr "length") 
12437      (if_then_else (match_operand 0 "register_operand" "") 
12438         (const_string "2")
12439         (const_string "*")))])
12440
12441 (define_insn "*rotrqi3_1"
12442   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12443         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12444                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12445    (clobber (reg:CC FLAGS_REG))]
12446   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12447   "@
12448    ror{b}\t{%2, %0|%0, %2}
12449    ror{b}\t{%b2, %0|%0, %b2}"
12450   [(set_attr "type" "rotate")
12451    (set_attr "mode" "QI")])
12452
12453 (define_insn "*rotrqi3_1_slp"
12454   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12455         (rotatert:QI (match_dup 0)
12456                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12459    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12460   "@
12461    ror{b}\t{%1, %0|%0, %1}
12462    ror{b}\t{%b1, %0|%0, %b1}"
12463   [(set_attr "type" "rotate1")
12464    (set_attr "mode" "QI")])
12465 \f
12466 ;; Bit set / bit test instructions
12467
12468 (define_expand "extv"
12469   [(set (match_operand:SI 0 "register_operand" "")
12470         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12471                          (match_operand:SI 2 "immediate_operand" "")
12472                          (match_operand:SI 3 "immediate_operand" "")))]
12473   ""
12474 {
12475   /* Handle extractions from %ah et al.  */
12476   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12477     FAIL;
12478
12479   /* From mips.md: extract_bit_field doesn't verify that our source
12480      matches the predicate, so check it again here.  */
12481   if (! ext_register_operand (operands[1], VOIDmode))
12482     FAIL;
12483 })
12484
12485 (define_expand "extzv"
12486   [(set (match_operand:SI 0 "register_operand" "")
12487         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12488                          (match_operand:SI 2 "immediate_operand" "")
12489                          (match_operand:SI 3 "immediate_operand" "")))]
12490   ""
12491 {
12492   /* Handle extractions from %ah et al.  */
12493   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12494     FAIL;
12495
12496   /* From mips.md: extract_bit_field doesn't verify that our source
12497      matches the predicate, so check it again here.  */
12498   if (! ext_register_operand (operands[1], VOIDmode))
12499     FAIL;
12500 })
12501
12502 (define_expand "insv"
12503   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12504                       (match_operand 1 "immediate_operand" "")
12505                       (match_operand 2 "immediate_operand" ""))
12506         (match_operand 3 "register_operand" ""))]
12507   ""
12508 {
12509   /* Handle extractions from %ah et al.  */
12510   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12511     FAIL;
12512
12513   /* From mips.md: insert_bit_field doesn't verify that our source
12514      matches the predicate, so check it again here.  */
12515   if (! ext_register_operand (operands[0], VOIDmode))
12516     FAIL;
12517
12518   if (TARGET_64BIT)
12519     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12520   else
12521     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12522
12523   DONE;
12524 })
12525
12526 ;; %%% bts, btr, btc, bt.
12527 ;; In general these instructions are *slow* when applied to memory,
12528 ;; since they enforce atomic operation.  When applied to registers,
12529 ;; it depends on the cpu implementation.  They're never faster than
12530 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12531 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12532 ;; within the instruction itself, so operating on bits in the high
12533 ;; 32-bits of a register becomes easier.
12534 ;;
12535 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12536 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12537 ;; negdf respectively, so they can never be disabled entirely.
12538
12539 (define_insn "*btsq"
12540   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12541                          (const_int 1)
12542                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12543         (const_int 1))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12546   "bts{q} %1,%0"
12547   [(set_attr "type" "alu1")])
12548
12549 (define_insn "*btrq"
12550   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12551                          (const_int 1)
12552                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12553         (const_int 0))
12554    (clobber (reg:CC FLAGS_REG))]
12555   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12556   "btr{q} %1,%0"
12557   [(set_attr "type" "alu1")])
12558
12559 (define_insn "*btcq"
12560   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12561                          (const_int 1)
12562                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12563         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12566   "btc{q} %1,%0"
12567   [(set_attr "type" "alu1")])
12568
12569 ;; Allow Nocona to avoid these instructions if a register is available.
12570
12571 (define_peephole2
12572   [(match_scratch:DI 2 "r")
12573    (parallel [(set (zero_extract:DI
12574                      (match_operand:DI 0 "register_operand" "")
12575                      (const_int 1)
12576                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12577                    (const_int 1))
12578               (clobber (reg:CC FLAGS_REG))])]
12579   "TARGET_64BIT && !TARGET_USE_BT"
12580   [(const_int 0)]
12581 {
12582   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12583   rtx op1;
12584
12585   if (HOST_BITS_PER_WIDE_INT >= 64)
12586     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12587   else if (i < HOST_BITS_PER_WIDE_INT)
12588     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12589   else
12590     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12591
12592   op1 = immed_double_const (lo, hi, DImode);
12593   if (i >= 31)
12594     {
12595       emit_move_insn (operands[2], op1);
12596       op1 = operands[2];
12597     }
12598
12599   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12600   DONE;
12601 })
12602
12603 (define_peephole2
12604   [(match_scratch:DI 2 "r")
12605    (parallel [(set (zero_extract:DI
12606                      (match_operand:DI 0 "register_operand" "")
12607                      (const_int 1)
12608                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12609                    (const_int 0))
12610               (clobber (reg:CC FLAGS_REG))])]
12611   "TARGET_64BIT && !TARGET_USE_BT"
12612   [(const_int 0)]
12613 {
12614   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615   rtx op1;
12616
12617   if (HOST_BITS_PER_WIDE_INT >= 64)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else if (i < HOST_BITS_PER_WIDE_INT)
12620     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621   else
12622     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12623
12624   op1 = immed_double_const (~lo, ~hi, DImode);
12625   if (i >= 32)
12626     {
12627       emit_move_insn (operands[2], op1);
12628       op1 = operands[2];
12629     }
12630
12631   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12632   DONE;
12633 })
12634
12635 (define_peephole2
12636   [(match_scratch:DI 2 "r")
12637    (parallel [(set (zero_extract:DI
12638                      (match_operand:DI 0 "register_operand" "")
12639                      (const_int 1)
12640                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12641               (not:DI (zero_extract:DI
12642                         (match_dup 0) (const_int 1) (match_dup 1))))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12646 {
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12649
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656
12657   op1 = immed_double_const (lo, hi, DImode);
12658   if (i >= 31)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12663
12664   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12665   DONE;
12666 })
12667 \f
12668 ;; Store-flag instructions.
12669
12670 ;; For all sCOND expanders, also expand the compare or test insn that
12671 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12672
12673 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12674 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12675 ;; way, which can later delete the movzx if only QImode is needed.
12676
12677 (define_expand "seq"
12678   [(set (match_operand:QI 0 "register_operand" "")
12679         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12680   ""
12681   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12682
12683 (define_expand "sne"
12684   [(set (match_operand:QI 0 "register_operand" "")
12685         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12686   ""
12687   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12688
12689 (define_expand "sgt"
12690   [(set (match_operand:QI 0 "register_operand" "")
12691         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12692   ""
12693   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12694
12695 (define_expand "sgtu"
12696   [(set (match_operand:QI 0 "register_operand" "")
12697         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12698   ""
12699   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12700
12701 (define_expand "slt"
12702   [(set (match_operand:QI 0 "register_operand" "")
12703         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12704   ""
12705   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12706
12707 (define_expand "sltu"
12708   [(set (match_operand:QI 0 "register_operand" "")
12709         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12710   ""
12711   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12712
12713 (define_expand "sge"
12714   [(set (match_operand:QI 0 "register_operand" "")
12715         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12716   ""
12717   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12718
12719 (define_expand "sgeu"
12720   [(set (match_operand:QI 0 "register_operand" "")
12721         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12722   ""
12723   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12724
12725 (define_expand "sle"
12726   [(set (match_operand:QI 0 "register_operand" "")
12727         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12728   ""
12729   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12730
12731 (define_expand "sleu"
12732   [(set (match_operand:QI 0 "register_operand" "")
12733         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12734   ""
12735   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12736
12737 (define_expand "sunordered"
12738   [(set (match_operand:QI 0 "register_operand" "")
12739         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12740   "TARGET_80387 || TARGET_SSE"
12741   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12742
12743 (define_expand "sordered"
12744   [(set (match_operand:QI 0 "register_operand" "")
12745         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12746   "TARGET_80387"
12747   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12748
12749 (define_expand "suneq"
12750   [(set (match_operand:QI 0 "register_operand" "")
12751         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12752   "TARGET_80387 || TARGET_SSE"
12753   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12754
12755 (define_expand "sunge"
12756   [(set (match_operand:QI 0 "register_operand" "")
12757         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12758   "TARGET_80387 || TARGET_SSE"
12759   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12760
12761 (define_expand "sungt"
12762   [(set (match_operand:QI 0 "register_operand" "")
12763         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12764   "TARGET_80387 || TARGET_SSE"
12765   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12766
12767 (define_expand "sunle"
12768   [(set (match_operand:QI 0 "register_operand" "")
12769         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12770   "TARGET_80387 || TARGET_SSE"
12771   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12772
12773 (define_expand "sunlt"
12774   [(set (match_operand:QI 0 "register_operand" "")
12775         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12776   "TARGET_80387 || TARGET_SSE"
12777   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12778
12779 (define_expand "sltgt"
12780   [(set (match_operand:QI 0 "register_operand" "")
12781         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12782   "TARGET_80387 || TARGET_SSE"
12783   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12784
12785 (define_insn "*setcc_1"
12786   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12787         (match_operator:QI 1 "ix86_comparison_operator"
12788           [(reg FLAGS_REG) (const_int 0)]))]
12789   ""
12790   "set%C1\t%0"
12791   [(set_attr "type" "setcc")
12792    (set_attr "mode" "QI")])
12793
12794 (define_insn "*setcc_2"
12795   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12796         (match_operator:QI 1 "ix86_comparison_operator"
12797           [(reg FLAGS_REG) (const_int 0)]))]
12798   ""
12799   "set%C1\t%0"
12800   [(set_attr "type" "setcc")
12801    (set_attr "mode" "QI")])
12802
12803 ;; In general it is not safe to assume too much about CCmode registers,
12804 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12805 ;; conditions this is safe on x86, so help combine not create
12806 ;;
12807 ;;      seta    %al
12808 ;;      testb   %al, %al
12809 ;;      sete    %al
12810
12811 (define_split 
12812   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12813         (ne:QI (match_operator 1 "ix86_comparison_operator"
12814                  [(reg FLAGS_REG) (const_int 0)])
12815             (const_int 0)))]
12816   ""
12817   [(set (match_dup 0) (match_dup 1))]
12818 {
12819   PUT_MODE (operands[1], QImode);
12820 })
12821
12822 (define_split 
12823   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12824         (ne:QI (match_operator 1 "ix86_comparison_operator"
12825                  [(reg FLAGS_REG) (const_int 0)])
12826             (const_int 0)))]
12827   ""
12828   [(set (match_dup 0) (match_dup 1))]
12829 {
12830   PUT_MODE (operands[1], QImode);
12831 })
12832
12833 (define_split 
12834   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12835         (eq:QI (match_operator 1 "ix86_comparison_operator"
12836                  [(reg FLAGS_REG) (const_int 0)])
12837             (const_int 0)))]
12838   ""
12839   [(set (match_dup 0) (match_dup 1))]
12840 {
12841   rtx new_op1 = copy_rtx (operands[1]);
12842   operands[1] = new_op1;
12843   PUT_MODE (new_op1, QImode);
12844   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12845                                              GET_MODE (XEXP (new_op1, 0))));
12846
12847   /* Make sure that (a) the CCmode we have for the flags is strong
12848      enough for the reversed compare or (b) we have a valid FP compare.  */
12849   if (! ix86_comparison_operator (new_op1, VOIDmode))
12850     FAIL;
12851 })
12852
12853 (define_split 
12854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12855         (eq:QI (match_operator 1 "ix86_comparison_operator"
12856                  [(reg FLAGS_REG) (const_int 0)])
12857             (const_int 0)))]
12858   ""
12859   [(set (match_dup 0) (match_dup 1))]
12860 {
12861   rtx new_op1 = copy_rtx (operands[1]);
12862   operands[1] = new_op1;
12863   PUT_MODE (new_op1, QImode);
12864   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12865                                              GET_MODE (XEXP (new_op1, 0))));
12866
12867   /* Make sure that (a) the CCmode we have for the flags is strong
12868      enough for the reversed compare or (b) we have a valid FP compare.  */
12869   if (! ix86_comparison_operator (new_op1, VOIDmode))
12870     FAIL;
12871 })
12872
12873 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12874 ;; subsequent logical operations are used to imitate conditional moves.
12875 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12876 ;; it directly.
12877
12878 (define_insn "*sse_setccsf"
12879   [(set (match_operand:SF 0 "register_operand" "=x")
12880         (match_operator:SF 1 "sse_comparison_operator"
12881           [(match_operand:SF 2 "register_operand" "0")
12882            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12883   "TARGET_SSE"
12884   "cmp%D1ss\t{%3, %0|%0, %3}"
12885   [(set_attr "type" "ssecmp")
12886    (set_attr "mode" "SF")])
12887
12888 (define_insn "*sse_setccdf"
12889   [(set (match_operand:DF 0 "register_operand" "=Y")
12890         (match_operator:DF 1 "sse_comparison_operator"
12891           [(match_operand:DF 2 "register_operand" "0")
12892            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12893   "TARGET_SSE2"
12894   "cmp%D1sd\t{%3, %0|%0, %3}"
12895   [(set_attr "type" "ssecmp")
12896    (set_attr "mode" "DF")])
12897 \f
12898 ;; Basic conditional jump instructions.
12899 ;; We ignore the overflow flag for signed branch instructions.
12900
12901 ;; For all bCOND expanders, also expand the compare or test insn that
12902 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12903
12904 (define_expand "beq"
12905   [(set (pc)
12906         (if_then_else (match_dup 1)
12907                       (label_ref (match_operand 0 "" ""))
12908                       (pc)))]
12909   ""
12910   "ix86_expand_branch (EQ, operands[0]); DONE;")
12911
12912 (define_expand "bne"
12913   [(set (pc)
12914         (if_then_else (match_dup 1)
12915                       (label_ref (match_operand 0 "" ""))
12916                       (pc)))]
12917   ""
12918   "ix86_expand_branch (NE, operands[0]); DONE;")
12919
12920 (define_expand "bgt"
12921   [(set (pc)
12922         (if_then_else (match_dup 1)
12923                       (label_ref (match_operand 0 "" ""))
12924                       (pc)))]
12925   ""
12926   "ix86_expand_branch (GT, operands[0]); DONE;")
12927
12928 (define_expand "bgtu"
12929   [(set (pc)
12930         (if_then_else (match_dup 1)
12931                       (label_ref (match_operand 0 "" ""))
12932                       (pc)))]
12933   ""
12934   "ix86_expand_branch (GTU, operands[0]); DONE;")
12935
12936 (define_expand "blt"
12937   [(set (pc)
12938         (if_then_else (match_dup 1)
12939                       (label_ref (match_operand 0 "" ""))
12940                       (pc)))]
12941   ""
12942   "ix86_expand_branch (LT, operands[0]); DONE;")
12943
12944 (define_expand "bltu"
12945   [(set (pc)
12946         (if_then_else (match_dup 1)
12947                       (label_ref (match_operand 0 "" ""))
12948                       (pc)))]
12949   ""
12950   "ix86_expand_branch (LTU, operands[0]); DONE;")
12951
12952 (define_expand "bge"
12953   [(set (pc)
12954         (if_then_else (match_dup 1)
12955                       (label_ref (match_operand 0 "" ""))
12956                       (pc)))]
12957   ""
12958   "ix86_expand_branch (GE, operands[0]); DONE;")
12959
12960 (define_expand "bgeu"
12961   [(set (pc)
12962         (if_then_else (match_dup 1)
12963                       (label_ref (match_operand 0 "" ""))
12964                       (pc)))]
12965   ""
12966   "ix86_expand_branch (GEU, operands[0]); DONE;")
12967
12968 (define_expand "ble"
12969   [(set (pc)
12970         (if_then_else (match_dup 1)
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "ix86_expand_branch (LE, operands[0]); DONE;")
12975
12976 (define_expand "bleu"
12977   [(set (pc)
12978         (if_then_else (match_dup 1)
12979                       (label_ref (match_operand 0 "" ""))
12980                       (pc)))]
12981   ""
12982   "ix86_expand_branch (LEU, operands[0]); DONE;")
12983
12984 (define_expand "bunordered"
12985   [(set (pc)
12986         (if_then_else (match_dup 1)
12987                       (label_ref (match_operand 0 "" ""))
12988                       (pc)))]
12989   "TARGET_80387 || TARGET_SSE_MATH"
12990   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12991
12992 (define_expand "bordered"
12993   [(set (pc)
12994         (if_then_else (match_dup 1)
12995                       (label_ref (match_operand 0 "" ""))
12996                       (pc)))]
12997   "TARGET_80387 || TARGET_SSE_MATH"
12998   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12999
13000 (define_expand "buneq"
13001   [(set (pc)
13002         (if_then_else (match_dup 1)
13003                       (label_ref (match_operand 0 "" ""))
13004                       (pc)))]
13005   "TARGET_80387 || TARGET_SSE_MATH"
13006   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13007
13008 (define_expand "bunge"
13009   [(set (pc)
13010         (if_then_else (match_dup 1)
13011                       (label_ref (match_operand 0 "" ""))
13012                       (pc)))]
13013   "TARGET_80387 || TARGET_SSE_MATH"
13014   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13015
13016 (define_expand "bungt"
13017   [(set (pc)
13018         (if_then_else (match_dup 1)
13019                       (label_ref (match_operand 0 "" ""))
13020                       (pc)))]
13021   "TARGET_80387 || TARGET_SSE_MATH"
13022   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13023
13024 (define_expand "bunle"
13025   [(set (pc)
13026         (if_then_else (match_dup 1)
13027                       (label_ref (match_operand 0 "" ""))
13028                       (pc)))]
13029   "TARGET_80387 || TARGET_SSE_MATH"
13030   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13031
13032 (define_expand "bunlt"
13033   [(set (pc)
13034         (if_then_else (match_dup 1)
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   "TARGET_80387 || TARGET_SSE_MATH"
13038   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13039
13040 (define_expand "bltgt"
13041   [(set (pc)
13042         (if_then_else (match_dup 1)
13043                       (label_ref (match_operand 0 "" ""))
13044                       (pc)))]
13045   "TARGET_80387 || TARGET_SSE_MATH"
13046   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13047
13048 (define_insn "*jcc_1"
13049   [(set (pc)
13050         (if_then_else (match_operator 1 "ix86_comparison_operator"
13051                                       [(reg FLAGS_REG) (const_int 0)])
13052                       (label_ref (match_operand 0 "" ""))
13053                       (pc)))]
13054   ""
13055   "%+j%C1\t%l0"
13056   [(set_attr "type" "ibr")
13057    (set_attr "modrm" "0")
13058    (set (attr "length")
13059            (if_then_else (and (ge (minus (match_dup 0) (pc))
13060                                   (const_int -126))
13061                               (lt (minus (match_dup 0) (pc))
13062                                   (const_int 128)))
13063              (const_int 2)
13064              (const_int 6)))])
13065
13066 (define_insn "*jcc_2"
13067   [(set (pc)
13068         (if_then_else (match_operator 1 "ix86_comparison_operator"
13069                                       [(reg FLAGS_REG) (const_int 0)])
13070                       (pc)
13071                       (label_ref (match_operand 0 "" ""))))]
13072   ""
13073   "%+j%c1\t%l0"
13074   [(set_attr "type" "ibr")
13075    (set_attr "modrm" "0")
13076    (set (attr "length")
13077            (if_then_else (and (ge (minus (match_dup 0) (pc))
13078                                   (const_int -126))
13079                               (lt (minus (match_dup 0) (pc))
13080                                   (const_int 128)))
13081              (const_int 2)
13082              (const_int 6)))])
13083
13084 ;; In general it is not safe to assume too much about CCmode registers,
13085 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13086 ;; conditions this is safe on x86, so help combine not create
13087 ;;
13088 ;;      seta    %al
13089 ;;      testb   %al, %al
13090 ;;      je      Lfoo
13091
13092 (define_split 
13093   [(set (pc)
13094         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13095                                       [(reg FLAGS_REG) (const_int 0)])
13096                           (const_int 0))
13097                       (label_ref (match_operand 1 "" ""))
13098                       (pc)))]
13099   ""
13100   [(set (pc)
13101         (if_then_else (match_dup 0)
13102                       (label_ref (match_dup 1))
13103                       (pc)))]
13104 {
13105   PUT_MODE (operands[0], VOIDmode);
13106 })
13107   
13108 (define_split 
13109   [(set (pc)
13110         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13111                                       [(reg FLAGS_REG) (const_int 0)])
13112                           (const_int 0))
13113                       (label_ref (match_operand 1 "" ""))
13114                       (pc)))]
13115   ""
13116   [(set (pc)
13117         (if_then_else (match_dup 0)
13118                       (label_ref (match_dup 1))
13119                       (pc)))]
13120 {
13121   rtx new_op0 = copy_rtx (operands[0]);
13122   operands[0] = new_op0;
13123   PUT_MODE (new_op0, VOIDmode);
13124   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13125                                              GET_MODE (XEXP (new_op0, 0))));
13126
13127   /* Make sure that (a) the CCmode we have for the flags is strong
13128      enough for the reversed compare or (b) we have a valid FP compare.  */
13129   if (! ix86_comparison_operator (new_op0, VOIDmode))
13130     FAIL;
13131 })
13132
13133 ;; Define combination compare-and-branch fp compare instructions to use
13134 ;; during early optimization.  Splitting the operation apart early makes
13135 ;; for bad code when we want to reverse the operation.
13136
13137 (define_insn "*fp_jcc_1_mixed"
13138   [(set (pc)
13139         (if_then_else (match_operator 0 "comparison_operator"
13140                         [(match_operand 1 "register_operand" "f#x,x#f")
13141                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13142           (label_ref (match_operand 3 "" ""))
13143           (pc)))
13144    (clobber (reg:CCFP FPSR_REG))
13145    (clobber (reg:CCFP FLAGS_REG))]
13146   "TARGET_MIX_SSE_I387
13147    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13148    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13149    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150   "#")
13151
13152 (define_insn "*fp_jcc_1_sse"
13153   [(set (pc)
13154         (if_then_else (match_operator 0 "comparison_operator"
13155                         [(match_operand 1 "register_operand" "x")
13156                          (match_operand 2 "nonimmediate_operand" "xm")])
13157           (label_ref (match_operand 3 "" ""))
13158           (pc)))
13159    (clobber (reg:CCFP FPSR_REG))
13160    (clobber (reg:CCFP FLAGS_REG))]
13161   "TARGET_SSE_MATH
13162    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13163    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13164    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13165   "#")
13166
13167 (define_insn "*fp_jcc_1_387"
13168   [(set (pc)
13169         (if_then_else (match_operator 0 "comparison_operator"
13170                         [(match_operand 1 "register_operand" "f")
13171                          (match_operand 2 "register_operand" "f")])
13172           (label_ref (match_operand 3 "" ""))
13173           (pc)))
13174    (clobber (reg:CCFP FPSR_REG))
13175    (clobber (reg:CCFP FLAGS_REG))]
13176   "TARGET_CMOVE && TARGET_80387
13177    && FLOAT_MODE_P (GET_MODE (operands[1]))
13178    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13179    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13180   "#")
13181
13182 (define_insn "*fp_jcc_2_mixed"
13183   [(set (pc)
13184         (if_then_else (match_operator 0 "comparison_operator"
13185                         [(match_operand 1 "register_operand" "f#x,x#f")
13186                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13187           (pc)
13188           (label_ref (match_operand 3 "" ""))))
13189    (clobber (reg:CCFP FPSR_REG))
13190    (clobber (reg:CCFP FLAGS_REG))]
13191   "TARGET_MIX_SSE_I387
13192    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13193    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13194    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195   "#")
13196
13197 (define_insn "*fp_jcc_2_sse"
13198   [(set (pc)
13199         (if_then_else (match_operator 0 "comparison_operator"
13200                         [(match_operand 1 "register_operand" "x")
13201                          (match_operand 2 "nonimmediate_operand" "xm")])
13202           (pc)
13203           (label_ref (match_operand 3 "" ""))))
13204    (clobber (reg:CCFP FPSR_REG))
13205    (clobber (reg:CCFP FLAGS_REG))]
13206   "TARGET_SSE_MATH
13207    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13208    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13209    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13210   "#")
13211
13212 (define_insn "*fp_jcc_2_387"
13213   [(set (pc)
13214         (if_then_else (match_operator 0 "comparison_operator"
13215                         [(match_operand 1 "register_operand" "f")
13216                          (match_operand 2 "register_operand" "f")])
13217           (pc)
13218           (label_ref (match_operand 3 "" ""))))
13219    (clobber (reg:CCFP FPSR_REG))
13220    (clobber (reg:CCFP FLAGS_REG))]
13221   "TARGET_CMOVE && TARGET_80387
13222    && FLOAT_MODE_P (GET_MODE (operands[1]))
13223    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225   "#")
13226
13227 (define_insn "*fp_jcc_3_387"
13228   [(set (pc)
13229         (if_then_else (match_operator 0 "comparison_operator"
13230                         [(match_operand 1 "register_operand" "f")
13231                          (match_operand 2 "nonimmediate_operand" "fm")])
13232           (label_ref (match_operand 3 "" ""))
13233           (pc)))
13234    (clobber (reg:CCFP FPSR_REG))
13235    (clobber (reg:CCFP FLAGS_REG))
13236    (clobber (match_scratch:HI 4 "=a"))]
13237   "TARGET_80387
13238    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13239    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13240    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13241    && SELECT_CC_MODE (GET_CODE (operands[0]),
13242                       operands[1], operands[2]) == CCFPmode
13243    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13244   "#")
13245
13246 (define_insn "*fp_jcc_4_387"
13247   [(set (pc)
13248         (if_then_else (match_operator 0 "comparison_operator"
13249                         [(match_operand 1 "register_operand" "f")
13250                          (match_operand 2 "nonimmediate_operand" "fm")])
13251           (pc)
13252           (label_ref (match_operand 3 "" ""))))
13253    (clobber (reg:CCFP FPSR_REG))
13254    (clobber (reg:CCFP FLAGS_REG))
13255    (clobber (match_scratch:HI 4 "=a"))]
13256   "TARGET_80387
13257    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13258    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13259    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13260    && SELECT_CC_MODE (GET_CODE (operands[0]),
13261                       operands[1], operands[2]) == CCFPmode
13262    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13263   "#")
13264
13265 (define_insn "*fp_jcc_5_387"
13266   [(set (pc)
13267         (if_then_else (match_operator 0 "comparison_operator"
13268                         [(match_operand 1 "register_operand" "f")
13269                          (match_operand 2 "register_operand" "f")])
13270           (label_ref (match_operand 3 "" ""))
13271           (pc)))
13272    (clobber (reg:CCFP FPSR_REG))
13273    (clobber (reg:CCFP FLAGS_REG))
13274    (clobber (match_scratch:HI 4 "=a"))]
13275   "TARGET_80387
13276    && FLOAT_MODE_P (GET_MODE (operands[1]))
13277    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13278    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279   "#")
13280
13281 (define_insn "*fp_jcc_6_387"
13282   [(set (pc)
13283         (if_then_else (match_operator 0 "comparison_operator"
13284                         [(match_operand 1 "register_operand" "f")
13285                          (match_operand 2 "register_operand" "f")])
13286           (pc)
13287           (label_ref (match_operand 3 "" ""))))
13288    (clobber (reg:CCFP FPSR_REG))
13289    (clobber (reg:CCFP FLAGS_REG))
13290    (clobber (match_scratch:HI 4 "=a"))]
13291   "TARGET_80387
13292    && FLOAT_MODE_P (GET_MODE (operands[1]))
13293    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13294    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295   "#")
13296
13297 (define_insn "*fp_jcc_7_387"
13298   [(set (pc)
13299         (if_then_else (match_operator 0 "comparison_operator"
13300                         [(match_operand 1 "register_operand" "f")
13301                          (match_operand 2 "const0_operand" "X")])
13302           (label_ref (match_operand 3 "" ""))
13303           (pc)))
13304    (clobber (reg:CCFP FPSR_REG))
13305    (clobber (reg:CCFP FLAGS_REG))
13306    (clobber (match_scratch:HI 4 "=a"))]
13307   "TARGET_80387
13308    && FLOAT_MODE_P (GET_MODE (operands[1]))
13309    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13310    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13311    && SELECT_CC_MODE (GET_CODE (operands[0]),
13312                       operands[1], operands[2]) == CCFPmode
13313    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13314   "#")
13315
13316 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13317 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13318 ;; with a precedence over other operators and is always put in the first
13319 ;; place. Swap condition and operands to match ficom instruction.
13320
13321 (define_insn "*fp_jcc_8<mode>_387"
13322   [(set (pc)
13323         (if_then_else (match_operator 0 "comparison_operator"
13324                         [(match_operator 1 "float_operator"
13325                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13326                            (match_operand 3 "register_operand" "f,f")])
13327           (label_ref (match_operand 4 "" ""))
13328           (pc)))
13329    (clobber (reg:CCFP FPSR_REG))
13330    (clobber (reg:CCFP FLAGS_REG))
13331    (clobber (match_scratch:HI 5 "=a,a"))]
13332   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13333    && FLOAT_MODE_P (GET_MODE (operands[3]))
13334    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13335    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13336    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13337    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13338   "#")
13339
13340 (define_split
13341   [(set (pc)
13342         (if_then_else (match_operator 0 "comparison_operator"
13343                         [(match_operand 1 "register_operand" "")
13344                          (match_operand 2 "nonimmediate_operand" "")])
13345           (match_operand 3 "" "")
13346           (match_operand 4 "" "")))
13347    (clobber (reg:CCFP FPSR_REG))
13348    (clobber (reg:CCFP FLAGS_REG))]
13349   "reload_completed"
13350   [(const_int 0)]
13351 {
13352   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13353                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13354   DONE;
13355 })
13356
13357 (define_split
13358   [(set (pc)
13359         (if_then_else (match_operator 0 "comparison_operator"
13360                         [(match_operand 1 "register_operand" "")
13361                          (match_operand 2 "general_operand" "")])
13362           (match_operand 3 "" "")
13363           (match_operand 4 "" "")))
13364    (clobber (reg:CCFP FPSR_REG))
13365    (clobber (reg:CCFP FLAGS_REG))
13366    (clobber (match_scratch:HI 5 "=a"))]
13367   "reload_completed"
13368   [(const_int 0)]
13369 {
13370   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13371                         operands[3], operands[4], operands[5], NULL_RTX);
13372   DONE;
13373 })
13374
13375 (define_split
13376   [(set (pc)
13377         (if_then_else (match_operator 0 "comparison_operator"
13378                         [(match_operator 1 "float_operator"
13379                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13380                            (match_operand 3 "register_operand" "")])
13381           (match_operand 4 "" "")
13382           (match_operand 5 "" "")))
13383    (clobber (reg:CCFP FPSR_REG))
13384    (clobber (reg:CCFP FLAGS_REG))
13385    (clobber (match_scratch:HI 6 "=a"))]
13386   "reload_completed"
13387   [(const_int 0)]
13388 {
13389   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13390   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13391                         operands[3], operands[7],
13392                         operands[4], operands[5], operands[6], NULL_RTX);
13393   DONE;
13394 })
13395
13396 ;; %%% Kill this when reload knows how to do it.
13397 (define_split
13398   [(set (pc)
13399         (if_then_else (match_operator 0 "comparison_operator"
13400                         [(match_operator 1 "float_operator"
13401                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13402                            (match_operand 3 "register_operand" "")])
13403           (match_operand 4 "" "")
13404           (match_operand 5 "" "")))
13405    (clobber (reg:CCFP FPSR_REG))
13406    (clobber (reg:CCFP FLAGS_REG))
13407    (clobber (match_scratch:HI 6 "=a"))]
13408   "reload_completed"
13409   [(const_int 0)]
13410 {
13411   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13412   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13413   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13414                         operands[3], operands[7],
13415                         operands[4], operands[5], operands[6], operands[2]);
13416   DONE;
13417 })
13418 \f
13419 ;; Unconditional and other jump instructions
13420
13421 (define_insn "jump"
13422   [(set (pc)
13423         (label_ref (match_operand 0 "" "")))]
13424   ""
13425   "jmp\t%l0"
13426   [(set_attr "type" "ibr")
13427    (set (attr "length")
13428            (if_then_else (and (ge (minus (match_dup 0) (pc))
13429                                   (const_int -126))
13430                               (lt (minus (match_dup 0) (pc))
13431                                   (const_int 128)))
13432              (const_int 2)
13433              (const_int 5)))
13434    (set_attr "modrm" "0")])
13435
13436 (define_expand "indirect_jump"
13437   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13438   ""
13439   "")
13440
13441 (define_insn "*indirect_jump"
13442   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13443   "!TARGET_64BIT"
13444   "jmp\t%A0"
13445   [(set_attr "type" "ibr")
13446    (set_attr "length_immediate" "0")])
13447
13448 (define_insn "*indirect_jump_rtx64"
13449   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13450   "TARGET_64BIT"
13451   "jmp\t%A0"
13452   [(set_attr "type" "ibr")
13453    (set_attr "length_immediate" "0")])
13454
13455 (define_expand "tablejump"
13456   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13457               (use (label_ref (match_operand 1 "" "")))])]
13458   ""
13459 {
13460   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13461      relative.  Convert the relative address to an absolute address.  */
13462   if (flag_pic)
13463     {
13464       rtx op0, op1;
13465       enum rtx_code code;
13466
13467       if (TARGET_64BIT)
13468         {
13469           code = PLUS;
13470           op0 = operands[0];
13471           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13472         }
13473       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13474         {
13475           code = PLUS;
13476           op0 = operands[0];
13477           op1 = pic_offset_table_rtx;
13478         }
13479       else
13480         {
13481           code = MINUS;
13482           op0 = pic_offset_table_rtx;
13483           op1 = operands[0];
13484         }
13485
13486       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13487                                          OPTAB_DIRECT);
13488     }
13489 })
13490
13491 (define_insn "*tablejump_1"
13492   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13493    (use (label_ref (match_operand 1 "" "")))]
13494   "!TARGET_64BIT"
13495   "jmp\t%A0"
13496   [(set_attr "type" "ibr")
13497    (set_attr "length_immediate" "0")])
13498
13499 (define_insn "*tablejump_1_rtx64"
13500   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13501    (use (label_ref (match_operand 1 "" "")))]
13502   "TARGET_64BIT"
13503   "jmp\t%A0"
13504   [(set_attr "type" "ibr")
13505    (set_attr "length_immediate" "0")])
13506 \f
13507 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13508
13509 (define_peephole2
13510   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13511    (set (match_operand:QI 1 "register_operand" "")
13512         (match_operator:QI 2 "ix86_comparison_operator"
13513           [(reg FLAGS_REG) (const_int 0)]))
13514    (set (match_operand 3 "q_regs_operand" "")
13515         (zero_extend (match_dup 1)))]
13516   "(peep2_reg_dead_p (3, operands[1])
13517     || operands_match_p (operands[1], operands[3]))
13518    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13519   [(set (match_dup 4) (match_dup 0))
13520    (set (strict_low_part (match_dup 5))
13521         (match_dup 2))]
13522 {
13523   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13524   operands[5] = gen_lowpart (QImode, operands[3]);
13525   ix86_expand_clear (operands[3]);
13526 })
13527
13528 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13529
13530 (define_peephole2
13531   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13532    (set (match_operand:QI 1 "register_operand" "")
13533         (match_operator:QI 2 "ix86_comparison_operator"
13534           [(reg FLAGS_REG) (const_int 0)]))
13535    (parallel [(set (match_operand 3 "q_regs_operand" "")
13536                    (zero_extend (match_dup 1)))
13537               (clobber (reg:CC FLAGS_REG))])]
13538   "(peep2_reg_dead_p (3, operands[1])
13539     || operands_match_p (operands[1], operands[3]))
13540    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541   [(set (match_dup 4) (match_dup 0))
13542    (set (strict_low_part (match_dup 5))
13543         (match_dup 2))]
13544 {
13545   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13546   operands[5] = gen_lowpart (QImode, operands[3]);
13547   ix86_expand_clear (operands[3]);
13548 })
13549 \f
13550 ;; Call instructions.
13551
13552 ;; The predicates normally associated with named expanders are not properly
13553 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13554 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13555
13556 ;; Call subroutine returning no value.
13557
13558 (define_expand "call_pop"
13559   [(parallel [(call (match_operand:QI 0 "" "")
13560                     (match_operand:SI 1 "" ""))
13561               (set (reg:SI SP_REG)
13562                    (plus:SI (reg:SI SP_REG)
13563                             (match_operand:SI 3 "" "")))])]
13564   "!TARGET_64BIT"
13565 {
13566   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13567   DONE;
13568 })
13569
13570 (define_insn "*call_pop_0"
13571   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13572          (match_operand:SI 1 "" ""))
13573    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13574                             (match_operand:SI 2 "immediate_operand" "")))]
13575   "!TARGET_64BIT"
13576 {
13577   if (SIBLING_CALL_P (insn))
13578     return "jmp\t%P0";
13579   else
13580     return "call\t%P0";
13581 }
13582   [(set_attr "type" "call")])
13583   
13584 (define_insn "*call_pop_1"
13585   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13586          (match_operand:SI 1 "" ""))
13587    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13588                             (match_operand:SI 2 "immediate_operand" "i")))]
13589   "!TARGET_64BIT"
13590 {
13591   if (constant_call_address_operand (operands[0], Pmode))
13592     {
13593       if (SIBLING_CALL_P (insn))
13594         return "jmp\t%P0";
13595       else
13596         return "call\t%P0";
13597     }
13598   if (SIBLING_CALL_P (insn))
13599     return "jmp\t%A0";
13600   else
13601     return "call\t%A0";
13602 }
13603   [(set_attr "type" "call")])
13604
13605 (define_expand "call"
13606   [(call (match_operand:QI 0 "" "")
13607          (match_operand 1 "" ""))
13608    (use (match_operand 2 "" ""))]
13609   ""
13610 {
13611   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13612   DONE;
13613 })
13614
13615 (define_expand "sibcall"
13616   [(call (match_operand:QI 0 "" "")
13617          (match_operand 1 "" ""))
13618    (use (match_operand 2 "" ""))]
13619   ""
13620 {
13621   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13622   DONE;
13623 })
13624
13625 (define_insn "*call_0"
13626   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13627          (match_operand 1 "" ""))]
13628   ""
13629 {
13630   if (SIBLING_CALL_P (insn))
13631     return "jmp\t%P0";
13632   else
13633     return "call\t%P0";
13634 }
13635   [(set_attr "type" "call")])
13636
13637 (define_insn "*call_1"
13638   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13639          (match_operand 1 "" ""))]
13640   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13641 {
13642   if (constant_call_address_operand (operands[0], Pmode))
13643     return "call\t%P0";
13644   return "call\t%A0";
13645 }
13646   [(set_attr "type" "call")])
13647
13648 (define_insn "*sibcall_1"
13649   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13650          (match_operand 1 "" ""))]
13651   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13652 {
13653   if (constant_call_address_operand (operands[0], Pmode))
13654     return "jmp\t%P0";
13655   return "jmp\t%A0";
13656 }
13657   [(set_attr "type" "call")])
13658
13659 (define_insn "*call_1_rex64"
13660   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13661          (match_operand 1 "" ""))]
13662   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13663 {
13664   if (constant_call_address_operand (operands[0], Pmode))
13665     return "call\t%P0";
13666   return "call\t%A0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*sibcall_1_rex64"
13671   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13672          (match_operand 1 "" ""))]
13673   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13674   "jmp\t%P0"
13675   [(set_attr "type" "call")])
13676
13677 (define_insn "*sibcall_1_rex64_v"
13678   [(call (mem:QI (reg:DI 40))
13679          (match_operand 0 "" ""))]
13680   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13681   "jmp\t*%%r11"
13682   [(set_attr "type" "call")])
13683
13684
13685 ;; Call subroutine, returning value in operand 0
13686
13687 (define_expand "call_value_pop"
13688   [(parallel [(set (match_operand 0 "" "")
13689                    (call (match_operand:QI 1 "" "")
13690                          (match_operand:SI 2 "" "")))
13691               (set (reg:SI SP_REG)
13692                    (plus:SI (reg:SI SP_REG)
13693                             (match_operand:SI 4 "" "")))])]
13694   "!TARGET_64BIT"
13695 {
13696   ix86_expand_call (operands[0], operands[1], operands[2],
13697                     operands[3], operands[4], 0);
13698   DONE;
13699 })
13700
13701 (define_expand "call_value"
13702   [(set (match_operand 0 "" "")
13703         (call (match_operand:QI 1 "" "")
13704               (match_operand:SI 2 "" "")))
13705    (use (match_operand:SI 3 "" ""))]
13706   ;; Operand 2 not used on the i386.
13707   ""
13708 {
13709   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13710   DONE;
13711 })
13712
13713 (define_expand "sibcall_value"
13714   [(set (match_operand 0 "" "")
13715         (call (match_operand:QI 1 "" "")
13716               (match_operand:SI 2 "" "")))
13717    (use (match_operand:SI 3 "" ""))]
13718   ;; Operand 2 not used on the i386.
13719   ""
13720 {
13721   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13722   DONE;
13723 })
13724
13725 ;; Call subroutine returning any type.
13726
13727 (define_expand "untyped_call"
13728   [(parallel [(call (match_operand 0 "" "")
13729                     (const_int 0))
13730               (match_operand 1 "" "")
13731               (match_operand 2 "" "")])]
13732   ""
13733 {
13734   int i;
13735
13736   /* In order to give reg-stack an easier job in validating two
13737      coprocessor registers as containing a possible return value,
13738      simply pretend the untyped call returns a complex long double
13739      value.  */
13740
13741   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13742                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13743                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13744                     NULL, 0);
13745
13746   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13747     {
13748       rtx set = XVECEXP (operands[2], 0, i);
13749       emit_move_insn (SET_DEST (set), SET_SRC (set));
13750     }
13751
13752   /* The optimizer does not know that the call sets the function value
13753      registers we stored in the result block.  We avoid problems by
13754      claiming that all hard registers are used and clobbered at this
13755      point.  */
13756   emit_insn (gen_blockage (const0_rtx));
13757
13758   DONE;
13759 })
13760 \f
13761 ;; Prologue and epilogue instructions
13762
13763 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13764 ;; all of memory.  This blocks insns from being moved across this point.
13765
13766 (define_insn "blockage"
13767   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13768   ""
13769   ""
13770   [(set_attr "length" "0")])
13771
13772 ;; Insn emitted into the body of a function to return from a function.
13773 ;; This is only done if the function's epilogue is known to be simple.
13774 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13775
13776 (define_expand "return"
13777   [(return)]
13778   "ix86_can_use_return_insn_p ()"
13779 {
13780   if (current_function_pops_args)
13781     {
13782       rtx popc = GEN_INT (current_function_pops_args);
13783       emit_jump_insn (gen_return_pop_internal (popc));
13784       DONE;
13785     }
13786 })
13787
13788 (define_insn "return_internal"
13789   [(return)]
13790   "reload_completed"
13791   "ret"
13792   [(set_attr "length" "1")
13793    (set_attr "length_immediate" "0")
13794    (set_attr "modrm" "0")])
13795
13796 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13797 ;; instruction Athlon and K8 have.
13798
13799 (define_insn "return_internal_long"
13800   [(return)
13801    (unspec [(const_int 0)] UNSPEC_REP)]
13802   "reload_completed"
13803   "rep {;} ret"
13804   [(set_attr "length" "1")
13805    (set_attr "length_immediate" "0")
13806    (set_attr "prefix_rep" "1")
13807    (set_attr "modrm" "0")])
13808
13809 (define_insn "return_pop_internal"
13810   [(return)
13811    (use (match_operand:SI 0 "const_int_operand" ""))]
13812   "reload_completed"
13813   "ret\t%0"
13814   [(set_attr "length" "3")
13815    (set_attr "length_immediate" "2")
13816    (set_attr "modrm" "0")])
13817
13818 (define_insn "return_indirect_internal"
13819   [(return)
13820    (use (match_operand:SI 0 "register_operand" "r"))]
13821   "reload_completed"
13822   "jmp\t%A0"
13823   [(set_attr "type" "ibr")
13824    (set_attr "length_immediate" "0")])
13825
13826 (define_insn "nop"
13827   [(const_int 0)]
13828   ""
13829   "nop"
13830   [(set_attr "length" "1")
13831    (set_attr "length_immediate" "0")
13832    (set_attr "modrm" "0")])
13833
13834 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13835 ;; branch prediction penalty for the third jump in a 16-byte
13836 ;; block on K8.
13837
13838 (define_insn "align"
13839   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13840   ""
13841 {
13842 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13843   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13844 #else
13845   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13846      The align insn is used to avoid 3 jump instructions in the row to improve
13847      branch prediction and the benefits hardly outweight the cost of extra 8
13848      nops on the average inserted by full alignment pseudo operation.  */
13849 #endif
13850   return "";
13851 }
13852   [(set_attr "length" "16")])
13853
13854 (define_expand "prologue"
13855   [(const_int 1)]
13856   ""
13857   "ix86_expand_prologue (); DONE;")
13858
13859 (define_insn "set_got"
13860   [(set (match_operand:SI 0 "register_operand" "=r")
13861         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13862    (clobber (reg:CC FLAGS_REG))]
13863   "!TARGET_64BIT"
13864   { return output_set_got (operands[0], NULL_RTX); }
13865   [(set_attr "type" "multi")
13866    (set_attr "length" "12")])
13867
13868 (define_insn "set_got_labelled"
13869   [(set (match_operand:SI 0 "register_operand" "=r")
13870         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13871          UNSPEC_SET_GOT))
13872    (clobber (reg:CC FLAGS_REG))]
13873   "!TARGET_64BIT"
13874   { return output_set_got (operands[0], operands[1]); }
13875   [(set_attr "type" "multi")
13876    (set_attr "length" "12")])
13877
13878 (define_insn "set_got_rex64"
13879   [(set (match_operand:DI 0 "register_operand" "=r")
13880         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13881   "TARGET_64BIT"
13882   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13883   [(set_attr "type" "lea")
13884    (set_attr "length" "6")])
13885
13886 (define_expand "epilogue"
13887   [(const_int 1)]
13888   ""
13889   "ix86_expand_epilogue (1); DONE;")
13890
13891 (define_expand "sibcall_epilogue"
13892   [(const_int 1)]
13893   ""
13894   "ix86_expand_epilogue (0); DONE;")
13895
13896 (define_expand "eh_return"
13897   [(use (match_operand 0 "register_operand" ""))]
13898   ""
13899 {
13900   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13901
13902   /* Tricky bit: we write the address of the handler to which we will
13903      be returning into someone else's stack frame, one word below the
13904      stack address we wish to restore.  */
13905   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13906   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13907   tmp = gen_rtx_MEM (Pmode, tmp);
13908   emit_move_insn (tmp, ra);
13909
13910   if (Pmode == SImode)
13911     emit_jump_insn (gen_eh_return_si (sa));
13912   else
13913     emit_jump_insn (gen_eh_return_di (sa));
13914   emit_barrier ();
13915   DONE;
13916 })
13917
13918 (define_insn_and_split "eh_return_si"
13919   [(set (pc) 
13920         (unspec [(match_operand:SI 0 "register_operand" "c")]
13921                  UNSPEC_EH_RETURN))]
13922   "!TARGET_64BIT"
13923   "#"
13924   "reload_completed"
13925   [(const_int 1)]
13926   "ix86_expand_epilogue (2); DONE;")
13927
13928 (define_insn_and_split "eh_return_di"
13929   [(set (pc) 
13930         (unspec [(match_operand:DI 0 "register_operand" "c")]
13931                  UNSPEC_EH_RETURN))]
13932   "TARGET_64BIT"
13933   "#"
13934   "reload_completed"
13935   [(const_int 1)]
13936   "ix86_expand_epilogue (2); DONE;")
13937
13938 (define_insn "leave"
13939   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13940    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13941    (clobber (mem:BLK (scratch)))]
13942   "!TARGET_64BIT"
13943   "leave"
13944   [(set_attr "type" "leave")])
13945
13946 (define_insn "leave_rex64"
13947   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13948    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13949    (clobber (mem:BLK (scratch)))]
13950   "TARGET_64BIT"
13951   "leave"
13952   [(set_attr "type" "leave")])
13953 \f
13954 (define_expand "ffssi2"
13955   [(parallel
13956      [(set (match_operand:SI 0 "register_operand" "") 
13957            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13958       (clobber (match_scratch:SI 2 ""))
13959       (clobber (reg:CC FLAGS_REG))])]
13960   ""
13961   "")
13962
13963 (define_insn_and_split "*ffs_cmove"
13964   [(set (match_operand:SI 0 "register_operand" "=r") 
13965         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13966    (clobber (match_scratch:SI 2 "=&r"))
13967    (clobber (reg:CC FLAGS_REG))]
13968   "TARGET_CMOVE"
13969   "#"
13970   "&& reload_completed"
13971   [(set (match_dup 2) (const_int -1))
13972    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13973               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13974    (set (match_dup 0) (if_then_else:SI
13975                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13976                         (match_dup 2)
13977                         (match_dup 0)))
13978    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13979               (clobber (reg:CC FLAGS_REG))])]
13980   "")
13981
13982 (define_insn_and_split "*ffs_no_cmove"
13983   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13984         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13985    (clobber (match_scratch:SI 2 "=&q"))
13986    (clobber (reg:CC FLAGS_REG))]
13987   ""
13988   "#"
13989   "reload_completed"
13990   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13991               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13992    (set (strict_low_part (match_dup 3))
13993         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13994    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13995               (clobber (reg:CC FLAGS_REG))])
13996    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13997               (clobber (reg:CC FLAGS_REG))])
13998    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13999               (clobber (reg:CC FLAGS_REG))])]
14000 {
14001   operands[3] = gen_lowpart (QImode, operands[2]);
14002   ix86_expand_clear (operands[2]);
14003 })
14004
14005 (define_insn "*ffssi_1"
14006   [(set (reg:CCZ FLAGS_REG)
14007         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14008                      (const_int 0)))
14009    (set (match_operand:SI 0 "register_operand" "=r")
14010         (ctz:SI (match_dup 1)))]
14011   ""
14012   "bsf{l}\t{%1, %0|%0, %1}"
14013   [(set_attr "prefix_0f" "1")])
14014
14015 (define_expand "ffsdi2"
14016   [(parallel
14017      [(set (match_operand:DI 0 "register_operand" "") 
14018            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14019       (clobber (match_scratch:DI 2 ""))
14020       (clobber (reg:CC FLAGS_REG))])]
14021   "TARGET_64BIT && TARGET_CMOVE"
14022   "")
14023
14024 (define_insn_and_split "*ffs_rex64"
14025   [(set (match_operand:DI 0 "register_operand" "=r") 
14026         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14027    (clobber (match_scratch:DI 2 "=&r"))
14028    (clobber (reg:CC FLAGS_REG))]
14029   "TARGET_64BIT && TARGET_CMOVE"
14030   "#"
14031   "&& reload_completed"
14032   [(set (match_dup 2) (const_int -1))
14033    (parallel [(set (reg:CCZ FLAGS_REG)
14034                    (compare:CCZ (match_dup 1) (const_int 0)))
14035               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14036    (set (match_dup 0) (if_then_else:DI
14037                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14038                         (match_dup 2)
14039                         (match_dup 0)))
14040    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14041               (clobber (reg:CC FLAGS_REG))])]
14042   "")
14043
14044 (define_insn "*ffsdi_1"
14045   [(set (reg:CCZ FLAGS_REG)
14046         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14047                      (const_int 0)))
14048    (set (match_operand:DI 0 "register_operand" "=r")
14049         (ctz:DI (match_dup 1)))]
14050   "TARGET_64BIT"
14051   "bsf{q}\t{%1, %0|%0, %1}"
14052   [(set_attr "prefix_0f" "1")])
14053
14054 (define_insn "ctzsi2"
14055   [(set (match_operand:SI 0 "register_operand" "=r")
14056         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14057    (clobber (reg:CC FLAGS_REG))]
14058   ""
14059   "bsf{l}\t{%1, %0|%0, %1}"
14060   [(set_attr "prefix_0f" "1")])
14061
14062 (define_insn "ctzdi2"
14063   [(set (match_operand:DI 0 "register_operand" "=r")
14064         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14065    (clobber (reg:CC FLAGS_REG))]
14066   "TARGET_64BIT"
14067   "bsf{q}\t{%1, %0|%0, %1}"
14068   [(set_attr "prefix_0f" "1")])
14069
14070 (define_expand "clzsi2"
14071   [(parallel
14072      [(set (match_operand:SI 0 "register_operand" "")
14073            (minus:SI (const_int 31)
14074                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14075       (clobber (reg:CC FLAGS_REG))])
14076    (parallel
14077      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14078       (clobber (reg:CC FLAGS_REG))])]
14079   ""
14080   "")
14081
14082 (define_insn "*bsr"
14083   [(set (match_operand:SI 0 "register_operand" "=r")
14084         (minus:SI (const_int 31)
14085                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14086    (clobber (reg:CC FLAGS_REG))]
14087   ""
14088   "bsr{l}\t{%1, %0|%0, %1}"
14089   [(set_attr "prefix_0f" "1")])
14090
14091 (define_expand "clzdi2"
14092   [(parallel
14093      [(set (match_operand:DI 0 "register_operand" "")
14094            (minus:DI (const_int 63)
14095                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14096       (clobber (reg:CC FLAGS_REG))])
14097    (parallel
14098      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14099       (clobber (reg:CC FLAGS_REG))])]
14100   "TARGET_64BIT"
14101   "")
14102
14103 (define_insn "*bsr_rex64"
14104   [(set (match_operand:DI 0 "register_operand" "=r")
14105         (minus:DI (const_int 63)
14106                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14107    (clobber (reg:CC FLAGS_REG))]
14108   "TARGET_64BIT"
14109   "bsr{q}\t{%1, %0|%0, %1}"
14110   [(set_attr "prefix_0f" "1")])
14111 \f
14112 ;; Thread-local storage patterns for ELF.
14113 ;;
14114 ;; Note that these code sequences must appear exactly as shown
14115 ;; in order to allow linker relaxation.
14116
14117 (define_insn "*tls_global_dynamic_32_gnu"
14118   [(set (match_operand:SI 0 "register_operand" "=a")
14119         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14120                     (match_operand:SI 2 "tls_symbolic_operand" "")
14121                     (match_operand:SI 3 "call_insn_operand" "")]
14122                     UNSPEC_TLS_GD))
14123    (clobber (match_scratch:SI 4 "=d"))
14124    (clobber (match_scratch:SI 5 "=c"))
14125    (clobber (reg:CC FLAGS_REG))]
14126   "!TARGET_64BIT && TARGET_GNU_TLS"
14127   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14128   [(set_attr "type" "multi")
14129    (set_attr "length" "12")])
14130
14131 (define_insn "*tls_global_dynamic_32_sun"
14132   [(set (match_operand:SI 0 "register_operand" "=a")
14133         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14134                     (match_operand:SI 2 "tls_symbolic_operand" "")
14135                     (match_operand:SI 3 "call_insn_operand" "")]
14136                     UNSPEC_TLS_GD))
14137    (clobber (match_scratch:SI 4 "=d"))
14138    (clobber (match_scratch:SI 5 "=c"))
14139    (clobber (reg:CC FLAGS_REG))]
14140   "!TARGET_64BIT && TARGET_SUN_TLS"
14141   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14142         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14143   [(set_attr "type" "multi")
14144    (set_attr "length" "14")])
14145
14146 (define_expand "tls_global_dynamic_32"
14147   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14148                    (unspec:SI
14149                     [(match_dup 2)
14150                      (match_operand:SI 1 "tls_symbolic_operand" "")
14151                      (match_dup 3)]
14152                     UNSPEC_TLS_GD))
14153               (clobber (match_scratch:SI 4 ""))
14154               (clobber (match_scratch:SI 5 ""))
14155               (clobber (reg:CC FLAGS_REG))])]
14156   ""
14157 {
14158   if (flag_pic)
14159     operands[2] = pic_offset_table_rtx;
14160   else
14161     {
14162       operands[2] = gen_reg_rtx (Pmode);
14163       emit_insn (gen_set_got (operands[2]));
14164     }
14165   if (TARGET_GNU2_TLS)
14166     {
14167        emit_insn (gen_tls_dynamic_gnu2_32
14168                   (operands[0], operands[1], operands[2]));
14169        DONE;
14170     }
14171   operands[3] = ix86_tls_get_addr ();
14172 })
14173
14174 (define_insn "*tls_global_dynamic_64"
14175   [(set (match_operand:DI 0 "register_operand" "=a")
14176         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14177                  (match_operand:DI 3 "" "")))
14178    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14179               UNSPEC_TLS_GD)]
14180   "TARGET_64BIT"
14181   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14182   [(set_attr "type" "multi")
14183    (set_attr "length" "16")])
14184
14185 (define_expand "tls_global_dynamic_64"
14186   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14187                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14188               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14189                          UNSPEC_TLS_GD)])]
14190   ""
14191 {
14192   if (TARGET_GNU2_TLS)
14193     {
14194        emit_insn (gen_tls_dynamic_gnu2_64
14195                   (operands[0], operands[1]));
14196        DONE;
14197     }
14198   operands[2] = ix86_tls_get_addr ();
14199 })
14200
14201 (define_insn "*tls_local_dynamic_base_32_gnu"
14202   [(set (match_operand:SI 0 "register_operand" "=a")
14203         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204                     (match_operand:SI 2 "call_insn_operand" "")]
14205                    UNSPEC_TLS_LD_BASE))
14206    (clobber (match_scratch:SI 3 "=d"))
14207    (clobber (match_scratch:SI 4 "=c"))
14208    (clobber (reg:CC FLAGS_REG))]
14209   "!TARGET_64BIT && TARGET_GNU_TLS"
14210   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211   [(set_attr "type" "multi")
14212    (set_attr "length" "11")])
14213
14214 (define_insn "*tls_local_dynamic_base_32_sun"
14215   [(set (match_operand:SI 0 "register_operand" "=a")
14216         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217                     (match_operand:SI 2 "call_insn_operand" "")]
14218                    UNSPEC_TLS_LD_BASE))
14219    (clobber (match_scratch:SI 3 "=d"))
14220    (clobber (match_scratch:SI 4 "=c"))
14221    (clobber (reg:CC FLAGS_REG))]
14222   "!TARGET_64BIT && TARGET_SUN_TLS"
14223   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225   [(set_attr "type" "multi")
14226    (set_attr "length" "13")])
14227
14228 (define_expand "tls_local_dynamic_base_32"
14229   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230                    (unspec:SI [(match_dup 1) (match_dup 2)]
14231                               UNSPEC_TLS_LD_BASE))
14232               (clobber (match_scratch:SI 3 ""))
14233               (clobber (match_scratch:SI 4 ""))
14234               (clobber (reg:CC FLAGS_REG))])]
14235   ""
14236 {
14237   if (flag_pic)
14238     operands[1] = pic_offset_table_rtx;
14239   else
14240     {
14241       operands[1] = gen_reg_rtx (Pmode);
14242       emit_insn (gen_set_got (operands[1]));
14243     }
14244   if (TARGET_GNU2_TLS)
14245     {
14246        emit_insn (gen_tls_dynamic_gnu2_32
14247                   (operands[0], ix86_tls_module_base (), operands[1]));
14248        DONE;
14249     }
14250   operands[2] = ix86_tls_get_addr ();
14251 })
14252
14253 (define_insn "*tls_local_dynamic_base_64"
14254   [(set (match_operand:DI 0 "register_operand" "=a")
14255         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14256                  (match_operand:DI 2 "" "")))
14257    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14258   "TARGET_64BIT"
14259   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14260   [(set_attr "type" "multi")
14261    (set_attr "length" "12")])
14262
14263 (define_expand "tls_local_dynamic_base_64"
14264   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14265                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14266               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14267   ""
14268 {
14269   if (TARGET_GNU2_TLS)
14270     {
14271        emit_insn (gen_tls_dynamic_gnu2_64
14272                   (operands[0], ix86_tls_module_base ()));
14273        DONE;
14274     }
14275   operands[1] = ix86_tls_get_addr ();
14276 })
14277
14278 ;; Local dynamic of a single variable is a lose.  Show combine how
14279 ;; to convert that back to global dynamic.
14280
14281 (define_insn_and_split "*tls_local_dynamic_32_once"
14282   [(set (match_operand:SI 0 "register_operand" "=a")
14283         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14284                              (match_operand:SI 2 "call_insn_operand" "")]
14285                             UNSPEC_TLS_LD_BASE)
14286                  (const:SI (unspec:SI
14287                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14288                             UNSPEC_DTPOFF))))
14289    (clobber (match_scratch:SI 4 "=d"))
14290    (clobber (match_scratch:SI 5 "=c"))
14291    (clobber (reg:CC FLAGS_REG))]
14292   ""
14293   "#"
14294   ""
14295   [(parallel [(set (match_dup 0)
14296                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14297                               UNSPEC_TLS_GD))
14298               (clobber (match_dup 4))
14299               (clobber (match_dup 5))
14300               (clobber (reg:CC FLAGS_REG))])]
14301   "")
14302
14303 ;; Load and add the thread base pointer from %gs:0.
14304
14305 (define_insn "*load_tp_si"
14306   [(set (match_operand:SI 0 "register_operand" "=r")
14307         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14308   "!TARGET_64BIT"
14309   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14310   [(set_attr "type" "imov")
14311    (set_attr "modrm" "0")
14312    (set_attr "length" "7")
14313    (set_attr "memory" "load")
14314    (set_attr "imm_disp" "false")])
14315
14316 (define_insn "*add_tp_si"
14317   [(set (match_operand:SI 0 "register_operand" "=r")
14318         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14319                  (match_operand:SI 1 "register_operand" "0")))
14320    (clobber (reg:CC FLAGS_REG))]
14321   "!TARGET_64BIT"
14322   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14323   [(set_attr "type" "alu")
14324    (set_attr "modrm" "0")
14325    (set_attr "length" "7")
14326    (set_attr "memory" "load")
14327    (set_attr "imm_disp" "false")])
14328
14329 (define_insn "*load_tp_di"
14330   [(set (match_operand:DI 0 "register_operand" "=r")
14331         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14332   "TARGET_64BIT"
14333   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14334   [(set_attr "type" "imov")
14335    (set_attr "modrm" "0")
14336    (set_attr "length" "7")
14337    (set_attr "memory" "load")
14338    (set_attr "imm_disp" "false")])
14339
14340 (define_insn "*add_tp_di"
14341   [(set (match_operand:DI 0 "register_operand" "=r")
14342         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14343                  (match_operand:DI 1 "register_operand" "0")))
14344    (clobber (reg:CC FLAGS_REG))]
14345   "TARGET_64BIT"
14346   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14347   [(set_attr "type" "alu")
14348    (set_attr "modrm" "0")
14349    (set_attr "length" "7")
14350    (set_attr "memory" "load")
14351    (set_attr "imm_disp" "false")])
14352
14353 ;; GNU2 TLS patterns can be split.
14354
14355 (define_expand "tls_dynamic_gnu2_32"
14356   [(set (match_dup 3)
14357         (plus:SI (match_operand:SI 2 "register_operand" "")
14358                  (const:SI
14359                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14360                              UNSPEC_TLSDESC))))
14361    (parallel
14362     [(set (match_operand:SI 0 "register_operand" "")
14363           (unspec:SI [(match_dup 1) (match_dup 3)
14364                       (match_dup 2) (reg:SI SP_REG)]
14365                       UNSPEC_TLSDESC))
14366      (clobber (reg:CC FLAGS_REG))])]
14367   "!TARGET_64BIT && TARGET_GNU2_TLS"
14368 {
14369   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14370   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14371 })
14372
14373 (define_insn "*tls_dynamic_lea_32"
14374   [(set (match_operand:SI 0 "register_operand" "=r")
14375         (plus:SI (match_operand:SI 1 "register_operand" "b")
14376                  (const:SI
14377                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14378                               UNSPEC_TLSDESC))))]
14379   "!TARGET_64BIT && TARGET_GNU2_TLS"
14380   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14381   [(set_attr "type" "lea")
14382    (set_attr "mode" "SI")
14383    (set_attr "length" "6")
14384    (set_attr "length_address" "4")])
14385
14386 (define_insn "*tls_dynamic_call_32"
14387   [(set (match_operand:SI 0 "register_operand" "=a")
14388         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14389                     (match_operand:SI 2 "register_operand" "0")
14390                     ;; we have to make sure %ebx still points to the GOT
14391                     (match_operand:SI 3 "register_operand" "b")
14392                     (reg:SI SP_REG)]
14393                    UNSPEC_TLSDESC))
14394    (clobber (reg:CC FLAGS_REG))]
14395   "!TARGET_64BIT && TARGET_GNU2_TLS"
14396   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14397   [(set_attr "type" "call")
14398    (set_attr "length" "2")
14399    (set_attr "length_address" "0")])
14400
14401 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14402   [(set (match_operand:SI 0 "register_operand" "=&a")
14403         (plus:SI
14404          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14405                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14406                               (match_operand:SI 5 "" "")
14407                               (match_operand:SI 2 "register_operand" "b")
14408                               (reg:SI SP_REG)]
14409                              UNSPEC_TLSDESC))
14410          (const:SI (unspec:SI
14411                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14412                     UNSPEC_DTPOFF))))
14413    (clobber (reg:CC FLAGS_REG))]
14414   "!TARGET_64BIT && TARGET_GNU2_TLS"
14415   "#"
14416   ""
14417   [(parallel
14418     [(set (match_dup 0)
14419           (plus:SI (match_dup 3)
14420                    (match_dup 5)))
14421      (clobber (reg:CC FLAGS_REG))])]
14422 {
14423   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14424   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14425 })
14426
14427 (define_expand "tls_dynamic_gnu2_64"
14428   [(set (match_dup 2)
14429         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14430                    UNSPEC_TLSDESC))
14431    (parallel
14432     [(set (match_operand:DI 0 "register_operand" "")
14433           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14434                      UNSPEC_TLSDESC))
14435      (clobber (reg:CC FLAGS_REG))])]
14436   "TARGET_64BIT && TARGET_GNU2_TLS"
14437 {
14438   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14439   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14440 })
14441
14442 (define_insn "*tls_dynamic_lea_64"
14443   [(set (match_operand:DI 0 "register_operand" "=r")
14444         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14445                    UNSPEC_TLSDESC))]
14446   "TARGET_64BIT && TARGET_GNU2_TLS"
14447   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14448   [(set_attr "type" "lea")
14449    (set_attr "mode" "DI")
14450    (set_attr "length" "7")
14451    (set_attr "length_address" "4")])
14452
14453 (define_insn "*tls_dynamic_call_64"
14454   [(set (match_operand:DI 0 "register_operand" "=a")
14455         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14456                     (match_operand:DI 2 "register_operand" "0")
14457                     (reg:DI SP_REG)]
14458                    UNSPEC_TLSDESC))
14459    (clobber (reg:CC FLAGS_REG))]
14460   "TARGET_64BIT && TARGET_GNU2_TLS"
14461   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14462   [(set_attr "type" "call")
14463    (set_attr "length" "2")
14464    (set_attr "length_address" "0")])
14465
14466 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14467   [(set (match_operand:DI 0 "register_operand" "=&a")
14468         (plus:DI
14469          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14470                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14471                               (match_operand:DI 4 "" "")
14472                               (reg:DI SP_REG)]
14473                               UNSPEC_TLSDESC))
14474          (const:DI (unspec:DI
14475                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14476                     UNSPEC_DTPOFF))))
14477    (clobber (reg:CC FLAGS_REG))]
14478   "TARGET_64BIT && TARGET_GNU2_TLS"
14479   "#"
14480   ""
14481   [(parallel
14482     [(set (match_dup 0)
14483           (plus:DI (match_dup 2)
14484                    (match_dup 4)))
14485      (clobber (reg:CC FLAGS_REG))])]
14486 {
14487   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14488   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14489 })
14490
14491 ;;
14492 \f
14493 ;; These patterns match the binary 387 instructions for addM3, subM3,
14494 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14495 ;; SFmode.  The first is the normal insn, the second the same insn but
14496 ;; with one operand a conversion, and the third the same insn but with
14497 ;; the other operand a conversion.  The conversion may be SFmode or
14498 ;; SImode if the target mode DFmode, but only SImode if the target mode
14499 ;; is SFmode.
14500
14501 ;; Gcc is slightly more smart about handling normal two address instructions
14502 ;; so use special patterns for add and mull.
14503
14504 (define_insn "*fop_sf_comm_mixed"
14505   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14506         (match_operator:SF 3 "binary_fp_operator"
14507                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14508                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14509   "TARGET_MIX_SSE_I387
14510    && COMMUTATIVE_ARITH_P (operands[3])
14511    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14512   "* return output_387_binary_op (insn, operands);"
14513   [(set (attr "type") 
14514         (if_then_else (eq_attr "alternative" "1")
14515            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14516               (const_string "ssemul")
14517               (const_string "sseadd"))
14518            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14519               (const_string "fmul")
14520               (const_string "fop"))))
14521    (set_attr "mode" "SF")])
14522
14523 (define_insn "*fop_sf_comm_sse"
14524   [(set (match_operand:SF 0 "register_operand" "=x")
14525         (match_operator:SF 3 "binary_fp_operator"
14526                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14527                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14528   "TARGET_SSE_MATH
14529    && COMMUTATIVE_ARITH_P (operands[3])
14530    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531   "* return output_387_binary_op (insn, operands);"
14532   [(set (attr "type") 
14533         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14534            (const_string "ssemul")
14535            (const_string "sseadd")))
14536    (set_attr "mode" "SF")])
14537
14538 (define_insn "*fop_sf_comm_i387"
14539   [(set (match_operand:SF 0 "register_operand" "=f")
14540         (match_operator:SF 3 "binary_fp_operator"
14541                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14542                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14543   "TARGET_80387
14544    && COMMUTATIVE_ARITH_P (operands[3])
14545    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14546   "* return output_387_binary_op (insn, operands);"
14547   [(set (attr "type") 
14548         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14549            (const_string "fmul")
14550            (const_string "fop")))
14551    (set_attr "mode" "SF")])
14552
14553 (define_insn "*fop_sf_1_mixed"
14554   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14555         (match_operator:SF 3 "binary_fp_operator"
14556                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14557                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14558   "TARGET_MIX_SSE_I387
14559    && !COMMUTATIVE_ARITH_P (operands[3])
14560    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14561   "* return output_387_binary_op (insn, operands);"
14562   [(set (attr "type") 
14563         (cond [(and (eq_attr "alternative" "2")
14564                     (match_operand:SF 3 "mult_operator" ""))
14565                  (const_string "ssemul")
14566                (and (eq_attr "alternative" "2")
14567                     (match_operand:SF 3 "div_operator" ""))
14568                  (const_string "ssediv")
14569                (eq_attr "alternative" "2")
14570                  (const_string "sseadd")
14571                (match_operand:SF 3 "mult_operator" "") 
14572                  (const_string "fmul")
14573                (match_operand:SF 3 "div_operator" "") 
14574                  (const_string "fdiv")
14575               ]
14576               (const_string "fop")))
14577    (set_attr "mode" "SF")])
14578
14579 (define_insn "*fop_sf_1_sse"
14580   [(set (match_operand:SF 0 "register_operand" "=x")
14581         (match_operator:SF 3 "binary_fp_operator"
14582                         [(match_operand:SF 1 "register_operand" "0")
14583                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14584   "TARGET_SSE_MATH
14585    && !COMMUTATIVE_ARITH_P (operands[3])"
14586   "* return output_387_binary_op (insn, operands);"
14587   [(set (attr "type") 
14588         (cond [(match_operand:SF 3 "mult_operator" "")
14589                  (const_string "ssemul")
14590                (match_operand:SF 3 "div_operator" "")
14591                  (const_string "ssediv")
14592               ]
14593               (const_string "sseadd")))
14594    (set_attr "mode" "SF")])
14595
14596 ;; This pattern is not fully shadowed by the pattern above.
14597 (define_insn "*fop_sf_1_i387"
14598   [(set (match_operand:SF 0 "register_operand" "=f,f")
14599         (match_operator:SF 3 "binary_fp_operator"
14600                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14601                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14602   "TARGET_80387 && !TARGET_SSE_MATH
14603    && !COMMUTATIVE_ARITH_P (operands[3])
14604    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14605   "* return output_387_binary_op (insn, operands);"
14606   [(set (attr "type") 
14607         (cond [(match_operand:SF 3 "mult_operator" "") 
14608                  (const_string "fmul")
14609                (match_operand:SF 3 "div_operator" "") 
14610                  (const_string "fdiv")
14611               ]
14612               (const_string "fop")))
14613    (set_attr "mode" "SF")])
14614
14615 ;; ??? Add SSE splitters for these!
14616 (define_insn "*fop_sf_2<mode>_i387"
14617   [(set (match_operand:SF 0 "register_operand" "=f,f")
14618         (match_operator:SF 3 "binary_fp_operator"
14619           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14620            (match_operand:SF 2 "register_operand" "0,0")]))]
14621   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14622   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14623   [(set (attr "type") 
14624         (cond [(match_operand:SF 3 "mult_operator" "") 
14625                  (const_string "fmul")
14626                (match_operand:SF 3 "div_operator" "") 
14627                  (const_string "fdiv")
14628               ]
14629               (const_string "fop")))
14630    (set_attr "fp_int_src" "true")
14631    (set_attr "mode" "<MODE>")])
14632
14633 (define_insn "*fop_sf_3<mode>_i387"
14634   [(set (match_operand:SF 0 "register_operand" "=f,f")
14635         (match_operator:SF 3 "binary_fp_operator"
14636           [(match_operand:SF 1 "register_operand" "0,0")
14637            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14638   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14639   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14640   [(set (attr "type") 
14641         (cond [(match_operand:SF 3 "mult_operator" "") 
14642                  (const_string "fmul")
14643                (match_operand:SF 3 "div_operator" "") 
14644                  (const_string "fdiv")
14645               ]
14646               (const_string "fop")))
14647    (set_attr "fp_int_src" "true")
14648    (set_attr "mode" "<MODE>")])
14649
14650 (define_insn "*fop_df_comm_mixed"
14651   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14652         (match_operator:DF 3 "binary_fp_operator"
14653                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14654                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14655   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14656    && COMMUTATIVE_ARITH_P (operands[3])
14657    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14658   "* return output_387_binary_op (insn, operands);"
14659   [(set (attr "type") 
14660         (if_then_else (eq_attr "alternative" "1")
14661            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14662               (const_string "ssemul")
14663               (const_string "sseadd"))
14664            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14665               (const_string "fmul")
14666               (const_string "fop"))))
14667    (set_attr "mode" "DF")])
14668
14669 (define_insn "*fop_df_comm_sse"
14670   [(set (match_operand:DF 0 "register_operand" "=Y")
14671         (match_operator:DF 3 "binary_fp_operator"
14672                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14673                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14674   "TARGET_SSE2 && TARGET_SSE_MATH
14675    && COMMUTATIVE_ARITH_P (operands[3])
14676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14677   "* return output_387_binary_op (insn, operands);"
14678   [(set (attr "type") 
14679         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14680            (const_string "ssemul")
14681            (const_string "sseadd")))
14682    (set_attr "mode" "DF")])
14683
14684 (define_insn "*fop_df_comm_i387"
14685   [(set (match_operand:DF 0 "register_operand" "=f")
14686         (match_operator:DF 3 "binary_fp_operator"
14687                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14688                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14689   "TARGET_80387
14690    && COMMUTATIVE_ARITH_P (operands[3])
14691    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14692   "* return output_387_binary_op (insn, operands);"
14693   [(set (attr "type") 
14694         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14695            (const_string "fmul")
14696            (const_string "fop")))
14697    (set_attr "mode" "DF")])
14698
14699 (define_insn "*fop_df_1_mixed"
14700   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14701         (match_operator:DF 3 "binary_fp_operator"
14702                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14703                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14704   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14705    && !COMMUTATIVE_ARITH_P (operands[3])
14706    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14707   "* return output_387_binary_op (insn, operands);"
14708   [(set (attr "type") 
14709         (cond [(and (eq_attr "alternative" "2")
14710                     (match_operand:SF 3 "mult_operator" ""))
14711                  (const_string "ssemul")
14712                (and (eq_attr "alternative" "2")
14713                     (match_operand:SF 3 "div_operator" ""))
14714                  (const_string "ssediv")
14715                (eq_attr "alternative" "2")
14716                  (const_string "sseadd")
14717                (match_operand:DF 3 "mult_operator" "") 
14718                  (const_string "fmul")
14719                (match_operand:DF 3 "div_operator" "") 
14720                  (const_string "fdiv")
14721               ]
14722               (const_string "fop")))
14723    (set_attr "mode" "DF")])
14724
14725 (define_insn "*fop_df_1_sse"
14726   [(set (match_operand:DF 0 "register_operand" "=Y")
14727         (match_operator:DF 3 "binary_fp_operator"
14728                         [(match_operand:DF 1 "register_operand" "0")
14729                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14730   "TARGET_SSE2 && TARGET_SSE_MATH
14731    && !COMMUTATIVE_ARITH_P (operands[3])"
14732   "* return output_387_binary_op (insn, operands);"
14733   [(set_attr "mode" "DF")
14734    (set (attr "type") 
14735         (cond [(match_operand:SF 3 "mult_operator" "")
14736                  (const_string "ssemul")
14737                (match_operand:SF 3 "div_operator" "")
14738                  (const_string "ssediv")
14739               ]
14740               (const_string "sseadd")))])
14741
14742 ;; This pattern is not fully shadowed by the pattern above.
14743 (define_insn "*fop_df_1_i387"
14744   [(set (match_operand:DF 0 "register_operand" "=f,f")
14745         (match_operator:DF 3 "binary_fp_operator"
14746                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14747                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14748   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14749    && !COMMUTATIVE_ARITH_P (operands[3])
14750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14751   "* return output_387_binary_op (insn, operands);"
14752   [(set (attr "type") 
14753         (cond [(match_operand:DF 3 "mult_operator" "") 
14754                  (const_string "fmul")
14755                (match_operand:DF 3 "div_operator" "")
14756                  (const_string "fdiv")
14757               ]
14758               (const_string "fop")))
14759    (set_attr "mode" "DF")])
14760
14761 ;; ??? Add SSE splitters for these!
14762 (define_insn "*fop_df_2<mode>_i387"
14763   [(set (match_operand:DF 0 "register_operand" "=f,f")
14764         (match_operator:DF 3 "binary_fp_operator"
14765            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14766             (match_operand:DF 2 "register_operand" "0,0")]))]
14767   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14768    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14769   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14770   [(set (attr "type") 
14771         (cond [(match_operand:DF 3 "mult_operator" "") 
14772                  (const_string "fmul")
14773                (match_operand:DF 3 "div_operator" "") 
14774                  (const_string "fdiv")
14775               ]
14776               (const_string "fop")))
14777    (set_attr "fp_int_src" "true")
14778    (set_attr "mode" "<MODE>")])
14779
14780 (define_insn "*fop_df_3<mode>_i387"
14781   [(set (match_operand:DF 0 "register_operand" "=f,f")
14782         (match_operator:DF 3 "binary_fp_operator"
14783            [(match_operand:DF 1 "register_operand" "0,0")
14784             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14785   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14786    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14787   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14788   [(set (attr "type") 
14789         (cond [(match_operand:DF 3 "mult_operator" "") 
14790                  (const_string "fmul")
14791                (match_operand:DF 3 "div_operator" "") 
14792                  (const_string "fdiv")
14793               ]
14794               (const_string "fop")))
14795    (set_attr "fp_int_src" "true")
14796    (set_attr "mode" "<MODE>")])
14797
14798 (define_insn "*fop_df_4_i387"
14799   [(set (match_operand:DF 0 "register_operand" "=f,f")
14800         (match_operator:DF 3 "binary_fp_operator"
14801            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14802             (match_operand:DF 2 "register_operand" "0,f")]))]
14803   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14804    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14805   "* return output_387_binary_op (insn, operands);"
14806   [(set (attr "type") 
14807         (cond [(match_operand:DF 3 "mult_operator" "") 
14808                  (const_string "fmul")
14809                (match_operand:DF 3 "div_operator" "") 
14810                  (const_string "fdiv")
14811               ]
14812               (const_string "fop")))
14813    (set_attr "mode" "SF")])
14814
14815 (define_insn "*fop_df_5_i387"
14816   [(set (match_operand:DF 0 "register_operand" "=f,f")
14817         (match_operator:DF 3 "binary_fp_operator"
14818           [(match_operand:DF 1 "register_operand" "0,f")
14819            (float_extend:DF
14820             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14821   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14822   "* return output_387_binary_op (insn, operands);"
14823   [(set (attr "type") 
14824         (cond [(match_operand:DF 3 "mult_operator" "") 
14825                  (const_string "fmul")
14826                (match_operand:DF 3 "div_operator" "") 
14827                  (const_string "fdiv")
14828               ]
14829               (const_string "fop")))
14830    (set_attr "mode" "SF")])
14831
14832 (define_insn "*fop_df_6_i387"
14833   [(set (match_operand:DF 0 "register_operand" "=f,f")
14834         (match_operator:DF 3 "binary_fp_operator"
14835           [(float_extend:DF
14836             (match_operand:SF 1 "register_operand" "0,f"))
14837            (float_extend:DF
14838             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14839   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14840   "* return output_387_binary_op (insn, operands);"
14841   [(set (attr "type") 
14842         (cond [(match_operand:DF 3 "mult_operator" "") 
14843                  (const_string "fmul")
14844                (match_operand:DF 3 "div_operator" "") 
14845                  (const_string "fdiv")
14846               ]
14847               (const_string "fop")))
14848    (set_attr "mode" "SF")])
14849
14850 (define_insn "*fop_xf_comm_i387"
14851   [(set (match_operand:XF 0 "register_operand" "=f")
14852         (match_operator:XF 3 "binary_fp_operator"
14853                         [(match_operand:XF 1 "register_operand" "%0")
14854                          (match_operand:XF 2 "register_operand" "f")]))]
14855   "TARGET_80387
14856    && COMMUTATIVE_ARITH_P (operands[3])"
14857   "* return output_387_binary_op (insn, operands);"
14858   [(set (attr "type") 
14859         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14860            (const_string "fmul")
14861            (const_string "fop")))
14862    (set_attr "mode" "XF")])
14863
14864 (define_insn "*fop_xf_1_i387"
14865   [(set (match_operand:XF 0 "register_operand" "=f,f")
14866         (match_operator:XF 3 "binary_fp_operator"
14867                         [(match_operand:XF 1 "register_operand" "0,f")
14868                          (match_operand:XF 2 "register_operand" "f,0")]))]
14869   "TARGET_80387
14870    && !COMMUTATIVE_ARITH_P (operands[3])"
14871   "* return output_387_binary_op (insn, operands);"
14872   [(set (attr "type") 
14873         (cond [(match_operand:XF 3 "mult_operator" "") 
14874                  (const_string "fmul")
14875                (match_operand:XF 3 "div_operator" "") 
14876                  (const_string "fdiv")
14877               ]
14878               (const_string "fop")))
14879    (set_attr "mode" "XF")])
14880
14881 (define_insn "*fop_xf_2<mode>_i387"
14882   [(set (match_operand:XF 0 "register_operand" "=f,f")
14883         (match_operator:XF 3 "binary_fp_operator"
14884            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14885             (match_operand:XF 2 "register_operand" "0,0")]))]
14886   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14887   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14888   [(set (attr "type") 
14889         (cond [(match_operand:XF 3 "mult_operator" "") 
14890                  (const_string "fmul")
14891                (match_operand:XF 3 "div_operator" "") 
14892                  (const_string "fdiv")
14893               ]
14894               (const_string "fop")))
14895    (set_attr "fp_int_src" "true")
14896    (set_attr "mode" "<MODE>")])
14897
14898 (define_insn "*fop_xf_3<mode>_i387"
14899   [(set (match_operand:XF 0 "register_operand" "=f,f")
14900         (match_operator:XF 3 "binary_fp_operator"
14901           [(match_operand:XF 1 "register_operand" "0,0")
14902            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14903   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14904   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14905   [(set (attr "type") 
14906         (cond [(match_operand:XF 3 "mult_operator" "") 
14907                  (const_string "fmul")
14908                (match_operand:XF 3 "div_operator" "") 
14909                  (const_string "fdiv")
14910               ]
14911               (const_string "fop")))
14912    (set_attr "fp_int_src" "true")
14913    (set_attr "mode" "<MODE>")])
14914
14915 (define_insn "*fop_xf_4_i387"
14916   [(set (match_operand:XF 0 "register_operand" "=f,f")
14917         (match_operator:XF 3 "binary_fp_operator"
14918            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14919             (match_operand:XF 2 "register_operand" "0,f")]))]
14920   "TARGET_80387"
14921   "* return output_387_binary_op (insn, operands);"
14922   [(set (attr "type") 
14923         (cond [(match_operand:XF 3 "mult_operator" "") 
14924                  (const_string "fmul")
14925                (match_operand:XF 3 "div_operator" "") 
14926                  (const_string "fdiv")
14927               ]
14928               (const_string "fop")))
14929    (set_attr "mode" "SF")])
14930
14931 (define_insn "*fop_xf_5_i387"
14932   [(set (match_operand:XF 0 "register_operand" "=f,f")
14933         (match_operator:XF 3 "binary_fp_operator"
14934           [(match_operand:XF 1 "register_operand" "0,f")
14935            (float_extend:XF
14936             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14937   "TARGET_80387"
14938   "* return output_387_binary_op (insn, operands);"
14939   [(set (attr "type") 
14940         (cond [(match_operand:XF 3 "mult_operator" "") 
14941                  (const_string "fmul")
14942                (match_operand:XF 3 "div_operator" "") 
14943                  (const_string "fdiv")
14944               ]
14945               (const_string "fop")))
14946    (set_attr "mode" "SF")])
14947
14948 (define_insn "*fop_xf_6_i387"
14949   [(set (match_operand:XF 0 "register_operand" "=f,f")
14950         (match_operator:XF 3 "binary_fp_operator"
14951           [(float_extend:XF
14952             (match_operand 1 "register_operand" "0,f"))
14953            (float_extend:XF
14954             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14955   "TARGET_80387"
14956   "* return output_387_binary_op (insn, operands);"
14957   [(set (attr "type") 
14958         (cond [(match_operand:XF 3 "mult_operator" "") 
14959                  (const_string "fmul")
14960                (match_operand:XF 3 "div_operator" "") 
14961                  (const_string "fdiv")
14962               ]
14963               (const_string "fop")))
14964    (set_attr "mode" "SF")])
14965
14966 (define_split
14967   [(set (match_operand 0 "register_operand" "")
14968         (match_operator 3 "binary_fp_operator"
14969            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14970             (match_operand 2 "register_operand" "")]))]
14971   "TARGET_80387 && reload_completed
14972    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14973   [(const_int 0)]
14974
14975   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14976   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14977   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14978                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14979                                           GET_MODE (operands[3]),
14980                                           operands[4],
14981                                           operands[2])));
14982   ix86_free_from_memory (GET_MODE (operands[1]));
14983   DONE;
14984 })
14985
14986 (define_split
14987   [(set (match_operand 0 "register_operand" "")
14988         (match_operator 3 "binary_fp_operator"
14989            [(match_operand 1 "register_operand" "")
14990             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14991   "TARGET_80387 && reload_completed
14992    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14993   [(const_int 0)]
14994 {
14995   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14996   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14997   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14998                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14999                                           GET_MODE (operands[3]),
15000                                           operands[1],
15001                                           operands[4])));
15002   ix86_free_from_memory (GET_MODE (operands[2]));
15003   DONE;
15004 })
15005 \f
15006 ;; FPU special functions.
15007
15008 (define_expand "sqrtsf2"
15009   [(set (match_operand:SF 0 "register_operand" "")
15010         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15011   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15012 {
15013   if (!TARGET_SSE_MATH)
15014     operands[1] = force_reg (SFmode, operands[1]);
15015 })
15016
15017 (define_insn "*sqrtsf2_mixed"
15018   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15019         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15020   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15021   "@
15022    fsqrt
15023    sqrtss\t{%1, %0|%0, %1}"
15024   [(set_attr "type" "fpspc,sse")
15025    (set_attr "mode" "SF,SF")
15026    (set_attr "athlon_decode" "direct,*")])
15027
15028 (define_insn "*sqrtsf2_sse"
15029   [(set (match_operand:SF 0 "register_operand" "=x")
15030         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15031   "TARGET_SSE_MATH"
15032   "sqrtss\t{%1, %0|%0, %1}"
15033   [(set_attr "type" "sse")
15034    (set_attr "mode" "SF")
15035    (set_attr "athlon_decode" "*")])
15036
15037 (define_insn "*sqrtsf2_i387"
15038   [(set (match_operand:SF 0 "register_operand" "=f")
15039         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15040   "TARGET_USE_FANCY_MATH_387"
15041   "fsqrt"
15042   [(set_attr "type" "fpspc")
15043    (set_attr "mode" "SF")
15044    (set_attr "athlon_decode" "direct")])
15045
15046 (define_expand "sqrtdf2"
15047   [(set (match_operand:DF 0 "register_operand" "")
15048         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15049   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15050 {
15051   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15052     operands[1] = force_reg (DFmode, operands[1]);
15053 })
15054
15055 (define_insn "*sqrtdf2_mixed"
15056   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15057         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15058   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15059   "@
15060    fsqrt
15061    sqrtsd\t{%1, %0|%0, %1}"
15062   [(set_attr "type" "fpspc,sse")
15063    (set_attr "mode" "DF,DF")
15064    (set_attr "athlon_decode" "direct,*")])
15065
15066 (define_insn "*sqrtdf2_sse"
15067   [(set (match_operand:DF 0 "register_operand" "=Y")
15068         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15069   "TARGET_SSE2 && TARGET_SSE_MATH"
15070   "sqrtsd\t{%1, %0|%0, %1}"
15071   [(set_attr "type" "sse")
15072    (set_attr "mode" "DF")
15073    (set_attr "athlon_decode" "*")])
15074
15075 (define_insn "*sqrtdf2_i387"
15076   [(set (match_operand:DF 0 "register_operand" "=f")
15077         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15078   "TARGET_USE_FANCY_MATH_387"
15079   "fsqrt"
15080   [(set_attr "type" "fpspc")
15081    (set_attr "mode" "DF")
15082    (set_attr "athlon_decode" "direct")])
15083
15084 (define_insn "*sqrtextendsfdf2_i387"
15085   [(set (match_operand:DF 0 "register_operand" "=f")
15086         (sqrt:DF (float_extend:DF
15087                   (match_operand:SF 1 "register_operand" "0"))))]
15088   "TARGET_USE_FANCY_MATH_387
15089    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15090   "fsqrt"
15091   [(set_attr "type" "fpspc")
15092    (set_attr "mode" "DF")
15093    (set_attr "athlon_decode" "direct")])
15094
15095 (define_insn "sqrtxf2"
15096   [(set (match_operand:XF 0 "register_operand" "=f")
15097         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15098   "TARGET_USE_FANCY_MATH_387 
15099    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15100   "fsqrt"
15101   [(set_attr "type" "fpspc")
15102    (set_attr "mode" "XF")
15103    (set_attr "athlon_decode" "direct")])
15104
15105 (define_insn "*sqrtextendsfxf2_i387"
15106   [(set (match_operand:XF 0 "register_operand" "=f")
15107         (sqrt:XF (float_extend:XF
15108                   (match_operand:SF 1 "register_operand" "0"))))]
15109   "TARGET_USE_FANCY_MATH_387"
15110   "fsqrt"
15111   [(set_attr "type" "fpspc")
15112    (set_attr "mode" "XF")
15113    (set_attr "athlon_decode" "direct")])
15114
15115 (define_insn "*sqrtextenddfxf2_i387"
15116   [(set (match_operand:XF 0 "register_operand" "=f")
15117         (sqrt:XF (float_extend:XF
15118                   (match_operand:DF 1 "register_operand" "0"))))]
15119   "TARGET_USE_FANCY_MATH_387"
15120   "fsqrt"
15121   [(set_attr "type" "fpspc")
15122    (set_attr "mode" "XF")
15123    (set_attr "athlon_decode" "direct")])
15124
15125 (define_insn "fpremxf4"
15126   [(set (match_operand:XF 0 "register_operand" "=f")
15127         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15128                     (match_operand:XF 3 "register_operand" "1")]
15129                    UNSPEC_FPREM_F))
15130    (set (match_operand:XF 1 "register_operand" "=u")
15131         (unspec:XF [(match_dup 2) (match_dup 3)]
15132                    UNSPEC_FPREM_U))
15133    (set (reg:CCFP FPSR_REG)
15134         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15135   "TARGET_USE_FANCY_MATH_387
15136    && flag_unsafe_math_optimizations"
15137   "fprem"
15138   [(set_attr "type" "fpspc")
15139    (set_attr "mode" "XF")])
15140
15141 (define_expand "fmodsf3"
15142   [(use (match_operand:SF 0 "register_operand" ""))
15143    (use (match_operand:SF 1 "register_operand" ""))
15144    (use (match_operand:SF 2 "register_operand" ""))]
15145   "TARGET_USE_FANCY_MATH_387
15146    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15147    && flag_unsafe_math_optimizations"
15148 {
15149   rtx label = gen_label_rtx ();
15150
15151   rtx op1 = gen_reg_rtx (XFmode);
15152   rtx op2 = gen_reg_rtx (XFmode);
15153
15154   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15155   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15156
15157   emit_label (label);
15158
15159   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15160   ix86_emit_fp_unordered_jump (label);
15161
15162   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15163   DONE;
15164 })
15165
15166 (define_expand "fmoddf3"
15167   [(use (match_operand:DF 0 "register_operand" ""))
15168    (use (match_operand:DF 1 "register_operand" ""))
15169    (use (match_operand:DF 2 "register_operand" ""))]
15170   "TARGET_USE_FANCY_MATH_387
15171    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15172    && flag_unsafe_math_optimizations"
15173 {
15174   rtx label = gen_label_rtx ();
15175
15176   rtx op1 = gen_reg_rtx (XFmode);
15177   rtx op2 = gen_reg_rtx (XFmode);
15178
15179   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15180   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15181
15182   emit_label (label);
15183
15184   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15185   ix86_emit_fp_unordered_jump (label);
15186
15187   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15188   DONE;
15189 })
15190
15191 (define_expand "fmodxf3"
15192   [(use (match_operand:XF 0 "register_operand" ""))
15193    (use (match_operand:XF 1 "register_operand" ""))
15194    (use (match_operand:XF 2 "register_operand" ""))]
15195   "TARGET_USE_FANCY_MATH_387
15196    && flag_unsafe_math_optimizations"
15197 {
15198   rtx label = gen_label_rtx ();
15199
15200   emit_label (label);
15201
15202   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15203                            operands[1], operands[2]));
15204   ix86_emit_fp_unordered_jump (label);
15205
15206   emit_move_insn (operands[0], operands[1]);
15207   DONE;
15208 })
15209
15210 (define_insn "fprem1xf4"
15211   [(set (match_operand:XF 0 "register_operand" "=f")
15212         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15213                     (match_operand:XF 3 "register_operand" "1")]
15214                    UNSPEC_FPREM1_F))
15215    (set (match_operand:XF 1 "register_operand" "=u")
15216         (unspec:XF [(match_dup 2) (match_dup 3)]
15217                    UNSPEC_FPREM1_U))
15218    (set (reg:CCFP FPSR_REG)
15219         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15220   "TARGET_USE_FANCY_MATH_387
15221    && flag_unsafe_math_optimizations"
15222   "fprem1"
15223   [(set_attr "type" "fpspc")
15224    (set_attr "mode" "XF")])
15225
15226 (define_expand "dremsf3"
15227   [(use (match_operand:SF 0 "register_operand" ""))
15228    (use (match_operand:SF 1 "register_operand" ""))
15229    (use (match_operand:SF 2 "register_operand" ""))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15232    && flag_unsafe_math_optimizations"
15233 {
15234   rtx label = gen_label_rtx ();
15235
15236   rtx op1 = gen_reg_rtx (XFmode);
15237   rtx op2 = gen_reg_rtx (XFmode);
15238
15239   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15240   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15241
15242   emit_label (label);
15243
15244   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15245   ix86_emit_fp_unordered_jump (label);
15246
15247   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15248   DONE;
15249 })
15250
15251 (define_expand "dremdf3"
15252   [(use (match_operand:DF 0 "register_operand" ""))
15253    (use (match_operand:DF 1 "register_operand" ""))
15254    (use (match_operand:DF 2 "register_operand" ""))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15257    && flag_unsafe_math_optimizations"
15258 {
15259   rtx label = gen_label_rtx ();
15260
15261   rtx op1 = gen_reg_rtx (XFmode);
15262   rtx op2 = gen_reg_rtx (XFmode);
15263
15264   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15265   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15266
15267   emit_label (label);
15268
15269   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15270   ix86_emit_fp_unordered_jump (label);
15271
15272   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15273   DONE;
15274 })
15275
15276 (define_expand "dremxf3"
15277   [(use (match_operand:XF 0 "register_operand" ""))
15278    (use (match_operand:XF 1 "register_operand" ""))
15279    (use (match_operand:XF 2 "register_operand" ""))]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations"
15282 {
15283   rtx label = gen_label_rtx ();
15284
15285   emit_label (label);
15286
15287   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15288                             operands[1], operands[2]));
15289   ix86_emit_fp_unordered_jump (label);
15290
15291   emit_move_insn (operands[0], operands[1]);
15292   DONE;
15293 })
15294
15295 (define_insn "*sindf2"
15296   [(set (match_operand:DF 0 "register_operand" "=f")
15297         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15298   "TARGET_USE_FANCY_MATH_387
15299    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15300    && flag_unsafe_math_optimizations"
15301   "fsin"
15302   [(set_attr "type" "fpspc")
15303    (set_attr "mode" "DF")])
15304
15305 (define_insn "*sinsf2"
15306   [(set (match_operand:SF 0 "register_operand" "=f")
15307         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15308   "TARGET_USE_FANCY_MATH_387
15309    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15310    && flag_unsafe_math_optimizations"
15311   "fsin"
15312   [(set_attr "type" "fpspc")
15313    (set_attr "mode" "SF")])
15314
15315 (define_insn "*sinextendsfdf2"
15316   [(set (match_operand:DF 0 "register_operand" "=f")
15317         (unspec:DF [(float_extend:DF
15318                      (match_operand:SF 1 "register_operand" "0"))]
15319                    UNSPEC_SIN))]
15320   "TARGET_USE_FANCY_MATH_387
15321    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15322    && flag_unsafe_math_optimizations"
15323   "fsin"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "DF")])
15326
15327 (define_insn "*sinxf2"
15328   [(set (match_operand:XF 0 "register_operand" "=f")
15329         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && flag_unsafe_math_optimizations"
15332   "fsin"
15333   [(set_attr "type" "fpspc")
15334    (set_attr "mode" "XF")])
15335
15336 (define_insn "*cosdf2"
15337   [(set (match_operand:DF 0 "register_operand" "=f")
15338         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15339   "TARGET_USE_FANCY_MATH_387
15340    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15341    && flag_unsafe_math_optimizations"
15342   "fcos"
15343   [(set_attr "type" "fpspc")
15344    (set_attr "mode" "DF")])
15345
15346 (define_insn "*cossf2"
15347   [(set (match_operand:SF 0 "register_operand" "=f")
15348         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15349   "TARGET_USE_FANCY_MATH_387
15350    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15351    && flag_unsafe_math_optimizations"
15352   "fcos"
15353   [(set_attr "type" "fpspc")
15354    (set_attr "mode" "SF")])
15355
15356 (define_insn "*cosextendsfdf2"
15357   [(set (match_operand:DF 0 "register_operand" "=f")
15358         (unspec:DF [(float_extend:DF
15359                      (match_operand:SF 1 "register_operand" "0"))]
15360                    UNSPEC_COS))]
15361   "TARGET_USE_FANCY_MATH_387
15362    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15363    && flag_unsafe_math_optimizations"
15364   "fcos"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "DF")])
15367
15368 (define_insn "*cosxf2"
15369   [(set (match_operand:XF 0 "register_operand" "=f")
15370         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && flag_unsafe_math_optimizations"
15373   "fcos"
15374   [(set_attr "type" "fpspc")
15375    (set_attr "mode" "XF")])
15376
15377 ;; With sincos pattern defined, sin and cos builtin function will be
15378 ;; expanded to sincos pattern with one of its outputs left unused. 
15379 ;; Cse pass  will detected, if two sincos patterns can be combined,
15380 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15381 ;; depending on the unused output.
15382
15383 (define_insn "sincosdf3"
15384   [(set (match_operand:DF 0 "register_operand" "=f")
15385         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15386                    UNSPEC_SINCOS_COS))
15387    (set (match_operand:DF 1 "register_operand" "=u")
15388         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15389   "TARGET_USE_FANCY_MATH_387
15390    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15391    && flag_unsafe_math_optimizations"
15392   "fsincos"
15393   [(set_attr "type" "fpspc")
15394    (set_attr "mode" "DF")])
15395
15396 (define_split
15397   [(set (match_operand:DF 0 "register_operand" "")
15398         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15399                    UNSPEC_SINCOS_COS))
15400    (set (match_operand:DF 1 "register_operand" "")
15401         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15402   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15403    && !reload_completed && !reload_in_progress"
15404   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15405   "")
15406
15407 (define_split
15408   [(set (match_operand:DF 0 "register_operand" "")
15409         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15410                    UNSPEC_SINCOS_COS))
15411    (set (match_operand:DF 1 "register_operand" "")
15412         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15413   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15414    && !reload_completed && !reload_in_progress"
15415   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15416   "")
15417
15418 (define_insn "sincossf3"
15419   [(set (match_operand:SF 0 "register_operand" "=f")
15420         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15421                    UNSPEC_SINCOS_COS))
15422    (set (match_operand:SF 1 "register_operand" "=u")
15423         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15424   "TARGET_USE_FANCY_MATH_387
15425    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15426    && flag_unsafe_math_optimizations"
15427   "fsincos"
15428   [(set_attr "type" "fpspc")
15429    (set_attr "mode" "SF")])
15430
15431 (define_split
15432   [(set (match_operand:SF 0 "register_operand" "")
15433         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15434                    UNSPEC_SINCOS_COS))
15435    (set (match_operand:SF 1 "register_operand" "")
15436         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15437   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15438    && !reload_completed && !reload_in_progress"
15439   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15440   "")
15441
15442 (define_split
15443   [(set (match_operand:SF 0 "register_operand" "")
15444         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15445                    UNSPEC_SINCOS_COS))
15446    (set (match_operand:SF 1 "register_operand" "")
15447         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15448   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15449    && !reload_completed && !reload_in_progress"
15450   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15451   "")
15452
15453 (define_insn "*sincosextendsfdf3"
15454   [(set (match_operand:DF 0 "register_operand" "=f")
15455         (unspec:DF [(float_extend:DF
15456                      (match_operand:SF 2 "register_operand" "0"))]
15457                    UNSPEC_SINCOS_COS))
15458    (set (match_operand:DF 1 "register_operand" "=u")
15459         (unspec:DF [(float_extend:DF
15460                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15461   "TARGET_USE_FANCY_MATH_387
15462    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15463    && flag_unsafe_math_optimizations"
15464   "fsincos"
15465   [(set_attr "type" "fpspc")
15466    (set_attr "mode" "DF")])
15467
15468 (define_split
15469   [(set (match_operand:DF 0 "register_operand" "")
15470         (unspec:DF [(float_extend:DF
15471                      (match_operand:SF 2 "register_operand" ""))]
15472                    UNSPEC_SINCOS_COS))
15473    (set (match_operand:DF 1 "register_operand" "")
15474         (unspec:DF [(float_extend:DF
15475                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15476   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15477    && !reload_completed && !reload_in_progress"
15478   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15479                                    (match_dup 2))] UNSPEC_SIN))]
15480   "")
15481
15482 (define_split
15483   [(set (match_operand:DF 0 "register_operand" "")
15484         (unspec:DF [(float_extend:DF
15485                      (match_operand:SF 2 "register_operand" ""))]
15486                    UNSPEC_SINCOS_COS))
15487    (set (match_operand:DF 1 "register_operand" "")
15488         (unspec:DF [(float_extend:DF
15489                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15490   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15491    && !reload_completed && !reload_in_progress"
15492   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15493                                    (match_dup 2))] UNSPEC_COS))]
15494   "")
15495
15496 (define_insn "sincosxf3"
15497   [(set (match_operand:XF 0 "register_operand" "=f")
15498         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15499                    UNSPEC_SINCOS_COS))
15500    (set (match_operand:XF 1 "register_operand" "=u")
15501         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15502   "TARGET_USE_FANCY_MATH_387
15503    && flag_unsafe_math_optimizations"
15504   "fsincos"
15505   [(set_attr "type" "fpspc")
15506    (set_attr "mode" "XF")])
15507
15508 (define_split
15509   [(set (match_operand:XF 0 "register_operand" "")
15510         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15511                    UNSPEC_SINCOS_COS))
15512    (set (match_operand:XF 1 "register_operand" "")
15513         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15514   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15515    && !reload_completed && !reload_in_progress"
15516   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15517   "")
15518
15519 (define_split
15520   [(set (match_operand:XF 0 "register_operand" "")
15521         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15522                    UNSPEC_SINCOS_COS))
15523    (set (match_operand:XF 1 "register_operand" "")
15524         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15525   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15526    && !reload_completed && !reload_in_progress"
15527   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15528   "")
15529
15530 (define_insn "*tandf3_1"
15531   [(set (match_operand:DF 0 "register_operand" "=f")
15532         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15533                    UNSPEC_TAN_ONE))
15534    (set (match_operand:DF 1 "register_operand" "=u")
15535         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15536   "TARGET_USE_FANCY_MATH_387
15537    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15538    && flag_unsafe_math_optimizations"
15539   "fptan"
15540   [(set_attr "type" "fpspc")
15541    (set_attr "mode" "DF")])
15542
15543 ;; optimize sequence: fptan
15544 ;;                    fstp    %st(0)
15545 ;;                    fld1
15546 ;; into fptan insn.
15547
15548 (define_peephole2
15549   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15550                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15551                              UNSPEC_TAN_ONE))
15552              (set (match_operand:DF 1 "register_operand" "")
15553                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15554    (set (match_dup 0)
15555         (match_operand:DF 3 "immediate_operand" ""))]
15556   "standard_80387_constant_p (operands[3]) == 2"
15557   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15558              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15559   "")
15560
15561 (define_expand "tandf2"
15562   [(parallel [(set (match_dup 2)
15563                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15564                               UNSPEC_TAN_ONE))
15565               (set (match_operand:DF 0 "register_operand" "")
15566                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15567   "TARGET_USE_FANCY_MATH_387
15568    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15569    && flag_unsafe_math_optimizations"
15570 {
15571   operands[2] = gen_reg_rtx (DFmode);
15572 })
15573
15574 (define_insn "*tansf3_1"
15575   [(set (match_operand:SF 0 "register_operand" "=f")
15576         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15577                    UNSPEC_TAN_ONE))
15578    (set (match_operand:SF 1 "register_operand" "=u")
15579         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15580   "TARGET_USE_FANCY_MATH_387
15581    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15582    && flag_unsafe_math_optimizations"
15583   "fptan"
15584   [(set_attr "type" "fpspc")
15585    (set_attr "mode" "SF")])
15586
15587 ;; optimize sequence: fptan
15588 ;;                    fstp    %st(0)
15589 ;;                    fld1
15590 ;; into fptan insn.
15591
15592 (define_peephole2
15593   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15594                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15595                              UNSPEC_TAN_ONE))
15596              (set (match_operand:SF 1 "register_operand" "")
15597                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15598    (set (match_dup 0)
15599         (match_operand:SF 3 "immediate_operand" ""))]
15600   "standard_80387_constant_p (operands[3]) == 2"
15601   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15602              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15603   "")
15604
15605 (define_expand "tansf2"
15606   [(parallel [(set (match_dup 2)
15607                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15608                               UNSPEC_TAN_ONE))
15609               (set (match_operand:SF 0 "register_operand" "")
15610                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15611   "TARGET_USE_FANCY_MATH_387
15612    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15613    && flag_unsafe_math_optimizations"
15614 {
15615   operands[2] = gen_reg_rtx (SFmode);
15616 })
15617
15618 (define_insn "*tanxf3_1"
15619   [(set (match_operand:XF 0 "register_operand" "=f")
15620         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15621                    UNSPEC_TAN_ONE))
15622    (set (match_operand:XF 1 "register_operand" "=u")
15623         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15624   "TARGET_USE_FANCY_MATH_387
15625    && flag_unsafe_math_optimizations"
15626   "fptan"
15627   [(set_attr "type" "fpspc")
15628    (set_attr "mode" "XF")])
15629
15630 ;; optimize sequence: fptan
15631 ;;                    fstp    %st(0)
15632 ;;                    fld1
15633 ;; into fptan insn.
15634
15635 (define_peephole2
15636   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15637                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15638                              UNSPEC_TAN_ONE))
15639              (set (match_operand:XF 1 "register_operand" "")
15640                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15641    (set (match_dup 0)
15642         (match_operand:XF 3 "immediate_operand" ""))]
15643   "standard_80387_constant_p (operands[3]) == 2"
15644   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15645              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15646   "")
15647
15648 (define_expand "tanxf2"
15649   [(parallel [(set (match_dup 2)
15650                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15651                               UNSPEC_TAN_ONE))
15652               (set (match_operand:XF 0 "register_operand" "")
15653                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15654   "TARGET_USE_FANCY_MATH_387
15655    && flag_unsafe_math_optimizations"
15656 {
15657   operands[2] = gen_reg_rtx (XFmode);
15658 })
15659
15660 (define_insn "atan2df3_1"
15661   [(set (match_operand:DF 0 "register_operand" "=f")
15662         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15663                     (match_operand:DF 1 "register_operand" "u")]
15664                    UNSPEC_FPATAN))
15665    (clobber (match_scratch:DF 3 "=1"))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15668    && flag_unsafe_math_optimizations"
15669   "fpatan"
15670   [(set_attr "type" "fpspc")
15671    (set_attr "mode" "DF")])
15672
15673 (define_expand "atan2df3"
15674   [(use (match_operand:DF 0 "register_operand" ""))
15675    (use (match_operand:DF 2 "register_operand" ""))
15676    (use (match_operand:DF 1 "register_operand" ""))]
15677   "TARGET_USE_FANCY_MATH_387
15678    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15679    && flag_unsafe_math_optimizations"
15680 {
15681   rtx copy = gen_reg_rtx (DFmode);
15682   emit_move_insn (copy, operands[1]);
15683   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15684   DONE;
15685 })
15686
15687 (define_expand "atandf2"
15688   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15689                    (unspec:DF [(match_dup 2)
15690                                (match_operand:DF 1 "register_operand" "")]
15691                     UNSPEC_FPATAN))
15692               (clobber (match_scratch:DF 3 ""))])]
15693   "TARGET_USE_FANCY_MATH_387
15694    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15695    && flag_unsafe_math_optimizations"
15696 {
15697   operands[2] = gen_reg_rtx (DFmode);
15698   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15699 })
15700
15701 (define_insn "atan2sf3_1"
15702   [(set (match_operand:SF 0 "register_operand" "=f")
15703         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15704                     (match_operand:SF 1 "register_operand" "u")]
15705                    UNSPEC_FPATAN))
15706    (clobber (match_scratch:SF 3 "=1"))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15709    && flag_unsafe_math_optimizations"
15710   "fpatan"
15711   [(set_attr "type" "fpspc")
15712    (set_attr "mode" "SF")])
15713
15714 (define_expand "atan2sf3"
15715   [(use (match_operand:SF 0 "register_operand" ""))
15716    (use (match_operand:SF 2 "register_operand" ""))
15717    (use (match_operand:SF 1 "register_operand" ""))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15720    && flag_unsafe_math_optimizations"
15721 {
15722   rtx copy = gen_reg_rtx (SFmode);
15723   emit_move_insn (copy, operands[1]);
15724   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15725   DONE;
15726 })
15727
15728 (define_expand "atansf2"
15729   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15730                    (unspec:SF [(match_dup 2)
15731                                (match_operand:SF 1 "register_operand" "")]
15732                     UNSPEC_FPATAN))
15733               (clobber (match_scratch:SF 3 ""))])]
15734   "TARGET_USE_FANCY_MATH_387
15735    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15736    && flag_unsafe_math_optimizations"
15737 {
15738   operands[2] = gen_reg_rtx (SFmode);
15739   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15740 })
15741
15742 (define_insn "atan2xf3_1"
15743   [(set (match_operand:XF 0 "register_operand" "=f")
15744         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745                     (match_operand:XF 1 "register_operand" "u")]
15746                    UNSPEC_FPATAN))
15747    (clobber (match_scratch:XF 3 "=1"))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && flag_unsafe_math_optimizations"
15750   "fpatan"
15751   [(set_attr "type" "fpspc")
15752    (set_attr "mode" "XF")])
15753
15754 (define_expand "atan2xf3"
15755   [(use (match_operand:XF 0 "register_operand" ""))
15756    (use (match_operand:XF 2 "register_operand" ""))
15757    (use (match_operand:XF 1 "register_operand" ""))]
15758   "TARGET_USE_FANCY_MATH_387
15759    && flag_unsafe_math_optimizations"
15760 {
15761   rtx copy = gen_reg_rtx (XFmode);
15762   emit_move_insn (copy, operands[1]);
15763   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15764   DONE;
15765 })
15766
15767 (define_expand "atanxf2"
15768   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15769                    (unspec:XF [(match_dup 2)
15770                                (match_operand:XF 1 "register_operand" "")]
15771                     UNSPEC_FPATAN))
15772               (clobber (match_scratch:XF 3 ""))])]
15773   "TARGET_USE_FANCY_MATH_387
15774    && flag_unsafe_math_optimizations"
15775 {
15776   operands[2] = gen_reg_rtx (XFmode);
15777   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15778 })
15779
15780 (define_expand "asindf2"
15781   [(set (match_dup 2)
15782         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15783    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15784    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15785    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15786    (parallel [(set (match_dup 7)
15787                    (unspec:XF [(match_dup 6) (match_dup 2)]
15788                               UNSPEC_FPATAN))
15789               (clobber (match_scratch:XF 8 ""))])
15790    (set (match_operand:DF 0 "register_operand" "")
15791         (float_truncate:DF (match_dup 7)))]
15792   "TARGET_USE_FANCY_MATH_387
15793    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15794    && flag_unsafe_math_optimizations"
15795 {
15796   int i;
15797
15798   for (i=2; i<8; i++)
15799     operands[i] = gen_reg_rtx (XFmode);
15800
15801   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15802 })
15803
15804 (define_expand "asinsf2"
15805   [(set (match_dup 2)
15806         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15807    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15808    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15809    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15810    (parallel [(set (match_dup 7)
15811                    (unspec:XF [(match_dup 6) (match_dup 2)]
15812                               UNSPEC_FPATAN))
15813               (clobber (match_scratch:XF 8 ""))])
15814    (set (match_operand:SF 0 "register_operand" "")
15815         (float_truncate:SF (match_dup 7)))]
15816   "TARGET_USE_FANCY_MATH_387
15817    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15818    && flag_unsafe_math_optimizations"
15819 {
15820   int i;
15821
15822   for (i=2; i<8; i++)
15823     operands[i] = gen_reg_rtx (XFmode);
15824
15825   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15826 })
15827
15828 (define_expand "asinxf2"
15829   [(set (match_dup 2)
15830         (mult:XF (match_operand:XF 1 "register_operand" "")
15831                  (match_dup 1)))
15832    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15833    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15834    (parallel [(set (match_operand:XF 0 "register_operand" "")
15835                    (unspec:XF [(match_dup 5) (match_dup 1)]
15836                               UNSPEC_FPATAN))
15837               (clobber (match_scratch:XF 6 ""))])]
15838   "TARGET_USE_FANCY_MATH_387
15839    && flag_unsafe_math_optimizations"
15840 {
15841   int i;
15842
15843   for (i=2; i<6; i++)
15844     operands[i] = gen_reg_rtx (XFmode);
15845
15846   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15847 })
15848
15849 (define_expand "acosdf2"
15850   [(set (match_dup 2)
15851         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15852    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15853    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15854    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15855    (parallel [(set (match_dup 7)
15856                    (unspec:XF [(match_dup 2) (match_dup 6)]
15857                               UNSPEC_FPATAN))
15858               (clobber (match_scratch:XF 8 ""))])
15859    (set (match_operand:DF 0 "register_operand" "")
15860         (float_truncate:DF (match_dup 7)))]
15861   "TARGET_USE_FANCY_MATH_387
15862    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15863    && flag_unsafe_math_optimizations"
15864 {
15865   int i;
15866
15867   for (i=2; i<8; i++)
15868     operands[i] = gen_reg_rtx (XFmode);
15869
15870   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15871 })
15872
15873 (define_expand "acossf2"
15874   [(set (match_dup 2)
15875         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15876    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15877    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15878    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15879    (parallel [(set (match_dup 7)
15880                    (unspec:XF [(match_dup 2) (match_dup 6)]
15881                               UNSPEC_FPATAN))
15882               (clobber (match_scratch:XF 8 ""))])
15883    (set (match_operand:SF 0 "register_operand" "")
15884         (float_truncate:SF (match_dup 7)))]
15885   "TARGET_USE_FANCY_MATH_387
15886    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887    && flag_unsafe_math_optimizations"
15888 {
15889   int i;
15890
15891   for (i=2; i<8; i++)
15892     operands[i] = gen_reg_rtx (XFmode);
15893
15894   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15895 })
15896
15897 (define_expand "acosxf2"
15898   [(set (match_dup 2)
15899         (mult:XF (match_operand:XF 1 "register_operand" "")
15900                  (match_dup 1)))
15901    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15902    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15903    (parallel [(set (match_operand:XF 0 "register_operand" "")
15904                    (unspec:XF [(match_dup 1) (match_dup 5)]
15905                               UNSPEC_FPATAN))
15906               (clobber (match_scratch:XF 6 ""))])]
15907   "TARGET_USE_FANCY_MATH_387
15908    && flag_unsafe_math_optimizations"
15909 {
15910   int i;
15911
15912   for (i=2; i<6; i++)
15913     operands[i] = gen_reg_rtx (XFmode);
15914
15915   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15916 })
15917
15918 (define_insn "fyl2x_xf3"
15919   [(set (match_operand:XF 0 "register_operand" "=f")
15920         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15921                     (match_operand:XF 1 "register_operand" "u")]
15922                    UNSPEC_FYL2X))
15923    (clobber (match_scratch:XF 3 "=1"))]
15924   "TARGET_USE_FANCY_MATH_387
15925    && flag_unsafe_math_optimizations"
15926   "fyl2x"
15927   [(set_attr "type" "fpspc")
15928    (set_attr "mode" "XF")])
15929
15930 (define_expand "logsf2"
15931   [(set (match_dup 2)
15932         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15933    (parallel [(set (match_dup 4)
15934                    (unspec:XF [(match_dup 2)
15935                                (match_dup 3)] UNSPEC_FYL2X))
15936               (clobber (match_scratch:XF 5 ""))])
15937    (set (match_operand:SF 0 "register_operand" "")
15938         (float_truncate:SF (match_dup 4)))]
15939   "TARGET_USE_FANCY_MATH_387
15940    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15941    && flag_unsafe_math_optimizations"
15942 {
15943   rtx temp;
15944
15945   operands[2] = gen_reg_rtx (XFmode);
15946   operands[3] = gen_reg_rtx (XFmode);
15947   operands[4] = gen_reg_rtx (XFmode);
15948
15949   temp = standard_80387_constant_rtx (4); /* fldln2 */
15950   emit_move_insn (operands[3], temp);
15951 })
15952
15953 (define_expand "logdf2"
15954   [(set (match_dup 2)
15955         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15956    (parallel [(set (match_dup 4)
15957                    (unspec:XF [(match_dup 2)
15958                                (match_dup 3)] UNSPEC_FYL2X))
15959               (clobber (match_scratch:XF 5 ""))])
15960    (set (match_operand:DF 0 "register_operand" "")
15961         (float_truncate:DF (match_dup 4)))]
15962   "TARGET_USE_FANCY_MATH_387
15963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15964    && flag_unsafe_math_optimizations"
15965 {
15966   rtx temp;
15967
15968   operands[2] = gen_reg_rtx (XFmode);
15969   operands[3] = gen_reg_rtx (XFmode);
15970   operands[4] = gen_reg_rtx (XFmode);
15971
15972   temp = standard_80387_constant_rtx (4); /* fldln2 */
15973   emit_move_insn (operands[3], temp);
15974 })
15975
15976 (define_expand "logxf2"
15977   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15978                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15979                                (match_dup 2)] UNSPEC_FYL2X))
15980               (clobber (match_scratch:XF 3 ""))])]
15981   "TARGET_USE_FANCY_MATH_387
15982    && flag_unsafe_math_optimizations"
15983 {
15984   rtx temp;
15985
15986   operands[2] = gen_reg_rtx (XFmode);
15987   temp = standard_80387_constant_rtx (4); /* fldln2 */
15988   emit_move_insn (operands[2], temp);
15989 })
15990
15991 (define_expand "log10sf2"
15992   [(set (match_dup 2)
15993         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15994    (parallel [(set (match_dup 4)
15995                    (unspec:XF [(match_dup 2)
15996                                (match_dup 3)] UNSPEC_FYL2X))
15997               (clobber (match_scratch:XF 5 ""))])
15998    (set (match_operand:SF 0 "register_operand" "")
15999         (float_truncate:SF (match_dup 4)))]
16000   "TARGET_USE_FANCY_MATH_387
16001    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16002    && flag_unsafe_math_optimizations"
16003 {
16004   rtx temp;
16005
16006   operands[2] = gen_reg_rtx (XFmode);
16007   operands[3] = gen_reg_rtx (XFmode);
16008   operands[4] = gen_reg_rtx (XFmode);
16009
16010   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16011   emit_move_insn (operands[3], temp);
16012 })
16013
16014 (define_expand "log10df2"
16015   [(set (match_dup 2)
16016         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16017    (parallel [(set (match_dup 4)
16018                    (unspec:XF [(match_dup 2)
16019                                (match_dup 3)] UNSPEC_FYL2X))
16020               (clobber (match_scratch:XF 5 ""))])
16021    (set (match_operand:DF 0 "register_operand" "")
16022         (float_truncate:DF (match_dup 4)))]
16023   "TARGET_USE_FANCY_MATH_387
16024    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16025    && flag_unsafe_math_optimizations"
16026 {
16027   rtx temp;
16028
16029   operands[2] = gen_reg_rtx (XFmode);
16030   operands[3] = gen_reg_rtx (XFmode);
16031   operands[4] = gen_reg_rtx (XFmode);
16032
16033   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16034   emit_move_insn (operands[3], temp);
16035 })
16036
16037 (define_expand "log10xf2"
16038   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16039                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16040                                (match_dup 2)] UNSPEC_FYL2X))
16041               (clobber (match_scratch:XF 3 ""))])]
16042   "TARGET_USE_FANCY_MATH_387
16043    && flag_unsafe_math_optimizations"
16044 {
16045   rtx temp;
16046
16047   operands[2] = gen_reg_rtx (XFmode);
16048   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16049   emit_move_insn (operands[2], temp);
16050 })
16051
16052 (define_expand "log2sf2"
16053   [(set (match_dup 2)
16054         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16055    (parallel [(set (match_dup 4)
16056                    (unspec:XF [(match_dup 2)
16057                                (match_dup 3)] UNSPEC_FYL2X))
16058               (clobber (match_scratch:XF 5 ""))])
16059    (set (match_operand:SF 0 "register_operand" "")
16060         (float_truncate:SF (match_dup 4)))]
16061   "TARGET_USE_FANCY_MATH_387
16062    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16063    && flag_unsafe_math_optimizations"
16064 {
16065   operands[2] = gen_reg_rtx (XFmode);
16066   operands[3] = gen_reg_rtx (XFmode);
16067   operands[4] = gen_reg_rtx (XFmode);
16068
16069   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16070 })
16071
16072 (define_expand "log2df2"
16073   [(set (match_dup 2)
16074         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16075    (parallel [(set (match_dup 4)
16076                    (unspec:XF [(match_dup 2)
16077                                (match_dup 3)] UNSPEC_FYL2X))
16078               (clobber (match_scratch:XF 5 ""))])
16079    (set (match_operand:DF 0 "register_operand" "")
16080         (float_truncate:DF (match_dup 4)))]
16081   "TARGET_USE_FANCY_MATH_387
16082    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16083    && flag_unsafe_math_optimizations"
16084 {
16085   operands[2] = gen_reg_rtx (XFmode);
16086   operands[3] = gen_reg_rtx (XFmode);
16087   operands[4] = gen_reg_rtx (XFmode);
16088
16089   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16090 })
16091
16092 (define_expand "log2xf2"
16093   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16094                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16095                                (match_dup 2)] UNSPEC_FYL2X))
16096               (clobber (match_scratch:XF 3 ""))])]
16097   "TARGET_USE_FANCY_MATH_387
16098    && flag_unsafe_math_optimizations"
16099 {
16100   operands[2] = gen_reg_rtx (XFmode);
16101   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16102 })
16103
16104 (define_insn "fyl2xp1_xf3"
16105   [(set (match_operand:XF 0 "register_operand" "=f")
16106         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16107                     (match_operand:XF 1 "register_operand" "u")]
16108                    UNSPEC_FYL2XP1))
16109    (clobber (match_scratch:XF 3 "=1"))]
16110   "TARGET_USE_FANCY_MATH_387
16111    && flag_unsafe_math_optimizations"
16112   "fyl2xp1"
16113   [(set_attr "type" "fpspc")
16114    (set_attr "mode" "XF")])
16115
16116 (define_expand "log1psf2"
16117   [(use (match_operand:SF 0 "register_operand" ""))
16118    (use (match_operand:SF 1 "register_operand" ""))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16121    && flag_unsafe_math_optimizations"
16122 {
16123   rtx op0 = gen_reg_rtx (XFmode);
16124   rtx op1 = gen_reg_rtx (XFmode);
16125
16126   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16127   ix86_emit_i387_log1p (op0, op1);
16128   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16129   DONE;
16130 })
16131
16132 (define_expand "log1pdf2"
16133   [(use (match_operand:DF 0 "register_operand" ""))
16134    (use (match_operand:DF 1 "register_operand" ""))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16137    && flag_unsafe_math_optimizations"
16138 {
16139   rtx op0 = gen_reg_rtx (XFmode);
16140   rtx op1 = gen_reg_rtx (XFmode);
16141
16142   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16143   ix86_emit_i387_log1p (op0, op1);
16144   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16145   DONE;
16146 })
16147
16148 (define_expand "log1pxf2"
16149   [(use (match_operand:XF 0 "register_operand" ""))
16150    (use (match_operand:XF 1 "register_operand" ""))]
16151   "TARGET_USE_FANCY_MATH_387
16152    && flag_unsafe_math_optimizations"
16153 {
16154   ix86_emit_i387_log1p (operands[0], operands[1]);
16155   DONE;
16156 })
16157
16158 (define_insn "*fxtractxf3"
16159   [(set (match_operand:XF 0 "register_operand" "=f")
16160         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16161                    UNSPEC_XTRACT_FRACT))
16162    (set (match_operand:XF 1 "register_operand" "=u")
16163         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16164   "TARGET_USE_FANCY_MATH_387
16165    && flag_unsafe_math_optimizations"
16166   "fxtract"
16167   [(set_attr "type" "fpspc")
16168    (set_attr "mode" "XF")])
16169
16170 (define_expand "logbsf2"
16171   [(set (match_dup 2)
16172         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16173    (parallel [(set (match_dup 3)
16174                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16175               (set (match_dup 4)
16176                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16177    (set (match_operand:SF 0 "register_operand" "")
16178         (float_truncate:SF (match_dup 4)))]
16179   "TARGET_USE_FANCY_MATH_387
16180    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16181    && flag_unsafe_math_optimizations"
16182 {
16183   operands[2] = gen_reg_rtx (XFmode);
16184   operands[3] = gen_reg_rtx (XFmode);
16185   operands[4] = gen_reg_rtx (XFmode);
16186 })
16187
16188 (define_expand "logbdf2"
16189   [(set (match_dup 2)
16190         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16191    (parallel [(set (match_dup 3)
16192                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16193               (set (match_dup 4)
16194                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16195    (set (match_operand:DF 0 "register_operand" "")
16196         (float_truncate:DF (match_dup 4)))]
16197   "TARGET_USE_FANCY_MATH_387
16198    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16199    && flag_unsafe_math_optimizations"
16200 {
16201   operands[2] = gen_reg_rtx (XFmode);
16202   operands[3] = gen_reg_rtx (XFmode);
16203   operands[4] = gen_reg_rtx (XFmode);
16204 })
16205
16206 (define_expand "logbxf2"
16207   [(parallel [(set (match_dup 2)
16208                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16209                               UNSPEC_XTRACT_FRACT))
16210               (set (match_operand:XF 0 "register_operand" "")
16211                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16212   "TARGET_USE_FANCY_MATH_387
16213    && flag_unsafe_math_optimizations"
16214 {
16215   operands[2] = gen_reg_rtx (XFmode);
16216 })
16217
16218 (define_expand "ilogbsi2"
16219   [(parallel [(set (match_dup 2)
16220                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16221                               UNSPEC_XTRACT_FRACT))
16222               (set (match_operand:XF 3 "register_operand" "")
16223                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16224    (parallel [(set (match_operand:SI 0 "register_operand" "")
16225                    (fix:SI (match_dup 3)))
16226               (clobber (reg:CC FLAGS_REG))])]
16227   "TARGET_USE_FANCY_MATH_387
16228    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations"
16230 {
16231   operands[2] = gen_reg_rtx (XFmode);
16232   operands[3] = gen_reg_rtx (XFmode);
16233 })
16234
16235 (define_insn "*f2xm1xf2"
16236   [(set (match_operand:XF 0 "register_operand" "=f")
16237         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16238          UNSPEC_F2XM1))]
16239   "TARGET_USE_FANCY_MATH_387
16240    && flag_unsafe_math_optimizations"
16241   "f2xm1"
16242   [(set_attr "type" "fpspc")
16243    (set_attr "mode" "XF")])
16244
16245 (define_insn "*fscalexf4"
16246   [(set (match_operand:XF 0 "register_operand" "=f")
16247         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16248                     (match_operand:XF 3 "register_operand" "1")]
16249                    UNSPEC_FSCALE_FRACT))
16250    (set (match_operand:XF 1 "register_operand" "=u")
16251         (unspec:XF [(match_dup 2) (match_dup 3)]
16252                    UNSPEC_FSCALE_EXP))]
16253   "TARGET_USE_FANCY_MATH_387
16254    && flag_unsafe_math_optimizations"
16255   "fscale"
16256   [(set_attr "type" "fpspc")
16257    (set_attr "mode" "XF")])
16258
16259 (define_expand "expsf2"
16260   [(set (match_dup 2)
16261         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16262    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16263    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16264    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16265    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16266    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16267    (parallel [(set (match_dup 10)
16268                    (unspec:XF [(match_dup 9) (match_dup 5)]
16269                               UNSPEC_FSCALE_FRACT))
16270               (set (match_dup 11)
16271                    (unspec:XF [(match_dup 9) (match_dup 5)]
16272                               UNSPEC_FSCALE_EXP))])
16273    (set (match_operand:SF 0 "register_operand" "")
16274         (float_truncate:SF (match_dup 10)))]
16275   "TARGET_USE_FANCY_MATH_387
16276    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16277    && flag_unsafe_math_optimizations"
16278 {
16279   rtx temp;
16280   int i;
16281
16282   for (i=2; i<12; i++)
16283     operands[i] = gen_reg_rtx (XFmode);
16284   temp = standard_80387_constant_rtx (5); /* fldl2e */
16285   emit_move_insn (operands[3], temp);
16286   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16287 })
16288
16289 (define_expand "expdf2"
16290   [(set (match_dup 2)
16291         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16292    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16293    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16294    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16295    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16296    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16297    (parallel [(set (match_dup 10)
16298                    (unspec:XF [(match_dup 9) (match_dup 5)]
16299                               UNSPEC_FSCALE_FRACT))
16300               (set (match_dup 11)
16301                    (unspec:XF [(match_dup 9) (match_dup 5)]
16302                               UNSPEC_FSCALE_EXP))])
16303    (set (match_operand:DF 0 "register_operand" "")
16304         (float_truncate:DF (match_dup 10)))]
16305   "TARGET_USE_FANCY_MATH_387
16306    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16307    && flag_unsafe_math_optimizations"
16308 {
16309   rtx temp;
16310   int i;
16311
16312   for (i=2; i<12; i++)
16313     operands[i] = gen_reg_rtx (XFmode);
16314   temp = standard_80387_constant_rtx (5); /* fldl2e */
16315   emit_move_insn (operands[3], temp);
16316   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16317 })
16318
16319 (define_expand "expxf2"
16320   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16321                                (match_dup 2)))
16322    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16323    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16324    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16325    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16326    (parallel [(set (match_operand:XF 0 "register_operand" "")
16327                    (unspec:XF [(match_dup 8) (match_dup 4)]
16328                               UNSPEC_FSCALE_FRACT))
16329               (set (match_dup 9)
16330                    (unspec:XF [(match_dup 8) (match_dup 4)]
16331                               UNSPEC_FSCALE_EXP))])]
16332   "TARGET_USE_FANCY_MATH_387
16333    && flag_unsafe_math_optimizations"
16334 {
16335   rtx temp;
16336   int i;
16337
16338   for (i=2; i<10; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16340   temp = standard_80387_constant_rtx (5); /* fldl2e */
16341   emit_move_insn (operands[2], temp);
16342   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16343 })
16344
16345 (define_expand "exp10sf2"
16346   [(set (match_dup 2)
16347         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16348    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16349    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16350    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16351    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16352    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16353    (parallel [(set (match_dup 10)
16354                    (unspec:XF [(match_dup 9) (match_dup 5)]
16355                               UNSPEC_FSCALE_FRACT))
16356               (set (match_dup 11)
16357                    (unspec:XF [(match_dup 9) (match_dup 5)]
16358                               UNSPEC_FSCALE_EXP))])
16359    (set (match_operand:SF 0 "register_operand" "")
16360         (float_truncate:SF (match_dup 10)))]
16361   "TARGET_USE_FANCY_MATH_387
16362    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16363    && flag_unsafe_math_optimizations"
16364 {
16365   rtx temp;
16366   int i;
16367
16368   for (i=2; i<12; i++)
16369     operands[i] = gen_reg_rtx (XFmode);
16370   temp = standard_80387_constant_rtx (6); /* fldl2t */
16371   emit_move_insn (operands[3], temp);
16372   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16373 })
16374
16375 (define_expand "exp10df2"
16376   [(set (match_dup 2)
16377         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16378    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16379    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16380    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16381    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16382    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16383    (parallel [(set (match_dup 10)
16384                    (unspec:XF [(match_dup 9) (match_dup 5)]
16385                               UNSPEC_FSCALE_FRACT))
16386               (set (match_dup 11)
16387                    (unspec:XF [(match_dup 9) (match_dup 5)]
16388                               UNSPEC_FSCALE_EXP))])
16389    (set (match_operand:DF 0 "register_operand" "")
16390         (float_truncate:DF (match_dup 10)))]
16391   "TARGET_USE_FANCY_MATH_387
16392    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16393    && flag_unsafe_math_optimizations"
16394 {
16395   rtx temp;
16396   int i;
16397
16398   for (i=2; i<12; i++)
16399     operands[i] = gen_reg_rtx (XFmode);
16400   temp = standard_80387_constant_rtx (6); /* fldl2t */
16401   emit_move_insn (operands[3], temp);
16402   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16403 })
16404
16405 (define_expand "exp10xf2"
16406   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16407                                (match_dup 2)))
16408    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16409    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16410    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16411    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16412    (parallel [(set (match_operand:XF 0 "register_operand" "")
16413                    (unspec:XF [(match_dup 8) (match_dup 4)]
16414                               UNSPEC_FSCALE_FRACT))
16415               (set (match_dup 9)
16416                    (unspec:XF [(match_dup 8) (match_dup 4)]
16417                               UNSPEC_FSCALE_EXP))])]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420 {
16421   rtx temp;
16422   int i;
16423
16424   for (i=2; i<10; i++)
16425     operands[i] = gen_reg_rtx (XFmode);
16426   temp = standard_80387_constant_rtx (6); /* fldl2t */
16427   emit_move_insn (operands[2], temp);
16428   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16429 })
16430
16431 (define_expand "exp2sf2"
16432   [(set (match_dup 2)
16433         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16434    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16435    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16436    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16437    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16438    (parallel [(set (match_dup 8)
16439                    (unspec:XF [(match_dup 7) (match_dup 3)]
16440                               UNSPEC_FSCALE_FRACT))
16441               (set (match_dup 9)
16442                    (unspec:XF [(match_dup 7) (match_dup 3)]
16443                               UNSPEC_FSCALE_EXP))])
16444    (set (match_operand:SF 0 "register_operand" "")
16445         (float_truncate:SF (match_dup 8)))]
16446   "TARGET_USE_FANCY_MATH_387
16447    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16448    && flag_unsafe_math_optimizations"
16449 {
16450   int i;
16451
16452   for (i=2; i<10; i++)
16453     operands[i] = gen_reg_rtx (XFmode);
16454   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16455 })
16456
16457 (define_expand "exp2df2"
16458   [(set (match_dup 2)
16459         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16460    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16461    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16462    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16463    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16464    (parallel [(set (match_dup 8)
16465                    (unspec:XF [(match_dup 7) (match_dup 3)]
16466                               UNSPEC_FSCALE_FRACT))
16467               (set (match_dup 9)
16468                    (unspec:XF [(match_dup 7) (match_dup 3)]
16469                               UNSPEC_FSCALE_EXP))])
16470    (set (match_operand:DF 0 "register_operand" "")
16471         (float_truncate:DF (match_dup 8)))]
16472   "TARGET_USE_FANCY_MATH_387
16473    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16474    && flag_unsafe_math_optimizations"
16475 {
16476   int i;
16477
16478   for (i=2; i<10; i++)
16479     operands[i] = gen_reg_rtx (XFmode);
16480   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16481 })
16482
16483 (define_expand "exp2xf2"
16484   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16485    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16486    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16487    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16488    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16489    (parallel [(set (match_operand:XF 0 "register_operand" "")
16490                    (unspec:XF [(match_dup 7) (match_dup 3)]
16491                               UNSPEC_FSCALE_FRACT))
16492               (set (match_dup 8)
16493                    (unspec:XF [(match_dup 7) (match_dup 3)]
16494                               UNSPEC_FSCALE_EXP))])]
16495   "TARGET_USE_FANCY_MATH_387
16496    && flag_unsafe_math_optimizations"
16497 {
16498   int i;
16499
16500   for (i=2; i<9; i++)
16501     operands[i] = gen_reg_rtx (XFmode);
16502   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16503 })
16504
16505 (define_expand "expm1df2"
16506   [(set (match_dup 2)
16507         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16508    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16509    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16510    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16511    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16512    (parallel [(set (match_dup 8)
16513                    (unspec:XF [(match_dup 7) (match_dup 5)]
16514                               UNSPEC_FSCALE_FRACT))
16515                    (set (match_dup 9)
16516                    (unspec:XF [(match_dup 7) (match_dup 5)]
16517                               UNSPEC_FSCALE_EXP))])
16518    (parallel [(set (match_dup 11)
16519                    (unspec:XF [(match_dup 10) (match_dup 9)]
16520                               UNSPEC_FSCALE_FRACT))
16521               (set (match_dup 12)
16522                    (unspec:XF [(match_dup 10) (match_dup 9)]
16523                               UNSPEC_FSCALE_EXP))])
16524    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16525    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16526    (set (match_operand:DF 0 "register_operand" "")
16527         (float_truncate:DF (match_dup 14)))]
16528   "TARGET_USE_FANCY_MATH_387
16529    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16530    && flag_unsafe_math_optimizations"
16531 {
16532   rtx temp;
16533   int i;
16534
16535   for (i=2; i<15; i++)
16536     operands[i] = gen_reg_rtx (XFmode);
16537   temp = standard_80387_constant_rtx (5); /* fldl2e */
16538   emit_move_insn (operands[3], temp);
16539   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16540 })
16541
16542 (define_expand "expm1sf2"
16543   [(set (match_dup 2)
16544         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16545    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16546    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16547    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16548    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16549    (parallel [(set (match_dup 8)
16550                    (unspec:XF [(match_dup 7) (match_dup 5)]
16551                               UNSPEC_FSCALE_FRACT))
16552                    (set (match_dup 9)
16553                    (unspec:XF [(match_dup 7) (match_dup 5)]
16554                               UNSPEC_FSCALE_EXP))])
16555    (parallel [(set (match_dup 11)
16556                    (unspec:XF [(match_dup 10) (match_dup 9)]
16557                               UNSPEC_FSCALE_FRACT))
16558               (set (match_dup 12)
16559                    (unspec:XF [(match_dup 10) (match_dup 9)]
16560                               UNSPEC_FSCALE_EXP))])
16561    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16562    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16563    (set (match_operand:SF 0 "register_operand" "")
16564         (float_truncate:SF (match_dup 14)))]
16565   "TARGET_USE_FANCY_MATH_387
16566    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16567    && flag_unsafe_math_optimizations"
16568 {
16569   rtx temp;
16570   int i;
16571
16572   for (i=2; i<15; i++)
16573     operands[i] = gen_reg_rtx (XFmode);
16574   temp = standard_80387_constant_rtx (5); /* fldl2e */
16575   emit_move_insn (operands[3], temp);
16576   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16577 })
16578
16579 (define_expand "expm1xf2"
16580   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16581                                (match_dup 2)))
16582    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16583    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16584    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16585    (parallel [(set (match_dup 7)
16586                    (unspec:XF [(match_dup 6) (match_dup 4)]
16587                               UNSPEC_FSCALE_FRACT))
16588                    (set (match_dup 8)
16589                    (unspec:XF [(match_dup 6) (match_dup 4)]
16590                               UNSPEC_FSCALE_EXP))])
16591    (parallel [(set (match_dup 10)
16592                    (unspec:XF [(match_dup 9) (match_dup 8)]
16593                               UNSPEC_FSCALE_FRACT))
16594               (set (match_dup 11)
16595                    (unspec:XF [(match_dup 9) (match_dup 8)]
16596                               UNSPEC_FSCALE_EXP))])
16597    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16598    (set (match_operand:XF 0 "register_operand" "")
16599         (plus:XF (match_dup 12) (match_dup 7)))]
16600   "TARGET_USE_FANCY_MATH_387
16601    && flag_unsafe_math_optimizations"
16602 {
16603   rtx temp;
16604   int i;
16605
16606   for (i=2; i<13; i++)
16607     operands[i] = gen_reg_rtx (XFmode);
16608   temp = standard_80387_constant_rtx (5); /* fldl2e */
16609   emit_move_insn (operands[2], temp);
16610   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16611 })
16612
16613 (define_expand "ldexpdf3"
16614   [(set (match_dup 3)
16615         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16616    (set (match_dup 4)
16617         (float:XF (match_operand:SI 2 "register_operand" "")))
16618    (parallel [(set (match_dup 5)
16619                    (unspec:XF [(match_dup 3) (match_dup 4)]
16620                               UNSPEC_FSCALE_FRACT))
16621               (set (match_dup 6)
16622                    (unspec:XF [(match_dup 3) (match_dup 4)]
16623                               UNSPEC_FSCALE_EXP))])
16624    (set (match_operand:DF 0 "register_operand" "")
16625         (float_truncate:DF (match_dup 5)))]
16626   "TARGET_USE_FANCY_MATH_387
16627    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16628    && flag_unsafe_math_optimizations"
16629 {
16630   int i;
16631
16632   for (i=3; i<7; i++)
16633     operands[i] = gen_reg_rtx (XFmode);
16634 })
16635
16636 (define_expand "ldexpsf3"
16637   [(set (match_dup 3)
16638         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16639    (set (match_dup 4)
16640         (float:XF (match_operand:SI 2 "register_operand" "")))
16641    (parallel [(set (match_dup 5)
16642                    (unspec:XF [(match_dup 3) (match_dup 4)]
16643                               UNSPEC_FSCALE_FRACT))
16644               (set (match_dup 6)
16645                    (unspec:XF [(match_dup 3) (match_dup 4)]
16646                               UNSPEC_FSCALE_EXP))])
16647    (set (match_operand:SF 0 "register_operand" "")
16648         (float_truncate:SF (match_dup 5)))]
16649   "TARGET_USE_FANCY_MATH_387
16650    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16652 {
16653   int i;
16654
16655   for (i=3; i<7; i++)
16656     operands[i] = gen_reg_rtx (XFmode);
16657 })
16658
16659 (define_expand "ldexpxf3"
16660   [(set (match_dup 3)
16661         (float:XF (match_operand:SI 2 "register_operand" "")))
16662    (parallel [(set (match_operand:XF 0 " register_operand" "")
16663                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16664                                (match_dup 3)]
16665                               UNSPEC_FSCALE_FRACT))
16666               (set (match_dup 4)
16667                    (unspec:XF [(match_dup 1) (match_dup 3)]
16668                               UNSPEC_FSCALE_EXP))])]
16669   "TARGET_USE_FANCY_MATH_387
16670    && flag_unsafe_math_optimizations"
16671 {
16672   int i;
16673
16674   for (i=3; i<5; i++)
16675     operands[i] = gen_reg_rtx (XFmode);
16676 })
16677 \f
16678
16679 (define_insn "frndintxf2"
16680   [(set (match_operand:XF 0 "register_operand" "=f")
16681         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16682          UNSPEC_FRNDINT))]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16685   "frndint"
16686   [(set_attr "type" "fpspc")
16687    (set_attr "mode" "XF")])
16688
16689 (define_expand "rintdf2"
16690   [(use (match_operand:DF 0 "register_operand" ""))
16691    (use (match_operand:DF 1 "register_operand" ""))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694    && flag_unsafe_math_optimizations"
16695 {
16696   rtx op0 = gen_reg_rtx (XFmode);
16697   rtx op1 = gen_reg_rtx (XFmode);
16698
16699   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16700   emit_insn (gen_frndintxf2 (op0, op1));
16701
16702   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16703   DONE;
16704 })
16705
16706 (define_expand "rintsf2"
16707   [(use (match_operand:SF 0 "register_operand" ""))
16708    (use (match_operand:SF 1 "register_operand" ""))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16711    && flag_unsafe_math_optimizations"
16712 {
16713   rtx op0 = gen_reg_rtx (XFmode);
16714   rtx op1 = gen_reg_rtx (XFmode);
16715
16716   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16717   emit_insn (gen_frndintxf2 (op0, op1));
16718
16719   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16720   DONE;
16721 })
16722
16723 (define_expand "rintxf2"
16724   [(use (match_operand:XF 0 "register_operand" ""))
16725    (use (match_operand:XF 1 "register_operand" ""))]
16726   "TARGET_USE_FANCY_MATH_387
16727    && flag_unsafe_math_optimizations"
16728 {
16729   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16730   DONE;
16731 })
16732
16733 (define_insn_and_split "*fistdi2_1"
16734   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16735         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16736          UNSPEC_FIST))]
16737   "TARGET_USE_FANCY_MATH_387
16738    && flag_unsafe_math_optimizations
16739    && !(reload_completed || reload_in_progress)"
16740   "#"
16741   "&& 1"
16742   [(const_int 0)]
16743 {
16744   if (memory_operand (operands[0], VOIDmode))
16745     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16746   else
16747     {
16748       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16749       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16750                                          operands[2]));
16751     }
16752   DONE;
16753 }
16754   [(set_attr "type" "fpspc")
16755    (set_attr "mode" "DI")])
16756
16757 (define_insn "fistdi2"
16758   [(set (match_operand:DI 0 "memory_operand" "=m")
16759         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16760          UNSPEC_FIST))
16761    (clobber (match_scratch:XF 2 "=&1f"))]
16762   "TARGET_USE_FANCY_MATH_387
16763    && flag_unsafe_math_optimizations"
16764   "* return output_fix_trunc (insn, operands, 0);"
16765   [(set_attr "type" "fpspc")
16766    (set_attr "mode" "DI")])
16767
16768 (define_insn "fistdi2_with_temp"
16769   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16770         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16771          UNSPEC_FIST))
16772    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16773    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16774   "TARGET_USE_FANCY_MATH_387
16775    && flag_unsafe_math_optimizations"
16776   "#"
16777   [(set_attr "type" "fpspc")
16778    (set_attr "mode" "DI")])
16779
16780 (define_split 
16781   [(set (match_operand:DI 0 "register_operand" "")
16782         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16783          UNSPEC_FIST))
16784    (clobber (match_operand:DI 2 "memory_operand" ""))
16785    (clobber (match_scratch 3 ""))]
16786   "reload_completed"
16787   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16788               (clobber (match_dup 3))])
16789    (set (match_dup 0) (match_dup 2))]
16790   "")
16791
16792 (define_split 
16793   [(set (match_operand:DI 0 "memory_operand" "")
16794         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16795          UNSPEC_FIST))
16796    (clobber (match_operand:DI 2 "memory_operand" ""))
16797    (clobber (match_scratch 3 ""))]
16798   "reload_completed"
16799   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16800               (clobber (match_dup 3))])]
16801   "")
16802
16803 (define_insn_and_split "*fist<mode>2_1"
16804   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16805         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16806          UNSPEC_FIST))]
16807   "TARGET_USE_FANCY_MATH_387
16808    && flag_unsafe_math_optimizations
16809    && !(reload_completed || reload_in_progress)"
16810   "#"
16811   "&& 1"
16812   [(const_int 0)]
16813 {
16814   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16815   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16816                                         operands[2]));
16817   DONE;
16818 }
16819   [(set_attr "type" "fpspc")
16820    (set_attr "mode" "<MODE>")])
16821
16822 (define_insn "fist<mode>2"
16823   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16824         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16825          UNSPEC_FIST))]
16826   "TARGET_USE_FANCY_MATH_387
16827    && flag_unsafe_math_optimizations"
16828   "* return output_fix_trunc (insn, operands, 0);"
16829   [(set_attr "type" "fpspc")
16830    (set_attr "mode" "<MODE>")])
16831
16832 (define_insn "fist<mode>2_with_temp"
16833   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16834         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16835          UNSPEC_FIST))
16836    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16837   "TARGET_USE_FANCY_MATH_387
16838    && flag_unsafe_math_optimizations"
16839   "#"
16840   [(set_attr "type" "fpspc")
16841    (set_attr "mode" "<MODE>")])
16842
16843 (define_split 
16844   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16845         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16846          UNSPEC_FIST))
16847    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16848   "reload_completed"
16849   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16850                        UNSPEC_FIST))
16851    (set (match_dup 0) (match_dup 2))]
16852   "")
16853
16854 (define_split 
16855   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16856         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16857          UNSPEC_FIST))
16858    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16859   "reload_completed"
16860   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16861                        UNSPEC_FIST))]
16862   "")
16863
16864 (define_expand "lrint<mode>2"
16865   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16866         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16867          UNSPEC_FIST))]
16868   "TARGET_USE_FANCY_MATH_387
16869    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16870    && flag_unsafe_math_optimizations"
16871   "")
16872
16873 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16874 (define_insn_and_split "frndintxf2_floor"
16875   [(set (match_operand:XF 0 "register_operand" "=f")
16876         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16877          UNSPEC_FRNDINT_FLOOR))
16878    (clobber (reg:CC FLAGS_REG))]
16879   "TARGET_USE_FANCY_MATH_387
16880    && flag_unsafe_math_optimizations
16881    && !(reload_completed || reload_in_progress)"
16882   "#"
16883   "&& 1"
16884   [(const_int 0)]
16885 {
16886   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16887
16888   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16889   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16890
16891   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16892                                         operands[2], operands[3]));
16893   DONE;
16894 }
16895   [(set_attr "type" "frndint")
16896    (set_attr "i387_cw" "floor")
16897    (set_attr "mode" "XF")])
16898
16899 (define_insn "frndintxf2_floor_i387"
16900   [(set (match_operand:XF 0 "register_operand" "=f")
16901         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16902          UNSPEC_FRNDINT_FLOOR))
16903    (use (match_operand:HI 2 "memory_operand" "m"))
16904    (use (match_operand:HI 3 "memory_operand" "m"))]
16905   "TARGET_USE_FANCY_MATH_387
16906    && flag_unsafe_math_optimizations"
16907   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16908   [(set_attr "type" "frndint")
16909    (set_attr "i387_cw" "floor")
16910    (set_attr "mode" "XF")])
16911
16912 (define_expand "floorxf2"
16913   [(use (match_operand:XF 0 "register_operand" ""))
16914    (use (match_operand:XF 1 "register_operand" ""))]
16915   "TARGET_USE_FANCY_MATH_387
16916    && flag_unsafe_math_optimizations"
16917 {
16918   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16919   DONE;
16920 })
16921
16922 (define_expand "floordf2"
16923   [(use (match_operand:DF 0 "register_operand" ""))
16924    (use (match_operand:DF 1 "register_operand" ""))]
16925   "TARGET_USE_FANCY_MATH_387
16926    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16927    && flag_unsafe_math_optimizations"
16928 {
16929   rtx op0 = gen_reg_rtx (XFmode);
16930   rtx op1 = gen_reg_rtx (XFmode);
16931
16932   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16933   emit_insn (gen_frndintxf2_floor (op0, op1));
16934
16935   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16936   DONE;
16937 })
16938
16939 (define_expand "floorsf2"
16940   [(use (match_operand:SF 0 "register_operand" ""))
16941    (use (match_operand:SF 1 "register_operand" ""))]
16942   "TARGET_USE_FANCY_MATH_387
16943    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16944    && flag_unsafe_math_optimizations"
16945 {
16946   rtx op0 = gen_reg_rtx (XFmode);
16947   rtx op1 = gen_reg_rtx (XFmode);
16948
16949   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16950   emit_insn (gen_frndintxf2_floor (op0, op1));
16951
16952   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16953   DONE;
16954 })
16955
16956 (define_insn_and_split "*fist<mode>2_floor_1"
16957   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16958         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16959          UNSPEC_FIST_FLOOR))
16960    (clobber (reg:CC FLAGS_REG))]
16961   "TARGET_USE_FANCY_MATH_387
16962    && flag_unsafe_math_optimizations
16963    && !(reload_completed || reload_in_progress)"
16964   "#"
16965   "&& 1"
16966   [(const_int 0)]
16967 {
16968   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16969
16970   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16971   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16972   if (memory_operand (operands[0], VOIDmode))
16973     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16974                                       operands[2], operands[3]));
16975   else
16976     {
16977       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16978       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16979                                                   operands[2], operands[3],
16980                                                   operands[4]));
16981     }
16982   DONE;
16983 }
16984   [(set_attr "type" "fistp")
16985    (set_attr "i387_cw" "floor")
16986    (set_attr "mode" "<MODE>")])
16987
16988 (define_insn "fistdi2_floor"
16989   [(set (match_operand:DI 0 "memory_operand" "=m")
16990         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16991          UNSPEC_FIST_FLOOR))
16992    (use (match_operand:HI 2 "memory_operand" "m"))
16993    (use (match_operand:HI 3 "memory_operand" "m"))
16994    (clobber (match_scratch:XF 4 "=&1f"))]
16995   "TARGET_USE_FANCY_MATH_387
16996    && flag_unsafe_math_optimizations"
16997   "* return output_fix_trunc (insn, operands, 0);"
16998   [(set_attr "type" "fistp")
16999    (set_attr "i387_cw" "floor")
17000    (set_attr "mode" "DI")])
17001
17002 (define_insn "fistdi2_floor_with_temp"
17003   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17004         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17005          UNSPEC_FIST_FLOOR))
17006    (use (match_operand:HI 2 "memory_operand" "m,m"))
17007    (use (match_operand:HI 3 "memory_operand" "m,m"))
17008    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17009    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && flag_unsafe_math_optimizations"
17012   "#"
17013   [(set_attr "type" "fistp")
17014    (set_attr "i387_cw" "floor")
17015    (set_attr "mode" "DI")])
17016
17017 (define_split 
17018   [(set (match_operand:DI 0 "register_operand" "")
17019         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17020          UNSPEC_FIST_FLOOR))
17021    (use (match_operand:HI 2 "memory_operand" ""))
17022    (use (match_operand:HI 3 "memory_operand" ""))
17023    (clobber (match_operand:DI 4 "memory_operand" ""))
17024    (clobber (match_scratch 5 ""))]
17025   "reload_completed"
17026   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17027               (use (match_dup 2))
17028               (use (match_dup 3))
17029               (clobber (match_dup 5))])
17030    (set (match_dup 0) (match_dup 4))]
17031   "")
17032
17033 (define_split 
17034   [(set (match_operand:DI 0 "memory_operand" "")
17035         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17036          UNSPEC_FIST_FLOOR))
17037    (use (match_operand:HI 2 "memory_operand" ""))
17038    (use (match_operand:HI 3 "memory_operand" ""))
17039    (clobber (match_operand:DI 4 "memory_operand" ""))
17040    (clobber (match_scratch 5 ""))]
17041   "reload_completed"
17042   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17043               (use (match_dup 2))
17044               (use (match_dup 3))
17045               (clobber (match_dup 5))])]
17046   "")
17047
17048 (define_insn "fist<mode>2_floor"
17049   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17050         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17051          UNSPEC_FIST_FLOOR))
17052    (use (match_operand:HI 2 "memory_operand" "m"))
17053    (use (match_operand:HI 3 "memory_operand" "m"))]
17054   "TARGET_USE_FANCY_MATH_387
17055    && flag_unsafe_math_optimizations"
17056   "* return output_fix_trunc (insn, operands, 0);"
17057   [(set_attr "type" "fistp")
17058    (set_attr "i387_cw" "floor")
17059    (set_attr "mode" "<MODE>")])
17060
17061 (define_insn "fist<mode>2_floor_with_temp"
17062   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17063         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17064          UNSPEC_FIST_FLOOR))
17065    (use (match_operand:HI 2 "memory_operand" "m,m"))
17066    (use (match_operand:HI 3 "memory_operand" "m,m"))
17067    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17068   "TARGET_USE_FANCY_MATH_387
17069    && flag_unsafe_math_optimizations"
17070   "#"
17071   [(set_attr "type" "fistp")
17072    (set_attr "i387_cw" "floor")
17073    (set_attr "mode" "<MODE>")])
17074
17075 (define_split 
17076   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17077         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17078          UNSPEC_FIST_FLOOR))
17079    (use (match_operand:HI 2 "memory_operand" ""))
17080    (use (match_operand:HI 3 "memory_operand" ""))
17081    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17082   "reload_completed"
17083   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17084                                   UNSPEC_FIST_FLOOR))
17085               (use (match_dup 2))
17086               (use (match_dup 3))])
17087    (set (match_dup 0) (match_dup 4))]
17088   "")
17089
17090 (define_split 
17091   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17092         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17093          UNSPEC_FIST_FLOOR))
17094    (use (match_operand:HI 2 "memory_operand" ""))
17095    (use (match_operand:HI 3 "memory_operand" ""))
17096    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17097   "reload_completed"
17098   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17099                                   UNSPEC_FIST_FLOOR))
17100               (use (match_dup 2))
17101               (use (match_dup 3))])]
17102   "")
17103
17104 (define_expand "lfloor<mode>2"
17105   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17106                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17107                     UNSPEC_FIST_FLOOR))
17108               (clobber (reg:CC FLAGS_REG))])]
17109   "TARGET_USE_FANCY_MATH_387
17110    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17111    && flag_unsafe_math_optimizations"
17112   "")
17113
17114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17115 (define_insn_and_split "frndintxf2_ceil"
17116   [(set (match_operand:XF 0 "register_operand" "=f")
17117         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17118          UNSPEC_FRNDINT_CEIL))
17119    (clobber (reg:CC FLAGS_REG))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && flag_unsafe_math_optimizations
17122    && !(reload_completed || reload_in_progress)"
17123   "#"
17124   "&& 1"
17125   [(const_int 0)]
17126 {
17127   ix86_optimize_mode_switching[I387_CEIL] = 1;
17128
17129   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17130   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17131
17132   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17133                                        operands[2], operands[3]));
17134   DONE;
17135 }
17136   [(set_attr "type" "frndint")
17137    (set_attr "i387_cw" "ceil")
17138    (set_attr "mode" "XF")])
17139
17140 (define_insn "frndintxf2_ceil_i387"
17141   [(set (match_operand:XF 0 "register_operand" "=f")
17142         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17143          UNSPEC_FRNDINT_CEIL))
17144    (use (match_operand:HI 2 "memory_operand" "m"))
17145    (use (match_operand:HI 3 "memory_operand" "m"))]
17146   "TARGET_USE_FANCY_MATH_387
17147    && flag_unsafe_math_optimizations"
17148   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17149   [(set_attr "type" "frndint")
17150    (set_attr "i387_cw" "ceil")
17151    (set_attr "mode" "XF")])
17152
17153 (define_expand "ceilxf2"
17154   [(use (match_operand:XF 0 "register_operand" ""))
17155    (use (match_operand:XF 1 "register_operand" ""))]
17156   "TARGET_USE_FANCY_MATH_387
17157    && flag_unsafe_math_optimizations"
17158 {
17159   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17160   DONE;
17161 })
17162
17163 (define_expand "ceildf2"
17164   [(use (match_operand:DF 0 "register_operand" ""))
17165    (use (match_operand:DF 1 "register_operand" ""))]
17166   "TARGET_USE_FANCY_MATH_387
17167    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17168    && flag_unsafe_math_optimizations"
17169 {
17170   rtx op0 = gen_reg_rtx (XFmode);
17171   rtx op1 = gen_reg_rtx (XFmode);
17172
17173   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17174   emit_insn (gen_frndintxf2_ceil (op0, op1));
17175
17176   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17177   DONE;
17178 })
17179
17180 (define_expand "ceilsf2"
17181   [(use (match_operand:SF 0 "register_operand" ""))
17182    (use (match_operand:SF 1 "register_operand" ""))]
17183   "TARGET_USE_FANCY_MATH_387
17184    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17185    && flag_unsafe_math_optimizations"
17186 {
17187   rtx op0 = gen_reg_rtx (XFmode);
17188   rtx op1 = gen_reg_rtx (XFmode);
17189
17190   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17191   emit_insn (gen_frndintxf2_ceil (op0, op1));
17192
17193   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17194   DONE;
17195 })
17196
17197 (define_insn_and_split "*fist<mode>2_ceil_1"
17198   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17199         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17200          UNSPEC_FIST_CEIL))
17201    (clobber (reg:CC FLAGS_REG))]
17202   "TARGET_USE_FANCY_MATH_387
17203    && flag_unsafe_math_optimizations
17204    && !(reload_completed || reload_in_progress)"
17205   "#"
17206   "&& 1"
17207   [(const_int 0)]
17208 {
17209   ix86_optimize_mode_switching[I387_CEIL] = 1;
17210
17211   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17212   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17213   if (memory_operand (operands[0], VOIDmode))
17214     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17215                                      operands[2], operands[3]));
17216   else
17217     {
17218       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17219       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17220                                                  operands[2], operands[3],
17221                                                  operands[4]));
17222     }
17223   DONE;
17224 }
17225   [(set_attr "type" "fistp")
17226    (set_attr "i387_cw" "ceil")
17227    (set_attr "mode" "<MODE>")])
17228
17229 (define_insn "fistdi2_ceil"
17230   [(set (match_operand:DI 0 "memory_operand" "=m")
17231         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17232          UNSPEC_FIST_CEIL))
17233    (use (match_operand:HI 2 "memory_operand" "m"))
17234    (use (match_operand:HI 3 "memory_operand" "m"))
17235    (clobber (match_scratch:XF 4 "=&1f"))]
17236   "TARGET_USE_FANCY_MATH_387
17237    && flag_unsafe_math_optimizations"
17238   "* return output_fix_trunc (insn, operands, 0);"
17239   [(set_attr "type" "fistp")
17240    (set_attr "i387_cw" "ceil")
17241    (set_attr "mode" "DI")])
17242
17243 (define_insn "fistdi2_ceil_with_temp"
17244   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17245         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17246          UNSPEC_FIST_CEIL))
17247    (use (match_operand:HI 2 "memory_operand" "m,m"))
17248    (use (match_operand:HI 3 "memory_operand" "m,m"))
17249    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17250    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17251   "TARGET_USE_FANCY_MATH_387
17252    && flag_unsafe_math_optimizations"
17253   "#"
17254   [(set_attr "type" "fistp")
17255    (set_attr "i387_cw" "ceil")
17256    (set_attr "mode" "DI")])
17257
17258 (define_split 
17259   [(set (match_operand:DI 0 "register_operand" "")
17260         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17261          UNSPEC_FIST_CEIL))
17262    (use (match_operand:HI 2 "memory_operand" ""))
17263    (use (match_operand:HI 3 "memory_operand" ""))
17264    (clobber (match_operand:DI 4 "memory_operand" ""))
17265    (clobber (match_scratch 5 ""))]
17266   "reload_completed"
17267   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17268               (use (match_dup 2))
17269               (use (match_dup 3))
17270               (clobber (match_dup 5))])
17271    (set (match_dup 0) (match_dup 4))]
17272   "")
17273
17274 (define_split 
17275   [(set (match_operand:DI 0 "memory_operand" "")
17276         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17277          UNSPEC_FIST_CEIL))
17278    (use (match_operand:HI 2 "memory_operand" ""))
17279    (use (match_operand:HI 3 "memory_operand" ""))
17280    (clobber (match_operand:DI 4 "memory_operand" ""))
17281    (clobber (match_scratch 5 ""))]
17282   "reload_completed"
17283   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17284               (use (match_dup 2))
17285               (use (match_dup 3))
17286               (clobber (match_dup 5))])]
17287   "")
17288
17289 (define_insn "fist<mode>2_ceil"
17290   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17291         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17292          UNSPEC_FIST_CEIL))
17293    (use (match_operand:HI 2 "memory_operand" "m"))
17294    (use (match_operand:HI 3 "memory_operand" "m"))]
17295   "TARGET_USE_FANCY_MATH_387
17296    && flag_unsafe_math_optimizations"
17297   "* return output_fix_trunc (insn, operands, 0);"
17298   [(set_attr "type" "fistp")
17299    (set_attr "i387_cw" "ceil")
17300    (set_attr "mode" "<MODE>")])
17301
17302 (define_insn "fist<mode>2_ceil_with_temp"
17303   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17304         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17305          UNSPEC_FIST_CEIL))
17306    (use (match_operand:HI 2 "memory_operand" "m,m"))
17307    (use (match_operand:HI 3 "memory_operand" "m,m"))
17308    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17309   "TARGET_USE_FANCY_MATH_387
17310    && flag_unsafe_math_optimizations"
17311   "#"
17312   [(set_attr "type" "fistp")
17313    (set_attr "i387_cw" "ceil")
17314    (set_attr "mode" "<MODE>")])
17315
17316 (define_split 
17317   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17318         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17319          UNSPEC_FIST_CEIL))
17320    (use (match_operand:HI 2 "memory_operand" ""))
17321    (use (match_operand:HI 3 "memory_operand" ""))
17322    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17323   "reload_completed"
17324   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17325                                   UNSPEC_FIST_CEIL))
17326               (use (match_dup 2))
17327               (use (match_dup 3))])
17328    (set (match_dup 0) (match_dup 4))]
17329   "")
17330
17331 (define_split 
17332   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17333         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17334          UNSPEC_FIST_CEIL))
17335    (use (match_operand:HI 2 "memory_operand" ""))
17336    (use (match_operand:HI 3 "memory_operand" ""))
17337    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17338   "reload_completed"
17339   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17340                                   UNSPEC_FIST_CEIL))
17341               (use (match_dup 2))
17342               (use (match_dup 3))])]
17343   "")
17344
17345 (define_expand "lceil<mode>2"
17346   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17347                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17348                     UNSPEC_FIST_CEIL))
17349               (clobber (reg:CC FLAGS_REG))])]
17350   "TARGET_USE_FANCY_MATH_387
17351    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17352    && flag_unsafe_math_optimizations"
17353   "")
17354
17355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17356 (define_insn_and_split "frndintxf2_trunc"
17357   [(set (match_operand:XF 0 "register_operand" "=f")
17358         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17359          UNSPEC_FRNDINT_TRUNC))
17360    (clobber (reg:CC FLAGS_REG))]
17361   "TARGET_USE_FANCY_MATH_387
17362    && flag_unsafe_math_optimizations
17363    && !(reload_completed || reload_in_progress)"
17364   "#"
17365   "&& 1"
17366   [(const_int 0)]
17367 {
17368   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17369
17370   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17371   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17372
17373   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17374                                         operands[2], operands[3]));
17375   DONE;
17376 }
17377   [(set_attr "type" "frndint")
17378    (set_attr "i387_cw" "trunc")
17379    (set_attr "mode" "XF")])
17380
17381 (define_insn "frndintxf2_trunc_i387"
17382   [(set (match_operand:XF 0 "register_operand" "=f")
17383         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384          UNSPEC_FRNDINT_TRUNC))
17385    (use (match_operand:HI 2 "memory_operand" "m"))
17386    (use (match_operand:HI 3 "memory_operand" "m"))]
17387   "TARGET_USE_FANCY_MATH_387
17388    && flag_unsafe_math_optimizations"
17389   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17390   [(set_attr "type" "frndint")
17391    (set_attr "i387_cw" "trunc")
17392    (set_attr "mode" "XF")])
17393
17394 (define_expand "btruncxf2"
17395   [(use (match_operand:XF 0 "register_operand" ""))
17396    (use (match_operand:XF 1 "register_operand" ""))]
17397   "TARGET_USE_FANCY_MATH_387
17398    && flag_unsafe_math_optimizations"
17399 {
17400   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17401   DONE;
17402 })
17403
17404 (define_expand "btruncdf2"
17405   [(use (match_operand:DF 0 "register_operand" ""))
17406    (use (match_operand:DF 1 "register_operand" ""))]
17407   "TARGET_USE_FANCY_MATH_387
17408    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17409    && flag_unsafe_math_optimizations"
17410 {
17411   rtx op0 = gen_reg_rtx (XFmode);
17412   rtx op1 = gen_reg_rtx (XFmode);
17413
17414   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17415   emit_insn (gen_frndintxf2_trunc (op0, op1));
17416
17417   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17418   DONE;
17419 })
17420
17421 (define_expand "btruncsf2"
17422   [(use (match_operand:SF 0 "register_operand" ""))
17423    (use (match_operand:SF 1 "register_operand" ""))]
17424   "TARGET_USE_FANCY_MATH_387
17425    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17426    && flag_unsafe_math_optimizations"
17427 {
17428   rtx op0 = gen_reg_rtx (XFmode);
17429   rtx op1 = gen_reg_rtx (XFmode);
17430
17431   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17432   emit_insn (gen_frndintxf2_trunc (op0, op1));
17433
17434   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17435   DONE;
17436 })
17437
17438 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17439 (define_insn_and_split "frndintxf2_mask_pm"
17440   [(set (match_operand:XF 0 "register_operand" "=f")
17441         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17442          UNSPEC_FRNDINT_MASK_PM))
17443    (clobber (reg:CC FLAGS_REG))]
17444   "TARGET_USE_FANCY_MATH_387
17445    && flag_unsafe_math_optimizations
17446    && !(reload_completed || reload_in_progress)"
17447   "#"
17448   "&& 1"
17449   [(const_int 0)]
17450 {
17451   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17452
17453   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17454   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17455
17456   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17457                                           operands[2], operands[3]));
17458   DONE;
17459 }
17460   [(set_attr "type" "frndint")
17461    (set_attr "i387_cw" "mask_pm")
17462    (set_attr "mode" "XF")])
17463
17464 (define_insn "frndintxf2_mask_pm_i387"
17465   [(set (match_operand:XF 0 "register_operand" "=f")
17466         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17467          UNSPEC_FRNDINT_MASK_PM))
17468    (use (match_operand:HI 2 "memory_operand" "m"))
17469    (use (match_operand:HI 3 "memory_operand" "m"))]
17470   "TARGET_USE_FANCY_MATH_387
17471    && flag_unsafe_math_optimizations"
17472   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17473   [(set_attr "type" "frndint")
17474    (set_attr "i387_cw" "mask_pm")
17475    (set_attr "mode" "XF")])
17476
17477 (define_expand "nearbyintxf2"
17478   [(use (match_operand:XF 0 "register_operand" ""))
17479    (use (match_operand:XF 1 "register_operand" ""))]
17480   "TARGET_USE_FANCY_MATH_387
17481    && flag_unsafe_math_optimizations"
17482 {
17483   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17484
17485   DONE;
17486 })
17487
17488 (define_expand "nearbyintdf2"
17489   [(use (match_operand:DF 0 "register_operand" ""))
17490    (use (match_operand:DF 1 "register_operand" ""))]
17491   "TARGET_USE_FANCY_MATH_387
17492    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17493    && flag_unsafe_math_optimizations"
17494 {
17495   rtx op0 = gen_reg_rtx (XFmode);
17496   rtx op1 = gen_reg_rtx (XFmode);
17497
17498   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17499   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17500
17501   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17502   DONE;
17503 })
17504
17505 (define_expand "nearbyintsf2"
17506   [(use (match_operand:SF 0 "register_operand" ""))
17507    (use (match_operand:SF 1 "register_operand" ""))]
17508   "TARGET_USE_FANCY_MATH_387
17509    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17510    && flag_unsafe_math_optimizations"
17511 {
17512   rtx op0 = gen_reg_rtx (XFmode);
17513   rtx op1 = gen_reg_rtx (XFmode);
17514
17515   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17516   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17517
17518   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17519   DONE;
17520 })
17521
17522 \f
17523 ;; Block operation instructions
17524
17525 (define_insn "cld"
17526  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17527  ""
17528  "cld"
17529   [(set_attr "type" "cld")])
17530
17531 (define_expand "movmemsi"
17532   [(use (match_operand:BLK 0 "memory_operand" ""))
17533    (use (match_operand:BLK 1 "memory_operand" ""))
17534    (use (match_operand:SI 2 "nonmemory_operand" ""))
17535    (use (match_operand:SI 3 "const_int_operand" ""))]
17536   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17537 {
17538  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17539    DONE;
17540  else
17541    FAIL;
17542 })
17543
17544 (define_expand "movmemdi"
17545   [(use (match_operand:BLK 0 "memory_operand" ""))
17546    (use (match_operand:BLK 1 "memory_operand" ""))
17547    (use (match_operand:DI 2 "nonmemory_operand" ""))
17548    (use (match_operand:DI 3 "const_int_operand" ""))]
17549   "TARGET_64BIT"
17550 {
17551  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17552    DONE;
17553  else
17554    FAIL;
17555 })
17556
17557 ;; Most CPUs don't like single string operations
17558 ;; Handle this case here to simplify previous expander.
17559
17560 (define_expand "strmov"
17561   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17562    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17563    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17564               (clobber (reg:CC FLAGS_REG))])
17565    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17566               (clobber (reg:CC FLAGS_REG))])]
17567   ""
17568 {
17569   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17570
17571   /* If .md ever supports :P for Pmode, these can be directly
17572      in the pattern above.  */
17573   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17574   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17575
17576   if (TARGET_SINGLE_STRINGOP || optimize_size)
17577     {
17578       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17579                                       operands[2], operands[3],
17580                                       operands[5], operands[6]));
17581       DONE;
17582     }
17583
17584   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17585 })
17586
17587 (define_expand "strmov_singleop"
17588   [(parallel [(set (match_operand 1 "memory_operand" "")
17589                    (match_operand 3 "memory_operand" ""))
17590               (set (match_operand 0 "register_operand" "")
17591                    (match_operand 4 "" ""))
17592               (set (match_operand 2 "register_operand" "")
17593                    (match_operand 5 "" ""))
17594               (use (reg:SI DIRFLAG_REG))])]
17595   "TARGET_SINGLE_STRINGOP || optimize_size"
17596   "")
17597
17598 (define_insn "*strmovdi_rex_1"
17599   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17600         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17601    (set (match_operand:DI 0 "register_operand" "=D")
17602         (plus:DI (match_dup 2)
17603                  (const_int 8)))
17604    (set (match_operand:DI 1 "register_operand" "=S")
17605         (plus:DI (match_dup 3)
17606                  (const_int 8)))
17607    (use (reg:SI DIRFLAG_REG))]
17608   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17609   "movsq"
17610   [(set_attr "type" "str")
17611    (set_attr "mode" "DI")
17612    (set_attr "memory" "both")])
17613
17614 (define_insn "*strmovsi_1"
17615   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17616         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17617    (set (match_operand:SI 0 "register_operand" "=D")
17618         (plus:SI (match_dup 2)
17619                  (const_int 4)))
17620    (set (match_operand:SI 1 "register_operand" "=S")
17621         (plus:SI (match_dup 3)
17622                  (const_int 4)))
17623    (use (reg:SI DIRFLAG_REG))]
17624   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17625   "{movsl|movsd}"
17626   [(set_attr "type" "str")
17627    (set_attr "mode" "SI")
17628    (set_attr "memory" "both")])
17629
17630 (define_insn "*strmovsi_rex_1"
17631   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17632         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17633    (set (match_operand:DI 0 "register_operand" "=D")
17634         (plus:DI (match_dup 2)
17635                  (const_int 4)))
17636    (set (match_operand:DI 1 "register_operand" "=S")
17637         (plus:DI (match_dup 3)
17638                  (const_int 4)))
17639    (use (reg:SI DIRFLAG_REG))]
17640   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17641   "{movsl|movsd}"
17642   [(set_attr "type" "str")
17643    (set_attr "mode" "SI")
17644    (set_attr "memory" "both")])
17645
17646 (define_insn "*strmovhi_1"
17647   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17648         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17649    (set (match_operand:SI 0 "register_operand" "=D")
17650         (plus:SI (match_dup 2)
17651                  (const_int 2)))
17652    (set (match_operand:SI 1 "register_operand" "=S")
17653         (plus:SI (match_dup 3)
17654                  (const_int 2)))
17655    (use (reg:SI DIRFLAG_REG))]
17656   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17657   "movsw"
17658   [(set_attr "type" "str")
17659    (set_attr "memory" "both")
17660    (set_attr "mode" "HI")])
17661
17662 (define_insn "*strmovhi_rex_1"
17663   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17664         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17665    (set (match_operand:DI 0 "register_operand" "=D")
17666         (plus:DI (match_dup 2)
17667                  (const_int 2)))
17668    (set (match_operand:DI 1 "register_operand" "=S")
17669         (plus:DI (match_dup 3)
17670                  (const_int 2)))
17671    (use (reg:SI DIRFLAG_REG))]
17672   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17673   "movsw"
17674   [(set_attr "type" "str")
17675    (set_attr "memory" "both")
17676    (set_attr "mode" "HI")])
17677
17678 (define_insn "*strmovqi_1"
17679   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17680         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17681    (set (match_operand:SI 0 "register_operand" "=D")
17682         (plus:SI (match_dup 2)
17683                  (const_int 1)))
17684    (set (match_operand:SI 1 "register_operand" "=S")
17685         (plus:SI (match_dup 3)
17686                  (const_int 1)))
17687    (use (reg:SI DIRFLAG_REG))]
17688   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17689   "movsb"
17690   [(set_attr "type" "str")
17691    (set_attr "memory" "both")
17692    (set_attr "mode" "QI")])
17693
17694 (define_insn "*strmovqi_rex_1"
17695   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17696         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17697    (set (match_operand:DI 0 "register_operand" "=D")
17698         (plus:DI (match_dup 2)
17699                  (const_int 1)))
17700    (set (match_operand:DI 1 "register_operand" "=S")
17701         (plus:DI (match_dup 3)
17702                  (const_int 1)))
17703    (use (reg:SI DIRFLAG_REG))]
17704   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17705   "movsb"
17706   [(set_attr "type" "str")
17707    (set_attr "memory" "both")
17708    (set_attr "mode" "QI")])
17709
17710 (define_expand "rep_mov"
17711   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17712               (set (match_operand 0 "register_operand" "")
17713                    (match_operand 5 "" ""))
17714               (set (match_operand 2 "register_operand" "")
17715                    (match_operand 6 "" ""))
17716               (set (match_operand 1 "memory_operand" "")
17717                    (match_operand 3 "memory_operand" ""))
17718               (use (match_dup 4))
17719               (use (reg:SI DIRFLAG_REG))])]
17720   ""
17721   "")
17722
17723 (define_insn "*rep_movdi_rex64"
17724   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17725    (set (match_operand:DI 0 "register_operand" "=D") 
17726         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17727                             (const_int 3))
17728                  (match_operand:DI 3 "register_operand" "0")))
17729    (set (match_operand:DI 1 "register_operand" "=S") 
17730         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17731                  (match_operand:DI 4 "register_operand" "1")))
17732    (set (mem:BLK (match_dup 3))
17733         (mem:BLK (match_dup 4)))
17734    (use (match_dup 5))
17735    (use (reg:SI DIRFLAG_REG))]
17736   "TARGET_64BIT"
17737   "{rep\;movsq|rep movsq}"
17738   [(set_attr "type" "str")
17739    (set_attr "prefix_rep" "1")
17740    (set_attr "memory" "both")
17741    (set_attr "mode" "DI")])
17742
17743 (define_insn "*rep_movsi"
17744   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17745    (set (match_operand:SI 0 "register_operand" "=D") 
17746         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17747                             (const_int 2))
17748                  (match_operand:SI 3 "register_operand" "0")))
17749    (set (match_operand:SI 1 "register_operand" "=S") 
17750         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17751                  (match_operand:SI 4 "register_operand" "1")))
17752    (set (mem:BLK (match_dup 3))
17753         (mem:BLK (match_dup 4)))
17754    (use (match_dup 5))
17755    (use (reg:SI DIRFLAG_REG))]
17756   "!TARGET_64BIT"
17757   "{rep\;movsl|rep movsd}"
17758   [(set_attr "type" "str")
17759    (set_attr "prefix_rep" "1")
17760    (set_attr "memory" "both")
17761    (set_attr "mode" "SI")])
17762
17763 (define_insn "*rep_movsi_rex64"
17764   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17765    (set (match_operand:DI 0 "register_operand" "=D") 
17766         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17767                             (const_int 2))
17768                  (match_operand:DI 3 "register_operand" "0")))
17769    (set (match_operand:DI 1 "register_operand" "=S") 
17770         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17771                  (match_operand:DI 4 "register_operand" "1")))
17772    (set (mem:BLK (match_dup 3))
17773         (mem:BLK (match_dup 4)))
17774    (use (match_dup 5))
17775    (use (reg:SI DIRFLAG_REG))]
17776   "TARGET_64BIT"
17777   "{rep\;movsl|rep movsd}"
17778   [(set_attr "type" "str")
17779    (set_attr "prefix_rep" "1")
17780    (set_attr "memory" "both")
17781    (set_attr "mode" "SI")])
17782
17783 (define_insn "*rep_movqi"
17784   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17785    (set (match_operand:SI 0 "register_operand" "=D") 
17786         (plus:SI (match_operand:SI 3 "register_operand" "0")
17787                  (match_operand:SI 5 "register_operand" "2")))
17788    (set (match_operand:SI 1 "register_operand" "=S") 
17789         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17790    (set (mem:BLK (match_dup 3))
17791         (mem:BLK (match_dup 4)))
17792    (use (match_dup 5))
17793    (use (reg:SI DIRFLAG_REG))]
17794   "!TARGET_64BIT"
17795   "{rep\;movsb|rep movsb}"
17796   [(set_attr "type" "str")
17797    (set_attr "prefix_rep" "1")
17798    (set_attr "memory" "both")
17799    (set_attr "mode" "SI")])
17800
17801 (define_insn "*rep_movqi_rex64"
17802   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17803    (set (match_operand:DI 0 "register_operand" "=D") 
17804         (plus:DI (match_operand:DI 3 "register_operand" "0")
17805                  (match_operand:DI 5 "register_operand" "2")))
17806    (set (match_operand:DI 1 "register_operand" "=S") 
17807         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17808    (set (mem:BLK (match_dup 3))
17809         (mem:BLK (match_dup 4)))
17810    (use (match_dup 5))
17811    (use (reg:SI DIRFLAG_REG))]
17812   "TARGET_64BIT"
17813   "{rep\;movsb|rep movsb}"
17814   [(set_attr "type" "str")
17815    (set_attr "prefix_rep" "1")
17816    (set_attr "memory" "both")
17817    (set_attr "mode" "SI")])
17818
17819 (define_expand "setmemsi"
17820    [(use (match_operand:BLK 0 "memory_operand" ""))
17821     (use (match_operand:SI 1 "nonmemory_operand" ""))
17822     (use (match_operand 2 "const_int_operand" ""))
17823     (use (match_operand 3 "const_int_operand" ""))]
17824   ""
17825 {
17826  /* If value to set is not zero, use the library routine.  */
17827  if (operands[2] != const0_rtx)
17828    FAIL;
17829
17830  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17831    DONE;
17832  else
17833    FAIL;
17834 })
17835
17836 (define_expand "setmemdi"
17837    [(use (match_operand:BLK 0 "memory_operand" ""))
17838     (use (match_operand:DI 1 "nonmemory_operand" ""))
17839     (use (match_operand 2 "const_int_operand" ""))
17840     (use (match_operand 3 "const_int_operand" ""))]
17841   "TARGET_64BIT"
17842 {
17843  /* If value to set is not zero, use the library routine.  */
17844  if (operands[2] != const0_rtx)
17845    FAIL;
17846
17847  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17848    DONE;
17849  else
17850    FAIL;
17851 })
17852
17853 ;; Most CPUs don't like single string operations
17854 ;; Handle this case here to simplify previous expander.
17855
17856 (define_expand "strset"
17857   [(set (match_operand 1 "memory_operand" "")
17858         (match_operand 2 "register_operand" ""))
17859    (parallel [(set (match_operand 0 "register_operand" "")
17860                    (match_dup 3))
17861               (clobber (reg:CC FLAGS_REG))])]
17862   ""
17863 {
17864   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17865     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17866
17867   /* If .md ever supports :P for Pmode, this can be directly
17868      in the pattern above.  */
17869   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17870                               GEN_INT (GET_MODE_SIZE (GET_MODE
17871                                                       (operands[2]))));
17872   if (TARGET_SINGLE_STRINGOP || optimize_size)
17873     {
17874       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17875                                       operands[3]));
17876       DONE;
17877     }
17878 })
17879
17880 (define_expand "strset_singleop"
17881   [(parallel [(set (match_operand 1 "memory_operand" "")
17882                    (match_operand 2 "register_operand" ""))
17883               (set (match_operand 0 "register_operand" "")
17884                    (match_operand 3 "" ""))
17885               (use (reg:SI DIRFLAG_REG))])]
17886   "TARGET_SINGLE_STRINGOP || optimize_size"
17887   "")
17888
17889 (define_insn "*strsetdi_rex_1"
17890   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17891         (match_operand:DI 2 "register_operand" "a"))
17892    (set (match_operand:DI 0 "register_operand" "=D")
17893         (plus:DI (match_dup 1)
17894                  (const_int 8)))
17895    (use (reg:SI DIRFLAG_REG))]
17896   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17897   "stosq"
17898   [(set_attr "type" "str")
17899    (set_attr "memory" "store")
17900    (set_attr "mode" "DI")])
17901
17902 (define_insn "*strsetsi_1"
17903   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17904         (match_operand:SI 2 "register_operand" "a"))
17905    (set (match_operand:SI 0 "register_operand" "=D")
17906         (plus:SI (match_dup 1)
17907                  (const_int 4)))
17908    (use (reg:SI DIRFLAG_REG))]
17909   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17910   "{stosl|stosd}"
17911   [(set_attr "type" "str")
17912    (set_attr "memory" "store")
17913    (set_attr "mode" "SI")])
17914
17915 (define_insn "*strsetsi_rex_1"
17916   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17917         (match_operand:SI 2 "register_operand" "a"))
17918    (set (match_operand:DI 0 "register_operand" "=D")
17919         (plus:DI (match_dup 1)
17920                  (const_int 4)))
17921    (use (reg:SI DIRFLAG_REG))]
17922   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17923   "{stosl|stosd}"
17924   [(set_attr "type" "str")
17925    (set_attr "memory" "store")
17926    (set_attr "mode" "SI")])
17927
17928 (define_insn "*strsethi_1"
17929   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17930         (match_operand:HI 2 "register_operand" "a"))
17931    (set (match_operand:SI 0 "register_operand" "=D")
17932         (plus:SI (match_dup 1)
17933                  (const_int 2)))
17934    (use (reg:SI DIRFLAG_REG))]
17935   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17936   "stosw"
17937   [(set_attr "type" "str")
17938    (set_attr "memory" "store")
17939    (set_attr "mode" "HI")])
17940
17941 (define_insn "*strsethi_rex_1"
17942   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17943         (match_operand:HI 2 "register_operand" "a"))
17944    (set (match_operand:DI 0 "register_operand" "=D")
17945         (plus:DI (match_dup 1)
17946                  (const_int 2)))
17947    (use (reg:SI DIRFLAG_REG))]
17948   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17949   "stosw"
17950   [(set_attr "type" "str")
17951    (set_attr "memory" "store")
17952    (set_attr "mode" "HI")])
17953
17954 (define_insn "*strsetqi_1"
17955   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17956         (match_operand:QI 2 "register_operand" "a"))
17957    (set (match_operand:SI 0 "register_operand" "=D")
17958         (plus:SI (match_dup 1)
17959                  (const_int 1)))
17960    (use (reg:SI DIRFLAG_REG))]
17961   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17962   "stosb"
17963   [(set_attr "type" "str")
17964    (set_attr "memory" "store")
17965    (set_attr "mode" "QI")])
17966
17967 (define_insn "*strsetqi_rex_1"
17968   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17969         (match_operand:QI 2 "register_operand" "a"))
17970    (set (match_operand:DI 0 "register_operand" "=D")
17971         (plus:DI (match_dup 1)
17972                  (const_int 1)))
17973    (use (reg:SI DIRFLAG_REG))]
17974   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17975   "stosb"
17976   [(set_attr "type" "str")
17977    (set_attr "memory" "store")
17978    (set_attr "mode" "QI")])
17979
17980 (define_expand "rep_stos"
17981   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17982               (set (match_operand 0 "register_operand" "")
17983                    (match_operand 4 "" ""))
17984               (set (match_operand 2 "memory_operand" "") (const_int 0))
17985               (use (match_operand 3 "register_operand" ""))
17986               (use (match_dup 1))
17987               (use (reg:SI DIRFLAG_REG))])]
17988   ""
17989   "")
17990
17991 (define_insn "*rep_stosdi_rex64"
17992   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17993    (set (match_operand:DI 0 "register_operand" "=D") 
17994         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17995                             (const_int 3))
17996                  (match_operand:DI 3 "register_operand" "0")))
17997    (set (mem:BLK (match_dup 3))
17998         (const_int 0))
17999    (use (match_operand:DI 2 "register_operand" "a"))
18000    (use (match_dup 4))
18001    (use (reg:SI DIRFLAG_REG))]
18002   "TARGET_64BIT"
18003   "{rep\;stosq|rep stosq}"
18004   [(set_attr "type" "str")
18005    (set_attr "prefix_rep" "1")
18006    (set_attr "memory" "store")
18007    (set_attr "mode" "DI")])
18008
18009 (define_insn "*rep_stossi"
18010   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18011    (set (match_operand:SI 0 "register_operand" "=D") 
18012         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18013                             (const_int 2))
18014                  (match_operand:SI 3 "register_operand" "0")))
18015    (set (mem:BLK (match_dup 3))
18016         (const_int 0))
18017    (use (match_operand:SI 2 "register_operand" "a"))
18018    (use (match_dup 4))
18019    (use (reg:SI DIRFLAG_REG))]
18020   "!TARGET_64BIT"
18021   "{rep\;stosl|rep stosd}"
18022   [(set_attr "type" "str")
18023    (set_attr "prefix_rep" "1")
18024    (set_attr "memory" "store")
18025    (set_attr "mode" "SI")])
18026
18027 (define_insn "*rep_stossi_rex64"
18028   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18029    (set (match_operand:DI 0 "register_operand" "=D") 
18030         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18031                             (const_int 2))
18032                  (match_operand:DI 3 "register_operand" "0")))
18033    (set (mem:BLK (match_dup 3))
18034         (const_int 0))
18035    (use (match_operand:SI 2 "register_operand" "a"))
18036    (use (match_dup 4))
18037    (use (reg:SI DIRFLAG_REG))]
18038   "TARGET_64BIT"
18039   "{rep\;stosl|rep stosd}"
18040   [(set_attr "type" "str")
18041    (set_attr "prefix_rep" "1")
18042    (set_attr "memory" "store")
18043    (set_attr "mode" "SI")])
18044
18045 (define_insn "*rep_stosqi"
18046   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18047    (set (match_operand:SI 0 "register_operand" "=D") 
18048         (plus:SI (match_operand:SI 3 "register_operand" "0")
18049                  (match_operand:SI 4 "register_operand" "1")))
18050    (set (mem:BLK (match_dup 3))
18051         (const_int 0))
18052    (use (match_operand:QI 2 "register_operand" "a"))
18053    (use (match_dup 4))
18054    (use (reg:SI DIRFLAG_REG))]
18055   "!TARGET_64BIT"
18056   "{rep\;stosb|rep stosb}"
18057   [(set_attr "type" "str")
18058    (set_attr "prefix_rep" "1")
18059    (set_attr "memory" "store")
18060    (set_attr "mode" "QI")])
18061
18062 (define_insn "*rep_stosqi_rex64"
18063   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18064    (set (match_operand:DI 0 "register_operand" "=D") 
18065         (plus:DI (match_operand:DI 3 "register_operand" "0")
18066                  (match_operand:DI 4 "register_operand" "1")))
18067    (set (mem:BLK (match_dup 3))
18068         (const_int 0))
18069    (use (match_operand:QI 2 "register_operand" "a"))
18070    (use (match_dup 4))
18071    (use (reg:SI DIRFLAG_REG))]
18072   "TARGET_64BIT"
18073   "{rep\;stosb|rep stosb}"
18074   [(set_attr "type" "str")
18075    (set_attr "prefix_rep" "1")
18076    (set_attr "memory" "store")
18077    (set_attr "mode" "QI")])
18078
18079 (define_expand "cmpstrnsi"
18080   [(set (match_operand:SI 0 "register_operand" "")
18081         (compare:SI (match_operand:BLK 1 "general_operand" "")
18082                     (match_operand:BLK 2 "general_operand" "")))
18083    (use (match_operand 3 "general_operand" ""))
18084    (use (match_operand 4 "immediate_operand" ""))]
18085   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18086 {
18087   rtx addr1, addr2, out, outlow, count, countreg, align;
18088
18089   /* Can't use this if the user has appropriated esi or edi.  */
18090   if (global_regs[4] || global_regs[5])
18091     FAIL;
18092
18093   out = operands[0];
18094   if (GET_CODE (out) != REG)
18095     out = gen_reg_rtx (SImode);
18096
18097   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18098   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18099   if (addr1 != XEXP (operands[1], 0))
18100     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18101   if (addr2 != XEXP (operands[2], 0))
18102     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18103
18104   count = operands[3];
18105   countreg = ix86_zero_extend_to_Pmode (count);
18106
18107   /* %%% Iff we are testing strict equality, we can use known alignment
18108      to good advantage.  This may be possible with combine, particularly
18109      once cc0 is dead.  */
18110   align = operands[4];
18111
18112   emit_insn (gen_cld ());
18113   if (GET_CODE (count) == CONST_INT)
18114     {
18115       if (INTVAL (count) == 0)
18116         {
18117           emit_move_insn (operands[0], const0_rtx);
18118           DONE;
18119         }
18120       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18121                                      operands[1], operands[2]));
18122     }
18123   else
18124     {
18125       if (TARGET_64BIT)
18126         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18127       else
18128         emit_insn (gen_cmpsi_1 (countreg, countreg));
18129       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18130                                   operands[1], operands[2]));
18131     }
18132
18133   outlow = gen_lowpart (QImode, out);
18134   emit_insn (gen_cmpintqi (outlow));
18135   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18136
18137   if (operands[0] != out)
18138     emit_move_insn (operands[0], out);
18139
18140   DONE;
18141 })
18142
18143 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18144
18145 (define_expand "cmpintqi"
18146   [(set (match_dup 1)
18147         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18148    (set (match_dup 2)
18149         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18150    (parallel [(set (match_operand:QI 0 "register_operand" "")
18151                    (minus:QI (match_dup 1)
18152                              (match_dup 2)))
18153               (clobber (reg:CC FLAGS_REG))])]
18154   ""
18155   "operands[1] = gen_reg_rtx (QImode);
18156    operands[2] = gen_reg_rtx (QImode);")
18157
18158 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18159 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18160
18161 (define_expand "cmpstrnqi_nz_1"
18162   [(parallel [(set (reg:CC FLAGS_REG)
18163                    (compare:CC (match_operand 4 "memory_operand" "")
18164                                (match_operand 5 "memory_operand" "")))
18165               (use (match_operand 2 "register_operand" ""))
18166               (use (match_operand:SI 3 "immediate_operand" ""))
18167               (use (reg:SI DIRFLAG_REG))
18168               (clobber (match_operand 0 "register_operand" ""))
18169               (clobber (match_operand 1 "register_operand" ""))
18170               (clobber (match_dup 2))])]
18171   ""
18172   "")
18173
18174 (define_insn "*cmpstrnqi_nz_1"
18175   [(set (reg:CC FLAGS_REG)
18176         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18177                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18178    (use (match_operand:SI 6 "register_operand" "2"))
18179    (use (match_operand:SI 3 "immediate_operand" "i"))
18180    (use (reg:SI DIRFLAG_REG))
18181    (clobber (match_operand:SI 0 "register_operand" "=S"))
18182    (clobber (match_operand:SI 1 "register_operand" "=D"))
18183    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18184   "!TARGET_64BIT"
18185   "repz{\;| }cmpsb"
18186   [(set_attr "type" "str")
18187    (set_attr "mode" "QI")
18188    (set_attr "prefix_rep" "1")])
18189
18190 (define_insn "*cmpstrnqi_nz_rex_1"
18191   [(set (reg:CC FLAGS_REG)
18192         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18193                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18194    (use (match_operand:DI 6 "register_operand" "2"))
18195    (use (match_operand:SI 3 "immediate_operand" "i"))
18196    (use (reg:SI DIRFLAG_REG))
18197    (clobber (match_operand:DI 0 "register_operand" "=S"))
18198    (clobber (match_operand:DI 1 "register_operand" "=D"))
18199    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18200   "TARGET_64BIT"
18201   "repz{\;| }cmpsb"
18202   [(set_attr "type" "str")
18203    (set_attr "mode" "QI")
18204    (set_attr "prefix_rep" "1")])
18205
18206 ;; The same, but the count is not known to not be zero.
18207
18208 (define_expand "cmpstrnqi_1"
18209   [(parallel [(set (reg:CC FLAGS_REG)
18210                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18211                                      (const_int 0))
18212                   (compare:CC (match_operand 4 "memory_operand" "")
18213                               (match_operand 5 "memory_operand" ""))
18214                   (const_int 0)))
18215               (use (match_operand:SI 3 "immediate_operand" ""))
18216               (use (reg:CC FLAGS_REG))
18217               (use (reg:SI DIRFLAG_REG))
18218               (clobber (match_operand 0 "register_operand" ""))
18219               (clobber (match_operand 1 "register_operand" ""))
18220               (clobber (match_dup 2))])]
18221   ""
18222   "")
18223
18224 (define_insn "*cmpstrnqi_1"
18225   [(set (reg:CC FLAGS_REG)
18226         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18227                              (const_int 0))
18228           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18229                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18230           (const_int 0)))
18231    (use (match_operand:SI 3 "immediate_operand" "i"))
18232    (use (reg:CC FLAGS_REG))
18233    (use (reg:SI DIRFLAG_REG))
18234    (clobber (match_operand:SI 0 "register_operand" "=S"))
18235    (clobber (match_operand:SI 1 "register_operand" "=D"))
18236    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18237   "!TARGET_64BIT"
18238   "repz{\;| }cmpsb"
18239   [(set_attr "type" "str")
18240    (set_attr "mode" "QI")
18241    (set_attr "prefix_rep" "1")])
18242
18243 (define_insn "*cmpstrnqi_rex_1"
18244   [(set (reg:CC FLAGS_REG)
18245         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18246                              (const_int 0))
18247           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18248                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18249           (const_int 0)))
18250    (use (match_operand:SI 3 "immediate_operand" "i"))
18251    (use (reg:CC FLAGS_REG))
18252    (use (reg:SI DIRFLAG_REG))
18253    (clobber (match_operand:DI 0 "register_operand" "=S"))
18254    (clobber (match_operand:DI 1 "register_operand" "=D"))
18255    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18256   "TARGET_64BIT"
18257   "repz{\;| }cmpsb"
18258   [(set_attr "type" "str")
18259    (set_attr "mode" "QI")
18260    (set_attr "prefix_rep" "1")])
18261
18262 (define_expand "strlensi"
18263   [(set (match_operand:SI 0 "register_operand" "")
18264         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18265                     (match_operand:QI 2 "immediate_operand" "")
18266                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18267   ""
18268 {
18269  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18270    DONE;
18271  else
18272    FAIL;
18273 })
18274
18275 (define_expand "strlendi"
18276   [(set (match_operand:DI 0 "register_operand" "")
18277         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18278                     (match_operand:QI 2 "immediate_operand" "")
18279                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18280   ""
18281 {
18282  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18283    DONE;
18284  else
18285    FAIL;
18286 })
18287
18288 (define_expand "strlenqi_1"
18289   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18290               (use (reg:SI DIRFLAG_REG))
18291               (clobber (match_operand 1 "register_operand" ""))
18292               (clobber (reg:CC FLAGS_REG))])]
18293   ""
18294   "")
18295
18296 (define_insn "*strlenqi_1"
18297   [(set (match_operand:SI 0 "register_operand" "=&c")
18298         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18299                     (match_operand:QI 2 "register_operand" "a")
18300                     (match_operand:SI 3 "immediate_operand" "i")
18301                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18302    (use (reg:SI DIRFLAG_REG))
18303    (clobber (match_operand:SI 1 "register_operand" "=D"))
18304    (clobber (reg:CC FLAGS_REG))]
18305   "!TARGET_64BIT"
18306   "repnz{\;| }scasb"
18307   [(set_attr "type" "str")
18308    (set_attr "mode" "QI")
18309    (set_attr "prefix_rep" "1")])
18310
18311 (define_insn "*strlenqi_rex_1"
18312   [(set (match_operand:DI 0 "register_operand" "=&c")
18313         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18314                     (match_operand:QI 2 "register_operand" "a")
18315                     (match_operand:DI 3 "immediate_operand" "i")
18316                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18317    (use (reg:SI DIRFLAG_REG))
18318    (clobber (match_operand:DI 1 "register_operand" "=D"))
18319    (clobber (reg:CC FLAGS_REG))]
18320   "TARGET_64BIT"
18321   "repnz{\;| }scasb"
18322   [(set_attr "type" "str")
18323    (set_attr "mode" "QI")
18324    (set_attr "prefix_rep" "1")])
18325
18326 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18327 ;; handled in combine, but it is not currently up to the task.
18328 ;; When used for their truth value, the cmpstrn* expanders generate
18329 ;; code like this:
18330 ;;
18331 ;;   repz cmpsb
18332 ;;   seta       %al
18333 ;;   setb       %dl
18334 ;;   cmpb       %al, %dl
18335 ;;   jcc        label
18336 ;;
18337 ;; The intermediate three instructions are unnecessary.
18338
18339 ;; This one handles cmpstrn*_nz_1...
18340 (define_peephole2
18341   [(parallel[
18342      (set (reg:CC FLAGS_REG)
18343           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18344                       (mem:BLK (match_operand 5 "register_operand" ""))))
18345      (use (match_operand 6 "register_operand" ""))
18346      (use (match_operand:SI 3 "immediate_operand" ""))
18347      (use (reg:SI DIRFLAG_REG))
18348      (clobber (match_operand 0 "register_operand" ""))
18349      (clobber (match_operand 1 "register_operand" ""))
18350      (clobber (match_operand 2 "register_operand" ""))])
18351    (set (match_operand:QI 7 "register_operand" "")
18352         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18353    (set (match_operand:QI 8 "register_operand" "")
18354         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18355    (set (reg FLAGS_REG)
18356         (compare (match_dup 7) (match_dup 8)))
18357   ]
18358   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18359   [(parallel[
18360      (set (reg:CC FLAGS_REG)
18361           (compare:CC (mem:BLK (match_dup 4))
18362                       (mem:BLK (match_dup 5))))
18363      (use (match_dup 6))
18364      (use (match_dup 3))
18365      (use (reg:SI DIRFLAG_REG))
18366      (clobber (match_dup 0))
18367      (clobber (match_dup 1))
18368      (clobber (match_dup 2))])]
18369   "")
18370
18371 ;; ...and this one handles cmpstrn*_1.
18372 (define_peephole2
18373   [(parallel[
18374      (set (reg:CC FLAGS_REG)
18375           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18376                                (const_int 0))
18377             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18378                         (mem:BLK (match_operand 5 "register_operand" "")))
18379             (const_int 0)))
18380      (use (match_operand:SI 3 "immediate_operand" ""))
18381      (use (reg:CC FLAGS_REG))
18382      (use (reg:SI DIRFLAG_REG))
18383      (clobber (match_operand 0 "register_operand" ""))
18384      (clobber (match_operand 1 "register_operand" ""))
18385      (clobber (match_operand 2 "register_operand" ""))])
18386    (set (match_operand:QI 7 "register_operand" "")
18387         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388    (set (match_operand:QI 8 "register_operand" "")
18389         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18390    (set (reg FLAGS_REG)
18391         (compare (match_dup 7) (match_dup 8)))
18392   ]
18393   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18394   [(parallel[
18395      (set (reg:CC FLAGS_REG)
18396           (if_then_else:CC (ne (match_dup 6)
18397                                (const_int 0))
18398             (compare:CC (mem:BLK (match_dup 4))
18399                         (mem:BLK (match_dup 5)))
18400             (const_int 0)))
18401      (use (match_dup 3))
18402      (use (reg:CC FLAGS_REG))
18403      (use (reg:SI DIRFLAG_REG))
18404      (clobber (match_dup 0))
18405      (clobber (match_dup 1))
18406      (clobber (match_dup 2))])]
18407   "")
18408
18409
18410 \f
18411 ;; Conditional move instructions.
18412
18413 (define_expand "movdicc"
18414   [(set (match_operand:DI 0 "register_operand" "")
18415         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18416                          (match_operand:DI 2 "general_operand" "")
18417                          (match_operand:DI 3 "general_operand" "")))]
18418   "TARGET_64BIT"
18419   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18420
18421 (define_insn "x86_movdicc_0_m1_rex64"
18422   [(set (match_operand:DI 0 "register_operand" "=r")
18423         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18424           (const_int -1)
18425           (const_int 0)))
18426    (clobber (reg:CC FLAGS_REG))]
18427   "TARGET_64BIT"
18428   "sbb{q}\t%0, %0"
18429   ; Since we don't have the proper number of operands for an alu insn,
18430   ; fill in all the blanks.
18431   [(set_attr "type" "alu")
18432    (set_attr "pent_pair" "pu")
18433    (set_attr "memory" "none")
18434    (set_attr "imm_disp" "false")
18435    (set_attr "mode" "DI")
18436    (set_attr "length_immediate" "0")])
18437
18438 (define_insn "*movdicc_c_rex64"
18439   [(set (match_operand:DI 0 "register_operand" "=r,r")
18440         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18441                                 [(reg FLAGS_REG) (const_int 0)])
18442                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18443                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18444   "TARGET_64BIT && TARGET_CMOVE
18445    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18446   "@
18447    cmov%O2%C1\t{%2, %0|%0, %2}
18448    cmov%O2%c1\t{%3, %0|%0, %3}"
18449   [(set_attr "type" "icmov")
18450    (set_attr "mode" "DI")])
18451
18452 (define_expand "movsicc"
18453   [(set (match_operand:SI 0 "register_operand" "")
18454         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18455                          (match_operand:SI 2 "general_operand" "")
18456                          (match_operand:SI 3 "general_operand" "")))]
18457   ""
18458   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18459
18460 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18461 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18462 ;; So just document what we're doing explicitly.
18463
18464 (define_insn "x86_movsicc_0_m1"
18465   [(set (match_operand:SI 0 "register_operand" "=r")
18466         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18467           (const_int -1)
18468           (const_int 0)))
18469    (clobber (reg:CC FLAGS_REG))]
18470   ""
18471   "sbb{l}\t%0, %0"
18472   ; Since we don't have the proper number of operands for an alu insn,
18473   ; fill in all the blanks.
18474   [(set_attr "type" "alu")
18475    (set_attr "pent_pair" "pu")
18476    (set_attr "memory" "none")
18477    (set_attr "imm_disp" "false")
18478    (set_attr "mode" "SI")
18479    (set_attr "length_immediate" "0")])
18480
18481 (define_insn "*movsicc_noc"
18482   [(set (match_operand:SI 0 "register_operand" "=r,r")
18483         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18484                                 [(reg FLAGS_REG) (const_int 0)])
18485                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18486                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18487   "TARGET_CMOVE
18488    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18489   "@
18490    cmov%O2%C1\t{%2, %0|%0, %2}
18491    cmov%O2%c1\t{%3, %0|%0, %3}"
18492   [(set_attr "type" "icmov")
18493    (set_attr "mode" "SI")])
18494
18495 (define_expand "movhicc"
18496   [(set (match_operand:HI 0 "register_operand" "")
18497         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18498                          (match_operand:HI 2 "general_operand" "")
18499                          (match_operand:HI 3 "general_operand" "")))]
18500   "TARGET_HIMODE_MATH"
18501   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18502
18503 (define_insn "*movhicc_noc"
18504   [(set (match_operand:HI 0 "register_operand" "=r,r")
18505         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18506                                 [(reg FLAGS_REG) (const_int 0)])
18507                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18508                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18509   "TARGET_CMOVE
18510    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18511   "@
18512    cmov%O2%C1\t{%2, %0|%0, %2}
18513    cmov%O2%c1\t{%3, %0|%0, %3}"
18514   [(set_attr "type" "icmov")
18515    (set_attr "mode" "HI")])
18516
18517 (define_expand "movqicc"
18518   [(set (match_operand:QI 0 "register_operand" "")
18519         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18520                          (match_operand:QI 2 "general_operand" "")
18521                          (match_operand:QI 3 "general_operand" "")))]
18522   "TARGET_QIMODE_MATH"
18523   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18524
18525 (define_insn_and_split "*movqicc_noc"
18526   [(set (match_operand:QI 0 "register_operand" "=r,r")
18527         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18528                                 [(match_operand 4 "flags_reg_operand" "")
18529                                  (const_int 0)])
18530                       (match_operand:QI 2 "register_operand" "r,0")
18531                       (match_operand:QI 3 "register_operand" "0,r")))]
18532   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18533   "#"
18534   "&& reload_completed"
18535   [(set (match_dup 0)
18536         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18537                       (match_dup 2)
18538                       (match_dup 3)))]
18539   "operands[0] = gen_lowpart (SImode, operands[0]);
18540    operands[2] = gen_lowpart (SImode, operands[2]);
18541    operands[3] = gen_lowpart (SImode, operands[3]);"
18542   [(set_attr "type" "icmov")
18543    (set_attr "mode" "SI")])
18544
18545 (define_expand "movsfcc"
18546   [(set (match_operand:SF 0 "register_operand" "")
18547         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18548                          (match_operand:SF 2 "register_operand" "")
18549                          (match_operand:SF 3 "register_operand" "")))]
18550   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18551   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18552
18553 (define_insn "*movsfcc_1_387"
18554   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18555         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18556                                 [(reg FLAGS_REG) (const_int 0)])
18557                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18558                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18559   "TARGET_80387 && TARGET_CMOVE
18560    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18561   "@
18562    fcmov%F1\t{%2, %0|%0, %2}
18563    fcmov%f1\t{%3, %0|%0, %3}
18564    cmov%O2%C1\t{%2, %0|%0, %2}
18565    cmov%O2%c1\t{%3, %0|%0, %3}"
18566   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18567    (set_attr "mode" "SF,SF,SI,SI")])
18568
18569 (define_expand "movdfcc"
18570   [(set (match_operand:DF 0 "register_operand" "")
18571         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18572                          (match_operand:DF 2 "register_operand" "")
18573                          (match_operand:DF 3 "register_operand" "")))]
18574   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18575   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18576
18577 (define_insn "*movdfcc_1"
18578   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18579         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18580                                 [(reg FLAGS_REG) (const_int 0)])
18581                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18582                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18583   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18584    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18585   "@
18586    fcmov%F1\t{%2, %0|%0, %2}
18587    fcmov%f1\t{%3, %0|%0, %3}
18588    #
18589    #"
18590   [(set_attr "type" "fcmov,fcmov,multi,multi")
18591    (set_attr "mode" "DF")])
18592
18593 (define_insn "*movdfcc_1_rex64"
18594   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18595         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18596                                 [(reg FLAGS_REG) (const_int 0)])
18597                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18598                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18599   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18600    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18601   "@
18602    fcmov%F1\t{%2, %0|%0, %2}
18603    fcmov%f1\t{%3, %0|%0, %3}
18604    cmov%O2%C1\t{%2, %0|%0, %2}
18605    cmov%O2%c1\t{%3, %0|%0, %3}"
18606   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18607    (set_attr "mode" "DF")])
18608
18609 (define_split
18610   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18611         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18612                                 [(match_operand 4 "flags_reg_operand" "")
18613                                  (const_int 0)])
18614                       (match_operand:DF 2 "nonimmediate_operand" "")
18615                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18616   "!TARGET_64BIT && reload_completed"
18617   [(set (match_dup 2)
18618         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18619                       (match_dup 5)
18620                       (match_dup 7)))
18621    (set (match_dup 3)
18622         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18623                       (match_dup 6)
18624                       (match_dup 8)))]
18625   "split_di (operands+2, 1, operands+5, operands+6);
18626    split_di (operands+3, 1, operands+7, operands+8);
18627    split_di (operands, 1, operands+2, operands+3);")
18628
18629 (define_expand "movxfcc"
18630   [(set (match_operand:XF 0 "register_operand" "")
18631         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18632                          (match_operand:XF 2 "register_operand" "")
18633                          (match_operand:XF 3 "register_operand" "")))]
18634   "TARGET_80387 && TARGET_CMOVE"
18635   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18636
18637 (define_insn "*movxfcc_1"
18638   [(set (match_operand:XF 0 "register_operand" "=f,f")
18639         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18640                                 [(reg FLAGS_REG) (const_int 0)])
18641                       (match_operand:XF 2 "register_operand" "f,0")
18642                       (match_operand:XF 3 "register_operand" "0,f")))]
18643   "TARGET_80387 && TARGET_CMOVE"
18644   "@
18645    fcmov%F1\t{%2, %0|%0, %2}
18646    fcmov%f1\t{%3, %0|%0, %3}"
18647   [(set_attr "type" "fcmov")
18648    (set_attr "mode" "XF")])
18649
18650 ;; These versions of the min/max patterns are intentionally ignorant of
18651 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18652 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18653 ;; are undefined in this condition, we're certain this is correct.
18654
18655 (define_insn "sminsf3"
18656   [(set (match_operand:SF 0 "register_operand" "=x")
18657         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18658                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18659   "TARGET_SSE_MATH"
18660   "minss\t{%2, %0|%0, %2}"
18661   [(set_attr "type" "sseadd")
18662    (set_attr "mode" "SF")])
18663
18664 (define_insn "smaxsf3"
18665   [(set (match_operand:SF 0 "register_operand" "=x")
18666         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18667                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18668   "TARGET_SSE_MATH"
18669   "maxss\t{%2, %0|%0, %2}"
18670   [(set_attr "type" "sseadd")
18671    (set_attr "mode" "SF")])
18672
18673 (define_insn "smindf3"
18674   [(set (match_operand:DF 0 "register_operand" "=x")
18675         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18676                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18677   "TARGET_SSE2 && TARGET_SSE_MATH"
18678   "minsd\t{%2, %0|%0, %2}"
18679   [(set_attr "type" "sseadd")
18680    (set_attr "mode" "DF")])
18681
18682 (define_insn "smaxdf3"
18683   [(set (match_operand:DF 0 "register_operand" "=x")
18684         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18685                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18686   "TARGET_SSE2 && TARGET_SSE_MATH"
18687   "maxsd\t{%2, %0|%0, %2}"
18688   [(set_attr "type" "sseadd")
18689    (set_attr "mode" "DF")])
18690
18691 ;; These versions of the min/max patterns implement exactly the operations
18692 ;;   min = (op1 < op2 ? op1 : op2)
18693 ;;   max = (!(op1 < op2) ? op1 : op2)
18694 ;; Their operands are not commutative, and thus they may be used in the
18695 ;; presence of -0.0 and NaN.
18696
18697 (define_insn "*ieee_sminsf3"
18698   [(set (match_operand:SF 0 "register_operand" "=x")
18699         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18700                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18701                    UNSPEC_IEEE_MIN))]
18702   "TARGET_SSE_MATH"
18703   "minss\t{%2, %0|%0, %2}"
18704   [(set_attr "type" "sseadd")
18705    (set_attr "mode" "SF")])
18706
18707 (define_insn "*ieee_smaxsf3"
18708   [(set (match_operand:SF 0 "register_operand" "=x")
18709         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18710                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18711                    UNSPEC_IEEE_MAX))]
18712   "TARGET_SSE_MATH"
18713   "maxss\t{%2, %0|%0, %2}"
18714   [(set_attr "type" "sseadd")
18715    (set_attr "mode" "SF")])
18716
18717 (define_insn "*ieee_smindf3"
18718   [(set (match_operand:DF 0 "register_operand" "=x")
18719         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18720                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18721                    UNSPEC_IEEE_MIN))]
18722   "TARGET_SSE2 && TARGET_SSE_MATH"
18723   "minsd\t{%2, %0|%0, %2}"
18724   [(set_attr "type" "sseadd")
18725    (set_attr "mode" "DF")])
18726
18727 (define_insn "*ieee_smaxdf3"
18728   [(set (match_operand:DF 0 "register_operand" "=x")
18729         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18730                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18731                    UNSPEC_IEEE_MAX))]
18732   "TARGET_SSE2 && TARGET_SSE_MATH"
18733   "maxsd\t{%2, %0|%0, %2}"
18734   [(set_attr "type" "sseadd")
18735    (set_attr "mode" "DF")])
18736
18737 ;; Conditional addition patterns
18738 (define_expand "addqicc"
18739   [(match_operand:QI 0 "register_operand" "")
18740    (match_operand 1 "comparison_operator" "")
18741    (match_operand:QI 2 "register_operand" "")
18742    (match_operand:QI 3 "const_int_operand" "")]
18743   ""
18744   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18745
18746 (define_expand "addhicc"
18747   [(match_operand:HI 0 "register_operand" "")
18748    (match_operand 1 "comparison_operator" "")
18749    (match_operand:HI 2 "register_operand" "")
18750    (match_operand:HI 3 "const_int_operand" "")]
18751   ""
18752   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18753
18754 (define_expand "addsicc"
18755   [(match_operand:SI 0 "register_operand" "")
18756    (match_operand 1 "comparison_operator" "")
18757    (match_operand:SI 2 "register_operand" "")
18758    (match_operand:SI 3 "const_int_operand" "")]
18759   ""
18760   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18761
18762 (define_expand "adddicc"
18763   [(match_operand:DI 0 "register_operand" "")
18764    (match_operand 1 "comparison_operator" "")
18765    (match_operand:DI 2 "register_operand" "")
18766    (match_operand:DI 3 "const_int_operand" "")]
18767   "TARGET_64BIT"
18768   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18769
18770 \f
18771 ;; Misc patterns (?)
18772
18773 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18774 ;; Otherwise there will be nothing to keep
18775 ;; 
18776 ;; [(set (reg ebp) (reg esp))]
18777 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18778 ;;  (clobber (eflags)]
18779 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18780 ;;
18781 ;; in proper program order.
18782 (define_insn "pro_epilogue_adjust_stack_1"
18783   [(set (match_operand:SI 0 "register_operand" "=r,r")
18784         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18785                  (match_operand:SI 2 "immediate_operand" "i,i")))
18786    (clobber (reg:CC FLAGS_REG))
18787    (clobber (mem:BLK (scratch)))]
18788   "!TARGET_64BIT"
18789 {
18790   switch (get_attr_type (insn))
18791     {
18792     case TYPE_IMOV:
18793       return "mov{l}\t{%1, %0|%0, %1}";
18794
18795     case TYPE_ALU:
18796       if (GET_CODE (operands[2]) == CONST_INT
18797           && (INTVAL (operands[2]) == 128
18798               || (INTVAL (operands[2]) < 0
18799                   && INTVAL (operands[2]) != -128)))
18800         {
18801           operands[2] = GEN_INT (-INTVAL (operands[2]));
18802           return "sub{l}\t{%2, %0|%0, %2}";
18803         }
18804       return "add{l}\t{%2, %0|%0, %2}";
18805
18806     case TYPE_LEA:
18807       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18808       return "lea{l}\t{%a2, %0|%0, %a2}";
18809
18810     default:
18811       gcc_unreachable ();
18812     }
18813 }
18814   [(set (attr "type")
18815         (cond [(eq_attr "alternative" "0")
18816                  (const_string "alu")
18817                (match_operand:SI 2 "const0_operand" "")
18818                  (const_string "imov")
18819               ]
18820               (const_string "lea")))
18821    (set_attr "mode" "SI")])
18822
18823 (define_insn "pro_epilogue_adjust_stack_rex64"
18824   [(set (match_operand:DI 0 "register_operand" "=r,r")
18825         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18826                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18827    (clobber (reg:CC FLAGS_REG))
18828    (clobber (mem:BLK (scratch)))]
18829   "TARGET_64BIT"
18830 {
18831   switch (get_attr_type (insn))
18832     {
18833     case TYPE_IMOV:
18834       return "mov{q}\t{%1, %0|%0, %1}";
18835
18836     case TYPE_ALU:
18837       if (GET_CODE (operands[2]) == CONST_INT
18838           /* Avoid overflows.  */
18839           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18840           && (INTVAL (operands[2]) == 128
18841               || (INTVAL (operands[2]) < 0
18842                   && INTVAL (operands[2]) != -128)))
18843         {
18844           operands[2] = GEN_INT (-INTVAL (operands[2]));
18845           return "sub{q}\t{%2, %0|%0, %2}";
18846         }
18847       return "add{q}\t{%2, %0|%0, %2}";
18848
18849     case TYPE_LEA:
18850       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18851       return "lea{q}\t{%a2, %0|%0, %a2}";
18852
18853     default:
18854       gcc_unreachable ();
18855     }
18856 }
18857   [(set (attr "type")
18858         (cond [(eq_attr "alternative" "0")
18859                  (const_string "alu")
18860                (match_operand:DI 2 "const0_operand" "")
18861                  (const_string "imov")
18862               ]
18863               (const_string "lea")))
18864    (set_attr "mode" "DI")])
18865
18866 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18867   [(set (match_operand:DI 0 "register_operand" "=r,r")
18868         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18869                  (match_operand:DI 3 "immediate_operand" "i,i")))
18870    (use (match_operand:DI 2 "register_operand" "r,r"))
18871    (clobber (reg:CC FLAGS_REG))
18872    (clobber (mem:BLK (scratch)))]
18873   "TARGET_64BIT"
18874 {
18875   switch (get_attr_type (insn))
18876     {
18877     case TYPE_ALU:
18878       return "add{q}\t{%2, %0|%0, %2}";
18879
18880     case TYPE_LEA:
18881       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18882       return "lea{q}\t{%a2, %0|%0, %a2}";
18883
18884     default:
18885       gcc_unreachable ();
18886     }
18887 }
18888   [(set_attr "type" "alu,lea")
18889    (set_attr "mode" "DI")])
18890
18891 (define_expand "allocate_stack_worker"
18892   [(match_operand:SI 0 "register_operand" "")]
18893   "TARGET_STACK_PROBE"
18894 {
18895   if (reload_completed)
18896     {
18897       if (TARGET_64BIT)
18898         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18899       else
18900         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18901     }
18902   else
18903     {
18904       if (TARGET_64BIT)
18905         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18906       else
18907         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18908     }
18909   DONE;
18910 })
18911
18912 (define_insn "allocate_stack_worker_1"
18913   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18914     UNSPECV_STACK_PROBE)
18915    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18916    (clobber (match_scratch:SI 1 "=0"))
18917    (clobber (reg:CC FLAGS_REG))]
18918   "!TARGET_64BIT && TARGET_STACK_PROBE"
18919   "call\t__alloca"
18920   [(set_attr "type" "multi")
18921    (set_attr "length" "5")])
18922
18923 (define_expand "allocate_stack_worker_postreload"
18924   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18925                                     UNSPECV_STACK_PROBE)
18926               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18927               (clobber (match_dup 0))
18928               (clobber (reg:CC FLAGS_REG))])]
18929   ""
18930   "")
18931
18932 (define_insn "allocate_stack_worker_rex64"
18933   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18934     UNSPECV_STACK_PROBE)
18935    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18936    (clobber (match_scratch:DI 1 "=0"))
18937    (clobber (reg:CC FLAGS_REG))]
18938   "TARGET_64BIT && TARGET_STACK_PROBE"
18939   "call\t__alloca"
18940   [(set_attr "type" "multi")
18941    (set_attr "length" "5")])
18942
18943 (define_expand "allocate_stack_worker_rex64_postreload"
18944   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18945                                     UNSPECV_STACK_PROBE)
18946               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18947               (clobber (match_dup 0))
18948               (clobber (reg:CC FLAGS_REG))])]
18949   ""
18950   "")
18951
18952 (define_expand "allocate_stack"
18953   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18954                    (minus:SI (reg:SI SP_REG)
18955                              (match_operand:SI 1 "general_operand" "")))
18956               (clobber (reg:CC FLAGS_REG))])
18957    (parallel [(set (reg:SI SP_REG)
18958                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18959               (clobber (reg:CC FLAGS_REG))])]
18960   "TARGET_STACK_PROBE"
18961 {
18962 #ifdef CHECK_STACK_LIMIT
18963   if (GET_CODE (operands[1]) == CONST_INT
18964       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18965     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18966                            operands[1]));
18967   else 
18968 #endif
18969     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18970                                                             operands[1])));
18971
18972   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18973   DONE;
18974 })
18975
18976 (define_expand "builtin_setjmp_receiver"
18977   [(label_ref (match_operand 0 "" ""))]
18978   "!TARGET_64BIT && flag_pic"
18979 {
18980   if (TARGET_MACHO)
18981     {
18982       rtx xops[3];
18983       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18984       rtx label_rtx = gen_label_rtx ();
18985       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18986       emit_label (label_rtx);
18987       xops[0] = xops[1] = picreg;
18988       xops[2] = gen_rtx_CONST (SImode,
18989                   gen_rtx_MINUS (SImode,
18990                     gen_rtx_LABEL_REF (SImode, label_rtx),
18991                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
18992       ix86_expand_binary_operator (MINUS, SImode, xops);
18993     }
18994   else
18995     emit_insn (gen_set_got (pic_offset_table_rtx));
18996   DONE;
18997 })
18998 \f
18999 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19000
19001 (define_split
19002   [(set (match_operand 0 "register_operand" "")
19003         (match_operator 3 "promotable_binary_operator"
19004            [(match_operand 1 "register_operand" "")
19005             (match_operand 2 "aligned_operand" "")]))
19006    (clobber (reg:CC FLAGS_REG))]
19007   "! TARGET_PARTIAL_REG_STALL && reload_completed
19008    && ((GET_MODE (operands[0]) == HImode 
19009         && ((!optimize_size && !TARGET_FAST_PREFIX)
19010             || GET_CODE (operands[2]) != CONST_INT
19011             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19012        || (GET_MODE (operands[0]) == QImode 
19013            && (TARGET_PROMOTE_QImode || optimize_size)))"
19014   [(parallel [(set (match_dup 0)
19015                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19016               (clobber (reg:CC FLAGS_REG))])]
19017   "operands[0] = gen_lowpart (SImode, operands[0]);
19018    operands[1] = gen_lowpart (SImode, operands[1]);
19019    if (GET_CODE (operands[3]) != ASHIFT)
19020      operands[2] = gen_lowpart (SImode, operands[2]);
19021    PUT_MODE (operands[3], SImode);")
19022
19023 ; Promote the QImode tests, as i386 has encoding of the AND
19024 ; instruction with 32-bit sign-extended immediate and thus the
19025 ; instruction size is unchanged, except in the %eax case for
19026 ; which it is increased by one byte, hence the ! optimize_size.
19027 (define_split
19028   [(set (match_operand 0 "flags_reg_operand" "")
19029         (match_operator 2 "compare_operator"
19030           [(and (match_operand 3 "aligned_operand" "")
19031                 (match_operand 4 "const_int_operand" ""))
19032            (const_int 0)]))
19033    (set (match_operand 1 "register_operand" "")
19034         (and (match_dup 3) (match_dup 4)))]
19035   "! TARGET_PARTIAL_REG_STALL && reload_completed
19036    /* Ensure that the operand will remain sign-extended immediate.  */
19037    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19038    && ! optimize_size
19039    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19040        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19041   [(parallel [(set (match_dup 0)
19042                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19043                                     (const_int 0)]))
19044               (set (match_dup 1)
19045                    (and:SI (match_dup 3) (match_dup 4)))])]
19046 {
19047   operands[4]
19048     = gen_int_mode (INTVAL (operands[4])
19049                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19050   operands[1] = gen_lowpart (SImode, operands[1]);
19051   operands[3] = gen_lowpart (SImode, operands[3]);
19052 })
19053
19054 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19055 ; the TEST instruction with 32-bit sign-extended immediate and thus
19056 ; the instruction size would at least double, which is not what we
19057 ; want even with ! optimize_size.
19058 (define_split
19059   [(set (match_operand 0 "flags_reg_operand" "")
19060         (match_operator 1 "compare_operator"
19061           [(and (match_operand:HI 2 "aligned_operand" "")
19062                 (match_operand:HI 3 "const_int_operand" ""))
19063            (const_int 0)]))]
19064   "! TARGET_PARTIAL_REG_STALL && reload_completed
19065    /* Ensure that the operand will remain sign-extended immediate.  */
19066    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19067    && ! TARGET_FAST_PREFIX
19068    && ! optimize_size"
19069   [(set (match_dup 0)
19070         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19071                          (const_int 0)]))]
19072 {
19073   operands[3]
19074     = gen_int_mode (INTVAL (operands[3])
19075                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19076   operands[2] = gen_lowpart (SImode, operands[2]);
19077 })
19078
19079 (define_split
19080   [(set (match_operand 0 "register_operand" "")
19081         (neg (match_operand 1 "register_operand" "")))
19082    (clobber (reg:CC FLAGS_REG))]
19083   "! TARGET_PARTIAL_REG_STALL && reload_completed
19084    && (GET_MODE (operands[0]) == HImode
19085        || (GET_MODE (operands[0]) == QImode 
19086            && (TARGET_PROMOTE_QImode || optimize_size)))"
19087   [(parallel [(set (match_dup 0)
19088                    (neg:SI (match_dup 1)))
19089               (clobber (reg:CC FLAGS_REG))])]
19090   "operands[0] = gen_lowpart (SImode, operands[0]);
19091    operands[1] = gen_lowpart (SImode, operands[1]);")
19092
19093 (define_split
19094   [(set (match_operand 0 "register_operand" "")
19095         (not (match_operand 1 "register_operand" "")))]
19096   "! TARGET_PARTIAL_REG_STALL && reload_completed
19097    && (GET_MODE (operands[0]) == HImode
19098        || (GET_MODE (operands[0]) == QImode 
19099            && (TARGET_PROMOTE_QImode || optimize_size)))"
19100   [(set (match_dup 0)
19101         (not:SI (match_dup 1)))]
19102   "operands[0] = gen_lowpart (SImode, operands[0]);
19103    operands[1] = gen_lowpart (SImode, operands[1]);")
19104
19105 (define_split 
19106   [(set (match_operand 0 "register_operand" "")
19107         (if_then_else (match_operator 1 "comparison_operator" 
19108                                 [(reg FLAGS_REG) (const_int 0)])
19109                       (match_operand 2 "register_operand" "")
19110                       (match_operand 3 "register_operand" "")))]
19111   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19112    && (GET_MODE (operands[0]) == HImode
19113        || (GET_MODE (operands[0]) == QImode 
19114            && (TARGET_PROMOTE_QImode || optimize_size)))"
19115   [(set (match_dup 0)
19116         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19117   "operands[0] = gen_lowpart (SImode, operands[0]);
19118    operands[2] = gen_lowpart (SImode, operands[2]);
19119    operands[3] = gen_lowpart (SImode, operands[3]);")
19120                         
19121 \f
19122 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19123 ;; transform a complex memory operation into two memory to register operations.
19124
19125 ;; Don't push memory operands
19126 (define_peephole2
19127   [(set (match_operand:SI 0 "push_operand" "")
19128         (match_operand:SI 1 "memory_operand" ""))
19129    (match_scratch:SI 2 "r")]
19130   "!optimize_size && !TARGET_PUSH_MEMORY
19131    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19132   [(set (match_dup 2) (match_dup 1))
19133    (set (match_dup 0) (match_dup 2))]
19134   "")
19135
19136 (define_peephole2
19137   [(set (match_operand:DI 0 "push_operand" "")
19138         (match_operand:DI 1 "memory_operand" ""))
19139    (match_scratch:DI 2 "r")]
19140   "!optimize_size && !TARGET_PUSH_MEMORY
19141    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19142   [(set (match_dup 2) (match_dup 1))
19143    (set (match_dup 0) (match_dup 2))]
19144   "")
19145
19146 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19147 ;; SImode pushes.
19148 (define_peephole2
19149   [(set (match_operand:SF 0 "push_operand" "")
19150         (match_operand:SF 1 "memory_operand" ""))
19151    (match_scratch:SF 2 "r")]
19152   "!optimize_size && !TARGET_PUSH_MEMORY
19153    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19154   [(set (match_dup 2) (match_dup 1))
19155    (set (match_dup 0) (match_dup 2))]
19156   "")
19157
19158 (define_peephole2
19159   [(set (match_operand:HI 0 "push_operand" "")
19160         (match_operand:HI 1 "memory_operand" ""))
19161    (match_scratch:HI 2 "r")]
19162   "!optimize_size && !TARGET_PUSH_MEMORY
19163    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19164   [(set (match_dup 2) (match_dup 1))
19165    (set (match_dup 0) (match_dup 2))]
19166   "")
19167
19168 (define_peephole2
19169   [(set (match_operand:QI 0 "push_operand" "")
19170         (match_operand:QI 1 "memory_operand" ""))
19171    (match_scratch:QI 2 "q")]
19172   "!optimize_size && !TARGET_PUSH_MEMORY
19173    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19174   [(set (match_dup 2) (match_dup 1))
19175    (set (match_dup 0) (match_dup 2))]
19176   "")
19177
19178 ;; Don't move an immediate directly to memory when the instruction
19179 ;; gets too big.
19180 (define_peephole2
19181   [(match_scratch:SI 1 "r")
19182    (set (match_operand:SI 0 "memory_operand" "")
19183         (const_int 0))]
19184   "! optimize_size
19185    && ! TARGET_USE_MOV0
19186    && TARGET_SPLIT_LONG_MOVES
19187    && get_attr_length (insn) >= ix86_cost->large_insn
19188    && peep2_regno_dead_p (0, FLAGS_REG)"
19189   [(parallel [(set (match_dup 1) (const_int 0))
19190               (clobber (reg:CC FLAGS_REG))])
19191    (set (match_dup 0) (match_dup 1))]
19192   "")
19193
19194 (define_peephole2
19195   [(match_scratch:HI 1 "r")
19196    (set (match_operand:HI 0 "memory_operand" "")
19197         (const_int 0))]
19198   "! optimize_size
19199    && ! TARGET_USE_MOV0
19200    && TARGET_SPLIT_LONG_MOVES
19201    && get_attr_length (insn) >= ix86_cost->large_insn
19202    && peep2_regno_dead_p (0, FLAGS_REG)"
19203   [(parallel [(set (match_dup 2) (const_int 0))
19204               (clobber (reg:CC FLAGS_REG))])
19205    (set (match_dup 0) (match_dup 1))]
19206   "operands[2] = gen_lowpart (SImode, operands[1]);")
19207
19208 (define_peephole2
19209   [(match_scratch:QI 1 "q")
19210    (set (match_operand:QI 0 "memory_operand" "")
19211         (const_int 0))]
19212   "! optimize_size
19213    && ! TARGET_USE_MOV0
19214    && TARGET_SPLIT_LONG_MOVES
19215    && get_attr_length (insn) >= ix86_cost->large_insn
19216    && peep2_regno_dead_p (0, FLAGS_REG)"
19217   [(parallel [(set (match_dup 2) (const_int 0))
19218               (clobber (reg:CC FLAGS_REG))])
19219    (set (match_dup 0) (match_dup 1))]
19220   "operands[2] = gen_lowpart (SImode, operands[1]);")
19221
19222 (define_peephole2
19223   [(match_scratch:SI 2 "r")
19224    (set (match_operand:SI 0 "memory_operand" "")
19225         (match_operand:SI 1 "immediate_operand" ""))]
19226   "! optimize_size
19227    && get_attr_length (insn) >= ix86_cost->large_insn
19228    && TARGET_SPLIT_LONG_MOVES"
19229   [(set (match_dup 2) (match_dup 1))
19230    (set (match_dup 0) (match_dup 2))]
19231   "")
19232
19233 (define_peephole2
19234   [(match_scratch:HI 2 "r")
19235    (set (match_operand:HI 0 "memory_operand" "")
19236         (match_operand:HI 1 "immediate_operand" ""))]
19237   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19238   && TARGET_SPLIT_LONG_MOVES"
19239   [(set (match_dup 2) (match_dup 1))
19240    (set (match_dup 0) (match_dup 2))]
19241   "")
19242
19243 (define_peephole2
19244   [(match_scratch:QI 2 "q")
19245    (set (match_operand:QI 0 "memory_operand" "")
19246         (match_operand:QI 1 "immediate_operand" ""))]
19247   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19248   && TARGET_SPLIT_LONG_MOVES"
19249   [(set (match_dup 2) (match_dup 1))
19250    (set (match_dup 0) (match_dup 2))]
19251   "")
19252
19253 ;; Don't compare memory with zero, load and use a test instead.
19254 (define_peephole2
19255   [(set (match_operand 0 "flags_reg_operand" "")
19256         (match_operator 1 "compare_operator"
19257           [(match_operand:SI 2 "memory_operand" "")
19258            (const_int 0)]))
19259    (match_scratch:SI 3 "r")]
19260   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19261   [(set (match_dup 3) (match_dup 2))
19262    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19263   "")
19264
19265 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19266 ;; Don't split NOTs with a displacement operand, because resulting XOR
19267 ;; will not be pairable anyway.
19268 ;;
19269 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19270 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19271 ;; so this split helps here as well.
19272 ;;
19273 ;; Note: Can't do this as a regular split because we can't get proper
19274 ;; lifetime information then.
19275
19276 (define_peephole2
19277   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19278         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19279   "!optimize_size
19280    && peep2_regno_dead_p (0, FLAGS_REG)
19281    && ((TARGET_PENTIUM 
19282         && (GET_CODE (operands[0]) != MEM
19283             || !memory_displacement_operand (operands[0], SImode)))
19284        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19285   [(parallel [(set (match_dup 0)
19286                    (xor:SI (match_dup 1) (const_int -1)))
19287               (clobber (reg:CC FLAGS_REG))])]
19288   "")
19289
19290 (define_peephole2
19291   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19292         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19293   "!optimize_size
19294    && peep2_regno_dead_p (0, FLAGS_REG)
19295    && ((TARGET_PENTIUM 
19296         && (GET_CODE (operands[0]) != MEM
19297             || !memory_displacement_operand (operands[0], HImode)))
19298        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19299   [(parallel [(set (match_dup 0)
19300                    (xor:HI (match_dup 1) (const_int -1)))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   "")
19303
19304 (define_peephole2
19305   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19306         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19307   "!optimize_size
19308    && peep2_regno_dead_p (0, FLAGS_REG)
19309    && ((TARGET_PENTIUM 
19310         && (GET_CODE (operands[0]) != MEM
19311             || !memory_displacement_operand (operands[0], QImode)))
19312        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19313   [(parallel [(set (match_dup 0)
19314                    (xor:QI (match_dup 1) (const_int -1)))
19315               (clobber (reg:CC FLAGS_REG))])]
19316   "")
19317
19318 ;; Non pairable "test imm, reg" instructions can be translated to
19319 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19320 ;; byte opcode instead of two, have a short form for byte operands),
19321 ;; so do it for other CPUs as well.  Given that the value was dead,
19322 ;; this should not create any new dependencies.  Pass on the sub-word
19323 ;; versions if we're concerned about partial register stalls.
19324
19325 (define_peephole2
19326   [(set (match_operand 0 "flags_reg_operand" "")
19327         (match_operator 1 "compare_operator"
19328           [(and:SI (match_operand:SI 2 "register_operand" "")
19329                    (match_operand:SI 3 "immediate_operand" ""))
19330            (const_int 0)]))]
19331   "ix86_match_ccmode (insn, CCNOmode)
19332    && (true_regnum (operands[2]) != 0
19333        || (GET_CODE (operands[3]) == CONST_INT
19334            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19335    && peep2_reg_dead_p (1, operands[2])"
19336   [(parallel
19337      [(set (match_dup 0)
19338            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19339                             (const_int 0)]))
19340       (set (match_dup 2)
19341            (and:SI (match_dup 2) (match_dup 3)))])]
19342   "")
19343
19344 ;; We don't need to handle HImode case, because it will be promoted to SImode
19345 ;; on ! TARGET_PARTIAL_REG_STALL
19346
19347 (define_peephole2
19348   [(set (match_operand 0 "flags_reg_operand" "")
19349         (match_operator 1 "compare_operator"
19350           [(and:QI (match_operand:QI 2 "register_operand" "")
19351                    (match_operand:QI 3 "immediate_operand" ""))
19352            (const_int 0)]))]
19353   "! TARGET_PARTIAL_REG_STALL
19354    && ix86_match_ccmode (insn, CCNOmode)
19355    && true_regnum (operands[2]) != 0
19356    && peep2_reg_dead_p (1, operands[2])"
19357   [(parallel
19358      [(set (match_dup 0)
19359            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19360                             (const_int 0)]))
19361       (set (match_dup 2)
19362            (and:QI (match_dup 2) (match_dup 3)))])]
19363   "")
19364
19365 (define_peephole2
19366   [(set (match_operand 0 "flags_reg_operand" "")
19367         (match_operator 1 "compare_operator"
19368           [(and:SI
19369              (zero_extract:SI
19370                (match_operand 2 "ext_register_operand" "")
19371                (const_int 8)
19372                (const_int 8))
19373              (match_operand 3 "const_int_operand" ""))
19374            (const_int 0)]))]
19375   "! TARGET_PARTIAL_REG_STALL
19376    && ix86_match_ccmode (insn, CCNOmode)
19377    && true_regnum (operands[2]) != 0
19378    && peep2_reg_dead_p (1, operands[2])"
19379   [(parallel [(set (match_dup 0)
19380                    (match_op_dup 1
19381                      [(and:SI
19382                         (zero_extract:SI
19383                           (match_dup 2)
19384                           (const_int 8)
19385                           (const_int 8))
19386                         (match_dup 3))
19387                       (const_int 0)]))
19388               (set (zero_extract:SI (match_dup 2)
19389                                     (const_int 8)
19390                                     (const_int 8))
19391                    (and:SI 
19392                      (zero_extract:SI
19393                        (match_dup 2)
19394                        (const_int 8)
19395                        (const_int 8))
19396                      (match_dup 3)))])]
19397   "")
19398
19399 ;; Don't do logical operations with memory inputs.
19400 (define_peephole2
19401   [(match_scratch:SI 2 "r")
19402    (parallel [(set (match_operand:SI 0 "register_operand" "")
19403                    (match_operator:SI 3 "arith_or_logical_operator"
19404                      [(match_dup 0)
19405                       (match_operand:SI 1 "memory_operand" "")]))
19406               (clobber (reg:CC FLAGS_REG))])]
19407   "! optimize_size && ! TARGET_READ_MODIFY"
19408   [(set (match_dup 2) (match_dup 1))
19409    (parallel [(set (match_dup 0)
19410                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19411               (clobber (reg:CC FLAGS_REG))])]
19412   "")
19413
19414 (define_peephole2
19415   [(match_scratch:SI 2 "r")
19416    (parallel [(set (match_operand:SI 0 "register_operand" "")
19417                    (match_operator:SI 3 "arith_or_logical_operator"
19418                      [(match_operand:SI 1 "memory_operand" "")
19419                       (match_dup 0)]))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   "! optimize_size && ! TARGET_READ_MODIFY"
19422   [(set (match_dup 2) (match_dup 1))
19423    (parallel [(set (match_dup 0)
19424                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19425               (clobber (reg:CC FLAGS_REG))])]
19426   "")
19427
19428 ; Don't do logical operations with memory outputs
19429 ;
19430 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19431 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19432 ; the same decoder scheduling characteristics as the original.
19433
19434 (define_peephole2
19435   [(match_scratch:SI 2 "r")
19436    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19437                    (match_operator:SI 3 "arith_or_logical_operator"
19438                      [(match_dup 0)
19439                       (match_operand:SI 1 "nonmemory_operand" "")]))
19440               (clobber (reg:CC FLAGS_REG))])]
19441   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19442   [(set (match_dup 2) (match_dup 0))
19443    (parallel [(set (match_dup 2)
19444                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19445               (clobber (reg:CC FLAGS_REG))])
19446    (set (match_dup 0) (match_dup 2))]
19447   "")
19448
19449 (define_peephole2
19450   [(match_scratch:SI 2 "r")
19451    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19452                    (match_operator:SI 3 "arith_or_logical_operator"
19453                      [(match_operand:SI 1 "nonmemory_operand" "")
19454                       (match_dup 0)]))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19457   [(set (match_dup 2) (match_dup 0))
19458    (parallel [(set (match_dup 2)
19459                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19460               (clobber (reg:CC FLAGS_REG))])
19461    (set (match_dup 0) (match_dup 2))]
19462   "")
19463
19464 ;; Attempt to always use XOR for zeroing registers.
19465 (define_peephole2
19466   [(set (match_operand 0 "register_operand" "")
19467         (match_operand 1 "const0_operand" ""))]
19468   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19469    && (! TARGET_USE_MOV0 || optimize_size)
19470    && GENERAL_REG_P (operands[0])
19471    && peep2_regno_dead_p (0, FLAGS_REG)"
19472   [(parallel [(set (match_dup 0) (const_int 0))
19473               (clobber (reg:CC FLAGS_REG))])]
19474 {
19475   operands[0] = gen_lowpart (word_mode, operands[0]);
19476 })
19477
19478 (define_peephole2
19479   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19480         (const_int 0))]
19481   "(GET_MODE (operands[0]) == QImode
19482     || GET_MODE (operands[0]) == HImode)
19483    && (! TARGET_USE_MOV0 || optimize_size)
19484    && peep2_regno_dead_p (0, FLAGS_REG)"
19485   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19486               (clobber (reg:CC FLAGS_REG))])])
19487
19488 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19489 (define_peephole2
19490   [(set (match_operand 0 "register_operand" "")
19491         (const_int -1))]
19492   "(GET_MODE (operands[0]) == HImode
19493     || GET_MODE (operands[0]) == SImode 
19494     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19495    && (optimize_size || TARGET_PENTIUM)
19496    && peep2_regno_dead_p (0, FLAGS_REG)"
19497   [(parallel [(set (match_dup 0) (const_int -1))
19498               (clobber (reg:CC FLAGS_REG))])]
19499   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19500                               operands[0]);")
19501
19502 ;; Attempt to convert simple leas to adds. These can be created by
19503 ;; move expanders.
19504 (define_peephole2
19505   [(set (match_operand:SI 0 "register_operand" "")
19506         (plus:SI (match_dup 0)
19507                  (match_operand:SI 1 "nonmemory_operand" "")))]
19508   "peep2_regno_dead_p (0, FLAGS_REG)"
19509   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19510               (clobber (reg:CC FLAGS_REG))])]
19511   "")
19512
19513 (define_peephole2
19514   [(set (match_operand:SI 0 "register_operand" "")
19515         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19516                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19517   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19518   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19519               (clobber (reg:CC FLAGS_REG))])]
19520   "operands[2] = gen_lowpart (SImode, operands[2]);")
19521
19522 (define_peephole2
19523   [(set (match_operand:DI 0 "register_operand" "")
19524         (plus:DI (match_dup 0)
19525                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19526   "peep2_regno_dead_p (0, FLAGS_REG)"
19527   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19528               (clobber (reg:CC FLAGS_REG))])]
19529   "")
19530
19531 (define_peephole2
19532   [(set (match_operand:SI 0 "register_operand" "")
19533         (mult:SI (match_dup 0)
19534                  (match_operand:SI 1 "const_int_operand" "")))]
19535   "exact_log2 (INTVAL (operands[1])) >= 0
19536    && peep2_regno_dead_p (0, FLAGS_REG)"
19537   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19538               (clobber (reg:CC FLAGS_REG))])]
19539   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19540
19541 (define_peephole2
19542   [(set (match_operand:DI 0 "register_operand" "")
19543         (mult:DI (match_dup 0)
19544                  (match_operand:DI 1 "const_int_operand" "")))]
19545   "exact_log2 (INTVAL (operands[1])) >= 0
19546    && peep2_regno_dead_p (0, FLAGS_REG)"
19547   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19548               (clobber (reg:CC FLAGS_REG))])]
19549   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19550
19551 (define_peephole2
19552   [(set (match_operand:SI 0 "register_operand" "")
19553         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19554                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19555   "exact_log2 (INTVAL (operands[2])) >= 0
19556    && REGNO (operands[0]) == REGNO (operands[1])
19557    && peep2_regno_dead_p (0, FLAGS_REG)"
19558   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19559               (clobber (reg:CC FLAGS_REG))])]
19560   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19561
19562 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19563 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19564 ;; many CPUs it is also faster, since special hardware to avoid esp
19565 ;; dependencies is present.
19566
19567 ;; While some of these conversions may be done using splitters, we use peepholes
19568 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19569
19570 ;; Convert prologue esp subtractions to push.
19571 ;; We need register to push.  In order to keep verify_flow_info happy we have
19572 ;; two choices
19573 ;; - use scratch and clobber it in order to avoid dependencies
19574 ;; - use already live register
19575 ;; We can't use the second way right now, since there is no reliable way how to
19576 ;; verify that given register is live.  First choice will also most likely in
19577 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19578 ;; call clobbered registers are dead.  We may want to use base pointer as an
19579 ;; alternative when no register is available later.
19580
19581 (define_peephole2
19582   [(match_scratch:SI 0 "r")
19583    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19584               (clobber (reg:CC FLAGS_REG))
19585               (clobber (mem:BLK (scratch)))])]
19586   "optimize_size || !TARGET_SUB_ESP_4"
19587   [(clobber (match_dup 0))
19588    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19589               (clobber (mem:BLK (scratch)))])])
19590
19591 (define_peephole2
19592   [(match_scratch:SI 0 "r")
19593    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19594               (clobber (reg:CC FLAGS_REG))
19595               (clobber (mem:BLK (scratch)))])]
19596   "optimize_size || !TARGET_SUB_ESP_8"
19597   [(clobber (match_dup 0))
19598    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19599    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19600               (clobber (mem:BLK (scratch)))])])
19601
19602 ;; Convert esp subtractions to push.
19603 (define_peephole2
19604   [(match_scratch:SI 0 "r")
19605    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19606               (clobber (reg:CC FLAGS_REG))])]
19607   "optimize_size || !TARGET_SUB_ESP_4"
19608   [(clobber (match_dup 0))
19609    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19610
19611 (define_peephole2
19612   [(match_scratch:SI 0 "r")
19613    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19614               (clobber (reg:CC FLAGS_REG))])]
19615   "optimize_size || !TARGET_SUB_ESP_8"
19616   [(clobber (match_dup 0))
19617    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19618    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19619
19620 ;; Convert epilogue deallocator to pop.
19621 (define_peephole2
19622   [(match_scratch:SI 0 "r")
19623    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19624               (clobber (reg:CC FLAGS_REG))
19625               (clobber (mem:BLK (scratch)))])]
19626   "optimize_size || !TARGET_ADD_ESP_4"
19627   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19628               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19629               (clobber (mem:BLK (scratch)))])]
19630   "")
19631
19632 ;; Two pops case is tricky, since pop causes dependency on destination register.
19633 ;; We use two registers if available.
19634 (define_peephole2
19635   [(match_scratch:SI 0 "r")
19636    (match_scratch:SI 1 "r")
19637    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19638               (clobber (reg:CC FLAGS_REG))
19639               (clobber (mem:BLK (scratch)))])]
19640   "optimize_size || !TARGET_ADD_ESP_8"
19641   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19642               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19643               (clobber (mem:BLK (scratch)))])
19644    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19645               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19646   "")
19647
19648 (define_peephole2
19649   [(match_scratch:SI 0 "r")
19650    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19651               (clobber (reg:CC FLAGS_REG))
19652               (clobber (mem:BLK (scratch)))])]
19653   "optimize_size"
19654   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19655               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656               (clobber (mem:BLK (scratch)))])
19657    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19658               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19659   "")
19660
19661 ;; Convert esp additions to pop.
19662 (define_peephole2
19663   [(match_scratch:SI 0 "r")
19664    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19665               (clobber (reg:CC FLAGS_REG))])]
19666   ""
19667   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19668               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19669   "")
19670
19671 ;; Two pops case is tricky, since pop causes dependency on destination register.
19672 ;; We use two registers if available.
19673 (define_peephole2
19674   [(match_scratch:SI 0 "r")
19675    (match_scratch:SI 1 "r")
19676    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19677               (clobber (reg:CC FLAGS_REG))])]
19678   ""
19679   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19680               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19681    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19682               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19683   "")
19684
19685 (define_peephole2
19686   [(match_scratch:SI 0 "r")
19687    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19688               (clobber (reg:CC FLAGS_REG))])]
19689   "optimize_size"
19690   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19691               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19692    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19693               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19694   "")
19695 \f
19696 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19697 ;; required and register dies.  Similarly for 128 to plus -128.
19698 (define_peephole2
19699   [(set (match_operand 0 "flags_reg_operand" "")
19700         (match_operator 1 "compare_operator"
19701           [(match_operand 2 "register_operand" "")
19702            (match_operand 3 "const_int_operand" "")]))]
19703   "(INTVAL (operands[3]) == -1
19704     || INTVAL (operands[3]) == 1
19705     || INTVAL (operands[3]) == 128)
19706    && ix86_match_ccmode (insn, CCGCmode)
19707    && peep2_reg_dead_p (1, operands[2])"
19708   [(parallel [(set (match_dup 0)
19709                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19710               (clobber (match_dup 2))])]
19711   "")
19712 \f
19713 (define_peephole2
19714   [(match_scratch:DI 0 "r")
19715    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19716               (clobber (reg:CC FLAGS_REG))
19717               (clobber (mem:BLK (scratch)))])]
19718   "optimize_size || !TARGET_SUB_ESP_4"
19719   [(clobber (match_dup 0))
19720    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19721               (clobber (mem:BLK (scratch)))])])
19722
19723 (define_peephole2
19724   [(match_scratch:DI 0 "r")
19725    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19726               (clobber (reg:CC FLAGS_REG))
19727               (clobber (mem:BLK (scratch)))])]
19728   "optimize_size || !TARGET_SUB_ESP_8"
19729   [(clobber (match_dup 0))
19730    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19731    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19732               (clobber (mem:BLK (scratch)))])])
19733
19734 ;; Convert esp subtractions to push.
19735 (define_peephole2
19736   [(match_scratch:DI 0 "r")
19737    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19738               (clobber (reg:CC FLAGS_REG))])]
19739   "optimize_size || !TARGET_SUB_ESP_4"
19740   [(clobber (match_dup 0))
19741    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19742
19743 (define_peephole2
19744   [(match_scratch:DI 0 "r")
19745    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19746               (clobber (reg:CC FLAGS_REG))])]
19747   "optimize_size || !TARGET_SUB_ESP_8"
19748   [(clobber (match_dup 0))
19749    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19750    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19751
19752 ;; Convert epilogue deallocator to pop.
19753 (define_peephole2
19754   [(match_scratch:DI 0 "r")
19755    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19756               (clobber (reg:CC FLAGS_REG))
19757               (clobber (mem:BLK (scratch)))])]
19758   "optimize_size || !TARGET_ADD_ESP_4"
19759   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19760               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19761               (clobber (mem:BLK (scratch)))])]
19762   "")
19763
19764 ;; Two pops case is tricky, since pop causes dependency on destination register.
19765 ;; We use two registers if available.
19766 (define_peephole2
19767   [(match_scratch:DI 0 "r")
19768    (match_scratch:DI 1 "r")
19769    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19770               (clobber (reg:CC FLAGS_REG))
19771               (clobber (mem:BLK (scratch)))])]
19772   "optimize_size || !TARGET_ADD_ESP_8"
19773   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19774               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19775               (clobber (mem:BLK (scratch)))])
19776    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19777               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19778   "")
19779
19780 (define_peephole2
19781   [(match_scratch:DI 0 "r")
19782    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19783               (clobber (reg:CC FLAGS_REG))
19784               (clobber (mem:BLK (scratch)))])]
19785   "optimize_size"
19786   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19787               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788               (clobber (mem:BLK (scratch)))])
19789    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19790               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19791   "")
19792
19793 ;; Convert esp additions to pop.
19794 (define_peephole2
19795   [(match_scratch:DI 0 "r")
19796    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19797               (clobber (reg:CC FLAGS_REG))])]
19798   ""
19799   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19800               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19801   "")
19802
19803 ;; Two pops case is tricky, since pop causes dependency on destination register.
19804 ;; We use two registers if available.
19805 (define_peephole2
19806   [(match_scratch:DI 0 "r")
19807    (match_scratch:DI 1 "r")
19808    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19809               (clobber (reg:CC FLAGS_REG))])]
19810   ""
19811   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19812               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19813    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19814               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19815   "")
19816
19817 (define_peephole2
19818   [(match_scratch:DI 0 "r")
19819    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19820               (clobber (reg:CC FLAGS_REG))])]
19821   "optimize_size"
19822   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19823               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19824    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826   "")
19827 \f
19828 ;; Convert imul by three, five and nine into lea
19829 (define_peephole2
19830   [(parallel
19831     [(set (match_operand:SI 0 "register_operand" "")
19832           (mult:SI (match_operand:SI 1 "register_operand" "")
19833                    (match_operand:SI 2 "const_int_operand" "")))
19834      (clobber (reg:CC FLAGS_REG))])]
19835   "INTVAL (operands[2]) == 3
19836    || INTVAL (operands[2]) == 5
19837    || INTVAL (operands[2]) == 9"
19838   [(set (match_dup 0)
19839         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19840                  (match_dup 1)))]
19841   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19842
19843 (define_peephole2
19844   [(parallel
19845     [(set (match_operand:SI 0 "register_operand" "")
19846           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19847                    (match_operand:SI 2 "const_int_operand" "")))
19848      (clobber (reg:CC FLAGS_REG))])]
19849   "!optimize_size 
19850    && (INTVAL (operands[2]) == 3
19851        || INTVAL (operands[2]) == 5
19852        || INTVAL (operands[2]) == 9)"
19853   [(set (match_dup 0) (match_dup 1))
19854    (set (match_dup 0)
19855         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19856                  (match_dup 0)))]
19857   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19858
19859 (define_peephole2
19860   [(parallel
19861     [(set (match_operand:DI 0 "register_operand" "")
19862           (mult:DI (match_operand:DI 1 "register_operand" "")
19863                    (match_operand:DI 2 "const_int_operand" "")))
19864      (clobber (reg:CC FLAGS_REG))])]
19865   "TARGET_64BIT
19866    && (INTVAL (operands[2]) == 3
19867        || INTVAL (operands[2]) == 5
19868        || INTVAL (operands[2]) == 9)"
19869   [(set (match_dup 0)
19870         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19871                  (match_dup 1)))]
19872   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19873
19874 (define_peephole2
19875   [(parallel
19876     [(set (match_operand:DI 0 "register_operand" "")
19877           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19878                    (match_operand:DI 2 "const_int_operand" "")))
19879      (clobber (reg:CC FLAGS_REG))])]
19880   "TARGET_64BIT
19881    && !optimize_size 
19882    && (INTVAL (operands[2]) == 3
19883        || INTVAL (operands[2]) == 5
19884        || INTVAL (operands[2]) == 9)"
19885   [(set (match_dup 0) (match_dup 1))
19886    (set (match_dup 0)
19887         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19888                  (match_dup 0)))]
19889   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19890
19891 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19892 ;; imul $32bit_imm, reg, reg is direct decoded.
19893 (define_peephole2
19894   [(match_scratch:DI 3 "r")
19895    (parallel [(set (match_operand:DI 0 "register_operand" "")
19896                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19897                             (match_operand:DI 2 "immediate_operand" "")))
19898               (clobber (reg:CC FLAGS_REG))])]
19899   "TARGET_K8 && !optimize_size
19900    && (GET_CODE (operands[2]) != CONST_INT
19901        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19902   [(set (match_dup 3) (match_dup 1))
19903    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19904               (clobber (reg:CC FLAGS_REG))])]
19905 "")
19906
19907 (define_peephole2
19908   [(match_scratch:SI 3 "r")
19909    (parallel [(set (match_operand:SI 0 "register_operand" "")
19910                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19911                             (match_operand:SI 2 "immediate_operand" "")))
19912               (clobber (reg:CC FLAGS_REG))])]
19913   "TARGET_K8 && !optimize_size
19914    && (GET_CODE (operands[2]) != CONST_INT
19915        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19916   [(set (match_dup 3) (match_dup 1))
19917    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19918               (clobber (reg:CC FLAGS_REG))])]
19919 "")
19920
19921 (define_peephole2
19922   [(match_scratch:SI 3 "r")
19923    (parallel [(set (match_operand:DI 0 "register_operand" "")
19924                    (zero_extend:DI
19925                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19926                               (match_operand:SI 2 "immediate_operand" ""))))
19927               (clobber (reg:CC FLAGS_REG))])]
19928   "TARGET_K8 && !optimize_size
19929    && (GET_CODE (operands[2]) != CONST_INT
19930        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19931   [(set (match_dup 3) (match_dup 1))
19932    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19933               (clobber (reg:CC FLAGS_REG))])]
19934 "")
19935
19936 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19937 ;; Convert it into imul reg, reg
19938 ;; It would be better to force assembler to encode instruction using long
19939 ;; immediate, but there is apparently no way to do so.
19940 (define_peephole2
19941   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19942                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19943                             (match_operand:DI 2 "const_int_operand" "")))
19944               (clobber (reg:CC FLAGS_REG))])
19945    (match_scratch:DI 3 "r")]
19946   "TARGET_K8 && !optimize_size
19947    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19948   [(set (match_dup 3) (match_dup 2))
19949    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19950               (clobber (reg:CC FLAGS_REG))])]
19951 {
19952   if (!rtx_equal_p (operands[0], operands[1]))
19953     emit_move_insn (operands[0], operands[1]);
19954 })
19955
19956 (define_peephole2
19957   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19958                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19959                             (match_operand:SI 2 "const_int_operand" "")))
19960               (clobber (reg:CC FLAGS_REG))])
19961    (match_scratch:SI 3 "r")]
19962   "TARGET_K8 && !optimize_size
19963    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19964   [(set (match_dup 3) (match_dup 2))
19965    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19966               (clobber (reg:CC FLAGS_REG))])]
19967 {
19968   if (!rtx_equal_p (operands[0], operands[1]))
19969     emit_move_insn (operands[0], operands[1]);
19970 })
19971
19972 (define_peephole2
19973   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19974                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19975                             (match_operand:HI 2 "immediate_operand" "")))
19976               (clobber (reg:CC FLAGS_REG))])
19977    (match_scratch:HI 3 "r")]
19978   "TARGET_K8 && !optimize_size"
19979   [(set (match_dup 3) (match_dup 2))
19980    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19981               (clobber (reg:CC FLAGS_REG))])]
19982 {
19983   if (!rtx_equal_p (operands[0], operands[1]))
19984     emit_move_insn (operands[0], operands[1]);
19985 })
19986
19987 ;; After splitting up read-modify operations, array accesses with memory
19988 ;; operands might end up in form:
19989 ;;  sall    $2, %eax
19990 ;;  movl    4(%esp), %edx
19991 ;;  addl    %edx, %eax
19992 ;; instead of pre-splitting:
19993 ;;  sall    $2, %eax
19994 ;;  addl    4(%esp), %eax
19995 ;; Turn it into:
19996 ;;  movl    4(%esp), %edx
19997 ;;  leal    (%edx,%eax,4), %eax
19998
19999 (define_peephole2
20000   [(parallel [(set (match_operand 0 "register_operand" "")
20001                    (ashift (match_operand 1 "register_operand" "")
20002                            (match_operand 2 "const_int_operand" "")))
20003                (clobber (reg:CC FLAGS_REG))])
20004    (set (match_operand 3 "register_operand")
20005         (match_operand 4 "x86_64_general_operand" ""))
20006    (parallel [(set (match_operand 5 "register_operand" "")
20007                    (plus (match_operand 6 "register_operand" "")
20008                          (match_operand 7 "register_operand" "")))
20009                    (clobber (reg:CC FLAGS_REG))])]
20010   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20011    /* Validate MODE for lea.  */
20012    && ((!TARGET_PARTIAL_REG_STALL
20013         && (GET_MODE (operands[0]) == QImode
20014             || GET_MODE (operands[0]) == HImode))
20015        || GET_MODE (operands[0]) == SImode 
20016        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20017    /* We reorder load and the shift.  */
20018    && !rtx_equal_p (operands[1], operands[3])
20019    && !reg_overlap_mentioned_p (operands[0], operands[4])
20020    /* Last PLUS must consist of operand 0 and 3.  */
20021    && !rtx_equal_p (operands[0], operands[3])
20022    && (rtx_equal_p (operands[3], operands[6])
20023        || rtx_equal_p (operands[3], operands[7]))
20024    && (rtx_equal_p (operands[0], operands[6])
20025        || rtx_equal_p (operands[0], operands[7]))
20026    /* The intermediate operand 0 must die or be same as output.  */
20027    && (rtx_equal_p (operands[0], operands[5])
20028        || peep2_reg_dead_p (3, operands[0]))"
20029   [(set (match_dup 3) (match_dup 4))
20030    (set (match_dup 0) (match_dup 1))]
20031 {
20032   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20033   int scale = 1 << INTVAL (operands[2]);
20034   rtx index = gen_lowpart (Pmode, operands[1]);
20035   rtx base = gen_lowpart (Pmode, operands[3]);
20036   rtx dest = gen_lowpart (mode, operands[5]);
20037
20038   operands[1] = gen_rtx_PLUS (Pmode, base,
20039                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20040   if (mode != Pmode)
20041     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20042   operands[0] = dest;
20043 })
20044 \f
20045 ;; Call-value patterns last so that the wildcard operand does not
20046 ;; disrupt insn-recog's switch tables.
20047
20048 (define_insn "*call_value_pop_0"
20049   [(set (match_operand 0 "" "")
20050         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20051               (match_operand:SI 2 "" "")))
20052    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20053                             (match_operand:SI 3 "immediate_operand" "")))]
20054   "!TARGET_64BIT"
20055 {
20056   if (SIBLING_CALL_P (insn))
20057     return "jmp\t%P1";
20058   else
20059     return "call\t%P1";
20060 }
20061   [(set_attr "type" "callv")])
20062
20063 (define_insn "*call_value_pop_1"
20064   [(set (match_operand 0 "" "")
20065         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20066               (match_operand:SI 2 "" "")))
20067    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20068                             (match_operand:SI 3 "immediate_operand" "i")))]
20069   "!TARGET_64BIT"
20070 {
20071   if (constant_call_address_operand (operands[1], Pmode))
20072     {
20073       if (SIBLING_CALL_P (insn))
20074         return "jmp\t%P1";
20075       else
20076         return "call\t%P1";
20077     }
20078   if (SIBLING_CALL_P (insn))
20079     return "jmp\t%A1";
20080   else
20081     return "call\t%A1";
20082 }
20083   [(set_attr "type" "callv")])
20084
20085 (define_insn "*call_value_0"
20086   [(set (match_operand 0 "" "")
20087         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20088               (match_operand:SI 2 "" "")))]
20089   "!TARGET_64BIT"
20090 {
20091   if (SIBLING_CALL_P (insn))
20092     return "jmp\t%P1";
20093   else
20094     return "call\t%P1";
20095 }
20096   [(set_attr "type" "callv")])
20097
20098 (define_insn "*call_value_0_rex64"
20099   [(set (match_operand 0 "" "")
20100         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20101               (match_operand:DI 2 "const_int_operand" "")))]
20102   "TARGET_64BIT"
20103 {
20104   if (SIBLING_CALL_P (insn))
20105     return "jmp\t%P1";
20106   else
20107     return "call\t%P1";
20108 }
20109   [(set_attr "type" "callv")])
20110
20111 (define_insn "*call_value_1"
20112   [(set (match_operand 0 "" "")
20113         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20114               (match_operand:SI 2 "" "")))]
20115   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20116 {
20117   if (constant_call_address_operand (operands[1], Pmode))
20118     return "call\t%P1";
20119   return "call\t%A1";
20120 }
20121   [(set_attr "type" "callv")])
20122
20123 (define_insn "*sibcall_value_1"
20124   [(set (match_operand 0 "" "")
20125         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20126               (match_operand:SI 2 "" "")))]
20127   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20128 {
20129   if (constant_call_address_operand (operands[1], Pmode))
20130     return "jmp\t%P1";
20131   return "jmp\t%A1";
20132 }
20133   [(set_attr "type" "callv")])
20134
20135 (define_insn "*call_value_1_rex64"
20136   [(set (match_operand 0 "" "")
20137         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20138               (match_operand:DI 2 "" "")))]
20139   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20140 {
20141   if (constant_call_address_operand (operands[1], Pmode))
20142     return "call\t%P1";
20143   return "call\t%A1";
20144 }
20145   [(set_attr "type" "callv")])
20146
20147 (define_insn "*sibcall_value_1_rex64"
20148   [(set (match_operand 0 "" "")
20149         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20150               (match_operand:DI 2 "" "")))]
20151   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20152   "jmp\t%P1"
20153   [(set_attr "type" "callv")])
20154
20155 (define_insn "*sibcall_value_1_rex64_v"
20156   [(set (match_operand 0 "" "")
20157         (call (mem:QI (reg:DI 40))
20158               (match_operand:DI 1 "" "")))]
20159   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20160   "jmp\t*%%r11"
20161   [(set_attr "type" "callv")])
20162 \f
20163 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20164 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20165 ;; caught for use by garbage collectors and the like.  Using an insn that
20166 ;; maps to SIGILL makes it more likely the program will rightfully die.
20167 ;; Keeping with tradition, "6" is in honor of #UD.
20168 (define_insn "trap"
20169   [(trap_if (const_int 1) (const_int 6))]
20170   ""
20171   ".word\t0x0b0f"
20172   [(set_attr "length" "2")])
20173
20174 (define_expand "sse_prologue_save"
20175   [(parallel [(set (match_operand:BLK 0 "" "")
20176                    (unspec:BLK [(reg:DI 21)
20177                                 (reg:DI 22)
20178                                 (reg:DI 23)
20179                                 (reg:DI 24)
20180                                 (reg:DI 25)
20181                                 (reg:DI 26)
20182                                 (reg:DI 27)
20183                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20184               (use (match_operand:DI 1 "register_operand" ""))
20185               (use (match_operand:DI 2 "immediate_operand" ""))
20186               (use (label_ref:DI (match_operand 3 "" "")))])]
20187   "TARGET_64BIT"
20188   "")
20189
20190 (define_insn "*sse_prologue_save_insn"
20191   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20192                           (match_operand:DI 4 "const_int_operand" "n")))
20193         (unspec:BLK [(reg:DI 21)
20194                      (reg:DI 22)
20195                      (reg:DI 23)
20196                      (reg:DI 24)
20197                      (reg:DI 25)
20198                      (reg:DI 26)
20199                      (reg:DI 27)
20200                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20201    (use (match_operand:DI 1 "register_operand" "r"))
20202    (use (match_operand:DI 2 "const_int_operand" "i"))
20203    (use (label_ref:DI (match_operand 3 "" "X")))]
20204   "TARGET_64BIT
20205    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20206    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20207   "*
20208 {
20209   int i;
20210   operands[0] = gen_rtx_MEM (Pmode,
20211                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20212   output_asm_insn (\"jmp\\t%A1\", operands);
20213   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20214     {
20215       operands[4] = adjust_address (operands[0], DImode, i*16);
20216       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20217       PUT_MODE (operands[4], TImode);
20218       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20219         output_asm_insn (\"rex\", operands);
20220       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20221     }
20222   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20223                              CODE_LABEL_NUMBER (operands[3]));
20224   RET;
20225 }
20226   "
20227   [(set_attr "type" "other")
20228    (set_attr "length_immediate" "0")
20229    (set_attr "length_address" "0")
20230    (set_attr "length" "135")
20231    (set_attr "memory" "store")
20232    (set_attr "modrm" "0")
20233    (set_attr "mode" "DI")])
20234
20235 (define_expand "prefetch"
20236   [(prefetch (match_operand 0 "address_operand" "")
20237              (match_operand:SI 1 "const_int_operand" "")
20238              (match_operand:SI 2 "const_int_operand" ""))]
20239   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20240 {
20241   int rw = INTVAL (operands[1]);
20242   int locality = INTVAL (operands[2]);
20243
20244   gcc_assert (rw == 0 || rw == 1);
20245   gcc_assert (locality >= 0 && locality <= 3);
20246   gcc_assert (GET_MODE (operands[0]) == Pmode
20247               || GET_MODE (operands[0]) == VOIDmode);
20248
20249   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20250      supported by SSE counterpart or the SSE prefetch is not available
20251      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20252      of locality.  */
20253   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20254     operands[2] = GEN_INT (3);
20255   else
20256     operands[1] = const0_rtx;
20257 })
20258
20259 (define_insn "*prefetch_sse"
20260   [(prefetch (match_operand:SI 0 "address_operand" "p")
20261              (const_int 0)
20262              (match_operand:SI 1 "const_int_operand" ""))]
20263   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20264 {
20265   static const char * const patterns[4] = {
20266    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20267   };
20268
20269   int locality = INTVAL (operands[1]);
20270   gcc_assert (locality >= 0 && locality <= 3);
20271
20272   return patterns[locality];  
20273 }
20274   [(set_attr "type" "sse")
20275    (set_attr "memory" "none")])
20276
20277 (define_insn "*prefetch_sse_rex"
20278   [(prefetch (match_operand:DI 0 "address_operand" "p")
20279              (const_int 0)
20280              (match_operand:SI 1 "const_int_operand" ""))]
20281   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20282 {
20283   static const char * const patterns[4] = {
20284    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20285   };
20286
20287   int locality = INTVAL (operands[1]);
20288   gcc_assert (locality >= 0 && locality <= 3);
20289
20290   return patterns[locality];  
20291 }
20292   [(set_attr "type" "sse")
20293    (set_attr "memory" "none")])
20294
20295 (define_insn "*prefetch_3dnow"
20296   [(prefetch (match_operand:SI 0 "address_operand" "p")
20297              (match_operand:SI 1 "const_int_operand" "n")
20298              (const_int 3))]
20299   "TARGET_3DNOW && !TARGET_64BIT"
20300 {
20301   if (INTVAL (operands[1]) == 0)
20302     return "prefetch\t%a0";
20303   else
20304     return "prefetchw\t%a0";
20305 }
20306   [(set_attr "type" "mmx")
20307    (set_attr "memory" "none")])
20308
20309 (define_insn "*prefetch_3dnow_rex"
20310   [(prefetch (match_operand:DI 0 "address_operand" "p")
20311              (match_operand:SI 1 "const_int_operand" "n")
20312              (const_int 3))]
20313   "TARGET_3DNOW && TARGET_64BIT"
20314 {
20315   if (INTVAL (operands[1]) == 0)
20316     return "prefetch\t%a0";
20317   else
20318     return "prefetchw\t%a0";
20319 }
20320   [(set_attr "type" "mmx")
20321    (set_attr "memory" "none")])
20322
20323 (define_expand "stack_protect_set"
20324   [(match_operand 0 "memory_operand" "")
20325    (match_operand 1 "memory_operand" "")]
20326   ""
20327 {
20328 #ifdef TARGET_THREAD_SSP_OFFSET
20329   if (TARGET_64BIT)
20330     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20331                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20332   else
20333     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20334                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20335 #else
20336   if (TARGET_64BIT)
20337     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20338   else
20339     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20340 #endif
20341   DONE;
20342 })
20343
20344 (define_insn "stack_protect_set_si"
20345   [(set (match_operand:SI 0 "memory_operand" "=m")
20346         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20347    (set (match_scratch:SI 2 "=&r") (const_int 0))
20348    (clobber (reg:CC FLAGS_REG))]
20349   ""
20350   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20351   [(set_attr "type" "multi")])
20352
20353 (define_insn "stack_protect_set_di"
20354   [(set (match_operand:DI 0 "memory_operand" "=m")
20355         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20356    (set (match_scratch:DI 2 "=&r") (const_int 0))
20357    (clobber (reg:CC FLAGS_REG))]
20358   "TARGET_64BIT"
20359   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20360   [(set_attr "type" "multi")])
20361
20362 (define_insn "stack_tls_protect_set_si"
20363   [(set (match_operand:SI 0 "memory_operand" "=m")
20364         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20365    (set (match_scratch:SI 2 "=&r") (const_int 0))
20366    (clobber (reg:CC FLAGS_REG))]
20367   ""
20368   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20369   [(set_attr "type" "multi")])
20370
20371 (define_insn "stack_tls_protect_set_di"
20372   [(set (match_operand:DI 0 "memory_operand" "=m")
20373         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20374    (set (match_scratch:DI 2 "=&r") (const_int 0))
20375    (clobber (reg:CC FLAGS_REG))]
20376   "TARGET_64BIT"
20377   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20378   [(set_attr "type" "multi")])
20379
20380 (define_expand "stack_protect_test"
20381   [(match_operand 0 "memory_operand" "")
20382    (match_operand 1 "memory_operand" "")
20383    (match_operand 2 "" "")]
20384   ""
20385 {
20386   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20387   ix86_compare_op0 = operands[0];
20388   ix86_compare_op1 = operands[1];
20389   ix86_compare_emitted = flags;
20390
20391 #ifdef TARGET_THREAD_SSP_OFFSET
20392   if (TARGET_64BIT)
20393     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20394                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20395   else
20396     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20397                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20398 #else
20399   if (TARGET_64BIT)
20400     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20401   else
20402     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20403 #endif
20404   emit_jump_insn (gen_beq (operands[2]));
20405   DONE;
20406 })
20407
20408 (define_insn "stack_protect_test_si"
20409   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20410         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20411                      (match_operand:SI 2 "memory_operand" "m")]
20412                     UNSPEC_SP_TEST))
20413    (clobber (match_scratch:SI 3 "=&r"))]
20414   ""
20415   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20416   [(set_attr "type" "multi")])
20417
20418 (define_insn "stack_protect_test_di"
20419   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20420         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20421                      (match_operand:DI 2 "memory_operand" "m")]
20422                     UNSPEC_SP_TEST))
20423    (clobber (match_scratch:DI 3 "=&r"))]
20424   "TARGET_64BIT"
20425   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20426   [(set_attr "type" "multi")])
20427
20428 (define_insn "stack_tls_protect_test_si"
20429   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20430         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20431                      (match_operand:SI 2 "const_int_operand" "i")]
20432                     UNSPEC_SP_TLS_TEST))
20433    (clobber (match_scratch:SI 3 "=r"))]
20434   ""
20435   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20436   [(set_attr "type" "multi")])
20437
20438 (define_insn "stack_tls_protect_test_di"
20439   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20440         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20441                      (match_operand:DI 2 "const_int_operand" "i")]
20442                     UNSPEC_SP_TLS_TEST))
20443    (clobber (match_scratch:DI 3 "=r"))]
20444   "TARGET_64BIT"
20445   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20446   [(set_attr "type" "multi")])
20447
20448 (include "sse.md")
20449 (include "mmx.md")
20450 (include "sync.md")