OSDN Git Service

* output.h (enum section_category): Export from varasm.c
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
104
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
109
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
119
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
127
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
141
142    ; SSP patterns
143    (UNSPEC_SP_SET               100)
144    (UNSPEC_SP_TEST              101)
145    (UNSPEC_SP_TLS_SET           102)
146    (UNSPEC_SP_TLS_TEST          103)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         1)
152    (UNSPECV_EMMS                2)
153    (UNSPECV_LDMXCSR             3)
154    (UNSPECV_STMXCSR             4)
155    (UNSPECV_FEMMS               5)
156    (UNSPECV_CLFLUSH             6)
157    (UNSPECV_ALIGN               7)
158    (UNSPECV_MONITOR             8)
159    (UNSPECV_MWAIT               9)
160    (UNSPECV_CMPXCHG_1           10)
161    (UNSPECV_CMPXCHG_2           11)
162    (UNSPECV_XCHG                12)
163    (UNSPECV_LOCK                13)
164   ])
165
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       gcc_unreachable (),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439   (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448  
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457  
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpti"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
484                     (match_operand:TI 1 "x86_64_general_operand" "")))]
485   "TARGET_64BIT"
486 {
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (TImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
492 })
493
494 (define_expand "cmpdi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
497                     (match_operand:DI 1 "x86_64_general_operand" "")))]
498   ""
499 {
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (DImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
505 })
506
507 (define_expand "cmpsi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
510                     (match_operand:SI 1 "general_operand" "")))]
511   ""
512 {
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (SImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
518 })
519
520 (define_expand "cmphi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
523                     (match_operand:HI 1 "general_operand" "")))]
524   ""
525 {
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (HImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
531 })
532
533 (define_expand "cmpqi"
534   [(set (reg:CC FLAGS_REG)
535         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
536                     (match_operand:QI 1 "general_operand" "")))]
537   "TARGET_QIMODE_MATH"
538 {
539   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
540     operands[0] = force_reg (QImode, operands[0]);
541   ix86_compare_op0 = operands[0];
542   ix86_compare_op1 = operands[1];
543   DONE;
544 })
545
546 (define_insn "cmpdi_ccno_1_rex64"
547   [(set (reg FLAGS_REG)
548         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
549                  (match_operand:DI 1 "const0_operand" "n,n")))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
551   "@
552    test{q}\t{%0, %0|%0, %0}
553    cmp{q}\t{%1, %0|%0, %1}"
554   [(set_attr "type" "test,icmp")
555    (set_attr "length_immediate" "0,1")
556    (set_attr "mode" "DI")])
557
558 (define_insn "*cmpdi_minus_1_rex64"
559   [(set (reg FLAGS_REG)
560         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
561                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
562                  (const_int 0)))]
563   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
564   "cmp{q}\t{%1, %0|%0, %1}"
565   [(set_attr "type" "icmp")
566    (set_attr "mode" "DI")])
567
568 (define_expand "cmpdi_1_rex64"
569   [(set (reg:CC FLAGS_REG)
570         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
571                     (match_operand:DI 1 "general_operand" "")))]
572   "TARGET_64BIT"
573   "")
574
575 (define_insn "cmpdi_1_insn_rex64"
576   [(set (reg FLAGS_REG)
577         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
578                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
579   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
580   "cmp{q}\t{%1, %0|%0, %1}"
581   [(set_attr "type" "icmp")
582    (set_attr "mode" "DI")])
583
584
585 (define_insn "*cmpsi_ccno_1"
586   [(set (reg FLAGS_REG)
587         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
588                  (match_operand:SI 1 "const0_operand" "n,n")))]
589   "ix86_match_ccmode (insn, CCNOmode)"
590   "@
591    test{l}\t{%0, %0|%0, %0}
592    cmp{l}\t{%1, %0|%0, %1}"
593   [(set_attr "type" "test,icmp")
594    (set_attr "length_immediate" "0,1")
595    (set_attr "mode" "SI")])
596
597 (define_insn "*cmpsi_minus_1"
598   [(set (reg FLAGS_REG)
599         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
600                            (match_operand:SI 1 "general_operand" "ri,mr"))
601                  (const_int 0)))]
602   "ix86_match_ccmode (insn, CCGOCmode)"
603   "cmp{l}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "SI")])
606
607 (define_expand "cmpsi_1"
608   [(set (reg:CC FLAGS_REG)
609         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610                     (match_operand:SI 1 "general_operand" "ri,mr")))]
611   ""
612   "")
613
614 (define_insn "*cmpsi_1_insn"
615   [(set (reg FLAGS_REG)
616         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                  (match_operand:SI 1 "general_operand" "ri,mr")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619     && ix86_match_ccmode (insn, CCmode)"
620   "cmp{l}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "SI")])
623
624 (define_insn "*cmphi_ccno_1"
625   [(set (reg FLAGS_REG)
626         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
627                  (match_operand:HI 1 "const0_operand" "n,n")))]
628   "ix86_match_ccmode (insn, CCNOmode)"
629   "@
630    test{w}\t{%0, %0|%0, %0}
631    cmp{w}\t{%1, %0|%0, %1}"
632   [(set_attr "type" "test,icmp")
633    (set_attr "length_immediate" "0,1")
634    (set_attr "mode" "HI")])
635
636 (define_insn "*cmphi_minus_1"
637   [(set (reg FLAGS_REG)
638         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
639                            (match_operand:HI 1 "general_operand" "ri,mr"))
640                  (const_int 0)))]
641   "ix86_match_ccmode (insn, CCGOCmode)"
642   "cmp{w}\t{%1, %0|%0, %1}"
643   [(set_attr "type" "icmp")
644    (set_attr "mode" "HI")])
645
646 (define_insn "*cmphi_1"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:HI 1 "general_operand" "ri,mr")))]
650   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
651    && ix86_match_ccmode (insn, CCmode)"
652   "cmp{w}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "HI")])
655
656 (define_insn "*cmpqi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
659                  (match_operand:QI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{b}\t{%0, %0|%0, %0}
663    cmp{b}\t{$0, %0|%0, 0}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "QI")])
667
668 (define_insn "*cmpqi_1"
669   [(set (reg FLAGS_REG)
670         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
671                  (match_operand:QI 1 "general_operand" "qi,mq")))]
672   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
673     && ix86_match_ccmode (insn, CCmode)"
674   "cmp{b}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "QI")])
677
678 (define_insn "*cmpqi_minus_1"
679   [(set (reg FLAGS_REG)
680         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681                            (match_operand:QI 1 "general_operand" "qi,mq"))
682                  (const_int 0)))]
683   "ix86_match_ccmode (insn, CCGOCmode)"
684   "cmp{b}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "QI")])
687
688 (define_insn "*cmpqi_ext_1"
689   [(set (reg FLAGS_REG)
690         (compare
691           (match_operand:QI 0 "general_operand" "Qm")
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 1 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)))]
697   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%h1, %0|%0, %h1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_ext_1_rex64"
703   [(set (reg FLAGS_REG)
704         (compare
705           (match_operand:QI 0 "register_operand" "Q")
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 1 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)))]
711   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712   "cmp{b}\t{%h1, %0|%0, %h1}"
713   [(set_attr "type" "icmp")
714    (set_attr "mode" "QI")])
715
716 (define_insn "*cmpqi_ext_2"
717   [(set (reg FLAGS_REG)
718         (compare
719           (subreg:QI
720             (zero_extract:SI
721               (match_operand 0 "ext_register_operand" "Q")
722               (const_int 8)
723               (const_int 8)) 0)
724           (match_operand:QI 1 "const0_operand" "n")))]
725   "ix86_match_ccmode (insn, CCNOmode)"
726   "test{b}\t%h0, %h0"
727   [(set_attr "type" "test")
728    (set_attr "length_immediate" "0")
729    (set_attr "mode" "QI")])
730
731 (define_expand "cmpqi_ext_3"
732   [(set (reg:CC FLAGS_REG)
733         (compare:CC
734           (subreg:QI
735             (zero_extract:SI
736               (match_operand 0 "ext_register_operand" "")
737               (const_int 8)
738               (const_int 8)) 0)
739           (match_operand:QI 1 "general_operand" "")))]
740   ""
741   "")
742
743 (define_insn "cmpqi_ext_3_insn"
744   [(set (reg FLAGS_REG)
745         (compare
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 0 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)
751           (match_operand:QI 1 "general_operand" "Qmn")))]
752   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%1, %h0|%h0, %1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
756
757 (define_insn "cmpqi_ext_3_insn_rex64"
758   [(set (reg FLAGS_REG)
759         (compare
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 0 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)
765           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
766   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767   "cmp{b}\t{%1, %h0|%h0, %1}"
768   [(set_attr "type" "icmp")
769    (set_attr "mode" "QI")])
770
771 (define_insn "*cmpqi_ext_4"
772   [(set (reg FLAGS_REG)
773         (compare
774           (subreg:QI
775             (zero_extract:SI
776               (match_operand 0 "ext_register_operand" "Q")
777               (const_int 8)
778               (const_int 8)) 0)
779           (subreg:QI
780             (zero_extract:SI
781               (match_operand 1 "ext_register_operand" "Q")
782               (const_int 8)
783               (const_int 8)) 0)))]
784   "ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%h1, %h0|%h0, %h1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 ;; These implement float point compares.
790 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
791 ;; which would allow mix and match FP modes on the compares.  Which is what
792 ;; the old patterns did, but with many more of them.
793
794 (define_expand "cmpxf"
795   [(set (reg:CC FLAGS_REG)
796         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
797                     (match_operand:XF 1 "nonmemory_operand" "")))]
798   "TARGET_80387"
799 {
800   ix86_compare_op0 = operands[0];
801   ix86_compare_op1 = operands[1];
802   DONE;
803 })
804
805 (define_expand "cmpdf"
806   [(set (reg:CC FLAGS_REG)
807         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
808                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
809   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
810 {
811   ix86_compare_op0 = operands[0];
812   ix86_compare_op1 = operands[1];
813   DONE;
814 })
815
816 (define_expand "cmpsf"
817   [(set (reg:CC FLAGS_REG)
818         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
819                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
820   "TARGET_80387 || TARGET_SSE_MATH"
821 {
822   ix86_compare_op0 = operands[0];
823   ix86_compare_op1 = operands[1];
824   DONE;
825 })
826
827 ;; FP compares, step 1:
828 ;; Set the FP condition codes.
829 ;;
830 ;; CCFPmode     compare with exceptions
831 ;; CCFPUmode    compare with no exceptions
832
833 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
834 ;; used to manage the reg stack popping would not be preserved.
835
836 (define_insn "*cmpfp_0"
837   [(set (match_operand:HI 0 "register_operand" "=a")
838         (unspec:HI
839           [(compare:CCFP
840              (match_operand 1 "register_operand" "f")
841              (match_operand 2 "const0_operand" "X"))]
842         UNSPEC_FNSTSW))]
843   "TARGET_80387
844    && FLOAT_MODE_P (GET_MODE (operands[1]))
845    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "multi")
848    (set_attr "unit" "i387")
849    (set (attr "mode")
850      (cond [(match_operand:SF 1 "" "")
851               (const_string "SF")
852             (match_operand:DF 1 "" "")
853               (const_string "DF")
854            ]
855            (const_string "XF")))])
856
857 (define_insn "*cmpfp_sf"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:SF 1 "register_operand" "f")
862              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 0, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "unit" "i387")
868    (set_attr "mode" "SF")])
869
870 (define_insn "*cmpfp_df"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:DF 1 "register_operand" "f")
875              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set_attr "mode" "DF")])
882
883 (define_insn "*cmpfp_xf"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFP
887              (match_operand:XF 1 "register_operand" "f")
888              (match_operand:XF 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "unit" "i387")
894    (set_attr "mode" "XF")])
895
896 (define_insn "*cmpfp_u"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFPU
900              (match_operand 1 "register_operand" "f")
901              (match_operand 2 "register_operand" "f"))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
906   "* return output_fp_compare (insn, operands, 0, 1);"
907   [(set_attr "type" "multi")
908    (set_attr "unit" "i387")
909    (set (attr "mode")
910      (cond [(match_operand:SF 1 "" "")
911               (const_string "SF")
912             (match_operand:DF 1 "" "")
913               (const_string "DF")
914            ]
915            (const_string "XF")))])
916
917 (define_insn "*cmpfp_<mode>"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI
920           [(compare:CCFP
921              (match_operand 1 "register_operand" "f")
922              (match_operator 3 "float_operator"
923                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
924           UNSPEC_FNSTSW))]
925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
926    && FLOAT_MODE_P (GET_MODE (operands[1]))
927    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
928   "* return output_fp_compare (insn, operands, 0, 0);"
929   [(set_attr "type" "multi")
930    (set_attr "unit" "i387")
931    (set_attr "fp_int_src" "true")
932    (set_attr "mode" "<MODE>")])
933
934 ;; FP compares, step 2
935 ;; Move the fpsw to ax.
936
937 (define_insn "x86_fnstsw_1"
938   [(set (match_operand:HI 0 "register_operand" "=a")
939         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
940   "TARGET_80387"
941   "fnstsw\t%0"
942   [(set_attr "length" "2")
943    (set_attr "mode" "SI")
944    (set_attr "unit" "i387")])
945
946 ;; FP compares, step 3
947 ;; Get ax into flags, general case.
948
949 (define_insn "x86_sahf_1"
950   [(set (reg:CC FLAGS_REG)
951         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
952   "!TARGET_64BIT"
953   "sahf"
954   [(set_attr "length" "1")
955    (set_attr "athlon_decode" "vector")
956    (set_attr "mode" "SI")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i_mixed"
961   [(set (reg:CCFP FLAGS_REG)
962         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
963                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
964   "TARGET_MIX_SSE_I387
965    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
967   "* return output_fp_compare (insn, operands, 1, 0);"
968   [(set_attr "type" "fcmp,ssecomi")
969    (set (attr "mode")
970      (if_then_else (match_operand:SF 1 "" "")
971         (const_string "SF")
972         (const_string "DF")))
973    (set_attr "athlon_decode" "vector")])
974
975 (define_insn "*cmpfp_i_sse"
976   [(set (reg:CCFP FLAGS_REG)
977         (compare:CCFP (match_operand 0 "register_operand" "x")
978                       (match_operand 1 "nonimmediate_operand" "xm")))]
979   "TARGET_SSE_MATH
980    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982   "* return output_fp_compare (insn, operands, 1, 0);"
983   [(set_attr "type" "ssecomi")
984    (set (attr "mode")
985      (if_then_else (match_operand:SF 1 "" "")
986         (const_string "SF")
987         (const_string "DF")))
988    (set_attr "athlon_decode" "vector")])
989
990 (define_insn "*cmpfp_i_i387"
991   [(set (reg:CCFP FLAGS_REG)
992         (compare:CCFP (match_operand 0 "register_operand" "f")
993                       (match_operand 1 "register_operand" "f")))]
994   "TARGET_80387 && TARGET_CMOVE
995    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
996    && FLOAT_MODE_P (GET_MODE (operands[0]))
997    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
998   "* return output_fp_compare (insn, operands, 1, 0);"
999   [(set_attr "type" "fcmp")
1000    (set (attr "mode")
1001      (cond [(match_operand:SF 1 "" "")
1002               (const_string "SF")
1003             (match_operand:DF 1 "" "")
1004               (const_string "DF")
1005            ]
1006            (const_string "XF")))
1007    (set_attr "athlon_decode" "vector")])
1008
1009 (define_insn "*cmpfp_iu_mixed"
1010   [(set (reg:CCFPU FLAGS_REG)
1011         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1012                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013   "TARGET_MIX_SSE_I387
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 1);"
1017   [(set_attr "type" "fcmp,ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")])
1023
1024 (define_insn "*cmpfp_iu_sse"
1025   [(set (reg:CCFPU FLAGS_REG)
1026         (compare:CCFPU (match_operand 0 "register_operand" "x")
1027                        (match_operand 1 "nonimmediate_operand" "xm")))]
1028   "TARGET_SSE_MATH
1029    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031   "* return output_fp_compare (insn, operands, 1, 1);"
1032   [(set_attr "type" "ssecomi")
1033    (set (attr "mode")
1034      (if_then_else (match_operand:SF 1 "" "")
1035         (const_string "SF")
1036         (const_string "DF")))
1037    (set_attr "athlon_decode" "vector")])
1038
1039 (define_insn "*cmpfp_iu_387"
1040   [(set (reg:CCFPU FLAGS_REG)
1041         (compare:CCFPU (match_operand 0 "register_operand" "f")
1042                        (match_operand 1 "register_operand" "f")))]
1043   "TARGET_80387 && TARGET_CMOVE
1044    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1045    && FLOAT_MODE_P (GET_MODE (operands[0]))
1046    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047   "* return output_fp_compare (insn, operands, 1, 1);"
1048   [(set_attr "type" "fcmp")
1049    (set (attr "mode")
1050      (cond [(match_operand:SF 1 "" "")
1051               (const_string "SF")
1052             (match_operand:DF 1 "" "")
1053               (const_string "DF")
1054            ]
1055            (const_string "XF")))
1056    (set_attr "athlon_decode" "vector")])
1057 \f
1058 ;; Move instructions.
1059
1060 ;; General case of fullword move.
1061
1062 (define_expand "movsi"
1063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1064         (match_operand:SI 1 "general_operand" ""))]
1065   ""
1066   "ix86_expand_move (SImode, operands); DONE;")
1067
1068 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1069 ;; general_operand.
1070 ;;
1071 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1072 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1073 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1074 ;; targets without our curiosities, and it is just as easy to represent
1075 ;; this differently.
1076
1077 (define_insn "*pushsi2"
1078   [(set (match_operand:SI 0 "push_operand" "=<")
1079         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1080   "!TARGET_64BIT"
1081   "push{l}\t%1"
1082   [(set_attr "type" "push")
1083    (set_attr "mode" "SI")])
1084
1085 ;; For 64BIT abi we always round up to 8 bytes.
1086 (define_insn "*pushsi2_rex64"
1087   [(set (match_operand:SI 0 "push_operand" "=X")
1088         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1089   "TARGET_64BIT"
1090   "push{q}\t%q1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1093
1094 (define_insn "*pushsi2_prologue"
1095   [(set (match_operand:SI 0 "push_operand" "=<")
1096         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1097    (clobber (mem:BLK (scratch)))]
1098   "!TARGET_64BIT"
1099   "push{l}\t%1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1102
1103 (define_insn "*popsi1_epilogue"
1104   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1105         (mem:SI (reg:SI SP_REG)))
1106    (set (reg:SI SP_REG)
1107         (plus:SI (reg:SI SP_REG) (const_int 4)))
1108    (clobber (mem:BLK (scratch)))]
1109   "!TARGET_64BIT"
1110   "pop{l}\t%0"
1111   [(set_attr "type" "pop")
1112    (set_attr "mode" "SI")])
1113
1114 (define_insn "popsi1"
1115   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116         (mem:SI (reg:SI SP_REG)))
1117    (set (reg:SI SP_REG)
1118         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1119   "!TARGET_64BIT"
1120   "pop{l}\t%0"
1121   [(set_attr "type" "pop")
1122    (set_attr "mode" "SI")])
1123
1124 (define_insn "*movsi_xor"
1125   [(set (match_operand:SI 0 "register_operand" "=r")
1126         (match_operand:SI 1 "const0_operand" "i"))
1127    (clobber (reg:CC FLAGS_REG))]
1128   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1129   "xor{l}\t{%0, %0|%0, %0}"
1130   [(set_attr "type" "alu1")
1131    (set_attr "mode" "SI")
1132    (set_attr "length_immediate" "0")])
1133  
1134 (define_insn "*movsi_or"
1135   [(set (match_operand:SI 0 "register_operand" "=r")
1136         (match_operand:SI 1 "immediate_operand" "i"))
1137    (clobber (reg:CC FLAGS_REG))]
1138   "reload_completed
1139    && operands[1] == constm1_rtx
1140    && (TARGET_PENTIUM || optimize_size)"
1141 {
1142   operands[1] = constm1_rtx;
1143   return "or{l}\t{%1, %0|%0, %1}";
1144 }
1145   [(set_attr "type" "alu1")
1146    (set_attr "mode" "SI")
1147    (set_attr "length_immediate" "1")])
1148
1149 (define_insn "*movsi_1"
1150   [(set (match_operand:SI 0 "nonimmediate_operand"
1151                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1152         (match_operand:SI 1 "general_operand"
1153                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1154   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1155 {
1156   switch (get_attr_type (insn))
1157     {
1158     case TYPE_SSELOG1:
1159       if (get_attr_mode (insn) == MODE_TI)
1160         return "pxor\t%0, %0";
1161       return "xorps\t%0, %0";
1162
1163     case TYPE_SSEMOV:
1164       switch (get_attr_mode (insn))
1165         {
1166         case MODE_TI:
1167           return "movdqa\t{%1, %0|%0, %1}";
1168         case MODE_V4SF:
1169           return "movaps\t{%1, %0|%0, %1}";
1170         case MODE_SI:
1171           return "movd\t{%1, %0|%0, %1}";
1172         case MODE_SF:
1173           return "movss\t{%1, %0|%0, %1}";
1174         default:
1175           gcc_unreachable ();
1176         }
1177
1178     case TYPE_MMXADD:
1179       return "pxor\t%0, %0";
1180
1181     case TYPE_MMXMOV:
1182       if (get_attr_mode (insn) == MODE_DI)
1183         return "movq\t{%1, %0|%0, %1}";
1184       return "movd\t{%1, %0|%0, %1}";
1185
1186     case TYPE_LEA:
1187       return "lea{l}\t{%1, %0|%0, %1}";
1188
1189     default:
1190       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2")
1196               (const_string "mmx")
1197             (eq_attr "alternative" "3,4,5")
1198               (const_string "mmxmov")
1199             (eq_attr "alternative" "6")
1200               (const_string "sselog1")
1201             (eq_attr "alternative" "7,8,9,10,11")
1202               (const_string "ssemov")
1203             (and (ne (symbol_ref "flag_pic") (const_int 0))
1204                  (match_operand:SI 1 "symbolic_operand" ""))
1205               (const_string "lea")
1206            ]
1207            (const_string "imov")))
1208    (set (attr "mode")
1209      (cond [(eq_attr "alternative" "2,3")
1210               (const_string "DI")
1211             (eq_attr "alternative" "6,7")
1212               (if_then_else
1213                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1214                 (const_string "V4SF")
1215                 (const_string "TI"))
1216             (and (eq_attr "alternative" "8,9,10,11")
1217                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1218               (const_string "SF")
1219            ]
1220            (const_string "SI")))])
1221
1222 ;; Stores and loads of ax to arbitrary constant address.
1223 ;; We fake an second form of instruction to force reload to load address
1224 ;; into register when rax is not available
1225 (define_insn "*movabssi_1_rex64"
1226   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1227         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1228   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1229   "@
1230    movabs{l}\t{%1, %P0|%P0, %1}
1231    mov{l}\t{%1, %a0|%a0, %1}"
1232   [(set_attr "type" "imov")
1233    (set_attr "modrm" "0,*")
1234    (set_attr "length_address" "8,0")
1235    (set_attr "length_immediate" "0,*")
1236    (set_attr "memory" "store")
1237    (set_attr "mode" "SI")])
1238
1239 (define_insn "*movabssi_2_rex64"
1240   [(set (match_operand:SI 0 "register_operand" "=a,r")
1241         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1242   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1243   "@
1244    movabs{l}\t{%P1, %0|%0, %P1}
1245    mov{l}\t{%a1, %0|%0, %a1}"
1246   [(set_attr "type" "imov")
1247    (set_attr "modrm" "0,*")
1248    (set_attr "length_address" "8,0")
1249    (set_attr "length_immediate" "0")
1250    (set_attr "memory" "load")
1251    (set_attr "mode" "SI")])
1252
1253 (define_insn "*swapsi"
1254   [(set (match_operand:SI 0 "register_operand" "+r")
1255         (match_operand:SI 1 "register_operand" "+r"))
1256    (set (match_dup 1)
1257         (match_dup 0))]
1258   ""
1259   "xchg{l}\t%1, %0"
1260   [(set_attr "type" "imov")
1261    (set_attr "mode" "SI")
1262    (set_attr "pent_pair" "np")
1263    (set_attr "athlon_decode" "vector")])
1264
1265 (define_expand "movhi"
1266   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1267         (match_operand:HI 1 "general_operand" ""))]
1268   ""
1269   "ix86_expand_move (HImode, operands); DONE;")
1270
1271 (define_insn "*pushhi2"
1272   [(set (match_operand:HI 0 "push_operand" "=<,<")
1273         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1274   "!TARGET_64BIT"
1275   "@
1276    push{w}\t{|WORD PTR }%1
1277    push{w}\t%1"
1278   [(set_attr "type" "push")
1279    (set_attr "mode" "HI")])
1280
1281 ;; For 64BIT abi we always round up to 8 bytes.
1282 (define_insn "*pushhi2_rex64"
1283   [(set (match_operand:HI 0 "push_operand" "=X")
1284         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1285   "TARGET_64BIT"
1286   "push{q}\t%q1"
1287   [(set_attr "type" "push")
1288    (set_attr "mode" "QI")])
1289
1290 (define_insn "*movhi_1"
1291   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1292         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1293   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1294 {
1295   switch (get_attr_type (insn))
1296     {
1297     case TYPE_IMOVX:
1298       /* movzwl is faster than movw on p2 due to partial word stalls,
1299          though not as fast as an aligned movl.  */
1300       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1301     default:
1302       if (get_attr_mode (insn) == MODE_SI)
1303         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1304       else
1305         return "mov{w}\t{%1, %0|%0, %1}";
1306     }
1307 }
1308   [(set (attr "type")
1309      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1310               (const_string "imov")
1311             (and (eq_attr "alternative" "0")
1312                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1313                           (const_int 0))
1314                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1315                           (const_int 0))))
1316               (const_string "imov")
1317             (and (eq_attr "alternative" "1,2")
1318                  (match_operand:HI 1 "aligned_operand" ""))
1319               (const_string "imov")
1320             (and (ne (symbol_ref "TARGET_MOVX")
1321                      (const_int 0))
1322                  (eq_attr "alternative" "0,2"))
1323               (const_string "imovx")
1324            ]
1325            (const_string "imov")))
1326     (set (attr "mode")
1327       (cond [(eq_attr "type" "imovx")
1328                (const_string "SI")
1329              (and (eq_attr "alternative" "1,2")
1330                   (match_operand:HI 1 "aligned_operand" ""))
1331                (const_string "SI")
1332              (and (eq_attr "alternative" "0")
1333                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334                            (const_int 0))
1335                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1336                            (const_int 0))))
1337                (const_string "SI")
1338             ]
1339             (const_string "HI")))])
1340
1341 ;; Stores and loads of ax to arbitrary constant address.
1342 ;; We fake an second form of instruction to force reload to load address
1343 ;; into register when rax is not available
1344 (define_insn "*movabshi_1_rex64"
1345   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1346         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1347   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1348   "@
1349    movabs{w}\t{%1, %P0|%P0, %1}
1350    mov{w}\t{%1, %a0|%a0, %1}"
1351   [(set_attr "type" "imov")
1352    (set_attr "modrm" "0,*")
1353    (set_attr "length_address" "8,0")
1354    (set_attr "length_immediate" "0,*")
1355    (set_attr "memory" "store")
1356    (set_attr "mode" "HI")])
1357
1358 (define_insn "*movabshi_2_rex64"
1359   [(set (match_operand:HI 0 "register_operand" "=a,r")
1360         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1361   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1362   "@
1363    movabs{w}\t{%P1, %0|%0, %P1}
1364    mov{w}\t{%a1, %0|%0, %a1}"
1365   [(set_attr "type" "imov")
1366    (set_attr "modrm" "0,*")
1367    (set_attr "length_address" "8,0")
1368    (set_attr "length_immediate" "0")
1369    (set_attr "memory" "load")
1370    (set_attr "mode" "HI")])
1371
1372 (define_insn "*swaphi_1"
1373   [(set (match_operand:HI 0 "register_operand" "+r")
1374         (match_operand:HI 1 "register_operand" "+r"))
1375    (set (match_dup 1)
1376         (match_dup 0))]
1377   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1378   "xchg{l}\t%k1, %k0"
1379   [(set_attr "type" "imov")
1380    (set_attr "mode" "SI")
1381    (set_attr "pent_pair" "np")
1382    (set_attr "athlon_decode" "vector")])
1383
1384 (define_insn "*swaphi_2"
1385   [(set (match_operand:HI 0 "register_operand" "+r")
1386         (match_operand:HI 1 "register_operand" "+r"))
1387    (set (match_dup 1)
1388         (match_dup 0))]
1389   "TARGET_PARTIAL_REG_STALL"
1390   "xchg{w}\t%1, %0"
1391   [(set_attr "type" "imov")
1392    (set_attr "mode" "HI")
1393    (set_attr "pent_pair" "np")
1394    (set_attr "athlon_decode" "vector")])
1395
1396 (define_expand "movstricthi"
1397   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1398         (match_operand:HI 1 "general_operand" ""))]
1399   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1400 {
1401   /* Don't generate memory->memory moves, go through a register */
1402   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1403     operands[1] = force_reg (HImode, operands[1]);
1404 })
1405
1406 (define_insn "*movstricthi_1"
1407   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1408         (match_operand:HI 1 "general_operand" "rn,m"))]
1409   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1410    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1411   "mov{w}\t{%1, %0|%0, %1}"
1412   [(set_attr "type" "imov")
1413    (set_attr "mode" "HI")])
1414
1415 (define_insn "*movstricthi_xor"
1416   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1417         (match_operand:HI 1 "const0_operand" "i"))
1418    (clobber (reg:CC FLAGS_REG))]
1419   "reload_completed
1420    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1421   "xor{w}\t{%0, %0|%0, %0}"
1422   [(set_attr "type" "alu1")
1423    (set_attr "mode" "HI")
1424    (set_attr "length_immediate" "0")])
1425
1426 (define_expand "movqi"
1427   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1428         (match_operand:QI 1 "general_operand" ""))]
1429   ""
1430   "ix86_expand_move (QImode, operands); DONE;")
1431
1432 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1433 ;; "push a byte".  But actually we use pushw, which has the effect
1434 ;; of rounding the amount pushed up to a halfword.
1435
1436 (define_insn "*pushqi2"
1437   [(set (match_operand:QI 0 "push_operand" "=X,X")
1438         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1439   "!TARGET_64BIT"
1440   "@
1441    push{w}\t{|word ptr }%1
1442    push{w}\t%w1"
1443   [(set_attr "type" "push")
1444    (set_attr "mode" "HI")])
1445
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushqi2_rex64"
1448   [(set (match_operand:QI 0 "push_operand" "=X")
1449         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1450   "TARGET_64BIT"
1451   "push{q}\t%q1"
1452   [(set_attr "type" "push")
1453    (set_attr "mode" "QI")])
1454
1455 ;; Situation is quite tricky about when to choose full sized (SImode) move
1456 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1457 ;; partial register dependency machines (such as AMD Athlon), where QImode
1458 ;; moves issue extra dependency and for partial register stalls machines
1459 ;; that don't use QImode patterns (and QImode move cause stall on the next
1460 ;; instruction).
1461 ;;
1462 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1463 ;; register stall machines with, where we use QImode instructions, since
1464 ;; partial register stall can be caused there.  Then we use movzx.
1465 (define_insn "*movqi_1"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1467         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1468   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1469 {
1470   switch (get_attr_type (insn))
1471     {
1472     case TYPE_IMOVX:
1473       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1474       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1475     default:
1476       if (get_attr_mode (insn) == MODE_SI)
1477         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1478       else
1479         return "mov{b}\t{%1, %0|%0, %1}";
1480     }
1481 }
1482   [(set (attr "type")
1483      (cond [(eq_attr "alternative" "5")
1484               (const_string "imovx")
1485             (ne (symbol_ref "optimize_size") (const_int 0))
1486               (const_string "imov")
1487             (and (eq_attr "alternative" "3")
1488                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1489                           (const_int 0))
1490                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1491                           (const_int 0))))
1492               (const_string "imov")
1493             (eq_attr "alternative" "3")
1494               (const_string "imovx")
1495             (and (ne (symbol_ref "TARGET_MOVX")
1496                      (const_int 0))
1497                  (eq_attr "alternative" "2"))
1498               (const_string "imovx")
1499            ]
1500            (const_string "imov")))
1501    (set (attr "mode")
1502       (cond [(eq_attr "alternative" "3,4,5")
1503                (const_string "SI")
1504              (eq_attr "alternative" "6")
1505                (const_string "QI")
1506              (eq_attr "type" "imovx")
1507                (const_string "SI")
1508              (and (eq_attr "type" "imov")
1509                   (and (eq_attr "alternative" "0,1")
1510                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1511                            (const_int 0))))
1512                (const_string "SI")
1513              ;; Avoid partial register stalls when not using QImode arithmetic
1514              (and (eq_attr "type" "imov")
1515                   (and (eq_attr "alternative" "0,1")
1516                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1517                                 (const_int 0))
1518                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1519                                 (const_int 0)))))
1520                (const_string "SI")
1521            ]
1522            (const_string "QI")))])
1523
1524 (define_expand "reload_outqi"
1525   [(parallel [(match_operand:QI 0 "" "=m")
1526               (match_operand:QI 1 "register_operand" "r")
1527               (match_operand:QI 2 "register_operand" "=&q")])]
1528   ""
1529 {
1530   rtx op0, op1, op2;
1531   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1532
1533   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1534   if (! q_regs_operand (op1, QImode))
1535     {
1536       emit_insn (gen_movqi (op2, op1));
1537       op1 = op2;
1538     }
1539   emit_insn (gen_movqi (op0, op1));
1540   DONE;
1541 })
1542
1543 (define_insn "*swapqi_1"
1544   [(set (match_operand:QI 0 "register_operand" "+r")
1545         (match_operand:QI 1 "register_operand" "+r"))
1546    (set (match_dup 1)
1547         (match_dup 0))]
1548   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1549   "xchg{l}\t%k1, %k0"
1550   [(set_attr "type" "imov")
1551    (set_attr "mode" "SI")
1552    (set_attr "pent_pair" "np")
1553    (set_attr "athlon_decode" "vector")])
1554
1555 (define_insn "*swapqi_2"
1556   [(set (match_operand:QI 0 "register_operand" "+q")
1557         (match_operand:QI 1 "register_operand" "+q"))
1558    (set (match_dup 1)
1559         (match_dup 0))]
1560   "TARGET_PARTIAL_REG_STALL"
1561   "xchg{b}\t%1, %0"
1562   [(set_attr "type" "imov")
1563    (set_attr "mode" "QI")
1564    (set_attr "pent_pair" "np")
1565    (set_attr "athlon_decode" "vector")])
1566
1567 (define_expand "movstrictqi"
1568   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1569         (match_operand:QI 1 "general_operand" ""))]
1570   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1571 {
1572   /* Don't generate memory->memory moves, go through a register.  */
1573   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1574     operands[1] = force_reg (QImode, operands[1]);
1575 })
1576
1577 (define_insn "*movstrictqi_1"
1578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1579         (match_operand:QI 1 "general_operand" "*qn,m"))]
1580   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1581    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1582   "mov{b}\t{%1, %0|%0, %1}"
1583   [(set_attr "type" "imov")
1584    (set_attr "mode" "QI")])
1585
1586 (define_insn "*movstrictqi_xor"
1587   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1588         (match_operand:QI 1 "const0_operand" "i"))
1589    (clobber (reg:CC FLAGS_REG))]
1590   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1591   "xor{b}\t{%0, %0|%0, %0}"
1592   [(set_attr "type" "alu1")
1593    (set_attr "mode" "QI")
1594    (set_attr "length_immediate" "0")])
1595
1596 (define_insn "*movsi_extv_1"
1597   [(set (match_operand:SI 0 "register_operand" "=R")
1598         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1599                          (const_int 8)
1600                          (const_int 8)))]
1601   ""
1602   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1603   [(set_attr "type" "imovx")
1604    (set_attr "mode" "SI")])
1605
1606 (define_insn "*movhi_extv_1"
1607   [(set (match_operand:HI 0 "register_operand" "=R")
1608         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1609                          (const_int 8)
1610                          (const_int 8)))]
1611   ""
1612   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1613   [(set_attr "type" "imovx")
1614    (set_attr "mode" "SI")])
1615
1616 (define_insn "*movqi_extv_1"
1617   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1618         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1619                          (const_int 8)
1620                          (const_int 8)))]
1621   "!TARGET_64BIT"
1622 {
1623   switch (get_attr_type (insn))
1624     {
1625     case TYPE_IMOVX:
1626       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1627     default:
1628       return "mov{b}\t{%h1, %0|%0, %h1}";
1629     }
1630 }
1631   [(set (attr "type")
1632      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1633                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1634                              (ne (symbol_ref "TARGET_MOVX")
1635                                  (const_int 0))))
1636         (const_string "imovx")
1637         (const_string "imov")))
1638    (set (attr "mode")
1639      (if_then_else (eq_attr "type" "imovx")
1640         (const_string "SI")
1641         (const_string "QI")))])
1642
1643 (define_insn "*movqi_extv_1_rex64"
1644   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1645         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1646                          (const_int 8)
1647                          (const_int 8)))]
1648   "TARGET_64BIT"
1649 {
1650   switch (get_attr_type (insn))
1651     {
1652     case TYPE_IMOVX:
1653       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1654     default:
1655       return "mov{b}\t{%h1, %0|%0, %h1}";
1656     }
1657 }
1658   [(set (attr "type")
1659      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1660                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1661                              (ne (symbol_ref "TARGET_MOVX")
1662                                  (const_int 0))))
1663         (const_string "imovx")
1664         (const_string "imov")))
1665    (set (attr "mode")
1666      (if_then_else (eq_attr "type" "imovx")
1667         (const_string "SI")
1668         (const_string "QI")))])
1669
1670 ;; Stores and loads of ax to arbitrary constant address.
1671 ;; We fake an second form of instruction to force reload to load address
1672 ;; into register when rax is not available
1673 (define_insn "*movabsqi_1_rex64"
1674   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1675         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1676   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1677   "@
1678    movabs{b}\t{%1, %P0|%P0, %1}
1679    mov{b}\t{%1, %a0|%a0, %1}"
1680   [(set_attr "type" "imov")
1681    (set_attr "modrm" "0,*")
1682    (set_attr "length_address" "8,0")
1683    (set_attr "length_immediate" "0,*")
1684    (set_attr "memory" "store")
1685    (set_attr "mode" "QI")])
1686
1687 (define_insn "*movabsqi_2_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=a,r")
1689         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1690   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1691   "@
1692    movabs{b}\t{%P1, %0|%0, %P1}
1693    mov{b}\t{%a1, %0|%0, %a1}"
1694   [(set_attr "type" "imov")
1695    (set_attr "modrm" "0,*")
1696    (set_attr "length_address" "8,0")
1697    (set_attr "length_immediate" "0")
1698    (set_attr "memory" "load")
1699    (set_attr "mode" "QI")])
1700
1701 (define_insn "*movdi_extzv_1"
1702   [(set (match_operand:DI 0 "register_operand" "=R")
1703         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1704                          (const_int 8)
1705                          (const_int 8)))]
1706   "TARGET_64BIT"
1707   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1708   [(set_attr "type" "imovx")
1709    (set_attr "mode" "DI")])
1710
1711 (define_insn "*movsi_extzv_1"
1712   [(set (match_operand:SI 0 "register_operand" "=R")
1713         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1714                          (const_int 8)
1715                          (const_int 8)))]
1716   ""
1717   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1718   [(set_attr "type" "imovx")
1719    (set_attr "mode" "SI")])
1720
1721 (define_insn "*movqi_extzv_2"
1722   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1723         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1724                                     (const_int 8)
1725                                     (const_int 8)) 0))]
1726   "!TARGET_64BIT"
1727 {
1728   switch (get_attr_type (insn))
1729     {
1730     case TYPE_IMOVX:
1731       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1732     default:
1733       return "mov{b}\t{%h1, %0|%0, %h1}";
1734     }
1735 }
1736   [(set (attr "type")
1737      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1738                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                              (ne (symbol_ref "TARGET_MOVX")
1740                                  (const_int 0))))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "*movqi_extzv_2_rex64"
1749   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1750         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1751                                     (const_int 8)
1752                                     (const_int 8)) 0))]
1753   "TARGET_64BIT"
1754 {
1755   switch (get_attr_type (insn))
1756     {
1757     case TYPE_IMOVX:
1758       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1759     default:
1760       return "mov{b}\t{%h1, %0|%0, %h1}";
1761     }
1762 }
1763   [(set (attr "type")
1764      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1765                         (ne (symbol_ref "TARGET_MOVX")
1766                             (const_int 0)))
1767         (const_string "imovx")
1768         (const_string "imov")))
1769    (set (attr "mode")
1770      (if_then_else (eq_attr "type" "imovx")
1771         (const_string "SI")
1772         (const_string "QI")))])
1773
1774 (define_insn "movsi_insv_1"
1775   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1776                          (const_int 8)
1777                          (const_int 8))
1778         (match_operand:SI 1 "general_operand" "Qmn"))]
1779   "!TARGET_64BIT"
1780   "mov{b}\t{%b1, %h0|%h0, %b1}"
1781   [(set_attr "type" "imov")
1782    (set_attr "mode" "QI")])
1783
1784 (define_insn "movdi_insv_1_rex64"
1785   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1786                          (const_int 8)
1787                          (const_int 8))
1788         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1789   "TARGET_64BIT"
1790   "mov{b}\t{%b1, %h0|%h0, %b1}"
1791   [(set_attr "type" "imov")
1792    (set_attr "mode" "QI")])
1793
1794 (define_insn "*movqi_insv_2"
1795   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1796                          (const_int 8)
1797                          (const_int 8))
1798         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1799                      (const_int 8)))]
1800   ""
1801   "mov{b}\t{%h1, %h0|%h0, %h1}"
1802   [(set_attr "type" "imov")
1803    (set_attr "mode" "QI")])
1804
1805 (define_expand "movdi"
1806   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1807         (match_operand:DI 1 "general_operand" ""))]
1808   ""
1809   "ix86_expand_move (DImode, operands); DONE;")
1810
1811 (define_insn "*pushdi"
1812   [(set (match_operand:DI 0 "push_operand" "=<")
1813         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1814   "!TARGET_64BIT"
1815   "#")
1816
1817 (define_insn "*pushdi2_rex64"
1818   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1819         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1820   "TARGET_64BIT"
1821   "@
1822    push{q}\t%1
1823    #"
1824   [(set_attr "type" "push,multi")
1825    (set_attr "mode" "DI")])
1826
1827 ;; Convert impossible pushes of immediate to existing instructions.
1828 ;; First try to get scratch register and go through it.  In case this
1829 ;; fails, push sign extended lower part first and then overwrite
1830 ;; upper part by 32bit move.
1831 (define_peephole2
1832   [(match_scratch:DI 2 "r")
1833    (set (match_operand:DI 0 "push_operand" "")
1834         (match_operand:DI 1 "immediate_operand" ""))]
1835   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 2) (match_dup 1))
1838    (set (match_dup 0) (match_dup 2))]
1839   "")
1840
1841 ;; We need to define this as both peepholer and splitter for case
1842 ;; peephole2 pass is not run.
1843 ;; "&& 1" is needed to keep it from matching the previous pattern.
1844 (define_peephole2
1845   [(set (match_operand:DI 0 "push_operand" "")
1846         (match_operand:DI 1 "immediate_operand" ""))]
1847   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1848    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1849   [(set (match_dup 0) (match_dup 1))
1850    (set (match_dup 2) (match_dup 3))]
1851   "split_di (operands + 1, 1, operands + 2, operands + 3);
1852    operands[1] = gen_lowpart (DImode, operands[2]);
1853    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1854                                                     GEN_INT (4)));
1855   ")
1856
1857 (define_split
1858   [(set (match_operand:DI 0 "push_operand" "")
1859         (match_operand:DI 1 "immediate_operand" ""))]
1860   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1861    && !symbolic_operand (operands[1], DImode)
1862    && !x86_64_immediate_operand (operands[1], DImode)"
1863   [(set (match_dup 0) (match_dup 1))
1864    (set (match_dup 2) (match_dup 3))]
1865   "split_di (operands + 1, 1, operands + 2, operands + 3);
1866    operands[1] = gen_lowpart (DImode, operands[2]);
1867    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1868                                                     GEN_INT (4)));
1869   ")
1870
1871 (define_insn "*pushdi2_prologue_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1874    (clobber (mem:BLK (scratch)))]
1875   "TARGET_64BIT"
1876   "push{q}\t%1"
1877   [(set_attr "type" "push")
1878    (set_attr "mode" "DI")])
1879
1880 (define_insn "*popdi1_epilogue_rex64"
1881   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1882         (mem:DI (reg:DI SP_REG)))
1883    (set (reg:DI SP_REG)
1884         (plus:DI (reg:DI SP_REG) (const_int 8)))
1885    (clobber (mem:BLK (scratch)))]
1886   "TARGET_64BIT"
1887   "pop{q}\t%0"
1888   [(set_attr "type" "pop")
1889    (set_attr "mode" "DI")])
1890
1891 (define_insn "popdi1"
1892   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1893         (mem:DI (reg:DI SP_REG)))
1894    (set (reg:DI SP_REG)
1895         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1896   "TARGET_64BIT"
1897   "pop{q}\t%0"
1898   [(set_attr "type" "pop")
1899    (set_attr "mode" "DI")])
1900
1901 (define_insn "*movdi_xor_rex64"
1902   [(set (match_operand:DI 0 "register_operand" "=r")
1903         (match_operand:DI 1 "const0_operand" "i"))
1904    (clobber (reg:CC FLAGS_REG))]
1905   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1906    && reload_completed"
1907   "xor{l}\t{%k0, %k0|%k0, %k0}"
1908   [(set_attr "type" "alu1")
1909    (set_attr "mode" "SI")
1910    (set_attr "length_immediate" "0")])
1911
1912 (define_insn "*movdi_or_rex64"
1913   [(set (match_operand:DI 0 "register_operand" "=r")
1914         (match_operand:DI 1 "const_int_operand" "i"))
1915    (clobber (reg:CC FLAGS_REG))]
1916   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1917    && reload_completed
1918    && operands[1] == constm1_rtx"
1919 {
1920   operands[1] = constm1_rtx;
1921   return "or{q}\t{%1, %0|%0, %1}";
1922 }
1923   [(set_attr "type" "alu1")
1924    (set_attr "mode" "DI")
1925    (set_attr "length_immediate" "1")])
1926
1927 (define_insn "*movdi_2"
1928   [(set (match_operand:DI 0 "nonimmediate_operand"
1929                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1930         (match_operand:DI 1 "general_operand"
1931                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1932   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1933   "@
1934    #
1935    #
1936    pxor\t%0, %0
1937    movq\t{%1, %0|%0, %1}
1938    movq\t{%1, %0|%0, %1}
1939    pxor\t%0, %0
1940    movq\t{%1, %0|%0, %1}
1941    movdqa\t{%1, %0|%0, %1}
1942    movq\t{%1, %0|%0, %1}
1943    xorps\t%0, %0
1944    movlps\t{%1, %0|%0, %1}
1945    movaps\t{%1, %0|%0, %1}
1946    movlps\t{%1, %0|%0, %1}"
1947   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1948    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1949
1950 (define_split
1951   [(set (match_operand:DI 0 "push_operand" "")
1952         (match_operand:DI 1 "general_operand" ""))]
1953   "!TARGET_64BIT && reload_completed
1954    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1955   [(const_int 0)]
1956   "ix86_split_long_move (operands); DONE;")
1957
1958 ;; %%% This multiword shite has got to go.
1959 (define_split
1960   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1961         (match_operand:DI 1 "general_operand" ""))]
1962   "!TARGET_64BIT && reload_completed
1963    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1964    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965   [(const_int 0)]
1966   "ix86_split_long_move (operands); DONE;")
1967
1968 (define_insn "*movdi_1_rex64"
1969   [(set (match_operand:DI 0 "nonimmediate_operand"
1970                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1971         (match_operand:DI 1 "general_operand"
1972                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1973   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1974 {
1975   switch (get_attr_type (insn))
1976     {
1977     case TYPE_SSECVT:
1978       if (which_alternative == 13)
1979         return "movq2dq\t{%1, %0|%0, %1}";
1980       else
1981         return "movdq2q\t{%1, %0|%0, %1}";
1982     case TYPE_SSEMOV:
1983       if (get_attr_mode (insn) == MODE_TI)
1984           return "movdqa\t{%1, %0|%0, %1}";
1985       /* FALLTHRU */
1986     case TYPE_MMXMOV:
1987       /* Moves from and into integer register is done using movd opcode with
1988          REX prefix.  */
1989       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1990           return "movd\t{%1, %0|%0, %1}";
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_SSELOG1:
1993     case TYPE_MMXADD:
1994       return "pxor\t%0, %0";
1995     case TYPE_MULTI:
1996       return "#";
1997     case TYPE_LEA:
1998       return "lea{q}\t{%a1, %0|%0, %a1}";
1999     default:
2000       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2001       if (get_attr_mode (insn) == MODE_SI)
2002         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2003       else if (which_alternative == 2)
2004         return "movabs{q}\t{%1, %0|%0, %1}";
2005       else
2006         return "mov{q}\t{%1, %0|%0, %1}";
2007     }
2008 }
2009   [(set (attr "type")
2010      (cond [(eq_attr "alternative" "5")
2011               (const_string "mmx")
2012             (eq_attr "alternative" "6,7,8")
2013               (const_string "mmxmov")
2014             (eq_attr "alternative" "9")
2015               (const_string "sselog1")
2016             (eq_attr "alternative" "10,11,12")
2017               (const_string "ssemov")
2018             (eq_attr "alternative" "13,14")
2019               (const_string "ssecvt")
2020             (eq_attr "alternative" "4")
2021               (const_string "multi")
2022             (and (ne (symbol_ref "flag_pic") (const_int 0))
2023                  (match_operand:DI 1 "symbolic_operand" ""))
2024               (const_string "lea")
2025            ]
2026            (const_string "imov")))
2027    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2028    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2029    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2030
2031 ;; Stores and loads of ax to arbitrary constant address.
2032 ;; We fake an second form of instruction to force reload to load address
2033 ;; into register when rax is not available
2034 (define_insn "*movabsdi_1_rex64"
2035   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2036         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2037   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2038   "@
2039    movabs{q}\t{%1, %P0|%P0, %1}
2040    mov{q}\t{%1, %a0|%a0, %1}"
2041   [(set_attr "type" "imov")
2042    (set_attr "modrm" "0,*")
2043    (set_attr "length_address" "8,0")
2044    (set_attr "length_immediate" "0,*")
2045    (set_attr "memory" "store")
2046    (set_attr "mode" "DI")])
2047
2048 (define_insn "*movabsdi_2_rex64"
2049   [(set (match_operand:DI 0 "register_operand" "=a,r")
2050         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2051   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2052   "@
2053    movabs{q}\t{%P1, %0|%0, %P1}
2054    mov{q}\t{%a1, %0|%0, %a1}"
2055   [(set_attr "type" "imov")
2056    (set_attr "modrm" "0,*")
2057    (set_attr "length_address" "8,0")
2058    (set_attr "length_immediate" "0")
2059    (set_attr "memory" "load")
2060    (set_attr "mode" "DI")])
2061
2062 ;; Convert impossible stores of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it.  In case this
2064 ;; fails, move by 32bit parts.
2065 (define_peephole2
2066   [(match_scratch:DI 2 "r")
2067    (set (match_operand:DI 0 "memory_operand" "")
2068         (match_operand:DI 1 "immediate_operand" ""))]
2069   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070    && !x86_64_immediate_operand (operands[1], DImode)"
2071   [(set (match_dup 2) (match_dup 1))
2072    (set (match_dup 0) (match_dup 2))]
2073   "")
2074
2075 ;; We need to define this as both peepholer and splitter for case
2076 ;; peephole2 pass is not run.
2077 ;; "&& 1" is needed to keep it from matching the previous pattern.
2078 (define_peephole2
2079   [(set (match_operand:DI 0 "memory_operand" "")
2080         (match_operand:DI 1 "immediate_operand" ""))]
2081   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2083   [(set (match_dup 2) (match_dup 3))
2084    (set (match_dup 4) (match_dup 5))]
2085   "split_di (operands, 2, operands + 2, operands + 4);")
2086
2087 (define_split
2088   [(set (match_operand:DI 0 "memory_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2091    && !symbolic_operand (operands[1], DImode)
2092    && !x86_64_immediate_operand (operands[1], DImode)"
2093   [(set (match_dup 2) (match_dup 3))
2094    (set (match_dup 4) (match_dup 5))]
2095   "split_di (operands, 2, operands + 2, operands + 4);")
2096
2097 (define_insn "*swapdi_rex64"
2098   [(set (match_operand:DI 0 "register_operand" "+r")
2099         (match_operand:DI 1 "register_operand" "+r"))
2100    (set (match_dup 1)
2101         (match_dup 0))]
2102   "TARGET_64BIT"
2103   "xchg{q}\t%1, %0"
2104   [(set_attr "type" "imov")
2105    (set_attr "mode" "DI")
2106    (set_attr "pent_pair" "np")
2107    (set_attr "athlon_decode" "vector")])
2108
2109 (define_expand "movti"
2110   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2111         (match_operand:TI 1 "nonimmediate_operand" ""))]
2112   "TARGET_SSE || TARGET_64BIT"
2113 {
2114   if (TARGET_64BIT)
2115     ix86_expand_move (TImode, operands);
2116   else
2117     ix86_expand_vector_move (TImode, operands);
2118   DONE;
2119 })
2120
2121 (define_insn "*movti_internal"
2122   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2123         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2124   "TARGET_SSE && !TARGET_64BIT
2125    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2126 {
2127   switch (which_alternative)
2128     {
2129     case 0:
2130       if (get_attr_mode (insn) == MODE_V4SF)
2131         return "xorps\t%0, %0";
2132       else
2133         return "pxor\t%0, %0";
2134     case 1:
2135     case 2:
2136       if (get_attr_mode (insn) == MODE_V4SF)
2137         return "movaps\t{%1, %0|%0, %1}";
2138       else
2139         return "movdqa\t{%1, %0|%0, %1}";
2140     default:
2141       gcc_unreachable ();
2142     }
2143 }
2144   [(set_attr "type" "ssemov,ssemov,ssemov")
2145    (set (attr "mode")
2146         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2147                  (const_string "V4SF")
2148
2149                (eq_attr "alternative" "0,1")
2150                  (if_then_else
2151                    (ne (symbol_ref "optimize_size")
2152                        (const_int 0))
2153                    (const_string "V4SF")
2154                    (const_string "TI"))
2155                (eq_attr "alternative" "2")
2156                  (if_then_else
2157                    (ne (symbol_ref "optimize_size")
2158                        (const_int 0))
2159                    (const_string "V4SF")
2160                    (const_string "TI"))]
2161                (const_string "TI")))])
2162
2163 (define_insn "*movti_rex64"
2164   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2165         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2166   "TARGET_64BIT
2167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2168 {
2169   switch (which_alternative)
2170     {
2171     case 0:
2172     case 1:
2173       return "#";
2174     case 2:
2175       if (get_attr_mode (insn) == MODE_V4SF)
2176         return "xorps\t%0, %0";
2177       else
2178         return "pxor\t%0, %0";
2179     case 3:
2180     case 4:
2181       if (get_attr_mode (insn) == MODE_V4SF)
2182         return "movaps\t{%1, %0|%0, %1}";
2183       else
2184         return "movdqa\t{%1, %0|%0, %1}";
2185     default:
2186       gcc_unreachable ();
2187     }
2188 }
2189   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2190    (set (attr "mode")
2191         (cond [(eq_attr "alternative" "2,3")
2192                  (if_then_else
2193                    (ne (symbol_ref "optimize_size")
2194                        (const_int 0))
2195                    (const_string "V4SF")
2196                    (const_string "TI"))
2197                (eq_attr "alternative" "4")
2198                  (if_then_else
2199                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2200                             (const_int 0))
2201                         (ne (symbol_ref "optimize_size")
2202                             (const_int 0)))
2203                    (const_string "V4SF")
2204                    (const_string "TI"))]
2205                (const_string "DI")))])
2206
2207 (define_split
2208   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2209         (match_operand:TI 1 "general_operand" ""))]
2210   "reload_completed && !SSE_REG_P (operands[0])
2211    && !SSE_REG_P (operands[1])"
2212   [(const_int 0)]
2213   "ix86_split_long_move (operands); DONE;")
2214
2215 (define_expand "movsf"
2216   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2217         (match_operand:SF 1 "general_operand" ""))]
2218   ""
2219   "ix86_expand_move (SFmode, operands); DONE;")
2220
2221 (define_insn "*pushsf"
2222   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2223         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2224   "!TARGET_64BIT"
2225 {
2226   /* Anything else should be already split before reg-stack.  */
2227   gcc_assert (which_alternative == 1);
2228   return "push{l}\t%1";
2229 }
2230   [(set_attr "type" "multi,push,multi")
2231    (set_attr "unit" "i387,*,*")
2232    (set_attr "mode" "SF,SI,SF")])
2233
2234 (define_insn "*pushsf_rex64"
2235   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2236         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2237   "TARGET_64BIT"
2238 {
2239   /* Anything else should be already split before reg-stack.  */
2240   gcc_assert (which_alternative == 1);
2241   return "push{q}\t%q1";
2242 }
2243   [(set_attr "type" "multi,push,multi")
2244    (set_attr "unit" "i387,*,*")
2245    (set_attr "mode" "SF,DI,SF")])
2246
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "memory_operand" ""))]
2250   "reload_completed
2251    && GET_CODE (operands[1]) == MEM
2252    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2253    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2254   [(set (match_dup 0)
2255         (match_dup 1))]
2256   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2257
2258
2259 ;; %%% Kill this when call knows how to work this out.
2260 (define_split
2261   [(set (match_operand:SF 0 "push_operand" "")
2262         (match_operand:SF 1 "any_fp_register_operand" ""))]
2263   "!TARGET_64BIT"
2264   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266
2267 (define_split
2268   [(set (match_operand:SF 0 "push_operand" "")
2269         (match_operand:SF 1 "any_fp_register_operand" ""))]
2270   "TARGET_64BIT"
2271   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273
2274 (define_insn "*movsf_1"
2275   [(set (match_operand:SF 0 "nonimmediate_operand"
2276           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2277         (match_operand:SF 1 "general_operand"
2278           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2279   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280    && (reload_in_progress || reload_completed
2281        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282        || GET_CODE (operands[1]) != CONST_DOUBLE
2283        || memory_operand (operands[0], SFmode))" 
2284 {
2285   switch (which_alternative)
2286     {
2287     case 0:
2288       return output_387_reg_move (insn, operands);
2289
2290     case 1:
2291       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292         return "fstp%z0\t%y0";
2293       else
2294         return "fst%z0\t%y0";
2295
2296     case 2:
2297       return standard_80387_constant_opcode (operands[1]);
2298
2299     case 3:
2300     case 4:
2301       return "mov{l}\t{%1, %0|%0, %1}";
2302     case 5:
2303       if (get_attr_mode (insn) == MODE_TI)
2304         return "pxor\t%0, %0";
2305       else
2306         return "xorps\t%0, %0";
2307     case 6:
2308       if (get_attr_mode (insn) == MODE_V4SF)
2309         return "movaps\t{%1, %0|%0, %1}";
2310       else
2311         return "movss\t{%1, %0|%0, %1}";
2312     case 7:
2313     case 8:
2314       return "movss\t{%1, %0|%0, %1}";
2315
2316     case 9:
2317     case 10:
2318       return "movd\t{%1, %0|%0, %1}";
2319
2320     case 11:
2321       return "movq\t{%1, %0|%0, %1}";
2322
2323     default:
2324       gcc_unreachable ();
2325     }
2326 }
2327   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328    (set (attr "mode")
2329         (cond [(eq_attr "alternative" "3,4,9,10")
2330                  (const_string "SI")
2331                (eq_attr "alternative" "5")
2332                  (if_then_else
2333                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334                                  (const_int 0))
2335                              (ne (symbol_ref "TARGET_SSE2")
2336                                  (const_int 0)))
2337                         (eq (symbol_ref "optimize_size")
2338                             (const_int 0)))
2339                    (const_string "TI")
2340                    (const_string "V4SF"))
2341                /* For architectures resolving dependencies on
2342                   whole SSE registers use APS move to break dependency
2343                   chains, otherwise use short move to avoid extra work. 
2344
2345                   Do the same for architectures resolving dependencies on
2346                   the parts.  While in DF mode it is better to always handle
2347                   just register parts, the SF mode is different due to lack
2348                   of instructions to load just part of the register.  It is
2349                   better to maintain the whole registers in single format
2350                   to avoid problems on using packed logical operations.  */
2351                (eq_attr "alternative" "6")
2352                  (if_then_else
2353                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354                             (const_int 0))
2355                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356                             (const_int 0)))
2357                    (const_string "V4SF")
2358                    (const_string "SF"))
2359                (eq_attr "alternative" "11")
2360                  (const_string "DI")]
2361                (const_string "SF")))])
2362
2363 (define_insn "*swapsf"
2364   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365         (match_operand:SF 1 "fp_register_operand" "+f"))
2366    (set (match_dup 1)
2367         (match_dup 0))]
2368   "reload_completed || TARGET_80387"
2369 {
2370   if (STACK_TOP_P (operands[0]))
2371     return "fxch\t%1";
2372   else
2373     return "fxch\t%0";
2374 }
2375   [(set_attr "type" "fxch")
2376    (set_attr "mode" "SF")])
2377
2378 (define_expand "movdf"
2379   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380         (match_operand:DF 1 "general_operand" ""))]
2381   ""
2382   "ix86_expand_move (DFmode, operands); DONE;")
2383
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter.  Allow this
2387 ;; pattern for optimize_size too.
2388
2389 (define_insn "*pushdf_nointeger"
2390   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393 {
2394   /* This insn should be already split before reg-stack.  */
2395   gcc_unreachable ();
2396 }
2397   [(set_attr "type" "multi")
2398    (set_attr "unit" "i387,*,*,*")
2399    (set_attr "mode" "DF,SI,SI,DF")])
2400
2401 (define_insn "*pushdf_integer"
2402   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405 {
2406   /* This insn should be already split before reg-stack.  */
2407   gcc_unreachable ();
2408 }
2409   [(set_attr "type" "multi")
2410    (set_attr "unit" "i387,*,*")
2411    (set_attr "mode" "DF,SI,DF")])
2412
2413 ;; %%% Kill this when call knows how to work this out.
2414 (define_split
2415   [(set (match_operand:DF 0 "push_operand" "")
2416         (match_operand:DF 1 "any_fp_register_operand" ""))]
2417   "!TARGET_64BIT && reload_completed"
2418   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420   "")
2421
2422 (define_split
2423   [(set (match_operand:DF 0 "push_operand" "")
2424         (match_operand:DF 1 "any_fp_register_operand" ""))]
2425   "TARGET_64BIT && reload_completed"
2426   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428   "")
2429
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "general_operand" ""))]
2433   "reload_completed"
2434   [(const_int 0)]
2435   "ix86_split_long_move (operands); DONE;")
2436
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2440
2441 (define_insn "*movdf_nointeger"
2442   [(set (match_operand:DF 0 "nonimmediate_operand"
2443                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2444         (match_operand:DF 1 "general_operand"
2445                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2446   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448    && (reload_in_progress || reload_completed
2449        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450        || GET_CODE (operands[1]) != CONST_DOUBLE
2451        || memory_operand (operands[0], DFmode))" 
2452 {
2453   switch (which_alternative)
2454     {
2455     case 0:
2456       return output_387_reg_move (insn, operands);
2457
2458     case 1:
2459       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460         return "fstp%z0\t%y0";
2461       else
2462         return "fst%z0\t%y0";
2463
2464     case 2:
2465       return standard_80387_constant_opcode (operands[1]);
2466
2467     case 3:
2468     case 4:
2469       return "#";
2470     case 5:
2471       switch (get_attr_mode (insn))
2472         {
2473         case MODE_V4SF:
2474           return "xorps\t%0, %0";
2475         case MODE_V2DF:
2476           return "xorpd\t%0, %0";
2477         case MODE_TI:
2478           return "pxor\t%0, %0";
2479         default:
2480           gcc_unreachable ();
2481         }
2482     case 6:
2483     case 7:
2484     case 8:
2485       switch (get_attr_mode (insn))
2486         {
2487         case MODE_V4SF:
2488           return "movaps\t{%1, %0|%0, %1}";
2489         case MODE_V2DF:
2490           return "movapd\t{%1, %0|%0, %1}";
2491         case MODE_TI:
2492           return "movdqa\t{%1, %0|%0, %1}";
2493         case MODE_DI:
2494           return "movq\t{%1, %0|%0, %1}";
2495         case MODE_DF:
2496           return "movsd\t{%1, %0|%0, %1}";
2497         case MODE_V1DF:
2498           return "movlpd\t{%1, %0|%0, %1}";
2499         case MODE_V2SF:
2500           return "movlps\t{%1, %0|%0, %1}";
2501         default:
2502           gcc_unreachable ();
2503         }
2504
2505     default:
2506       gcc_unreachable ();
2507     }
2508 }
2509   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2510    (set (attr "mode")
2511         (cond [(eq_attr "alternative" "0,1,2")
2512                  (const_string "DF")
2513                (eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (const_string "V4SF")
2520                        ]
2521                    (const_string "V2SF"))
2522
2523                /* xorps is one byte shorter.  */
2524                (eq_attr "alternative" "5")
2525                  (cond [(ne (symbol_ref "optimize_size")
2526                             (const_int 0))
2527                           (const_string "V4SF")
2528                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529                             (const_int 0))
2530                           (const_string "TI")
2531                        ]
2532                        (const_string "V2DF"))
2533
2534                /* For architectures resolving dependencies on
2535                   whole SSE registers use APD move to break dependency
2536                   chains, otherwise use short move to avoid extra work.
2537
2538                   movaps encodes one byte shorter.  */
2539                (eq_attr "alternative" "6")
2540                  (cond
2541                    [(ne (symbol_ref "optimize_size")
2542                         (const_int 0))
2543                       (const_string "V4SF")
2544                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545                         (const_int 0))
2546                       (const_string "V2DF")
2547                    ]
2548                    (const_string "DF"))
2549                /* For architectures resolving dependencies on register
2550                   parts we may avoid extra work to zero out upper part
2551                   of register.  */
2552                (eq_attr "alternative" "7")
2553                  (if_then_else
2554                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555                        (const_int 0))
2556                    (const_string "V1DF")
2557                    (const_string "DF"))
2558               ]
2559               (const_string "DF")))])
2560
2561 (define_insn "*movdf_integer"
2562   [(set (match_operand:DF 0 "nonimmediate_operand"
2563                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564         (match_operand:DF 1 "general_operand"
2565                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2566   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568    && (reload_in_progress || reload_completed
2569        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570        || GET_CODE (operands[1]) != CONST_DOUBLE
2571        || memory_operand (operands[0], DFmode))" 
2572 {
2573   switch (which_alternative)
2574     {
2575     case 0:
2576       return output_387_reg_move (insn, operands);
2577
2578     case 1:
2579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580         return "fstp%z0\t%y0";
2581       else
2582         return "fst%z0\t%y0";
2583
2584     case 2:
2585       return standard_80387_constant_opcode (operands[1]);
2586
2587     case 3:
2588     case 4:
2589       return "#";
2590
2591     case 5:
2592       switch (get_attr_mode (insn))
2593         {
2594         case MODE_V4SF:
2595           return "xorps\t%0, %0";
2596         case MODE_V2DF:
2597           return "xorpd\t%0, %0";
2598         case MODE_TI:
2599           return "pxor\t%0, %0";
2600         default:
2601           gcc_unreachable ();
2602         }
2603     case 6:
2604     case 7:
2605     case 8:
2606       switch (get_attr_mode (insn))
2607         {
2608         case MODE_V4SF:
2609           return "movaps\t{%1, %0|%0, %1}";
2610         case MODE_V2DF:
2611           return "movapd\t{%1, %0|%0, %1}";
2612         case MODE_TI:
2613           return "movdqa\t{%1, %0|%0, %1}";
2614         case MODE_DI:
2615           return "movq\t{%1, %0|%0, %1}";
2616         case MODE_DF:
2617           return "movsd\t{%1, %0|%0, %1}";
2618         case MODE_V1DF:
2619           return "movlpd\t{%1, %0|%0, %1}";
2620         case MODE_V2SF:
2621           return "movlps\t{%1, %0|%0, %1}";
2622         default:
2623           gcc_unreachable ();
2624         }
2625
2626     default:
2627       gcc_unreachable();
2628     }
2629 }
2630   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2631    (set (attr "mode")
2632         (cond [(eq_attr "alternative" "0,1,2")
2633                  (const_string "DF")
2634                (eq_attr "alternative" "3,4")
2635                  (const_string "SI")
2636
2637                /* For SSE1, we have many fewer alternatives.  */
2638                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639                  (cond [(eq_attr "alternative" "5,6")
2640                           (const_string "V4SF")
2641                        ]
2642                    (const_string "V2SF"))
2643
2644                /* xorps is one byte shorter.  */
2645                (eq_attr "alternative" "5")
2646                  (cond [(ne (symbol_ref "optimize_size")
2647                             (const_int 0))
2648                           (const_string "V4SF")
2649                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650                             (const_int 0))
2651                           (const_string "TI")
2652                        ]
2653                        (const_string "V2DF"))
2654
2655                /* For architectures resolving dependencies on
2656                   whole SSE registers use APD move to break dependency
2657                   chains, otherwise use short move to avoid extra work.
2658
2659                   movaps encodes one byte shorter.  */
2660                (eq_attr "alternative" "6")
2661                  (cond
2662                    [(ne (symbol_ref "optimize_size")
2663                         (const_int 0))
2664                       (const_string "V4SF")
2665                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666                         (const_int 0))
2667                       (const_string "V2DF")
2668                    ]
2669                    (const_string "DF"))
2670                /* For architectures resolving dependencies on register
2671                   parts we may avoid extra work to zero out upper part
2672                   of register.  */
2673                (eq_attr "alternative" "7")
2674                  (if_then_else
2675                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676                        (const_int 0))
2677                    (const_string "V1DF")
2678                    (const_string "DF"))
2679               ]
2680               (const_string "DF")))])
2681
2682 (define_split
2683   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684         (match_operand:DF 1 "general_operand" ""))]
2685   "reload_completed
2686    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687    && ! (ANY_FP_REG_P (operands[0]) || 
2688          (GET_CODE (operands[0]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690    && ! (ANY_FP_REG_P (operands[1]) || 
2691          (GET_CODE (operands[1]) == SUBREG
2692           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693   [(const_int 0)]
2694   "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698         (match_operand:DF 1 "fp_register_operand" "+f"))
2699    (set (match_dup 1)
2700         (match_dup 0))]
2701   "reload_completed || TARGET_80387"
2702 {
2703   if (STACK_TOP_P (operands[0]))
2704     return "fxch\t%1";
2705   else
2706     return "fxch\t%0";
2707 }
2708   [(set_attr "type" "fxch")
2709    (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713         (match_operand:XF 1 "general_operand" ""))]
2714   ""
2715   "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;;  handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727   "optimize_size"
2728 {
2729   /* This insn should be already split before reg-stack.  */
2730   gcc_unreachable ();
2731 }
2732   [(set_attr "type" "multi")
2733    (set_attr "unit" "i387,*,*")
2734    (set_attr "mode" "XF,SI,SI")])
2735
2736 (define_insn "*pushxf_integer"
2737   [(set (match_operand:XF 0 "push_operand" "=<,<")
2738         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739   "!optimize_size"
2740 {
2741   /* This insn should be already split before reg-stack.  */
2742   gcc_unreachable ();
2743 }
2744   [(set_attr "type" "multi")
2745    (set_attr "unit" "i387,*")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     default:
2803       gcc_unreachable ();
2804     }
2805 }
2806   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807    (set_attr "mode" "XF,XF,XF,SI,SI")])
2808
2809 (define_insn "*movxf_integer"
2810   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2812   "!optimize_size
2813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814    && (reload_in_progress || reload_completed
2815        || GET_CODE (operands[1]) != CONST_DOUBLE
2816        || memory_operand (operands[0], XFmode))" 
2817 {
2818   switch (which_alternative)
2819     {
2820     case 0:
2821       return output_387_reg_move (insn, operands);
2822
2823     case 1:
2824       /* There is no non-popping store to memory for XFmode.  So if
2825          we need one, follow the store with a load.  */
2826       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827         return "fstp%z0\t%y0\;fld%z0\t%y0";
2828       else
2829         return "fstp%z0\t%y0";
2830
2831     case 2:
2832       return standard_80387_constant_opcode (operands[1]);
2833
2834     case 3: case 4:
2835       return "#";
2836
2837     default:
2838       gcc_unreachable ();
2839     }
2840 }
2841   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842    (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
2844 (define_split
2845   [(set (match_operand 0 "nonimmediate_operand" "")
2846         (match_operand 1 "general_operand" ""))]
2847   "reload_completed
2848    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849    && GET_MODE (operands[0]) == XFmode
2850    && ! (ANY_FP_REG_P (operands[0]) || 
2851          (GET_CODE (operands[0]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853    && ! (ANY_FP_REG_P (operands[1]) || 
2854          (GET_CODE (operands[1]) == SUBREG
2855           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856   [(const_int 0)]
2857   "ix86_split_long_move (operands); DONE;")
2858
2859 (define_split
2860   [(set (match_operand 0 "register_operand" "")
2861         (match_operand 1 "memory_operand" ""))]
2862   "reload_completed
2863    && GET_CODE (operands[1]) == MEM
2864    && (GET_MODE (operands[0]) == XFmode
2865        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2867    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2868   [(set (match_dup 0) (match_dup 1))]
2869 {
2870   rtx c = get_pool_constant (XEXP (operands[1], 0));
2871   rtx r = operands[0];
2872
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2875
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2888
2889   operands[1] = c;
2890 })
2891
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2898 {
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2903 }
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2906
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2911 {
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2914 })
2915
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 {
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2941 }
2942   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2959
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2967 \f
2968 ;; Zero extension instructions
2969
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2974 {
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2981 })
2982
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2991
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3000
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3008
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3016
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3025
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3034
3035 (define_insn "*zero_extendqihi2_movzbw"
3036   [(set (match_operand:HI 0 "register_operand" "=r")
3037      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039   "movz{bw|x}\t{%1, %0|%0, %1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "HI")])
3042
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed 
3049    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && ANY_QI_REG_P (operands[0])
3062    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064   [(set (match_dup 0) (const_int 0))
3065    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066   "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
3068 ;; Rest is handled by single and.
3069 (define_split
3070   [(set (match_operand:HI 0 "register_operand" "")
3071         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "reload_completed
3074    && true_regnum (operands[0]) == true_regnum (operands[1])"
3075   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076               (clobber (reg:CC FLAGS_REG))])]
3077   "")
3078
3079 (define_expand "zero_extendqisi2"
3080   [(parallel
3081     [(set (match_operand:SI 0 "register_operand" "")
3082        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083      (clobber (reg:CC FLAGS_REG))])]
3084   ""
3085   "")
3086
3087 (define_insn "*zero_extendqisi2_and"
3088   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092   "#"
3093   [(set_attr "type" "alu1")
3094    (set_attr "mode" "SI")])
3095
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,r")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101   "#"
3102   [(set_attr "type" "imovx,alu1")
3103    (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw"
3106   [(set (match_operand:SI 0 "register_operand" "=r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109   "movz{bl|x}\t{%1, %0|%0, %1}"
3110   [(set_attr "type" "imovx")
3111    (set_attr "mode" "SI")])
3112
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115   [(set (match_operand:SI 0 "register_operand" "")
3116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117    (clobber (reg:CC FLAGS_REG))]
3118   "reload_completed 
3119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121   [(set (match_dup 0)
3122         (zero_extend:SI (match_dup 1)))])
3123
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127   [(set (match_operand:SI 0 "register_operand" "")
3128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129    (clobber (reg:CC FLAGS_REG))]
3130   "reload_completed
3131    && ANY_QI_REG_P (operands[0])
3132    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135   [(set (match_dup 0) (const_int 0))
3136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137   "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
3139 ;; Rest is handled by single and.
3140 (define_split
3141   [(set (match_operand:SI 0 "register_operand" "")
3142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143    (clobber (reg:CC FLAGS_REG))]
3144   "reload_completed
3145    && true_regnum (operands[0]) == true_regnum (operands[1])"
3146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147               (clobber (reg:CC FLAGS_REG))])]
3148   "")
3149
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152   [(set (match_operand:DI 0 "register_operand" "=r")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154   ""
3155   "if (!TARGET_64BIT)
3156      {
3157        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158        DONE;
3159      }
3160   ")
3161
3162 (define_insn "zero_extendsidi2_32"
3163   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165    (clobber (reg:CC FLAGS_REG))]
3166   "!TARGET_64BIT"
3167   "@
3168    #
3169    #
3170    #
3171    movd\t{%1, %0|%0, %1}
3172    movd\t{%1, %0|%0, %1}"
3173   [(set_attr "mode" "SI,SI,SI,DI,TI")
3174    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
3176 (define_insn "zero_extendsidi2_rex64"
3177   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179   "TARGET_64BIT"
3180   "@
3181    mov\t{%k1, %k0|%k0, %k1}
3182    #
3183    movd\t{%1, %0|%0, %1}
3184    movd\t{%1, %0|%0, %1}"
3185   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186    (set_attr "mode" "SI,DI,SI,SI")])
3187
3188 (define_split
3189   [(set (match_operand:DI 0 "memory_operand" "")
3190      (zero_extend:DI (match_dup 0)))]
3191   "TARGET_64BIT"
3192   [(set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_split 
3196   [(set (match_operand:DI 0 "register_operand" "")
3197         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198    (clobber (reg:CC FLAGS_REG))]
3199   "!TARGET_64BIT && reload_completed
3200    && true_regnum (operands[0]) == true_regnum (operands[1])"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split 
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210   [(set (match_dup 3) (match_dup 1))
3211    (set (match_dup 4) (const_int 0))]
3212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
3214 (define_insn "zero_extendhidi2"
3215   [(set (match_operand:DI 0 "register_operand" "=r")
3216      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217   "TARGET_64BIT"
3218   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219   [(set_attr "type" "imovx")
3220    (set_attr "mode" "DI")])
3221
3222 (define_insn "zero_extendqidi2"
3223   [(set (match_operand:DI 0 "register_operand" "=r")
3224      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225   "TARGET_64BIT"
3226   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")])
3229 \f
3230 ;; Sign extension instructions
3231
3232 (define_expand "extendsidi2"
3233   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235               (clobber (reg:CC FLAGS_REG))
3236               (clobber (match_scratch:SI 2 ""))])]
3237   ""
3238 {
3239   if (TARGET_64BIT)
3240     {
3241       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242       DONE;
3243     }
3244 })
3245
3246 (define_insn "*extendsidi2_1"
3247   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249    (clobber (reg:CC FLAGS_REG))
3250    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251   "!TARGET_64BIT"
3252   "#")
3253
3254 (define_insn "extendsidi2_rex64"
3255   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257   "TARGET_64BIT"
3258   "@
3259    {cltq|cdqe}
3260    movs{lq|x}\t{%1,%0|%0, %1}"
3261   [(set_attr "type" "imovx")
3262    (set_attr "mode" "DI")
3263    (set_attr "prefix_0f" "0")
3264    (set_attr "modrm" "0,1")])
3265
3266 (define_insn "extendhidi2"
3267   [(set (match_operand:DI 0 "register_operand" "=r")
3268         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269   "TARGET_64BIT"
3270   "movs{wq|x}\t{%1,%0|%0, %1}"
3271   [(set_attr "type" "imovx")
3272    (set_attr "mode" "DI")])
3273
3274 (define_insn "extendqidi2"
3275   [(set (match_operand:DI 0 "register_operand" "=r")
3276         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277   "TARGET_64BIT"
3278   "movs{bq|x}\t{%1,%0|%0, %1}"
3279    [(set_attr "type" "imovx")
3280     (set_attr "mode" "DI")])
3281
3282 ;; Extend to memory case when source register does die.
3283 (define_split 
3284   [(set (match_operand:DI 0 "memory_operand" "")
3285         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286    (clobber (reg:CC FLAGS_REG))
3287    (clobber (match_operand:SI 2 "register_operand" ""))]
3288   "(reload_completed
3289     && dead_or_set_p (insn, operands[1])
3290     && !reg_mentioned_p (operands[1], operands[0]))"
3291   [(set (match_dup 3) (match_dup 1))
3292    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293               (clobber (reg:CC FLAGS_REG))])
3294    (set (match_dup 4) (match_dup 1))]
3295   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
3297 ;; Extend to memory case when source register does not die.
3298 (define_split 
3299   [(set (match_operand:DI 0 "memory_operand" "")
3300         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301    (clobber (reg:CC FLAGS_REG))
3302    (clobber (match_operand:SI 2 "register_operand" ""))]
3303   "reload_completed"
3304   [(const_int 0)]
3305 {
3306   split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
3308   emit_move_insn (operands[3], operands[1]);
3309
3310   /* Generate a cltd if possible and doing so it profitable.  */
3311   if (true_regnum (operands[1]) == 0
3312       && true_regnum (operands[2]) == 1
3313       && (optimize_size || TARGET_USE_CLTD))
3314     {
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316     }
3317   else
3318     {
3319       emit_move_insn (operands[2], operands[1]);
3320       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321     }
3322   emit_move_insn (operands[4], operands[2]);
3323   DONE;
3324 })
3325
3326 ;; Extend to register case.  Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split 
3329   [(set (match_operand:DI 0 "register_operand" "")
3330         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331    (clobber (reg:CC FLAGS_REG))
3332    (clobber (match_scratch:SI 2 ""))]
3333   "reload_completed"
3334   [(const_int 0)]
3335 {
3336   split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339     emit_move_insn (operands[3], operands[1]);
3340
3341   /* Generate a cltd if possible and doing so it profitable.  */
3342   if (true_regnum (operands[3]) == 0
3343       && (optimize_size || TARGET_USE_CLTD))
3344     {
3345       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346       DONE;
3347     }
3348
3349   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350     emit_move_insn (operands[4], operands[1]);
3351
3352   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353   DONE;
3354 })
3355
3356 (define_insn "extendhisi2"
3357   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359   ""
3360 {
3361   switch (get_attr_prefix_0f (insn))
3362     {
3363     case 0:
3364       return "{cwtl|cwde}";
3365     default:
3366       return "movs{wl|x}\t{%1,%0|%0, %1}";
3367     }
3368 }
3369   [(set_attr "type" "imovx")
3370    (set_attr "mode" "SI")
3371    (set (attr "prefix_0f")
3372      ;; movsx is short decodable while cwtl is vector decoded.
3373      (if_then_else (and (eq_attr "cpu" "!k6")
3374                         (eq_attr "alternative" "0"))
3375         (const_string "0")
3376         (const_string "1")))
3377    (set (attr "modrm")
3378      (if_then_else (eq_attr "prefix_0f" "0")
3379         (const_string "0")
3380         (const_string "1")))])
3381
3382 (define_insn "*extendhisi2_zext"
3383   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384         (zero_extend:DI
3385           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386   "TARGET_64BIT"
3387 {
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cwtl|cwde}";
3392     default:
3393       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394     }
3395 }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "SI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3408
3409 (define_insn "extendqihi2"
3410   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412   ""
3413 {
3414   switch (get_attr_prefix_0f (insn))
3415     {
3416     case 0:
3417       return "{cbtw|cbw}";
3418     default:
3419       return "movs{bw|x}\t{%1,%0|%0, %1}";
3420     }
3421 }
3422   [(set_attr "type" "imovx")
3423    (set_attr "mode" "HI")
3424    (set (attr "prefix_0f")
3425      ;; movsx is short decodable while cwtl is vector decoded.
3426      (if_then_else (and (eq_attr "cpu" "!k6")
3427                         (eq_attr "alternative" "0"))
3428         (const_string "0")
3429         (const_string "1")))
3430    (set (attr "modrm")
3431      (if_then_else (eq_attr "prefix_0f" "0")
3432         (const_string "0")
3433         (const_string "1")))])
3434
3435 (define_insn "extendqisi2"
3436   [(set (match_operand:SI 0 "register_operand" "=r")
3437         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438   ""
3439   "movs{bl|x}\t{%1,%0|%0, %1}"
3440    [(set_attr "type" "imovx")
3441     (set_attr "mode" "SI")])
3442
3443 (define_insn "*extendqisi2_zext"
3444   [(set (match_operand:DI 0 "register_operand" "=r")
3445         (zero_extend:DI
3446           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447   "TARGET_64BIT"
3448   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3451 \f
3452 ;; Conversions between float and double.
3453
3454 ;; These are all no-ops in the model used for the 80387.  So just
3455 ;; emit moves.
3456
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3458 (define_insn "*dummy_extendsfdf2"
3459   [(set (match_operand:DF 0 "push_operand" "=<")
3460         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461   "0"
3462   "#")
3463
3464 (define_split
3465   [(set (match_operand:DF 0 "push_operand" "")
3466         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467   "!TARGET_64BIT"
3468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
3471 (define_split
3472   [(set (match_operand:DF 0 "push_operand" "")
3473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_insn "*dummy_extendsfxf2"
3479   [(set (match_operand:XF 0 "push_operand" "=<")
3480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481   "0"
3482   "#")
3483
3484 (define_split
3485   [(set (match_operand:XF 0 "push_operand" "")
3486         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487   ""
3488   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
3492 (define_split
3493   [(set (match_operand:XF 0 "push_operand" "")
3494         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "TARGET_64BIT"
3496   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
3500 (define_split
3501   [(set (match_operand:XF 0 "push_operand" "")
3502         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503   ""
3504   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 (define_split
3509   [(set (match_operand:XF 0 "push_operand" "")
3510         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511   "TARGET_64BIT"
3512   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
3516 (define_expand "extendsfdf2"
3517   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520 {
3521   /* ??? Needed for compress_float_constant since all fp constants
3522      are LEGITIMATE_CONSTANT_P.  */
3523   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526     operands[1] = force_reg (SFmode, operands[1]);
3527 })
3528
3529 (define_insn "*extendsfdf2_mixed"
3530   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534 {
3535   switch (which_alternative)
3536     {
3537     case 0:
3538       return output_387_reg_move (insn, operands);
3539
3540     case 1:
3541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542         return "fstp%z0\t%y0";
3543       else
3544         return "fst%z0\t%y0";
3545
3546     case 2:
3547       return "cvtss2sd\t{%1, %0|%0, %1}";
3548
3549     default:
3550       gcc_unreachable ();
3551     }
3552 }
3553   [(set_attr "type" "fmov,fmov,ssecvt")
3554    (set_attr "mode" "SF,XF,DF")])
3555
3556 (define_insn "*extendsfdf2_sse"
3557   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559   "TARGET_SSE2 && TARGET_SSE_MATH
3560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561   "cvtss2sd\t{%1, %0|%0, %1}"
3562   [(set_attr "type" "ssecvt")
3563    (set_attr "mode" "DF")])
3564
3565 (define_insn "*extendsfdf2_i387"
3566   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3568   "TARGET_80387
3569    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3570 {
3571   switch (which_alternative)
3572     {
3573     case 0:
3574       return output_387_reg_move (insn, operands);
3575
3576     case 1:
3577       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578         return "fstp%z0\t%y0";
3579       else
3580         return "fst%z0\t%y0";
3581
3582     default:
3583       gcc_unreachable ();
3584     }
3585 }
3586   [(set_attr "type" "fmov")
3587    (set_attr "mode" "SF,XF")])
3588
3589 (define_expand "extendsfxf2"
3590   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3592   "TARGET_80387"
3593 {
3594   /* ??? Needed for compress_float_constant since all fp constants
3595      are LEGITIMATE_CONSTANT_P.  */
3596   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599     operands[1] = force_reg (SFmode, operands[1]);
3600 })
3601
3602 (define_insn "*extendsfxf2_i387"
3603   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605   "TARGET_80387
3606    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3607 {
3608   switch (which_alternative)
3609     {
3610     case 0:
3611       return output_387_reg_move (insn, operands);
3612
3613     case 1:
3614       /* There is no non-popping store to memory for XFmode.  So if
3615          we need one, follow the store with a load.  */
3616       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617         return "fstp%z0\t%y0";
3618       else
3619         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3620
3621     default:
3622       gcc_unreachable ();
3623     }
3624 }
3625   [(set_attr "type" "fmov")
3626    (set_attr "mode" "SF,XF")])
3627
3628 (define_expand "extenddfxf2"
3629   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3631   "TARGET_80387"
3632 {
3633   /* ??? Needed for compress_float_constant since all fp constants
3634      are LEGITIMATE_CONSTANT_P.  */
3635   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638     operands[1] = force_reg (DFmode, operands[1]);
3639 })
3640
3641 (define_insn "*extenddfxf2_i387"
3642   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3644   "TARGET_80387
3645    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3646 {
3647   switch (which_alternative)
3648     {
3649     case 0:
3650       return output_387_reg_move (insn, operands);
3651
3652     case 1:
3653       /* There is no non-popping store to memory for XFmode.  So if
3654          we need one, follow the store with a load.  */
3655       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3657       else
3658         return "fstp%z0\t%y0";
3659
3660     default:
3661       gcc_unreachable ();
3662     }
3663 }
3664   [(set_attr "type" "fmov")
3665    (set_attr "mode" "DF,XF")])
3666
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case.  Otherwise this is just like a simple move
3670 ;; insn.  So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3672
3673 ;; Conversion from DFmode to SFmode.
3674
3675 (define_expand "truncdfsf2"
3676   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3677         (float_truncate:SF
3678           (match_operand:DF 1 "nonimmediate_operand" "")))]
3679   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3680 {
3681   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682     operands[1] = force_reg (DFmode, operands[1]);
3683
3684   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3685     ;
3686   else if (flag_unsafe_math_optimizations)
3687     ;
3688   else
3689     {
3690       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3692       DONE;
3693     }
3694 })
3695
3696 (define_expand "truncdfsf2_with_temp"
3697   [(parallel [(set (match_operand:SF 0 "" "")
3698                    (float_truncate:SF (match_operand:DF 1 "" "")))
3699               (clobber (match_operand:SF 2 "" ""))])]
3700   "")
3701
3702 (define_insn "*truncdfsf_fast_mixed"
3703   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3704         (float_truncate:SF
3705           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3707 {
3708   switch (which_alternative)
3709     {
3710     case 0:
3711       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0";
3713       else
3714         return "fst%z0\t%y0";
3715     case 1:
3716       return output_387_reg_move (insn, operands);
3717     case 2:
3718       return "cvtsd2ss\t{%1, %0|%0, %1}";
3719     default:
3720       gcc_unreachable ();
3721     }
3722 }
3723   [(set_attr "type" "fmov,fmov,ssecvt")
3724    (set_attr "mode" "SF")])
3725
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3730         (float_truncate:SF
3731           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732   "TARGET_SSE2 && TARGET_SSE_MATH"
3733   "cvtsd2ss\t{%1, %0|%0, %1}"
3734   [(set_attr "type" "ssecvt")
3735    (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_fast_i387"
3738   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741   "TARGET_80387 && flag_unsafe_math_optimizations"
3742   "* return output_387_reg_move (insn, operands);"
3743   [(set_attr "type" "fmov")
3744    (set_attr "mode" "SF")])
3745
3746 (define_insn "*truncdfsf_mixed"
3747   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3748         (float_truncate:SF
3749           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3750    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3751   "TARGET_MIX_SSE_I387"
3752 {
3753   switch (which_alternative)
3754     {
3755     case 0:
3756       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757         return "fstp%z0\t%y0";
3758       else
3759         return "fst%z0\t%y0";
3760     case 1:
3761       return "#";
3762     case 2:
3763       return "cvtsd2ss\t{%1, %0|%0, %1}";
3764     default:
3765       gcc_unreachable ();
3766     }
3767 }
3768   [(set_attr "type" "fmov,multi,ssecvt")
3769    (set_attr "unit" "*,i387,*")
3770    (set_attr "mode" "SF")])
3771
3772 (define_insn "*truncdfsf_i387"
3773   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3774         (float_truncate:SF
3775           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3777   "TARGET_80387"
3778 {
3779   switch (which_alternative)
3780     {
3781     case 0:
3782       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783         return "fstp%z0\t%y0";
3784       else
3785         return "fst%z0\t%y0";
3786     case 1:
3787       return "#";
3788     default:
3789       gcc_unreachable ();
3790     }
3791 }
3792   [(set_attr "type" "fmov,multi")
3793    (set_attr "unit" "*,i387")
3794    (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_i387_1"
3797   [(set (match_operand:SF 0 "memory_operand" "=m")
3798         (float_truncate:SF
3799           (match_operand:DF 1 "register_operand" "f")))]
3800   "TARGET_80387
3801    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802    && !TARGET_MIX_SSE_I387"
3803 {
3804   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805     return "fstp%z0\t%y0";
3806   else
3807     return "fst%z0\t%y0";
3808 }
3809   [(set_attr "type" "fmov")
3810    (set_attr "mode" "SF")])
3811
3812 (define_split
3813   [(set (match_operand:SF 0 "register_operand" "")
3814         (float_truncate:SF
3815          (match_operand:DF 1 "fp_register_operand" "")))
3816    (clobber (match_operand 2 "" ""))]
3817   "reload_completed"
3818   [(set (match_dup 2) (match_dup 1))
3819    (set (match_dup 0) (match_dup 2))]
3820 {
3821   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3822 })
3823
3824 ;; Conversion from XFmode to SFmode.
3825
3826 (define_expand "truncxfsf2"
3827   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3828                    (float_truncate:SF
3829                     (match_operand:XF 1 "register_operand" "")))
3830               (clobber (match_dup 2))])]
3831   "TARGET_80387"
3832 {
3833   if (flag_unsafe_math_optimizations)
3834     {
3835       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837       if (reg != operands[0])
3838         emit_move_insn (operands[0], reg);
3839       DONE;
3840     }
3841   else
3842     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3843 })
3844
3845 (define_insn "*truncxfsf2_mixed"
3846   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3847         (float_truncate:SF
3848          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850   "TARGET_MIX_SSE_I387"
3851 {
3852   gcc_assert (!which_alternative);
3853   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854     return "fstp%z0\t%y0";
3855   else
3856     return "fst%z0\t%y0";
3857 }
3858   [(set_attr "type" "fmov,multi,multi,multi")
3859    (set_attr "unit" "*,i387,i387,i387")
3860    (set_attr "mode" "SF")])
3861
3862 (define_insn "truncxfsf2_i387_noop"
3863   [(set (match_operand:SF 0 "register_operand" "=f")
3864         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865   "TARGET_80387 && flag_unsafe_math_optimizations"
3866 {
3867   return output_387_reg_move (insn, operands);
3868 }
3869   [(set_attr "type" "fmov")
3870    (set_attr "mode" "SF")])
3871
3872 (define_insn "*truncxfsf2_i387"
3873   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3874         (float_truncate:SF
3875          (match_operand:XF 1 "register_operand" "f,f,f")))
3876    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3877   "TARGET_80387"
3878 {
3879   gcc_assert (!which_alternative);
3880   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881     return "fstp%z0\t%y0";
3882    else
3883      return "fst%z0\t%y0";
3884 }
3885   [(set_attr "type" "fmov,multi,multi")
3886    (set_attr "unit" "*,i387,i387")
3887    (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncxfsf2_i387_1"
3890   [(set (match_operand:SF 0 "memory_operand" "=m")
3891         (float_truncate:SF
3892          (match_operand:XF 1 "register_operand" "f")))]
3893   "TARGET_80387"
3894 {
3895   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896     return "fstp%z0\t%y0";
3897   else
3898     return "fst%z0\t%y0";
3899 }
3900   [(set_attr "type" "fmov")
3901    (set_attr "mode" "SF")])
3902
3903 (define_split
3904   [(set (match_operand:SF 0 "register_operand" "")
3905         (float_truncate:SF
3906          (match_operand:XF 1 "register_operand" "")))
3907    (clobber (match_operand:SF 2 "memory_operand" ""))]
3908   "TARGET_80387 && reload_completed"
3909   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910    (set (match_dup 0) (match_dup 2))]
3911   "")
3912
3913 (define_split
3914   [(set (match_operand:SF 0 "memory_operand" "")
3915         (float_truncate:SF
3916          (match_operand:XF 1 "register_operand" "")))
3917    (clobber (match_operand:SF 2 "memory_operand" ""))]
3918   "TARGET_80387"
3919   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3920   "")
3921
3922 ;; Conversion from XFmode to DFmode.
3923
3924 (define_expand "truncxfdf2"
3925   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3926                    (float_truncate:DF
3927                     (match_operand:XF 1 "register_operand" "")))
3928               (clobber (match_dup 2))])]
3929   "TARGET_80387"
3930 {
3931   if (flag_unsafe_math_optimizations)
3932     {
3933       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935       if (reg != operands[0])
3936         emit_move_insn (operands[0], reg);
3937       DONE;
3938     }
3939   else
3940     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3941 })
3942
3943 (define_insn "*truncxfdf2_mixed"
3944   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945         (float_truncate:DF
3946          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3949 {
3950   gcc_assert (!which_alternative);
3951   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952     return "fstp%z0\t%y0";
3953   else
3954     return "fst%z0\t%y0";
3955 }
3956   [(set_attr "type" "fmov,multi,multi,multi")
3957    (set_attr "unit" "*,i387,i387,i387")
3958    (set_attr "mode" "DF")])
3959
3960 (define_insn "truncxfdf2_i387_noop"
3961   [(set (match_operand:DF 0 "register_operand" "=f")
3962         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963   "TARGET_80387 && flag_unsafe_math_optimizations"
3964 {
3965   return output_387_reg_move (insn, operands);
3966 }
3967   [(set_attr "type" "fmov")
3968    (set_attr "mode" "DF")])
3969
3970 (define_insn "*truncxfdf2_i387"
3971   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3972         (float_truncate:DF
3973          (match_operand:XF 1 "register_operand" "f,f,f")))
3974    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3975   "TARGET_80387"
3976 {
3977   gcc_assert (!which_alternative);
3978   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979     return "fstp%z0\t%y0";
3980   else
3981     return "fst%z0\t%y0";
3982 }
3983   [(set_attr "type" "fmov,multi,multi")
3984    (set_attr "unit" "*,i387,i387")
3985    (set_attr "mode" "DF")])
3986
3987 (define_insn "*truncxfdf2_i387_1"
3988   [(set (match_operand:DF 0 "memory_operand" "=m")
3989         (float_truncate:DF
3990           (match_operand:XF 1 "register_operand" "f")))]
3991   "TARGET_80387"
3992 {
3993   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994     return "fstp%z0\t%y0";
3995   else
3996     return "fst%z0\t%y0";
3997 }
3998   [(set_attr "type" "fmov")
3999    (set_attr "mode" "DF")])
4000
4001 (define_split
4002   [(set (match_operand:DF 0 "register_operand" "")
4003         (float_truncate:DF
4004          (match_operand:XF 1 "register_operand" "")))
4005    (clobber (match_operand:DF 2 "memory_operand" ""))]
4006   "TARGET_80387 && reload_completed"
4007   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008    (set (match_dup 0) (match_dup 2))]
4009   "")
4010
4011 (define_split
4012   [(set (match_operand:DF 0 "memory_operand" "")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "")))
4015    (clobber (match_operand:DF 2 "memory_operand" ""))]
4016   "TARGET_80387"
4017   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4018   "")
4019 \f
4020 ;; Signed conversion to DImode.
4021
4022 (define_expand "fix_truncxfdi2"
4023   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4025               (clobber (reg:CC FLAGS_REG))])]
4026   "TARGET_80387"
4027 {
4028   if (TARGET_FISTTP)
4029    {
4030      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4031      DONE;
4032    }
4033 })
4034
4035 (define_expand "fix_trunc<mode>di2"
4036   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038               (clobber (reg:CC FLAGS_REG))])]
4039   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4040 {
4041   if (TARGET_FISTTP
4042       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4043    {
4044      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4045      DONE;
4046    }
4047   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4048    {
4049      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051      if (out != operands[0])
4052         emit_move_insn (operands[0], out);
4053      DONE;
4054    }
4055 })
4056
4057 ;; Signed conversion to SImode.
4058
4059 (define_expand "fix_truncxfsi2"
4060   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4062               (clobber (reg:CC FLAGS_REG))])]
4063   "TARGET_80387"
4064 {
4065   if (TARGET_FISTTP)
4066    {
4067      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4068      DONE;
4069    }
4070 })
4071
4072 (define_expand "fix_trunc<mode>si2"
4073   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075               (clobber (reg:CC FLAGS_REG))])]
4076   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4077 {
4078   if (TARGET_FISTTP
4079       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4080    {
4081      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4082      DONE;
4083    }
4084   if (SSE_FLOAT_MODE_P (<MODE>mode))
4085    {
4086      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088      if (out != operands[0])
4089         emit_move_insn (operands[0], out);
4090      DONE;
4091    }
4092 })
4093
4094 ;; Signed conversion to HImode.
4095
4096 (define_expand "fix_trunc<mode>hi2"
4097   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099               (clobber (reg:CC FLAGS_REG))])]
4100   "TARGET_80387
4101    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4102 {
4103   if (TARGET_FISTTP)
4104    {
4105      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4106      DONE;
4107    }
4108 })
4109
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112   [(set (match_operand:DI 0 "register_operand" "=r,r")
4113         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115   "cvttss2si{q}\t{%1, %0|%0, %1}"
4116   [(set_attr "type" "sseicvt")
4117    (set_attr "mode" "SF")
4118    (set_attr "athlon_decode" "double,vector")])
4119
4120 (define_insn "fix_truncdfdi_sse"
4121   [(set (match_operand:DI 0 "register_operand" "=r,r")
4122         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125   [(set_attr "type" "sseicvt")
4126    (set_attr "mode" "DF")
4127    (set_attr "athlon_decode" "double,vector")])
4128
4129 (define_insn "fix_truncsfsi_sse"
4130   [(set (match_operand:SI 0 "register_operand" "=r,r")
4131         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133   "cvttss2si\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 (define_insn "fix_truncdfsi_sse"
4139   [(set (match_operand:SI 0 "register_operand" "=r,r")
4140         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142   "cvttsd2si\t{%1, %0|%0, %1}"
4143   [(set_attr "type" "sseicvt")
4144    (set_attr "mode" "DF")
4145    (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded forms of the instruction.
4148 (define_peephole2
4149   [(match_scratch:DF 2 "Y")
4150    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152   "TARGET_K8 && !optimize_size"
4153   [(set (match_dup 2) (match_dup 1))
4154    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4155   "")
4156
4157 (define_peephole2
4158   [(match_scratch:SF 2 "x")
4159    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161   "TARGET_K8 && !optimize_size"
4162   [(set (match_dup 2) (match_dup 1))
4163    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4164   "")
4165
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4169   "TARGET_80387 && TARGET_FISTTP
4170    && FLOAT_MODE_P (GET_MODE (operands[1]))
4171    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172          && (TARGET_64BIT || <MODE>mode != DImode))
4173         && TARGET_SSE_MATH)
4174    && !(reload_completed || reload_in_progress)"
4175   "#"
4176   "&& 1"
4177   [(const_int 0)]
4178 {
4179   if (memory_operand (operands[0], VOIDmode))
4180     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181   else
4182     {
4183       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4185                                                             operands[1],
4186                                                             operands[2]));
4187     }
4188   DONE;
4189 }
4190   [(set_attr "type" "fisttp")
4191    (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196    (clobber (match_scratch:XF 2 "=&1f"))]
4197   "TARGET_80387 && TARGET_FISTTP
4198    && FLOAT_MODE_P (GET_MODE (operands[1]))
4199    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200          && (TARGET_64BIT || <MODE>mode != DImode))
4201         && TARGET_SSE_MATH)"
4202   "* return output_fix_trunc (insn, operands, 1);"
4203   [(set_attr "type" "fisttp")
4204    (set_attr "mode" "<MODE>")])
4205
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211   "TARGET_80387 && TARGET_FISTTP
4212    && FLOAT_MODE_P (GET_MODE (operands[1]))
4213    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214         && (TARGET_64BIT || <MODE>mode != DImode))
4215         && TARGET_SSE_MATH)"
4216   "#"
4217   [(set_attr "type" "fisttp")
4218    (set_attr "mode" "<MODE>")])
4219
4220 (define_split
4221   [(set (match_operand:X87MODEI 0 "register_operand" "")
4222         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224    (clobber (match_scratch 3 ""))]
4225   "reload_completed"
4226   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227               (clobber (match_dup 3))])
4228    (set (match_dup 0) (match_dup 2))]
4229   "")
4230
4231 (define_split
4232   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235    (clobber (match_scratch 3 ""))]
4236   "reload_completed"
4237   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238               (clobber (match_dup 3))])]
4239   "")
4240
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249    (clobber (reg:CC FLAGS_REG))]
4250   "TARGET_80387 && !TARGET_FISTTP
4251    && FLOAT_MODE_P (GET_MODE (operands[1]))
4252    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253          && (TARGET_64BIT || <MODE>mode != DImode))
4254    && !(reload_completed || reload_in_progress)"
4255   "#"
4256   "&& 1"
4257   [(const_int 0)]
4258 {
4259   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4260
4261   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265                                          operands[2], operands[3]));
4266   else
4267     {
4268       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270                                                      operands[2], operands[3],
4271                                                      operands[4]));
4272     }
4273   DONE;
4274 }
4275   [(set_attr "type" "fistp")
4276    (set_attr "i387_cw" "trunc")
4277    (set_attr "mode" "<MODE>")])
4278
4279 (define_insn "fix_truncdi_i387"
4280   [(set (match_operand:DI 0 "memory_operand" "=m")
4281         (fix:DI (match_operand 1 "register_operand" "f")))
4282    (use (match_operand:HI 2 "memory_operand" "m"))
4283    (use (match_operand:HI 3 "memory_operand" "m"))
4284    (clobber (match_scratch:XF 4 "=&1f"))]
4285   "TARGET_80387 && !TARGET_FISTTP
4286    && FLOAT_MODE_P (GET_MODE (operands[1]))
4287    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288   "* return output_fix_trunc (insn, operands, 0);"
4289   [(set_attr "type" "fistp")
4290    (set_attr "i387_cw" "trunc")
4291    (set_attr "mode" "DI")])
4292
4293 (define_insn "fix_truncdi_i387_with_temp"
4294   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295         (fix:DI (match_operand 1 "register_operand" "f,f")))
4296    (use (match_operand:HI 2 "memory_operand" "m,m"))
4297    (use (match_operand:HI 3 "memory_operand" "m,m"))
4298    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300   "TARGET_80387 && !TARGET_FISTTP
4301    && FLOAT_MODE_P (GET_MODE (operands[1]))
4302    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303   "#"
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "DI")])
4307
4308 (define_split 
4309   [(set (match_operand:DI 0 "register_operand" "")
4310         (fix:DI (match_operand 1 "register_operand" "")))
4311    (use (match_operand:HI 2 "memory_operand" ""))
4312    (use (match_operand:HI 3 "memory_operand" ""))
4313    (clobber (match_operand:DI 4 "memory_operand" ""))
4314    (clobber (match_scratch 5 ""))]
4315   "reload_completed"
4316   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317               (use (match_dup 2))
4318               (use (match_dup 3))
4319               (clobber (match_dup 5))])
4320    (set (match_dup 0) (match_dup 4))]
4321   "")
4322
4323 (define_split 
4324   [(set (match_operand:DI 0 "memory_operand" "")
4325         (fix:DI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:DI 4 "memory_operand" ""))
4329    (clobber (match_scratch 5 ""))]
4330   "reload_completed"
4331   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332               (use (match_dup 2))
4333               (use (match_dup 3))
4334               (clobber (match_dup 5))])]
4335   "")
4336
4337 (define_insn "fix_trunc<mode>_i387"
4338   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340    (use (match_operand:HI 2 "memory_operand" "m"))
4341    (use (match_operand:HI 3 "memory_operand" "m"))]
4342   "TARGET_80387 && !TARGET_FISTTP
4343    && FLOAT_MODE_P (GET_MODE (operands[1]))
4344    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345   "* return output_fix_trunc (insn, operands, 0);"
4346   [(set_attr "type" "fistp")
4347    (set_attr "i387_cw" "trunc")
4348    (set_attr "mode" "<MODE>")])
4349
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353    (use (match_operand:HI 2 "memory_operand" "m,m"))
4354    (use (match_operand:HI 3 "memory_operand" "m,m"))
4355    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356   "TARGET_80387 && !TARGET_FISTTP
4357    && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359   "#"
4360   [(set_attr "type" "fistp")
4361    (set_attr "i387_cw" "trunc")
4362    (set_attr "mode" "<MODE>")])
4363
4364 (define_split 
4365   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367    (use (match_operand:HI 2 "memory_operand" ""))
4368    (use (match_operand:HI 3 "memory_operand" ""))
4369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370   "reload_completed"
4371   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372               (use (match_dup 2))
4373               (use (match_dup 3))])
4374    (set (match_dup 0) (match_dup 4))]
4375   "")
4376
4377 (define_split 
4378   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380    (use (match_operand:HI 2 "memory_operand" ""))
4381    (use (match_operand:HI 3 "memory_operand" ""))
4382    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383   "reload_completed"
4384   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385               (use (match_dup 2))
4386               (use (match_dup 3))])]
4387   "")
4388
4389 (define_insn "x86_fnstcw_1"
4390   [(set (match_operand:HI 0 "memory_operand" "=m")
4391         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392   "TARGET_80387"
4393   "fnstcw\t%0"
4394   [(set_attr "length" "2")
4395    (set_attr "mode" "HI")
4396    (set_attr "unit" "i387")])
4397
4398 (define_insn "x86_fldcw_1"
4399   [(set (reg:HI FPSR_REG)
4400         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401   "TARGET_80387"
4402   "fldcw\t%0"
4403   [(set_attr "length" "2")
4404    (set_attr "mode" "HI")
4405    (set_attr "unit" "i387")
4406    (set_attr "athlon_decode" "vector")])
4407 \f
4408 ;; Conversion between fixed point and floating point.
4409
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4412
4413 (define_expand "floathisf2"
4414   [(set (match_operand:SF 0 "register_operand" "")
4415         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416   "TARGET_80387 || TARGET_SSE_MATH"
4417 {
4418   if (TARGET_SSE_MATH)
4419     {
4420       emit_insn (gen_floatsisf2 (operands[0],
4421                                  convert_to_mode (SImode, operands[1], 0)));
4422       DONE;
4423     }
4424 })
4425
4426 (define_insn "*floathisf2_i387"
4427   [(set (match_operand:SF 0 "register_operand" "=f,f")
4428         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430   "@
4431    fild%z1\t%1
4432    #"
4433   [(set_attr "type" "fmov,multi")
4434    (set_attr "mode" "SF")
4435    (set_attr "unit" "*,i387")
4436    (set_attr "fp_int_src" "true")])
4437
4438 (define_expand "floatsisf2"
4439   [(set (match_operand:SF 0 "register_operand" "")
4440         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441   "TARGET_80387 || TARGET_SSE_MATH"
4442   "")
4443
4444 (define_insn "*floatsisf2_mixed"
4445   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447   "TARGET_MIX_SSE_I387"
4448   "@
4449    fild%z1\t%1
4450    #
4451    cvtsi2ss\t{%1, %0|%0, %1}
4452    cvtsi2ss\t{%1, %0|%0, %1}"
4453   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454    (set_attr "mode" "SF")
4455    (set_attr "unit" "*,i387,*,*")
4456    (set_attr "athlon_decode" "*,*,vector,double")
4457    (set_attr "fp_int_src" "true")])
4458
4459 (define_insn "*floatsisf2_sse"
4460   [(set (match_operand:SF 0 "register_operand" "=x,x")
4461         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4462   "TARGET_SSE_MATH"
4463   "cvtsi2ss\t{%1, %0|%0, %1}"
4464   [(set_attr "type" "sseicvt")
4465    (set_attr "mode" "SF")
4466    (set_attr "athlon_decode" "vector,double")
4467    (set_attr "fp_int_src" "true")])
4468
4469 (define_insn "*floatsisf2_i387"
4470   [(set (match_operand:SF 0 "register_operand" "=f,f")
4471         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4472   "TARGET_80387"
4473   "@
4474    fild%z1\t%1
4475    #"
4476   [(set_attr "type" "fmov,multi")
4477    (set_attr "mode" "SF")
4478    (set_attr "unit" "*,i387")
4479    (set_attr "fp_int_src" "true")])
4480
4481 (define_expand "floatdisf2"
4482   [(set (match_operand:SF 0 "register_operand" "")
4483         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4485   "")
4486
4487 (define_insn "*floatdisf2_mixed"
4488   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4491   "@
4492    fild%z1\t%1
4493    #
4494    cvtsi2ss{q}\t{%1, %0|%0, %1}
4495    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "unit" "*,i387,*,*")
4499    (set_attr "athlon_decode" "*,*,vector,double")
4500    (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatdisf2_sse"
4503   [(set (match_operand:SF 0 "register_operand" "=x,x")
4504         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505   "TARGET_64BIT && TARGET_SSE_MATH"
4506   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507   [(set_attr "type" "sseicvt")
4508    (set_attr "mode" "SF")
4509    (set_attr "athlon_decode" "vector,double")
4510    (set_attr "fp_int_src" "true")])
4511
4512 (define_insn "*floatdisf2_i387"
4513   [(set (match_operand:SF 0 "register_operand" "=f,f")
4514         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515   "TARGET_80387"
4516   "@
4517    fild%z1\t%1
4518    #"
4519   [(set_attr "type" "fmov,multi")
4520    (set_attr "mode" "SF")
4521    (set_attr "unit" "*,i387")
4522    (set_attr "fp_int_src" "true")])
4523
4524 (define_expand "floathidf2"
4525   [(set (match_operand:DF 0 "register_operand" "")
4526         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528 {
4529   if (TARGET_SSE2 && TARGET_SSE_MATH)
4530     {
4531       emit_insn (gen_floatsidf2 (operands[0],
4532                                  convert_to_mode (SImode, operands[1], 0)));
4533       DONE;
4534     }
4535 })
4536
4537 (define_insn "*floathidf2_i387"
4538   [(set (match_operand:DF 0 "register_operand" "=f,f")
4539         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4541   "@
4542    fild%z1\t%1
4543    #"
4544   [(set_attr "type" "fmov,multi")
4545    (set_attr "mode" "DF")
4546    (set_attr "unit" "*,i387")
4547    (set_attr "fp_int_src" "true")])
4548
4549 (define_expand "floatsidf2"
4550   [(set (match_operand:DF 0 "register_operand" "")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4553   "")
4554
4555 (define_insn "*floatsidf2_mixed"
4556   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4559   "@
4560    fild%z1\t%1
4561    #
4562    cvtsi2sd\t{%1, %0|%0, %1}
4563    cvtsi2sd\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565    (set_attr "mode" "DF")
4566    (set_attr "unit" "*,i387,*,*")
4567    (set_attr "athlon_decode" "*,*,double,direct")
4568    (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatsidf2_sse"
4571   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573   "TARGET_SSE2 && TARGET_SSE_MATH"
4574   "cvtsi2sd\t{%1, %0|%0, %1}"
4575   [(set_attr "type" "sseicvt")
4576    (set_attr "mode" "DF")
4577    (set_attr "athlon_decode" "double,direct")
4578    (set_attr "fp_int_src" "true")])
4579
4580 (define_insn "*floatsidf2_i387"
4581   [(set (match_operand:DF 0 "register_operand" "=f,f")
4582         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4583   "TARGET_80387"
4584   "@
4585    fild%z1\t%1
4586    #"
4587   [(set_attr "type" "fmov,multi")
4588    (set_attr "mode" "DF")
4589    (set_attr "unit" "*,i387")
4590    (set_attr "fp_int_src" "true")])
4591
4592 (define_expand "floatdidf2"
4593   [(set (match_operand:DF 0 "register_operand" "")
4594         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4596   "")
4597
4598 (define_insn "*floatdidf2_mixed"
4599   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4602   "@
4603    fild%z1\t%1
4604    #
4605    cvtsi2sd{q}\t{%1, %0|%0, %1}
4606    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608    (set_attr "mode" "DF")
4609    (set_attr "unit" "*,i387,*,*")
4610    (set_attr "athlon_decode" "*,*,double,direct")
4611    (set_attr "fp_int_src" "true")])
4612
4613 (define_insn "*floatdidf2_sse"
4614   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618   [(set_attr "type" "sseicvt")
4619    (set_attr "mode" "DF")
4620    (set_attr "athlon_decode" "double,direct")
4621    (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatdidf2_i387"
4624   [(set (match_operand:DF 0 "register_operand" "=f,f")
4625         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4626   "TARGET_80387"
4627   "@
4628    fild%z1\t%1
4629    #"
4630   [(set_attr "type" "fmov,multi")
4631    (set_attr "mode" "DF")
4632    (set_attr "unit" "*,i387")
4633    (set_attr "fp_int_src" "true")])
4634
4635 (define_insn "floathixf2"
4636   [(set (match_operand:XF 0 "register_operand" "=f,f")
4637         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638   "TARGET_80387"
4639   "@
4640    fild%z1\t%1
4641    #"
4642   [(set_attr "type" "fmov,multi")
4643    (set_attr "mode" "XF")
4644    (set_attr "unit" "*,i387")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "floatsixf2"
4648   [(set (match_operand:XF 0 "register_operand" "=f,f")
4649         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "XF")
4656    (set_attr "unit" "*,i387")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floatdixf2"
4660   [(set (match_operand:XF 0 "register_operand" "=f,f")
4661         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "XF")
4668    (set_attr "unit" "*,i387")
4669    (set_attr "fp_int_src" "true")])
4670
4671 ;; %%% Kill these when reload knows how to do it.
4672 (define_split
4673   [(set (match_operand 0 "fp_register_operand" "")
4674         (float (match_operand 1 "register_operand" "")))]
4675   "reload_completed
4676    && TARGET_80387
4677    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4678   [(const_int 0)]
4679 {
4680   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683   ix86_free_from_memory (GET_MODE (operands[1]));
4684   DONE;
4685 })
4686
4687 (define_expand "floatunssisf2"
4688   [(use (match_operand:SF 0 "register_operand" ""))
4689    (use (match_operand:SI 1 "register_operand" ""))]
4690   "!TARGET_64BIT && TARGET_SSE_MATH"
4691   "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdisf2"
4694   [(use (match_operand:SF 0 "register_operand" ""))
4695    (use (match_operand:DI 1 "register_operand" ""))]
4696   "TARGET_64BIT && TARGET_SSE_MATH"
4697   "x86_emit_floatuns (operands); DONE;")
4698
4699 (define_expand "floatunsdidf2"
4700   [(use (match_operand:DF 0 "register_operand" ""))
4701    (use (match_operand:DI 1 "register_operand" ""))]
4702   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703   "x86_emit_floatuns (operands); DONE;")
4704 \f
4705 ;; SSE extract/set expanders
4706
4707 \f
4708 ;; Add instructions
4709
4710 ;; %%% splits for addditi3
4711
4712 (define_expand "addti3"
4713   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715                  (match_operand:TI 2 "x86_64_general_operand" "")))
4716    (clobber (reg:CC FLAGS_REG))]
4717   "TARGET_64BIT"
4718   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4719
4720 (define_insn "*addti3_1"
4721   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4724    (clobber (reg:CC FLAGS_REG))]
4725   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4726   "#")
4727
4728 (define_split
4729   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731                  (match_operand:TI 2 "general_operand" "")))
4732    (clobber (reg:CC FLAGS_REG))]
4733   "TARGET_64BIT && reload_completed"
4734   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4735                                           UNSPEC_ADD_CARRY))
4736               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737    (parallel [(set (match_dup 3)
4738                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4739                                      (match_dup 4))
4740                             (match_dup 5)))
4741               (clobber (reg:CC FLAGS_REG))])]
4742   "split_ti (operands+0, 1, operands+0, operands+3);
4743    split_ti (operands+1, 1, operands+1, operands+4);
4744    split_ti (operands+2, 1, operands+2, operands+5);")
4745
4746 ;; %%% splits for addsidi3
4747 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4750
4751 (define_expand "adddi3"
4752   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754                  (match_operand:DI 2 "x86_64_general_operand" "")))
4755    (clobber (reg:CC FLAGS_REG))]
4756   ""
4757   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4758
4759 (define_insn "*adddi3_1"
4760   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4763    (clobber (reg:CC FLAGS_REG))]
4764   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4765   "#")
4766
4767 (define_split
4768   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770                  (match_operand:DI 2 "general_operand" "")))
4771    (clobber (reg:CC FLAGS_REG))]
4772   "!TARGET_64BIT && reload_completed"
4773   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4774                                           UNSPEC_ADD_CARRY))
4775               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776    (parallel [(set (match_dup 3)
4777                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4778                                      (match_dup 4))
4779                             (match_dup 5)))
4780               (clobber (reg:CC FLAGS_REG))])]
4781   "split_di (operands+0, 1, operands+0, operands+3);
4782    split_di (operands+1, 1, operands+1, operands+4);
4783    split_di (operands+2, 1, operands+2, operands+5);")
4784
4785 (define_insn "adddi3_carry_rex64"
4786   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790    (clobber (reg:CC FLAGS_REG))]
4791   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792   "adc{q}\t{%2, %0|%0, %2}"
4793   [(set_attr "type" "alu")
4794    (set_attr "pent_pair" "pu")
4795    (set_attr "mode" "DI")])
4796
4797 (define_insn "*adddi3_cc_rex64"
4798   [(set (reg:CC FLAGS_REG)
4799         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4801                    UNSPEC_ADD_CARRY))
4802    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803         (plus:DI (match_dup 1) (match_dup 2)))]
4804   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805   "add{q}\t{%2, %0|%0, %2}"
4806   [(set_attr "type" "alu")
4807    (set_attr "mode" "DI")])
4808
4809 (define_insn "addqi3_carry"
4810   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813                    (match_operand:QI 2 "general_operand" "qi,qm")))
4814    (clobber (reg:CC FLAGS_REG))]
4815   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816   "adc{b}\t{%2, %0|%0, %2}"
4817   [(set_attr "type" "alu")
4818    (set_attr "pent_pair" "pu")
4819    (set_attr "mode" "QI")])
4820
4821 (define_insn "addhi3_carry"
4822   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825                    (match_operand:HI 2 "general_operand" "ri,rm")))
4826    (clobber (reg:CC FLAGS_REG))]
4827   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828   "adc{w}\t{%2, %0|%0, %2}"
4829   [(set_attr "type" "alu")
4830    (set_attr "pent_pair" "pu")
4831    (set_attr "mode" "HI")])
4832
4833 (define_insn "addsi3_carry"
4834   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837                    (match_operand:SI 2 "general_operand" "ri,rm")))
4838    (clobber (reg:CC FLAGS_REG))]
4839   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840   "adc{l}\t{%2, %0|%0, %2}"
4841   [(set_attr "type" "alu")
4842    (set_attr "pent_pair" "pu")
4843    (set_attr "mode" "SI")])
4844
4845 (define_insn "*addsi3_carry_zext"
4846   [(set (match_operand:DI 0 "register_operand" "=r")
4847           (zero_extend:DI 
4848             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850                      (match_operand:SI 2 "general_operand" "rim"))))
4851    (clobber (reg:CC FLAGS_REG))]
4852   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853   "adc{l}\t{%2, %k0|%k0, %2}"
4854   [(set_attr "type" "alu")
4855    (set_attr "pent_pair" "pu")
4856    (set_attr "mode" "SI")])
4857
4858 (define_insn "*addsi3_cc"
4859   [(set (reg:CC FLAGS_REG)
4860         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861                     (match_operand:SI 2 "general_operand" "ri,rm")]
4862                    UNSPEC_ADD_CARRY))
4863    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864         (plus:SI (match_dup 1) (match_dup 2)))]
4865   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866   "add{l}\t{%2, %0|%0, %2}"
4867   [(set_attr "type" "alu")
4868    (set_attr "mode" "SI")])
4869
4870 (define_insn "addqi3_cc"
4871   [(set (reg:CC FLAGS_REG)
4872         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873                     (match_operand:QI 2 "general_operand" "qi,qm")]
4874                    UNSPEC_ADD_CARRY))
4875    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876         (plus:QI (match_dup 1) (match_dup 2)))]
4877   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878   "add{b}\t{%2, %0|%0, %2}"
4879   [(set_attr "type" "alu")
4880    (set_attr "mode" "QI")])
4881
4882 (define_expand "addsi3"
4883   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885                             (match_operand:SI 2 "general_operand" "")))
4886               (clobber (reg:CC FLAGS_REG))])]
4887   ""
4888   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4889
4890 (define_insn "*lea_1"
4891   [(set (match_operand:SI 0 "register_operand" "=r")
4892         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4893   "!TARGET_64BIT"
4894   "lea{l}\t{%a1, %0|%0, %a1}"
4895   [(set_attr "type" "lea")
4896    (set_attr "mode" "SI")])
4897
4898 (define_insn "*lea_1_rex64"
4899   [(set (match_operand:SI 0 "register_operand" "=r")
4900         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4901   "TARGET_64BIT"
4902   "lea{l}\t{%a1, %0|%0, %a1}"
4903   [(set_attr "type" "lea")
4904    (set_attr "mode" "SI")])
4905
4906 (define_insn "*lea_1_zext"
4907   [(set (match_operand:DI 0 "register_operand" "=r")
4908         (zero_extend:DI
4909          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4910   "TARGET_64BIT"
4911   "lea{l}\t{%a1, %k0|%k0, %a1}"
4912   [(set_attr "type" "lea")
4913    (set_attr "mode" "SI")])
4914
4915 (define_insn "*lea_2_rex64"
4916   [(set (match_operand:DI 0 "register_operand" "=r")
4917         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4918   "TARGET_64BIT"
4919   "lea{q}\t{%a1, %0|%0, %a1}"
4920   [(set_attr "type" "lea")
4921    (set_attr "mode" "DI")])
4922
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4925
4926 (define_insn_and_split "*lea_general_1"
4927   [(set (match_operand 0 "register_operand" "=r")
4928         (plus (plus (match_operand 1 "index_register_operand" "l")
4929                     (match_operand 2 "register_operand" "r"))
4930               (match_operand 3 "immediate_operand" "i")))]
4931   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937        || GET_MODE (operands[3]) == VOIDmode)"
4938   "#"
4939   "&& reload_completed"
4940   [(const_int 0)]
4941 {
4942   rtx pat;
4943   operands[0] = gen_lowpart (SImode, operands[0]);
4944   operands[1] = gen_lowpart (Pmode, operands[1]);
4945   operands[2] = gen_lowpart (Pmode, operands[2]);
4946   operands[3] = gen_lowpart (Pmode, operands[3]);
4947   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4948                       operands[3]);
4949   if (Pmode != SImode)
4950     pat = gen_rtx_SUBREG (SImode, pat, 0);
4951   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4952   DONE;
4953 }
4954   [(set_attr "type" "lea")
4955    (set_attr "mode" "SI")])
4956
4957 (define_insn_and_split "*lea_general_1_zext"
4958   [(set (match_operand:DI 0 "register_operand" "=r")
4959         (zero_extend:DI
4960           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961                             (match_operand:SI 2 "register_operand" "r"))
4962                    (match_operand:SI 3 "immediate_operand" "i"))))]
4963   "TARGET_64BIT"
4964   "#"
4965   "&& reload_completed"
4966   [(set (match_dup 0)
4967         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4968                                                      (match_dup 2))
4969                                             (match_dup 3)) 0)))]
4970 {
4971   operands[1] = gen_lowpart (Pmode, operands[1]);
4972   operands[2] = gen_lowpart (Pmode, operands[2]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975   [(set_attr "type" "lea")
4976    (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_2"
4979   [(set (match_operand 0 "register_operand" "=r")
4980         (plus (mult (match_operand 1 "index_register_operand" "l")
4981                     (match_operand 2 "const248_operand" "i"))
4982               (match_operand 3 "nonmemory_operand" "ri")))]
4983   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988        || GET_MODE (operands[3]) == VOIDmode)"
4989   "#"
4990   "&& reload_completed"
4991   [(const_int 0)]
4992 {
4993   rtx pat;
4994   operands[0] = gen_lowpart (SImode, operands[0]);
4995   operands[1] = gen_lowpart (Pmode, operands[1]);
4996   operands[3] = gen_lowpart (Pmode, operands[3]);
4997   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4998                       operands[3]);
4999   if (Pmode != SImode)
5000     pat = gen_rtx_SUBREG (SImode, pat, 0);
5001   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002   DONE;
5003 }
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2_zext"
5008   [(set (match_operand:DI 0 "register_operand" "=r")
5009         (zero_extend:DI
5010           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011                             (match_operand:SI 2 "const248_operand" "n"))
5012                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5013   "TARGET_64BIT"
5014   "#"
5015   "&& reload_completed"
5016   [(set (match_dup 0)
5017         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5018                                                      (match_dup 2))
5019                                             (match_dup 3)) 0)))]
5020 {
5021   operands[1] = gen_lowpart (Pmode, operands[1]);
5022   operands[3] = gen_lowpart (Pmode, operands[3]);
5023 }
5024   [(set_attr "type" "lea")
5025    (set_attr "mode" "SI")])
5026
5027 (define_insn_and_split "*lea_general_3"
5028   [(set (match_operand 0 "register_operand" "=r")
5029         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030                           (match_operand 2 "const248_operand" "i"))
5031                     (match_operand 3 "register_operand" "r"))
5032               (match_operand 4 "immediate_operand" "i")))]
5033   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5038   "#"
5039   "&& reload_completed"
5040   [(const_int 0)]
5041 {
5042   rtx pat;
5043   operands[0] = gen_lowpart (SImode, operands[0]);
5044   operands[1] = gen_lowpart (Pmode, operands[1]);
5045   operands[3] = gen_lowpart (Pmode, operands[3]);
5046   operands[4] = gen_lowpart (Pmode, operands[4]);
5047   pat = gen_rtx_PLUS (Pmode,
5048                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5049                                                          operands[2]),
5050                                     operands[3]),
5051                       operands[4]);
5052   if (Pmode != SImode)
5053     pat = gen_rtx_SUBREG (SImode, pat, 0);
5054   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5055   DONE;
5056 }
5057   [(set_attr "type" "lea")
5058    (set_attr "mode" "SI")])
5059
5060 (define_insn_and_split "*lea_general_3_zext"
5061   [(set (match_operand:DI 0 "register_operand" "=r")
5062         (zero_extend:DI
5063           (plus:SI (plus:SI (mult:SI
5064                               (match_operand:SI 1 "index_register_operand" "l")
5065                               (match_operand:SI 2 "const248_operand" "n"))
5066                             (match_operand:SI 3 "register_operand" "r"))
5067                    (match_operand:SI 4 "immediate_operand" "i"))))]
5068   "TARGET_64BIT"
5069   "#"
5070   "&& reload_completed"
5071   [(set (match_dup 0)
5072         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5073                                                               (match_dup 2))
5074                                                      (match_dup 3))
5075                                             (match_dup 4)) 0)))]
5076 {
5077   operands[1] = gen_lowpart (Pmode, operands[1]);
5078   operands[3] = gen_lowpart (Pmode, operands[3]);
5079   operands[4] = gen_lowpart (Pmode, operands[4]);
5080 }
5081   [(set_attr "type" "lea")
5082    (set_attr "mode" "SI")])
5083
5084 (define_insn "*adddi_1_rex64"
5085   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088    (clobber (reg:CC FLAGS_REG))]
5089   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5090 {
5091   switch (get_attr_type (insn))
5092     {
5093     case TYPE_LEA:
5094       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095       return "lea{q}\t{%a2, %0|%0, %a2}";
5096
5097     case TYPE_INCDEC:
5098       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099       if (operands[2] == const1_rtx)
5100         return "inc{q}\t%0";
5101       else
5102         {
5103           gcc_assert (operands[2] == constm1_rtx);
5104           return "dec{q}\t%0";
5105         }
5106
5107     default:
5108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5109
5110       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5112       if (GET_CODE (operands[2]) == CONST_INT
5113           /* Avoid overflows.  */
5114           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115           && (INTVAL (operands[2]) == 128
5116               || (INTVAL (operands[2]) < 0
5117                   && INTVAL (operands[2]) != -128)))
5118         {
5119           operands[2] = GEN_INT (-INTVAL (operands[2]));
5120           return "sub{q}\t{%2, %0|%0, %2}";
5121         }
5122       return "add{q}\t{%2, %0|%0, %2}";
5123     }
5124 }
5125   [(set (attr "type")
5126      (cond [(eq_attr "alternative" "2")
5127               (const_string "lea")
5128             ; Current assemblers are broken and do not allow @GOTOFF in
5129             ; ought but a memory context.
5130             (match_operand:DI 2 "pic_symbolic_operand" "")
5131               (const_string "lea")
5132             (match_operand:DI 2 "incdec_operand" "")
5133               (const_string "incdec")
5134            ]
5135            (const_string "alu")))
5136    (set_attr "mode" "DI")])
5137
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5139 (define_split
5140   [(set (match_operand:DI 0 "register_operand" "")
5141         (plus:DI (match_operand:DI 1 "register_operand" "")
5142                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143    (clobber (reg:CC FLAGS_REG))]
5144   "TARGET_64BIT && reload_completed
5145    && true_regnum (operands[0]) != true_regnum (operands[1])"
5146   [(set (match_dup 0)
5147         (plus:DI (match_dup 1)
5148                  (match_dup 2)))]
5149   "")
5150
5151 (define_insn "*adddi_2_rex64"
5152   [(set (reg FLAGS_REG)
5153         (compare
5154           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5156           (const_int 0)))                       
5157    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158         (plus:DI (match_dup 1) (match_dup 2)))]
5159   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160    && ix86_binary_operator_ok (PLUS, DImode, operands)
5161    /* Current assemblers are broken and do not allow @GOTOFF in
5162       ought but a memory context.  */
5163    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164 {
5165   switch (get_attr_type (insn))
5166     {
5167     case TYPE_INCDEC:
5168       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169       if (operands[2] == const1_rtx)
5170         return "inc{q}\t%0";
5171       else
5172         {
5173           gcc_assert (operands[2] == constm1_rtx);
5174           return "dec{q}\t%0";
5175         }
5176
5177     default:
5178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179       /* ???? We ought to handle there the 32bit case too
5180          - do we need new constraint?  */
5181       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5183       if (GET_CODE (operands[2]) == CONST_INT
5184           /* Avoid overflows.  */
5185           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186           && (INTVAL (operands[2]) == 128
5187               || (INTVAL (operands[2]) < 0
5188                   && INTVAL (operands[2]) != -128)))
5189         {
5190           operands[2] = GEN_INT (-INTVAL (operands[2]));
5191           return "sub{q}\t{%2, %0|%0, %2}";
5192         }
5193       return "add{q}\t{%2, %0|%0, %2}";
5194     }
5195 }
5196   [(set (attr "type")
5197      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198         (const_string "incdec")
5199         (const_string "alu")))
5200    (set_attr "mode" "DI")])
5201
5202 (define_insn "*adddi_3_rex64"
5203   [(set (reg FLAGS_REG)
5204         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206    (clobber (match_scratch:DI 0 "=r"))]
5207   "TARGET_64BIT
5208    && ix86_match_ccmode (insn, CCZmode)
5209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210    /* Current assemblers are broken and do not allow @GOTOFF in
5211       ought but a memory context.  */
5212    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 {
5214   switch (get_attr_type (insn))
5215     {
5216     case TYPE_INCDEC:
5217       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218       if (operands[2] == const1_rtx)
5219         return "inc{q}\t%0";
5220       else
5221         {
5222           gcc_assert (operands[2] == constm1_rtx);
5223           return "dec{q}\t%0";
5224         }
5225
5226     default:
5227       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228       /* ???? We ought to handle there the 32bit case too
5229          - do we need new constraint?  */
5230       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5232       if (GET_CODE (operands[2]) == CONST_INT
5233           /* Avoid overflows.  */
5234           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235           && (INTVAL (operands[2]) == 128
5236               || (INTVAL (operands[2]) < 0
5237                   && INTVAL (operands[2]) != -128)))
5238         {
5239           operands[2] = GEN_INT (-INTVAL (operands[2]));
5240           return "sub{q}\t{%2, %0|%0, %2}";
5241         }
5242       return "add{q}\t{%2, %0|%0, %2}";
5243     }
5244 }
5245   [(set (attr "type")
5246      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247         (const_string "incdec")
5248         (const_string "alu")))
5249    (set_attr "mode" "DI")])
5250
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5253 ; is matched then.  We can't accept general immediate, because for
5254 ; case of overflows,  the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5256 ; when negated.
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260   [(set (reg FLAGS_REG)
5261         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263    (clobber (match_scratch:DI 0 "=rm"))]
5264   "TARGET_64BIT
5265    &&  ix86_match_ccmode (insn, CCGCmode)"
5266 {
5267   switch (get_attr_type (insn))
5268     {
5269     case TYPE_INCDEC:
5270       if (operands[2] == constm1_rtx)
5271         return "inc{q}\t%0";
5272       else
5273         {
5274           gcc_assert (operands[2] == const1_rtx);
5275           return "dec{q}\t%0";
5276         }
5277
5278     default:
5279       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5282       if ((INTVAL (operands[2]) == -128
5283            || (INTVAL (operands[2]) > 0
5284                && INTVAL (operands[2]) != 128))
5285           /* Avoid overflows.  */
5286           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287         return "sub{q}\t{%2, %0|%0, %2}";
5288       operands[2] = GEN_INT (-INTVAL (operands[2]));
5289       return "add{q}\t{%2, %0|%0, %2}";
5290     }
5291 }
5292   [(set (attr "type")
5293      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294         (const_string "incdec")
5295         (const_string "alu")))
5296    (set_attr "mode" "DI")])
5297
5298 (define_insn "*adddi_5_rex64"
5299   [(set (reg FLAGS_REG)
5300         (compare
5301           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5303           (const_int 0)))                       
5304    (clobber (match_scratch:DI 0 "=r"))]
5305   "TARGET_64BIT
5306    && ix86_match_ccmode (insn, CCGOCmode)
5307    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308    /* Current assemblers are broken and do not allow @GOTOFF in
5309       ought but a memory context.  */
5310    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5311 {
5312   switch (get_attr_type (insn))
5313     {
5314     case TYPE_INCDEC:
5315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else
5319         {
5320           gcc_assert (operands[2] == constm1_rtx);
5321           return "dec{q}\t%0";
5322         }
5323
5324     default:
5325       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5328       if (GET_CODE (operands[2]) == CONST_INT
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331           && (INTVAL (operands[2]) == 128
5332               || (INTVAL (operands[2]) < 0
5333                   && INTVAL (operands[2]) != -128)))
5334         {
5335           operands[2] = GEN_INT (-INTVAL (operands[2]));
5336           return "sub{q}\t{%2, %0|%0, %2}";
5337         }
5338       return "add{q}\t{%2, %0|%0, %2}";
5339     }
5340 }
5341   [(set (attr "type")
5342      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343         (const_string "incdec")
5344         (const_string "alu")))
5345    (set_attr "mode" "DI")])
5346
5347
5348 (define_insn "*addsi_1"
5349   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352    (clobber (reg:CC FLAGS_REG))]
5353   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5354 {
5355   switch (get_attr_type (insn))
5356     {
5357     case TYPE_LEA:
5358       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359       return "lea{l}\t{%a2, %0|%0, %a2}";
5360
5361     case TYPE_INCDEC:
5362       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363       if (operands[2] == const1_rtx)
5364         return "inc{l}\t%0";
5365       else
5366         {
5367           gcc_assert (operands[2] == constm1_rtx);
5368           return "dec{l}\t%0";
5369         }
5370
5371     default:
5372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373
5374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5376       if (GET_CODE (operands[2]) == CONST_INT
5377           && (INTVAL (operands[2]) == 128
5378               || (INTVAL (operands[2]) < 0
5379                   && INTVAL (operands[2]) != -128)))
5380         {
5381           operands[2] = GEN_INT (-INTVAL (operands[2]));
5382           return "sub{l}\t{%2, %0|%0, %2}";
5383         }
5384       return "add{l}\t{%2, %0|%0, %2}";
5385     }
5386 }
5387   [(set (attr "type")
5388      (cond [(eq_attr "alternative" "2")
5389               (const_string "lea")
5390             ; Current assemblers are broken and do not allow @GOTOFF in
5391             ; ought but a memory context.
5392             (match_operand:SI 2 "pic_symbolic_operand" "")
5393               (const_string "lea")
5394             (match_operand:SI 2 "incdec_operand" "")
5395               (const_string "incdec")
5396            ]
5397            (const_string "alu")))
5398    (set_attr "mode" "SI")])
5399
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5401 (define_split
5402   [(set (match_operand 0 "register_operand" "")
5403         (plus (match_operand 1 "register_operand" "")
5404               (match_operand 2 "nonmemory_operand" "")))
5405    (clobber (reg:CC FLAGS_REG))]
5406   "reload_completed
5407    && true_regnum (operands[0]) != true_regnum (operands[1])"
5408   [(const_int 0)]
5409 {
5410   rtx pat;
5411   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412      may confuse gen_lowpart.  */
5413   if (GET_MODE (operands[0]) != Pmode)
5414     {
5415       operands[1] = gen_lowpart (Pmode, operands[1]);
5416       operands[2] = gen_lowpart (Pmode, operands[2]);
5417     }
5418   operands[0] = gen_lowpart (SImode, operands[0]);
5419   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420   if (Pmode != SImode)
5421     pat = gen_rtx_SUBREG (SImode, pat, 0);
5422   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5423   DONE;
5424 })
5425
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload.  This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432   [(set (match_operand:DI 0 "register_operand" "=r,r")
5433         (zero_extend:DI
5434           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436    (clobber (reg:CC FLAGS_REG))]
5437   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439   switch (get_attr_type (insn))
5440     {
5441     case TYPE_LEA:
5442       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5444
5445     case TYPE_INCDEC:
5446       if (operands[2] == const1_rtx)
5447         return "inc{l}\t%k0";
5448       else
5449         {
5450           gcc_assert (operands[2] == constm1_rtx);
5451           return "dec{l}\t%k0";
5452         }
5453
5454     default:
5455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5457       if (GET_CODE (operands[2]) == CONST_INT
5458           && (INTVAL (operands[2]) == 128
5459               || (INTVAL (operands[2]) < 0
5460                   && INTVAL (operands[2]) != -128)))
5461         {
5462           operands[2] = GEN_INT (-INTVAL (operands[2]));
5463           return "sub{l}\t{%2, %k0|%k0, %2}";
5464         }
5465       return "add{l}\t{%2, %k0|%k0, %2}";
5466     }
5467 }
5468   [(set (attr "type")
5469      (cond [(eq_attr "alternative" "1")
5470               (const_string "lea")
5471             ; Current assemblers are broken and do not allow @GOTOFF in
5472             ; ought but a memory context.
5473             (match_operand:SI 2 "pic_symbolic_operand" "")
5474               (const_string "lea")
5475             (match_operand:SI 2 "incdec_operand" "")
5476               (const_string "incdec")
5477            ]
5478            (const_string "alu")))
5479    (set_attr "mode" "SI")])
5480
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483   [(set (match_operand:DI 0 "register_operand" "")
5484         (zero_extend:DI
5485           (plus:SI (match_operand:SI 1 "register_operand" "")
5486                    (match_operand:SI 2 "nonmemory_operand" ""))))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "TARGET_64BIT && reload_completed
5489    && true_regnum (operands[0]) != true_regnum (operands[1])"
5490   [(set (match_dup 0)
5491         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5492 {
5493   operands[1] = gen_lowpart (Pmode, operands[1]);
5494   operands[2] = gen_lowpart (Pmode, operands[2]);
5495 })
5496
5497 (define_insn "*addsi_2"
5498   [(set (reg FLAGS_REG)
5499         (compare
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5502           (const_int 0)))                       
5503    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504         (plus:SI (match_dup 1) (match_dup 2)))]
5505   "ix86_match_ccmode (insn, CCGOCmode)
5506    && ix86_binary_operator_ok (PLUS, SImode, operands)
5507    /* Current assemblers are broken and do not allow @GOTOFF in
5508       ought but a memory context.  */
5509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_INCDEC:
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (operands[2] == const1_rtx)
5516         return "inc{l}\t%0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{l}\t%0";
5521         }
5522
5523     default:
5524       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5527       if (GET_CODE (operands[2]) == CONST_INT
5528           && (INTVAL (operands[2]) == 128
5529               || (INTVAL (operands[2]) < 0
5530                   && INTVAL (operands[2]) != -128)))
5531         {
5532           operands[2] = GEN_INT (-INTVAL (operands[2]));
5533           return "sub{l}\t{%2, %0|%0, %2}";
5534         }
5535       return "add{l}\t{%2, %0|%0, %2}";
5536     }
5537 }
5538   [(set (attr "type")
5539      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540         (const_string "incdec")
5541         (const_string "alu")))
5542    (set_attr "mode" "SI")])
5543
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546   [(set (reg FLAGS_REG)
5547         (compare
5548           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549                    (match_operand:SI 2 "general_operand" "rmni"))
5550           (const_int 0)))                       
5551    (set (match_operand:DI 0 "register_operand" "=r")
5552         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554    && ix86_binary_operator_ok (PLUS, SImode, operands)
5555    /* Current assemblers are broken and do not allow @GOTOFF in
5556       ought but a memory context.  */
5557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       if (operands[2] == const1_rtx)
5563         return "inc{l}\t%k0";
5564       else
5565         {
5566           gcc_assert (operands[2] == constm1_rtx);
5567           return "dec{l}\t%k0";
5568         }
5569
5570     default:
5571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5573       if (GET_CODE (operands[2]) == CONST_INT
5574           && (INTVAL (operands[2]) == 128
5575               || (INTVAL (operands[2]) < 0
5576                   && INTVAL (operands[2]) != -128)))
5577         {
5578           operands[2] = GEN_INT (-INTVAL (operands[2]));
5579           return "sub{l}\t{%2, %k0|%k0, %2}";
5580         }
5581       return "add{l}\t{%2, %k0|%k0, %2}";
5582     }
5583 }
5584   [(set (attr "type")
5585      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586         (const_string "incdec")
5587         (const_string "alu")))
5588    (set_attr "mode" "SI")])
5589
5590 (define_insn "*addsi_3"
5591   [(set (reg FLAGS_REG)
5592         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594    (clobber (match_scratch:SI 0 "=r"))]
5595   "ix86_match_ccmode (insn, CCZmode)
5596    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597    /* Current assemblers are broken and do not allow @GOTOFF in
5598       ought but a memory context.  */
5599    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5600 {
5601   switch (get_attr_type (insn))
5602     {
5603     case TYPE_INCDEC:
5604       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605       if (operands[2] == const1_rtx)
5606         return "inc{l}\t%0";
5607       else
5608         {
5609           gcc_assert (operands[2] == constm1_rtx);
5610           return "dec{l}\t%0";
5611         }
5612
5613     default:
5614       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5617       if (GET_CODE (operands[2]) == CONST_INT
5618           && (INTVAL (operands[2]) == 128
5619               || (INTVAL (operands[2]) < 0
5620                   && INTVAL (operands[2]) != -128)))
5621         {
5622           operands[2] = GEN_INT (-INTVAL (operands[2]));
5623           return "sub{l}\t{%2, %0|%0, %2}";
5624         }
5625       return "add{l}\t{%2, %0|%0, %2}";
5626     }
5627 }
5628   [(set (attr "type")
5629      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630         (const_string "incdec")
5631         (const_string "alu")))
5632    (set_attr "mode" "SI")])
5633
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636   [(set (reg FLAGS_REG)
5637         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639    (set (match_operand:DI 0 "register_operand" "=r")
5640         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642    && ix86_binary_operator_ok (PLUS, SImode, operands)
5643    /* Current assemblers are broken and do not allow @GOTOFF in
5644       ought but a memory context.  */
5645    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647   switch (get_attr_type (insn))
5648     {
5649     case TYPE_INCDEC:
5650       if (operands[2] == const1_rtx)
5651         return "inc{l}\t%k0";
5652       else
5653         {
5654           gcc_assert (operands[2] == constm1_rtx);
5655           return "dec{l}\t%k0";
5656         }
5657
5658     default:
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %k0|%k0, %2}";
5668         }
5669       return "add{l}\t{%2, %k0|%k0, %2}";
5670     }
5671 }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5677
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5680 ; is matched then.  We can't accept general immediate, because for
5681 ; case of overflows,  the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687   [(set (reg FLAGS_REG)
5688         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689                  (match_operand:SI 2 "const_int_operand" "n")))
5690    (clobber (match_scratch:SI 0 "=rm"))]
5691   "ix86_match_ccmode (insn, CCGCmode)
5692    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5693 {
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_INCDEC:
5697       if (operands[2] == constm1_rtx)
5698         return "inc{l}\t%0";
5699       else
5700         {
5701           gcc_assert (operands[2] == const1_rtx);
5702           return "dec{l}\t%0";
5703         }
5704
5705     default:
5706       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5709       if ((INTVAL (operands[2]) == -128
5710            || (INTVAL (operands[2]) > 0
5711                && INTVAL (operands[2]) != 128)))
5712         return "sub{l}\t{%2, %0|%0, %2}";
5713       operands[2] = GEN_INT (-INTVAL (operands[2]));
5714       return "add{l}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set_attr "mode" "SI")])
5722
5723 (define_insn "*addsi_5"
5724   [(set (reg FLAGS_REG)
5725         (compare
5726           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727                    (match_operand:SI 2 "general_operand" "rmni"))
5728           (const_int 0)))                       
5729    (clobber (match_scratch:SI 0 "=r"))]
5730   "ix86_match_ccmode (insn, CCGOCmode)
5731    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732    /* Current assemblers are broken and do not allow @GOTOFF in
5733       ought but a memory context.  */
5734    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736   switch (get_attr_type (insn))
5737     {
5738     case TYPE_INCDEC:
5739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740       if (operands[2] == const1_rtx)
5741         return "inc{l}\t%0";
5742       else
5743         {
5744           gcc_assert (operands[2] == constm1_rtx);
5745           return "dec{l}\t%0";
5746         }
5747
5748     default:
5749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5752       if (GET_CODE (operands[2]) == CONST_INT
5753           && (INTVAL (operands[2]) == 128
5754               || (INTVAL (operands[2]) < 0
5755                   && INTVAL (operands[2]) != -128)))
5756         {
5757           operands[2] = GEN_INT (-INTVAL (operands[2]));
5758           return "sub{l}\t{%2, %0|%0, %2}";
5759         }
5760       return "add{l}\t{%2, %0|%0, %2}";
5761     }
5762 }
5763   [(set (attr "type")
5764      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765         (const_string "incdec")
5766         (const_string "alu")))
5767    (set_attr "mode" "SI")])
5768
5769 (define_expand "addhi3"
5770   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772                             (match_operand:HI 2 "general_operand" "")))
5773               (clobber (reg:CC FLAGS_REG))])]
5774   "TARGET_HIMODE_MATH"
5775   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5776
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits.  This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5780
5781 (define_insn "*addhi_1_lea"
5782   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785    (clobber (reg:CC FLAGS_REG))]
5786   "!TARGET_PARTIAL_REG_STALL
5787    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5788 {
5789   switch (get_attr_type (insn))
5790     {
5791     case TYPE_LEA:
5792       return "#";
5793     case TYPE_INCDEC:
5794       if (operands[2] == const1_rtx)
5795         return "inc{w}\t%0";
5796       else
5797         {
5798           gcc_assert (operands[2] == constm1_rtx);
5799           return "dec{w}\t%0";
5800         }
5801
5802     default:
5803       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5805       if (GET_CODE (operands[2]) == CONST_INT
5806           && (INTVAL (operands[2]) == 128
5807               || (INTVAL (operands[2]) < 0
5808                   && INTVAL (operands[2]) != -128)))
5809         {
5810           operands[2] = GEN_INT (-INTVAL (operands[2]));
5811           return "sub{w}\t{%2, %0|%0, %2}";
5812         }
5813       return "add{w}\t{%2, %0|%0, %2}";
5814     }
5815 }
5816   [(set (attr "type")
5817      (if_then_else (eq_attr "alternative" "2")
5818         (const_string "lea")
5819         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820            (const_string "incdec")
5821            (const_string "alu"))))
5822    (set_attr "mode" "HI,HI,SI")])
5823
5824 (define_insn "*addhi_1"
5825   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827                  (match_operand:HI 2 "general_operand" "ri,rm")))
5828    (clobber (reg:CC FLAGS_REG))]
5829   "TARGET_PARTIAL_REG_STALL
5830    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5831 {
5832   switch (get_attr_type (insn))
5833     {
5834     case TYPE_INCDEC:
5835       if (operands[2] == const1_rtx)
5836         return "inc{w}\t%0";
5837       else
5838         {
5839           gcc_assert (operands[2] == constm1_rtx);
5840           return "dec{w}\t%0";
5841         }
5842
5843     default:
5844       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5846       if (GET_CODE (operands[2]) == CONST_INT
5847           && (INTVAL (operands[2]) == 128
5848               || (INTVAL (operands[2]) < 0
5849                   && INTVAL (operands[2]) != -128)))
5850         {
5851           operands[2] = GEN_INT (-INTVAL (operands[2]));
5852           return "sub{w}\t{%2, %0|%0, %2}";
5853         }
5854       return "add{w}\t{%2, %0|%0, %2}";
5855     }
5856 }
5857   [(set (attr "type")
5858      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859         (const_string "incdec")
5860         (const_string "alu")))
5861    (set_attr "mode" "HI")])
5862
5863 (define_insn "*addhi_2"
5864   [(set (reg FLAGS_REG)
5865         (compare
5866           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5868           (const_int 0)))                       
5869    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870         (plus:HI (match_dup 1) (match_dup 2)))]
5871   "ix86_match_ccmode (insn, CCGOCmode)
5872    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{w}\t%0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{w}\t%0";
5883         }
5884
5885     default:
5886       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5888       if (GET_CODE (operands[2]) == CONST_INT
5889           && (INTVAL (operands[2]) == 128
5890               || (INTVAL (operands[2]) < 0
5891                   && INTVAL (operands[2]) != -128)))
5892         {
5893           operands[2] = GEN_INT (-INTVAL (operands[2]));
5894           return "sub{w}\t{%2, %0|%0, %2}";
5895         }
5896       return "add{w}\t{%2, %0|%0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "HI")])
5904
5905 (define_insn "*addhi_3"
5906   [(set (reg FLAGS_REG)
5907         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909    (clobber (match_scratch:HI 0 "=r"))]
5910   "ix86_match_ccmode (insn, CCZmode)
5911    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5912 {
5913   switch (get_attr_type (insn))
5914     {
5915     case TYPE_INCDEC:
5916       if (operands[2] == const1_rtx)
5917         return "inc{w}\t%0";
5918       else
5919         {
5920           gcc_assert (operands[2] == constm1_rtx);
5921           return "dec{w}\t%0";
5922         }
5923
5924     default:
5925       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5927       if (GET_CODE (operands[2]) == CONST_INT
5928           && (INTVAL (operands[2]) == 128
5929               || (INTVAL (operands[2]) < 0
5930                   && INTVAL (operands[2]) != -128)))
5931         {
5932           operands[2] = GEN_INT (-INTVAL (operands[2]));
5933           return "sub{w}\t{%2, %0|%0, %2}";
5934         }
5935       return "add{w}\t{%2, %0|%0, %2}";
5936     }
5937 }
5938   [(set (attr "type")
5939      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940         (const_string "incdec")
5941         (const_string "alu")))
5942    (set_attr "mode" "HI")])
5943
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946   [(set (reg FLAGS_REG)
5947         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948                  (match_operand:HI 2 "const_int_operand" "n")))
5949    (clobber (match_scratch:HI 0 "=rm"))]
5950   "ix86_match_ccmode (insn, CCGCmode)
5951    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5952 {
5953   switch (get_attr_type (insn))
5954     {
5955     case TYPE_INCDEC:
5956       if (operands[2] == constm1_rtx)
5957         return "inc{w}\t%0";
5958       else
5959         {
5960           gcc_assert (operands[2] == const1_rtx);
5961           return "dec{w}\t%0";
5962         }
5963
5964     default:
5965       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5968       if ((INTVAL (operands[2]) == -128
5969            || (INTVAL (operands[2]) > 0
5970                && INTVAL (operands[2]) != 128)))
5971         return "sub{w}\t{%2, %0|%0, %2}";
5972       operands[2] = GEN_INT (-INTVAL (operands[2]));
5973       return "add{w}\t{%2, %0|%0, %2}";
5974     }
5975 }
5976   [(set (attr "type")
5977      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978         (const_string "incdec")
5979         (const_string "alu")))
5980    (set_attr "mode" "SI")])
5981
5982
5983 (define_insn "*addhi_5"
5984   [(set (reg FLAGS_REG)
5985         (compare
5986           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987                    (match_operand:HI 2 "general_operand" "rmni"))
5988           (const_int 0)))                       
5989    (clobber (match_scratch:HI 0 "=r"))]
5990   "ix86_match_ccmode (insn, CCGOCmode)
5991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5992 {
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_INCDEC:
5996       if (operands[2] == const1_rtx)
5997         return "inc{w}\t%0";
5998       else
5999         {
6000           gcc_assert (operands[2] == constm1_rtx);
6001           return "dec{w}\t%0";
6002         }
6003
6004     default:
6005       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6007       if (GET_CODE (operands[2]) == CONST_INT
6008           && (INTVAL (operands[2]) == 128
6009               || (INTVAL (operands[2]) < 0
6010                   && INTVAL (operands[2]) != -128)))
6011         {
6012           operands[2] = GEN_INT (-INTVAL (operands[2]));
6013           return "sub{w}\t{%2, %0|%0, %2}";
6014         }
6015       return "add{w}\t{%2, %0|%0, %2}";
6016     }
6017 }
6018   [(set (attr "type")
6019      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020         (const_string "incdec")
6021         (const_string "alu")))
6022    (set_attr "mode" "HI")])
6023
6024 (define_expand "addqi3"
6025   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027                             (match_operand:QI 2 "general_operand" "")))
6028               (clobber (reg:CC FLAGS_REG))])]
6029   "TARGET_QIMODE_MATH"
6030   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6031
6032 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6033 (define_insn "*addqi_1_lea"
6034   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037    (clobber (reg:CC FLAGS_REG))]
6038   "!TARGET_PARTIAL_REG_STALL
6039    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6040 {
6041   int widen = (which_alternative == 2);
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_LEA:
6045       return "#";
6046     case TYPE_INCDEC:
6047       if (operands[2] == const1_rtx)
6048         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6049       else
6050         {
6051           gcc_assert (operands[2] == constm1_rtx);
6052           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6053         }
6054
6055     default:
6056       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6058       if (GET_CODE (operands[2]) == CONST_INT
6059           && (INTVAL (operands[2]) == 128
6060               || (INTVAL (operands[2]) < 0
6061                   && INTVAL (operands[2]) != -128)))
6062         {
6063           operands[2] = GEN_INT (-INTVAL (operands[2]));
6064           if (widen)
6065             return "sub{l}\t{%2, %k0|%k0, %2}";
6066           else
6067             return "sub{b}\t{%2, %0|%0, %2}";
6068         }
6069       if (widen)
6070         return "add{l}\t{%k2, %k0|%k0, %k2}";
6071       else
6072         return "add{b}\t{%2, %0|%0, %2}";
6073     }
6074 }
6075   [(set (attr "type")
6076      (if_then_else (eq_attr "alternative" "3")
6077         (const_string "lea")
6078         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079            (const_string "incdec")
6080            (const_string "alu"))))
6081    (set_attr "mode" "QI,QI,SI,SI")])
6082
6083 (define_insn "*addqi_1"
6084   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087    (clobber (reg:CC FLAGS_REG))]
6088   "TARGET_PARTIAL_REG_STALL
6089    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6090 {
6091   int widen = (which_alternative == 2);
6092   switch (get_attr_type (insn))
6093     {
6094     case TYPE_INCDEC:
6095       if (operands[2] == const1_rtx)
6096         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6097       else
6098         {
6099           gcc_assert (operands[2] == constm1_rtx);
6100           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6101         }
6102
6103     default:
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if (GET_CODE (operands[2]) == CONST_INT
6107           && (INTVAL (operands[2]) == 128
6108               || (INTVAL (operands[2]) < 0
6109                   && INTVAL (operands[2]) != -128)))
6110         {
6111           operands[2] = GEN_INT (-INTVAL (operands[2]));
6112           if (widen)
6113             return "sub{l}\t{%2, %k0|%k0, %2}";
6114           else
6115             return "sub{b}\t{%2, %0|%0, %2}";
6116         }
6117       if (widen)
6118         return "add{l}\t{%k2, %k0|%k0, %k2}";
6119       else
6120         return "add{b}\t{%2, %0|%0, %2}";
6121     }
6122 }
6123   [(set (attr "type")
6124      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125         (const_string "incdec")
6126         (const_string "alu")))
6127    (set_attr "mode" "QI,QI,SI")])
6128
6129 (define_insn "*addqi_1_slp"
6130   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131         (plus:QI (match_dup 0)
6132                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6133    (clobber (reg:CC FLAGS_REG))]
6134   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6136 {
6137   switch (get_attr_type (insn))
6138     {
6139     case TYPE_INCDEC:
6140       if (operands[1] == const1_rtx)
6141         return "inc{b}\t%0";
6142       else
6143         {
6144           gcc_assert (operands[1] == constm1_rtx);
6145           return "dec{b}\t%0";
6146         }
6147
6148     default:
6149       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6150       if (GET_CODE (operands[1]) == CONST_INT
6151           && INTVAL (operands[1]) < 0)
6152         {
6153           operands[1] = GEN_INT (-INTVAL (operands[1]));
6154           return "sub{b}\t{%1, %0|%0, %1}";
6155         }
6156       return "add{b}\t{%1, %0|%0, %1}";
6157     }
6158 }
6159   [(set (attr "type")
6160      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161         (const_string "incdec")
6162         (const_string "alu1")))
6163    (set (attr "memory")
6164      (if_then_else (match_operand 1 "memory_operand" "")
6165         (const_string "load")
6166         (const_string "none")))
6167    (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_2"
6170   [(set (reg FLAGS_REG)
6171         (compare
6172           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6174           (const_int 0)))
6175    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176         (plus:QI (match_dup 1) (match_dup 2)))]
6177   "ix86_match_ccmode (insn, CCGOCmode)
6178    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6179 {
6180   switch (get_attr_type (insn))
6181     {
6182     case TYPE_INCDEC:
6183       if (operands[2] == const1_rtx)
6184         return "inc{b}\t%0";
6185       else
6186         {
6187           gcc_assert (operands[2] == constm1_rtx
6188                       || (GET_CODE (operands[2]) == CONST_INT
6189                           && INTVAL (operands[2]) == 255));
6190           return "dec{b}\t%0";
6191         }
6192
6193     default:
6194       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6195       if (GET_CODE (operands[2]) == CONST_INT
6196           && INTVAL (operands[2]) < 0)
6197         {
6198           operands[2] = GEN_INT (-INTVAL (operands[2]));
6199           return "sub{b}\t{%2, %0|%0, %2}";
6200         }
6201       return "add{b}\t{%2, %0|%0, %2}";
6202     }
6203 }
6204   [(set (attr "type")
6205      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206         (const_string "incdec")
6207         (const_string "alu")))
6208    (set_attr "mode" "QI")])
6209
6210 (define_insn "*addqi_3"
6211   [(set (reg FLAGS_REG)
6212         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214    (clobber (match_scratch:QI 0 "=q"))]
6215   "ix86_match_ccmode (insn, CCZmode)
6216    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6217 {
6218   switch (get_attr_type (insn))
6219     {
6220     case TYPE_INCDEC:
6221       if (operands[2] == const1_rtx)
6222         return "inc{b}\t%0";
6223       else
6224         {
6225           gcc_assert (operands[2] == constm1_rtx
6226                       || (GET_CODE (operands[2]) == CONST_INT
6227                           && INTVAL (operands[2]) == 255));
6228           return "dec{b}\t%0";
6229         }
6230
6231     default:
6232       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6233       if (GET_CODE (operands[2]) == CONST_INT
6234           && INTVAL (operands[2]) < 0)
6235         {
6236           operands[2] = GEN_INT (-INTVAL (operands[2]));
6237           return "sub{b}\t{%2, %0|%0, %2}";
6238         }
6239       return "add{b}\t{%2, %0|%0, %2}";
6240     }
6241 }
6242   [(set (attr "type")
6243      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244         (const_string "incdec")
6245         (const_string "alu")))
6246    (set_attr "mode" "QI")])
6247
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250   [(set (reg FLAGS_REG)
6251         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252                  (match_operand:QI 2 "const_int_operand" "n")))
6253    (clobber (match_scratch:QI 0 "=qm"))]
6254   "ix86_match_ccmode (insn, CCGCmode)
6255    && (INTVAL (operands[2]) & 0xff) != 0x80"
6256 {
6257   switch (get_attr_type (insn))
6258     {
6259     case TYPE_INCDEC:
6260       if (operands[2] == constm1_rtx
6261           || (GET_CODE (operands[2]) == CONST_INT
6262               && INTVAL (operands[2]) == 255))
6263         return "inc{b}\t%0";
6264       else
6265         {
6266           gcc_assert (operands[2] == const1_rtx);
6267           return "dec{b}\t%0";
6268         }
6269
6270     default:
6271       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272       if (INTVAL (operands[2]) < 0)
6273         {
6274           operands[2] = GEN_INT (-INTVAL (operands[2]));
6275           return "add{b}\t{%2, %0|%0, %2}";
6276         }
6277       return "sub{b}\t{%2, %0|%0, %2}";
6278     }
6279 }
6280   [(set (attr "type")
6281      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282         (const_string "incdec")
6283         (const_string "alu")))
6284    (set_attr "mode" "QI")])
6285
6286
6287 (define_insn "*addqi_5"
6288   [(set (reg FLAGS_REG)
6289         (compare
6290           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291                    (match_operand:QI 2 "general_operand" "qmni"))
6292           (const_int 0)))
6293    (clobber (match_scratch:QI 0 "=q"))]
6294   "ix86_match_ccmode (insn, CCGOCmode)
6295    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6296 {
6297   switch (get_attr_type (insn))
6298     {
6299     case TYPE_INCDEC:
6300       if (operands[2] == const1_rtx)
6301         return "inc{b}\t%0";
6302       else
6303         {
6304           gcc_assert (operands[2] == constm1_rtx
6305                       || (GET_CODE (operands[2]) == CONST_INT
6306                           && INTVAL (operands[2]) == 255));
6307           return "dec{b}\t%0";
6308         }
6309
6310     default:
6311       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6312       if (GET_CODE (operands[2]) == CONST_INT
6313           && INTVAL (operands[2]) < 0)
6314         {
6315           operands[2] = GEN_INT (-INTVAL (operands[2]));
6316           return "sub{b}\t{%2, %0|%0, %2}";
6317         }
6318       return "add{b}\t{%2, %0|%0, %2}";
6319     }
6320 }
6321   [(set (attr "type")
6322      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323         (const_string "incdec")
6324         (const_string "alu")))
6325    (set_attr "mode" "QI")])
6326
6327
6328 (define_insn "addqi_ext_1"
6329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6330                          (const_int 8)
6331                          (const_int 8))
6332         (plus:SI
6333           (zero_extract:SI
6334             (match_operand 1 "ext_register_operand" "0")
6335             (const_int 8)
6336             (const_int 8))
6337           (match_operand:QI 2 "general_operand" "Qmn")))
6338    (clobber (reg:CC FLAGS_REG))]
6339   "!TARGET_64BIT"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == const1_rtx)
6345         return "inc{b}\t%h0";
6346       else
6347         {
6348           gcc_assert (operands[2] == constm1_rtx
6349                       || (GET_CODE (operands[2]) == CONST_INT
6350                           && INTVAL (operands[2]) == 255));
6351           return "dec{b}\t%h0";
6352         }
6353
6354     default:
6355       return "add{b}\t{%2, %h0|%h0, %2}";
6356     }
6357 }
6358   [(set (attr "type")
6359      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360         (const_string "incdec")
6361         (const_string "alu")))
6362    (set_attr "mode" "QI")])
6363
6364 (define_insn "*addqi_ext_1_rex64"
6365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366                          (const_int 8)
6367                          (const_int 8))
6368         (plus:SI
6369           (zero_extract:SI
6370             (match_operand 1 "ext_register_operand" "0")
6371             (const_int 8)
6372             (const_int 8))
6373           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "TARGET_64BIT"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%h0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx
6385                       || (GET_CODE (operands[2]) == CONST_INT
6386                           && INTVAL (operands[2]) == 255));
6387           return "dec{b}\t%h0";
6388         }
6389
6390     default:
6391       return "add{b}\t{%2, %h0|%h0, %2}";
6392     }
6393 }
6394   [(set (attr "type")
6395      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396         (const_string "incdec")
6397         (const_string "alu")))
6398    (set_attr "mode" "QI")])
6399
6400 (define_insn "*addqi_ext_2"
6401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402                          (const_int 8)
6403                          (const_int 8))
6404         (plus:SI
6405           (zero_extract:SI
6406             (match_operand 1 "ext_register_operand" "%0")
6407             (const_int 8)
6408             (const_int 8))
6409           (zero_extract:SI
6410             (match_operand 2 "ext_register_operand" "Q")
6411             (const_int 8)
6412             (const_int 8))))
6413    (clobber (reg:CC FLAGS_REG))]
6414   ""
6415   "add{b}\t{%h2, %h0|%h0, %h2}"
6416   [(set_attr "type" "alu")
6417    (set_attr "mode" "QI")])
6418
6419 ;; The patterns that match these are at the end of this file.
6420
6421 (define_expand "addxf3"
6422   [(set (match_operand:XF 0 "register_operand" "")
6423         (plus:XF (match_operand:XF 1 "register_operand" "")
6424                  (match_operand:XF 2 "register_operand" "")))]
6425   "TARGET_80387"
6426   "")
6427
6428 (define_expand "adddf3"
6429   [(set (match_operand:DF 0 "register_operand" "")
6430         (plus:DF (match_operand:DF 1 "register_operand" "")
6431                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6432   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6433   "")
6434
6435 (define_expand "addsf3"
6436   [(set (match_operand:SF 0 "register_operand" "")
6437         (plus:SF (match_operand:SF 1 "register_operand" "")
6438                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6439   "TARGET_80387 || TARGET_SSE_MATH"
6440   "")
6441 \f
6442 ;; Subtract instructions
6443
6444 ;; %%% splits for subditi3
6445
6446 (define_expand "subti3"
6447   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449                              (match_operand:TI 2 "x86_64_general_operand" "")))
6450               (clobber (reg:CC FLAGS_REG))])]
6451   "TARGET_64BIT"
6452   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6453
6454 (define_insn "*subti3_1"
6455   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6460   "#")
6461
6462 (define_split
6463   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465                   (match_operand:TI 2 "general_operand" "")))
6466    (clobber (reg:CC FLAGS_REG))]
6467   "TARGET_64BIT && reload_completed"
6468   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470    (parallel [(set (match_dup 3)
6471                    (minus:DI (match_dup 4)
6472                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6473                                       (match_dup 5))))
6474               (clobber (reg:CC FLAGS_REG))])]
6475   "split_ti (operands+0, 1, operands+0, operands+3);
6476    split_ti (operands+1, 1, operands+1, operands+4);
6477    split_ti (operands+2, 1, operands+2, operands+5);")
6478
6479 ;; %%% splits for subsidi3
6480
6481 (define_expand "subdi3"
6482   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484                              (match_operand:DI 2 "x86_64_general_operand" "")))
6485               (clobber (reg:CC FLAGS_REG))])]
6486   ""
6487   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6488
6489 (define_insn "*subdi3_1"
6490   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6495   "#")
6496
6497 (define_split
6498   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500                   (match_operand:DI 2 "general_operand" "")))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "!TARGET_64BIT && reload_completed"
6503   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6505    (parallel [(set (match_dup 3)
6506                    (minus:SI (match_dup 4)
6507                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6508                                       (match_dup 5))))
6509               (clobber (reg:CC FLAGS_REG))])]
6510   "split_di (operands+0, 1, operands+0, operands+3);
6511    split_di (operands+1, 1, operands+1, operands+4);
6512    split_di (operands+2, 1, operands+2, operands+5);")
6513
6514 (define_insn "subdi3_carry_rex64"
6515   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521   "sbb{q}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "pent_pair" "pu")
6524    (set_attr "mode" "DI")])
6525
6526 (define_insn "*subdi_1_rex64"
6527   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532   "sub{q}\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "mode" "DI")])
6535
6536 (define_insn "*subdi_2_rex64"
6537   [(set (reg FLAGS_REG)
6538         (compare
6539           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6541           (const_int 0)))
6542    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543         (minus:DI (match_dup 1) (match_dup 2)))]
6544   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546   "sub{q}\t{%2, %0|%0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "mode" "DI")])
6549
6550 (define_insn "*subdi_3_rex63"
6551   [(set (reg FLAGS_REG)
6552         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555         (minus:DI (match_dup 1) (match_dup 2)))]
6556   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558   "sub{q}\t{%2, %0|%0, %2}"
6559   [(set_attr "type" "alu")
6560    (set_attr "mode" "DI")])
6561
6562 (define_insn "subqi3_carry"
6563   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566                (match_operand:QI 2 "general_operand" "qi,qm"))))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569   "sbb{b}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "alu")
6571    (set_attr "pent_pair" "pu")
6572    (set_attr "mode" "QI")])
6573
6574 (define_insn "subhi3_carry"
6575   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578                (match_operand:HI 2 "general_operand" "ri,rm"))))
6579    (clobber (reg:CC FLAGS_REG))]
6580   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581   "sbb{w}\t{%2, %0|%0, %2}"
6582   [(set_attr "type" "alu")
6583    (set_attr "pent_pair" "pu")
6584    (set_attr "mode" "HI")])
6585
6586 (define_insn "subsi3_carry"
6587   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590                (match_operand:SI 2 "general_operand" "ri,rm"))))
6591    (clobber (reg:CC FLAGS_REG))]
6592   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593   "sbb{l}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "alu")
6595    (set_attr "pent_pair" "pu")
6596    (set_attr "mode" "SI")])
6597
6598 (define_insn "subsi3_carry_zext"
6599   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6600           (zero_extend:DI
6601             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6604    (clobber (reg:CC FLAGS_REG))]
6605   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606   "sbb{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "pent_pair" "pu")
6609    (set_attr "mode" "SI")])
6610
6611 (define_expand "subsi3"
6612   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614                              (match_operand:SI 2 "general_operand" "")))
6615               (clobber (reg:CC FLAGS_REG))])]
6616   ""
6617   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6618
6619 (define_insn "*subsi_1"
6620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622                   (match_operand:SI 2 "general_operand" "ri,rm")))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625   "sub{l}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "mode" "SI")])
6628
6629 (define_insn "*subsi_1_zext"
6630   [(set (match_operand:DI 0 "register_operand" "=r")
6631         (zero_extend:DI
6632           (minus:SI (match_operand:SI 1 "register_operand" "0")
6633                     (match_operand:SI 2 "general_operand" "rim"))))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636   "sub{l}\t{%2, %k0|%k0, %2}"
6637   [(set_attr "type" "alu")
6638    (set_attr "mode" "SI")])
6639
6640 (define_insn "*subsi_2"
6641   [(set (reg FLAGS_REG)
6642         (compare
6643           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644                     (match_operand:SI 2 "general_operand" "ri,rm"))
6645           (const_int 0)))
6646    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:SI (match_dup 1) (match_dup 2)))]
6648   "ix86_match_ccmode (insn, CCGOCmode)
6649    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sub{l}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "SI")])
6653
6654 (define_insn "*subsi_2_zext"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:SI (match_operand:SI 1 "register_operand" "0")
6658                     (match_operand:SI 2 "general_operand" "rim"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "register_operand" "=r")
6661         (zero_extend:DI
6662           (minus:SI (match_dup 1)
6663                     (match_dup 2))))]
6664   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666   "sub{l}\t{%2, %k0|%k0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "SI")])
6669
6670 (define_insn "*subsi_3"
6671   [(set (reg FLAGS_REG)
6672         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673                  (match_operand:SI 2 "general_operand" "ri,rm")))
6674    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675         (minus:SI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCmode)
6677    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678   "sub{l}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "SI")])
6681
6682 (define_insn "*subsi_3_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare (match_operand:SI 1 "register_operand" "0")
6685                  (match_operand:SI 2 "general_operand" "rim")))
6686    (set (match_operand:DI 0 "register_operand" "=r")
6687         (zero_extend:DI
6688           (minus:SI (match_dup 1)
6689                     (match_dup 2))))]
6690   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692   "sub{q}\t{%2, %0|%0, %2}"
6693   [(set_attr "type" "alu")
6694    (set_attr "mode" "DI")])
6695
6696 (define_expand "subhi3"
6697   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699                              (match_operand:HI 2 "general_operand" "")))
6700               (clobber (reg:CC FLAGS_REG))])]
6701   "TARGET_HIMODE_MATH"
6702   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6703
6704 (define_insn "*subhi_1"
6705   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707                   (match_operand:HI 2 "general_operand" "ri,rm")))
6708    (clobber (reg:CC FLAGS_REG))]
6709   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710   "sub{w}\t{%2, %0|%0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "HI")])
6713
6714 (define_insn "*subhi_2"
6715   [(set (reg FLAGS_REG)
6716         (compare
6717           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718                     (match_operand:HI 2 "general_operand" "ri,rm"))
6719           (const_int 0)))
6720    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721         (minus:HI (match_dup 1) (match_dup 2)))]
6722   "ix86_match_ccmode (insn, CCGOCmode)
6723    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724   "sub{w}\t{%2, %0|%0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "mode" "HI")])
6727
6728 (define_insn "*subhi_3"
6729   [(set (reg FLAGS_REG)
6730         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731                  (match_operand:HI 2 "general_operand" "ri,rm")))
6732    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733         (minus:HI (match_dup 1) (match_dup 2)))]
6734   "ix86_match_ccmode (insn, CCmode)
6735    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736   "sub{w}\t{%2, %0|%0, %2}"
6737   [(set_attr "type" "alu")
6738    (set_attr "mode" "HI")])
6739
6740 (define_expand "subqi3"
6741   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743                              (match_operand:QI 2 "general_operand" "")))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   "TARGET_QIMODE_MATH"
6746   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6747
6748 (define_insn "*subqi_1"
6749   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754   "sub{b}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "QI")])
6757
6758 (define_insn "*subqi_1_slp"
6759   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760         (minus:QI (match_dup 0)
6761                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6762    (clobber (reg:CC FLAGS_REG))]
6763   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765   "sub{b}\t{%1, %0|%0, %1}"
6766   [(set_attr "type" "alu1")
6767    (set_attr "mode" "QI")])
6768
6769 (define_insn "*subqi_2"
6770   [(set (reg FLAGS_REG)
6771         (compare
6772           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773                     (match_operand:QI 2 "general_operand" "qi,qm"))
6774           (const_int 0)))
6775    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776         (minus:HI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCGOCmode)
6778    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779   "sub{b}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "QI")])
6782
6783 (define_insn "*subqi_3"
6784   [(set (reg FLAGS_REG)
6785         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786                  (match_operand:QI 2 "general_operand" "qi,qm")))
6787    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788         (minus:HI (match_dup 1) (match_dup 2)))]
6789   "ix86_match_ccmode (insn, CCmode)
6790    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791   "sub{b}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "mode" "QI")])
6794
6795 ;; The patterns that match these are at the end of this file.
6796
6797 (define_expand "subxf3"
6798   [(set (match_operand:XF 0 "register_operand" "")
6799         (minus:XF (match_operand:XF 1 "register_operand" "")
6800                   (match_operand:XF 2 "register_operand" "")))]
6801   "TARGET_80387"
6802   "")
6803
6804 (define_expand "subdf3"
6805   [(set (match_operand:DF 0 "register_operand" "")
6806         (minus:DF (match_operand:DF 1 "register_operand" "")
6807                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6808   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6809   "")
6810
6811 (define_expand "subsf3"
6812   [(set (match_operand:SF 0 "register_operand" "")
6813         (minus:SF (match_operand:SF 1 "register_operand" "")
6814                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6815   "TARGET_80387 || TARGET_SSE_MATH"
6816   "")
6817 \f
6818 ;; Multiply instructions
6819
6820 (define_expand "muldi3"
6821   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822                    (mult:DI (match_operand:DI 1 "register_operand" "")
6823                             (match_operand:DI 2 "x86_64_general_operand" "")))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   "TARGET_64BIT"
6826   "")
6827
6828 (define_insn "*muldi3_1_rex64"
6829   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832    (clobber (reg:CC FLAGS_REG))]
6833   "TARGET_64BIT
6834    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6835   "@
6836    imul{q}\t{%2, %1, %0|%0, %1, %2}
6837    imul{q}\t{%2, %1, %0|%0, %1, %2}
6838    imul{q}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "imul")
6840    (set_attr "prefix_0f" "0,0,1")
6841    (set (attr "athlon_decode")
6842         (cond [(eq_attr "cpu" "athlon")
6843                   (const_string "vector")
6844                (eq_attr "alternative" "1")
6845                   (const_string "vector")
6846                (and (eq_attr "alternative" "2")
6847                     (match_operand 1 "memory_operand" ""))
6848                   (const_string "vector")]
6849               (const_string "direct")))
6850    (set_attr "mode" "DI")])
6851
6852 (define_expand "mulsi3"
6853   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854                    (mult:SI (match_operand:SI 1 "register_operand" "")
6855                             (match_operand:SI 2 "general_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   ""
6858   "")
6859
6860 (define_insn "*mulsi3_1"
6861   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6866   "@
6867    imul{l}\t{%2, %1, %0|%0, %1, %2}
6868    imul{l}\t{%2, %1, %0|%0, %1, %2}
6869    imul{l}\t{%2, %0|%0, %2}"
6870   [(set_attr "type" "imul")
6871    (set_attr "prefix_0f" "0,0,1")
6872    (set (attr "athlon_decode")
6873         (cond [(eq_attr "cpu" "athlon")
6874                   (const_string "vector")
6875                (eq_attr "alternative" "1")
6876                   (const_string "vector")
6877                (and (eq_attr "alternative" "2")
6878                     (match_operand 1 "memory_operand" ""))
6879                   (const_string "vector")]
6880               (const_string "direct")))
6881    (set_attr "mode" "SI")])
6882
6883 (define_insn "*mulsi3_1_zext"
6884   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6885         (zero_extend:DI
6886           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "TARGET_64BIT
6890    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891   "@
6892    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894    imul{l}\t{%2, %k0|%k0, %2}"
6895   [(set_attr "type" "imul")
6896    (set_attr "prefix_0f" "0,0,1")
6897    (set (attr "athlon_decode")
6898         (cond [(eq_attr "cpu" "athlon")
6899                   (const_string "vector")
6900                (eq_attr "alternative" "1")
6901                   (const_string "vector")
6902                (and (eq_attr "alternative" "2")
6903                     (match_operand 1 "memory_operand" ""))
6904                   (const_string "vector")]
6905               (const_string "direct")))
6906    (set_attr "mode" "SI")])
6907
6908 (define_expand "mulhi3"
6909   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910                    (mult:HI (match_operand:HI 1 "register_operand" "")
6911                             (match_operand:HI 2 "general_operand" "")))
6912               (clobber (reg:CC FLAGS_REG))])]
6913   "TARGET_HIMODE_MATH"
6914   "")
6915
6916 (define_insn "*mulhi3_1"
6917   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6920    (clobber (reg:CC FLAGS_REG))]
6921   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6922   "@
6923    imul{w}\t{%2, %1, %0|%0, %1, %2}
6924    imul{w}\t{%2, %1, %0|%0, %1, %2}
6925    imul{w}\t{%2, %0|%0, %2}"
6926   [(set_attr "type" "imul")
6927    (set_attr "prefix_0f" "0,0,1")
6928    (set (attr "athlon_decode")
6929         (cond [(eq_attr "cpu" "athlon")
6930                   (const_string "vector")
6931                (eq_attr "alternative" "1,2")
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "HI")])
6935
6936 (define_expand "mulqi3"
6937   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939                             (match_operand:QI 2 "register_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_QIMODE_MATH"
6942   "")
6943
6944 (define_insn "*mulqi3_1"
6945   [(set (match_operand:QI 0 "register_operand" "=a")
6946         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "TARGET_QIMODE_MATH
6950    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6951   "mul{b}\t%2"
6952   [(set_attr "type" "imul")
6953    (set_attr "length_immediate" "0")
6954    (set (attr "athlon_decode")
6955      (if_then_else (eq_attr "cpu" "athlon")
6956         (const_string "vector")
6957         (const_string "direct")))
6958    (set_attr "mode" "QI")])
6959
6960 (define_expand "umulqihi3"
6961   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962                    (mult:HI (zero_extend:HI
6963                               (match_operand:QI 1 "nonimmediate_operand" ""))
6964                             (zero_extend:HI
6965                               (match_operand:QI 2 "register_operand" ""))))
6966               (clobber (reg:CC FLAGS_REG))])]
6967   "TARGET_QIMODE_MATH"
6968   "")
6969
6970 (define_insn "*umulqihi3_1"
6971   [(set (match_operand:HI 0 "register_operand" "=a")
6972         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974    (clobber (reg:CC FLAGS_REG))]
6975   "TARGET_QIMODE_MATH
6976    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6977   "mul{b}\t%2"
6978   [(set_attr "type" "imul")
6979    (set_attr "length_immediate" "0")
6980    (set (attr "athlon_decode")
6981      (if_then_else (eq_attr "cpu" "athlon")
6982         (const_string "vector")
6983         (const_string "direct")))
6984    (set_attr "mode" "QI")])
6985
6986 (define_expand "mulqihi3"
6987   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990               (clobber (reg:CC FLAGS_REG))])]
6991   "TARGET_QIMODE_MATH"
6992   "")
6993
6994 (define_insn "*mulqihi3_insn"
6995   [(set (match_operand:HI 0 "register_operand" "=a")
6996         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998    (clobber (reg:CC FLAGS_REG))]
6999   "TARGET_QIMODE_MATH
7000    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001   "imul{b}\t%2"
7002   [(set_attr "type" "imul")
7003    (set_attr "length_immediate" "0")
7004    (set (attr "athlon_decode")
7005      (if_then_else (eq_attr "cpu" "athlon")
7006         (const_string "vector")
7007         (const_string "direct")))
7008    (set_attr "mode" "QI")])
7009
7010 (define_expand "umulditi3"
7011   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012                    (mult:TI (zero_extend:TI
7013                               (match_operand:DI 1 "nonimmediate_operand" ""))
7014                             (zero_extend:TI
7015                               (match_operand:DI 2 "register_operand" ""))))
7016               (clobber (reg:CC FLAGS_REG))])]
7017   "TARGET_64BIT"
7018   "")
7019
7020 (define_insn "*umulditi3_insn"
7021   [(set (match_operand:TI 0 "register_operand" "=A")
7022         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024    (clobber (reg:CC FLAGS_REG))]
7025   "TARGET_64BIT
7026    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7027   "mul{q}\t%2"
7028   [(set_attr "type" "imul")
7029    (set_attr "length_immediate" "0")
7030    (set (attr "athlon_decode")
7031      (if_then_else (eq_attr "cpu" "athlon")
7032         (const_string "vector")
7033         (const_string "double")))
7034    (set_attr "mode" "DI")])
7035
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039                    (mult:DI (zero_extend:DI
7040                               (match_operand:SI 1 "nonimmediate_operand" ""))
7041                             (zero_extend:DI
7042                               (match_operand:SI 2 "register_operand" ""))))
7043               (clobber (reg:CC FLAGS_REG))])]
7044   "!TARGET_64BIT"
7045   "")
7046
7047 (define_insn "*umulsidi3_insn"
7048   [(set (match_operand:DI 0 "register_operand" "=A")
7049         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051    (clobber (reg:CC FLAGS_REG))]
7052   "!TARGET_64BIT
7053    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054   "mul{l}\t%2"
7055   [(set_attr "type" "imul")
7056    (set_attr "length_immediate" "0")
7057    (set (attr "athlon_decode")
7058      (if_then_else (eq_attr "cpu" "athlon")
7059         (const_string "vector")
7060         (const_string "double")))
7061    (set_attr "mode" "SI")])
7062
7063 (define_expand "mulditi3"
7064   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065                    (mult:TI (sign_extend:TI
7066                               (match_operand:DI 1 "nonimmediate_operand" ""))
7067                             (sign_extend:TI
7068                               (match_operand:DI 2 "register_operand" ""))))
7069               (clobber (reg:CC FLAGS_REG))])]
7070   "TARGET_64BIT"
7071   "")
7072
7073 (define_insn "*mulditi3_insn"
7074   [(set (match_operand:TI 0 "register_operand" "=A")
7075         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "TARGET_64BIT
7079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080   "imul{q}\t%2"
7081   [(set_attr "type" "imul")
7082    (set_attr "length_immediate" "0")
7083    (set (attr "athlon_decode")
7084      (if_then_else (eq_attr "cpu" "athlon")
7085         (const_string "vector")
7086         (const_string "double")))
7087    (set_attr "mode" "DI")])
7088
7089 (define_expand "mulsidi3"
7090   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091                    (mult:DI (sign_extend:DI
7092                               (match_operand:SI 1 "nonimmediate_operand" ""))
7093                             (sign_extend:DI
7094                               (match_operand:SI 2 "register_operand" ""))))
7095               (clobber (reg:CC FLAGS_REG))])]
7096   "!TARGET_64BIT"
7097   "")
7098
7099 (define_insn "*mulsidi3_insn"
7100   [(set (match_operand:DI 0 "register_operand" "=A")
7101         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103    (clobber (reg:CC FLAGS_REG))]
7104   "!TARGET_64BIT
7105    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106   "imul{l}\t%2"
7107   [(set_attr "type" "imul")
7108    (set_attr "length_immediate" "0")
7109    (set (attr "athlon_decode")
7110      (if_then_else (eq_attr "cpu" "athlon")
7111         (const_string "vector")
7112         (const_string "double")))
7113    (set_attr "mode" "SI")])
7114
7115 (define_expand "umuldi3_highpart"
7116   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7117                    (truncate:DI
7118                      (lshiftrt:TI
7119                        (mult:TI (zero_extend:TI
7120                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7121                                 (zero_extend:TI
7122                                   (match_operand:DI 2 "register_operand" "")))
7123                        (const_int 64))))
7124               (clobber (match_scratch:DI 3 ""))
7125               (clobber (reg:CC FLAGS_REG))])]
7126   "TARGET_64BIT"
7127   "")
7128
7129 (define_insn "*umuldi3_highpart_rex64"
7130   [(set (match_operand:DI 0 "register_operand" "=d")
7131         (truncate:DI
7132           (lshiftrt:TI
7133             (mult:TI (zero_extend:TI
7134                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7135                      (zero_extend:TI
7136                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7137             (const_int 64))))
7138    (clobber (match_scratch:DI 3 "=1"))
7139    (clobber (reg:CC FLAGS_REG))]
7140   "TARGET_64BIT
7141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142   "mul{q}\t%2"
7143   [(set_attr "type" "imul")
7144    (set_attr "length_immediate" "0")
7145    (set (attr "athlon_decode")
7146      (if_then_else (eq_attr "cpu" "athlon")
7147         (const_string "vector")
7148         (const_string "double")))
7149    (set_attr "mode" "DI")])
7150
7151 (define_expand "umulsi3_highpart"
7152   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7153                    (truncate:SI
7154                      (lshiftrt:DI
7155                        (mult:DI (zero_extend:DI
7156                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7157                                 (zero_extend:DI
7158                                   (match_operand:SI 2 "register_operand" "")))
7159                        (const_int 32))))
7160               (clobber (match_scratch:SI 3 ""))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   ""
7163   "")
7164
7165 (define_insn "*umulsi3_highpart_insn"
7166   [(set (match_operand:SI 0 "register_operand" "=d")
7167         (truncate:SI
7168           (lshiftrt:DI
7169             (mult:DI (zero_extend:DI
7170                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7171                      (zero_extend:DI
7172                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7173             (const_int 32))))
7174    (clobber (match_scratch:SI 3 "=1"))
7175    (clobber (reg:CC FLAGS_REG))]
7176   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7177   "mul{l}\t%2"
7178   [(set_attr "type" "imul")
7179    (set_attr "length_immediate" "0")
7180    (set (attr "athlon_decode")
7181      (if_then_else (eq_attr "cpu" "athlon")
7182         (const_string "vector")
7183         (const_string "double")))
7184    (set_attr "mode" "SI")])
7185
7186 (define_insn "*umulsi3_highpart_zext"
7187   [(set (match_operand:DI 0 "register_operand" "=d")
7188         (zero_extend:DI (truncate:SI
7189           (lshiftrt:DI
7190             (mult:DI (zero_extend:DI
7191                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7192                      (zero_extend:DI
7193                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7194             (const_int 32)))))
7195    (clobber (match_scratch:SI 3 "=1"))
7196    (clobber (reg:CC FLAGS_REG))]
7197   "TARGET_64BIT
7198    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7199   "mul{l}\t%2"
7200   [(set_attr "type" "imul")
7201    (set_attr "length_immediate" "0")
7202    (set (attr "athlon_decode")
7203      (if_then_else (eq_attr "cpu" "athlon")
7204         (const_string "vector")
7205         (const_string "double")))
7206    (set_attr "mode" "SI")])
7207
7208 (define_expand "smuldi3_highpart"
7209   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7210                    (truncate:DI
7211                      (lshiftrt:TI
7212                        (mult:TI (sign_extend:TI
7213                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7214                                 (sign_extend:TI
7215                                   (match_operand:DI 2 "register_operand" "")))
7216                        (const_int 64))))
7217               (clobber (match_scratch:DI 3 ""))
7218               (clobber (reg:CC FLAGS_REG))])]
7219   "TARGET_64BIT"
7220   "")
7221
7222 (define_insn "*smuldi3_highpart_rex64"
7223   [(set (match_operand:DI 0 "register_operand" "=d")
7224         (truncate:DI
7225           (lshiftrt:TI
7226             (mult:TI (sign_extend:TI
7227                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7228                      (sign_extend:TI
7229                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7230             (const_int 64))))
7231    (clobber (match_scratch:DI 3 "=1"))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_64BIT
7234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235   "imul{q}\t%2"
7236   [(set_attr "type" "imul")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "DI")])
7242
7243 (define_expand "smulsi3_highpart"
7244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245                    (truncate:SI
7246                      (lshiftrt:DI
7247                        (mult:DI (sign_extend:DI
7248                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7249                                 (sign_extend:DI
7250                                   (match_operand:SI 2 "register_operand" "")))
7251                        (const_int 32))))
7252               (clobber (match_scratch:SI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   "")
7256
7257 (define_insn "*smulsi3_highpart_insn"
7258   [(set (match_operand:SI 0 "register_operand" "=d")
7259         (truncate:SI
7260           (lshiftrt:DI
7261             (mult:DI (sign_extend:DI
7262                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263                      (sign_extend:DI
7264                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269   "imul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "mode" "SI")])
7276
7277 (define_insn "*smulsi3_highpart_zext"
7278   [(set (match_operand:DI 0 "register_operand" "=d")
7279         (zero_extend:DI (truncate:SI
7280           (lshiftrt:DI
7281             (mult:DI (sign_extend:DI
7282                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283                      (sign_extend:DI
7284                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285             (const_int 32)))))
7286    (clobber (match_scratch:SI 3 "=1"))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_64BIT
7289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290   "imul{l}\t%2"
7291   [(set_attr "type" "imul")
7292    (set (attr "athlon_decode")
7293      (if_then_else (eq_attr "cpu" "athlon")
7294         (const_string "vector")
7295         (const_string "double")))
7296    (set_attr "mode" "SI")])
7297
7298 ;; The patterns that match these are at the end of this file.
7299
7300 (define_expand "mulxf3"
7301   [(set (match_operand:XF 0 "register_operand" "")
7302         (mult:XF (match_operand:XF 1 "register_operand" "")
7303                  (match_operand:XF 2 "register_operand" "")))]
7304   "TARGET_80387"
7305   "")
7306
7307 (define_expand "muldf3"
7308   [(set (match_operand:DF 0 "register_operand" "")
7309         (mult:DF (match_operand:DF 1 "register_operand" "")
7310                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7311   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7312   "")
7313
7314 (define_expand "mulsf3"
7315   [(set (match_operand:SF 0 "register_operand" "")
7316         (mult:SF (match_operand:SF 1 "register_operand" "")
7317                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7318   "TARGET_80387 || TARGET_SSE_MATH"
7319   "")
7320 \f
7321 ;; Divide instructions
7322
7323 (define_insn "divqi3"
7324   [(set (match_operand:QI 0 "register_operand" "=a")
7325         (div:QI (match_operand:HI 1 "register_operand" "0")
7326                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_QIMODE_MATH"
7329   "idiv{b}\t%2"
7330   [(set_attr "type" "idiv")
7331    (set_attr "mode" "QI")])
7332
7333 (define_insn "udivqi3"
7334   [(set (match_operand:QI 0 "register_operand" "=a")
7335         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_QIMODE_MATH"
7339   "div{b}\t%2"
7340   [(set_attr "type" "idiv")
7341    (set_attr "mode" "QI")])
7342
7343 ;; The patterns that match these are at the end of this file.
7344
7345 (define_expand "divxf3"
7346   [(set (match_operand:XF 0 "register_operand" "")
7347         (div:XF (match_operand:XF 1 "register_operand" "")
7348                 (match_operand:XF 2 "register_operand" "")))]
7349   "TARGET_80387"
7350   "")
7351
7352 (define_expand "divdf3"
7353   [(set (match_operand:DF 0 "register_operand" "")
7354         (div:DF (match_operand:DF 1 "register_operand" "")
7355                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7357    "")
7358  
7359 (define_expand "divsf3"
7360   [(set (match_operand:SF 0 "register_operand" "")
7361         (div:SF (match_operand:SF 1 "register_operand" "")
7362                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363   "TARGET_80387 || TARGET_SSE_MATH"
7364   "")
7365 \f
7366 ;; Remainder instructions.
7367
7368 (define_expand "divmoddi4"
7369   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370                    (div:DI (match_operand:DI 1 "register_operand" "")
7371                            (match_operand:DI 2 "nonimmediate_operand" "")))
7372               (set (match_operand:DI 3 "register_operand" "")
7373                    (mod:DI (match_dup 1) (match_dup 2)))
7374               (clobber (reg:CC FLAGS_REG))])]
7375   "TARGET_64BIT"
7376   "")
7377
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7380 ;; of code.
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386         (mod:DI (match_dup 2) (match_dup 3)))
7387    (clobber (reg:CC FLAGS_REG))]
7388   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7389   "#"
7390   [(set_attr "type" "multi")])
7391
7392 (define_insn "*divmoddi4_cltd_rex64"
7393   [(set (match_operand:DI 0 "register_operand" "=a")
7394         (div:DI (match_operand:DI 2 "register_operand" "a")
7395                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396    (set (match_operand:DI 1 "register_operand" "=&d")
7397         (mod:DI (match_dup 2) (match_dup 3)))
7398    (clobber (reg:CC FLAGS_REG))]
7399   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7400   "#"
7401   [(set_attr "type" "multi")])
7402
7403 (define_insn "*divmoddi_noext_rex64"
7404   [(set (match_operand:DI 0 "register_operand" "=a")
7405         (div:DI (match_operand:DI 1 "register_operand" "0")
7406                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407    (set (match_operand:DI 3 "register_operand" "=d")
7408         (mod:DI (match_dup 1) (match_dup 2)))
7409    (use (match_operand:DI 4 "register_operand" "3"))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "TARGET_64BIT"
7412   "idiv{q}\t%2"
7413   [(set_attr "type" "idiv")
7414    (set_attr "mode" "DI")])
7415
7416 (define_split
7417   [(set (match_operand:DI 0 "register_operand" "")
7418         (div:DI (match_operand:DI 1 "register_operand" "")
7419                 (match_operand:DI 2 "nonimmediate_operand" "")))
7420    (set (match_operand:DI 3 "register_operand" "")
7421         (mod:DI (match_dup 1) (match_dup 2)))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "TARGET_64BIT && reload_completed"
7424   [(parallel [(set (match_dup 3)
7425                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7426               (clobber (reg:CC FLAGS_REG))])
7427    (parallel [(set (match_dup 0)
7428                    (div:DI (reg:DI 0) (match_dup 2)))
7429               (set (match_dup 3)
7430                    (mod:DI (reg:DI 0) (match_dup 2)))
7431               (use (match_dup 3))
7432               (clobber (reg:CC FLAGS_REG))])]
7433 {
7434   /* Avoid use of cltd in favor of a mov+shift.  */
7435   if (!TARGET_USE_CLTD && !optimize_size)
7436     {
7437       if (true_regnum (operands[1]))
7438         emit_move_insn (operands[0], operands[1]);
7439       else
7440         emit_move_insn (operands[3], operands[1]);
7441       operands[4] = operands[3];
7442     }
7443   else
7444     {
7445       gcc_assert (!true_regnum (operands[1]));
7446       operands[4] = operands[1];
7447     }
7448 })
7449
7450
7451 (define_expand "divmodsi4"
7452   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453                    (div:SI (match_operand:SI 1 "register_operand" "")
7454                            (match_operand:SI 2 "nonimmediate_operand" "")))
7455               (set (match_operand:SI 3 "register_operand" "")
7456                    (mod:SI (match_dup 1) (match_dup 2)))
7457               (clobber (reg:CC FLAGS_REG))])]
7458   ""
7459   "")
7460
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7463 ;; of code.
7464 (define_insn "*divmodsi4_nocltd"
7465   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469         (mod:SI (match_dup 2) (match_dup 3)))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "!optimize_size && !TARGET_USE_CLTD"
7472   "#"
7473   [(set_attr "type" "multi")])
7474
7475 (define_insn "*divmodsi4_cltd"
7476   [(set (match_operand:SI 0 "register_operand" "=a")
7477         (div:SI (match_operand:SI 2 "register_operand" "a")
7478                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479    (set (match_operand:SI 1 "register_operand" "=&d")
7480         (mod:SI (match_dup 2) (match_dup 3)))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "optimize_size || TARGET_USE_CLTD"
7483   "#"
7484   [(set_attr "type" "multi")])
7485
7486 (define_insn "*divmodsi_noext"
7487   [(set (match_operand:SI 0 "register_operand" "=a")
7488         (div:SI (match_operand:SI 1 "register_operand" "0")
7489                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490    (set (match_operand:SI 3 "register_operand" "=d")
7491         (mod:SI (match_dup 1) (match_dup 2)))
7492    (use (match_operand:SI 4 "register_operand" "3"))
7493    (clobber (reg:CC FLAGS_REG))]
7494   ""
7495   "idiv{l}\t%2"
7496   [(set_attr "type" "idiv")
7497    (set_attr "mode" "SI")])
7498
7499 (define_split
7500   [(set (match_operand:SI 0 "register_operand" "")
7501         (div:SI (match_operand:SI 1 "register_operand" "")
7502                 (match_operand:SI 2 "nonimmediate_operand" "")))
7503    (set (match_operand:SI 3 "register_operand" "")
7504         (mod:SI (match_dup 1) (match_dup 2)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "reload_completed"
7507   [(parallel [(set (match_dup 3)
7508                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7509               (clobber (reg:CC FLAGS_REG))])
7510    (parallel [(set (match_dup 0)
7511                    (div:SI (reg:SI 0) (match_dup 2)))
7512               (set (match_dup 3)
7513                    (mod:SI (reg:SI 0) (match_dup 2)))
7514               (use (match_dup 3))
7515               (clobber (reg:CC FLAGS_REG))])]
7516 {
7517   /* Avoid use of cltd in favor of a mov+shift.  */
7518   if (!TARGET_USE_CLTD && !optimize_size)
7519     {
7520       if (true_regnum (operands[1]))
7521         emit_move_insn (operands[0], operands[1]);
7522       else
7523         emit_move_insn (operands[3], operands[1]);
7524       operands[4] = operands[3];
7525     }
7526   else
7527     {
7528       gcc_assert (!true_regnum (operands[1]));
7529       operands[4] = operands[1];
7530     }
7531 })
7532 ;; %%% Split me.
7533 (define_insn "divmodhi4"
7534   [(set (match_operand:HI 0 "register_operand" "=a")
7535         (div:HI (match_operand:HI 1 "register_operand" "0")
7536                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537    (set (match_operand:HI 3 "register_operand" "=&d")
7538         (mod:HI (match_dup 1) (match_dup 2)))
7539    (clobber (reg:CC FLAGS_REG))]
7540   "TARGET_HIMODE_MATH"
7541   "cwtd\;idiv{w}\t%2"
7542   [(set_attr "type" "multi")
7543    (set_attr "length_immediate" "0")
7544    (set_attr "mode" "SI")])
7545
7546 (define_insn "udivmoddi4"
7547   [(set (match_operand:DI 0 "register_operand" "=a")
7548         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550    (set (match_operand:DI 3 "register_operand" "=&d")
7551         (umod:DI (match_dup 1) (match_dup 2)))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "TARGET_64BIT"
7554   "xor{q}\t%3, %3\;div{q}\t%2"
7555   [(set_attr "type" "multi")
7556    (set_attr "length_immediate" "0")
7557    (set_attr "mode" "DI")])
7558
7559 (define_insn "*udivmoddi4_noext"
7560   [(set (match_operand:DI 0 "register_operand" "=a")
7561         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563    (set (match_operand:DI 3 "register_operand" "=d")
7564         (umod:DI (match_dup 1) (match_dup 2)))
7565    (use (match_dup 3))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT"
7568   "div{q}\t%2"
7569   [(set_attr "type" "idiv")
7570    (set_attr "mode" "DI")])
7571
7572 (define_split
7573   [(set (match_operand:DI 0 "register_operand" "")
7574         (udiv:DI (match_operand:DI 1 "register_operand" "")
7575                  (match_operand:DI 2 "nonimmediate_operand" "")))
7576    (set (match_operand:DI 3 "register_operand" "")
7577         (umod:DI (match_dup 1) (match_dup 2)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && reload_completed"
7580   [(set (match_dup 3) (const_int 0))
7581    (parallel [(set (match_dup 0)
7582                    (udiv:DI (match_dup 1) (match_dup 2)))
7583               (set (match_dup 3)
7584                    (umod:DI (match_dup 1) (match_dup 2)))
7585               (use (match_dup 3))
7586               (clobber (reg:CC FLAGS_REG))])]
7587   "")
7588
7589 (define_insn "udivmodsi4"
7590   [(set (match_operand:SI 0 "register_operand" "=a")
7591         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593    (set (match_operand:SI 3 "register_operand" "=&d")
7594         (umod:SI (match_dup 1) (match_dup 2)))
7595    (clobber (reg:CC FLAGS_REG))]
7596   ""
7597   "xor{l}\t%3, %3\;div{l}\t%2"
7598   [(set_attr "type" "multi")
7599    (set_attr "length_immediate" "0")
7600    (set_attr "mode" "SI")])
7601
7602 (define_insn "*udivmodsi4_noext"
7603   [(set (match_operand:SI 0 "register_operand" "=a")
7604         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606    (set (match_operand:SI 3 "register_operand" "=d")
7607         (umod:SI (match_dup 1) (match_dup 2)))
7608    (use (match_dup 3))
7609    (clobber (reg:CC FLAGS_REG))]
7610   ""
7611   "div{l}\t%2"
7612   [(set_attr "type" "idiv")
7613    (set_attr "mode" "SI")])
7614
7615 (define_split
7616   [(set (match_operand:SI 0 "register_operand" "")
7617         (udiv:SI (match_operand:SI 1 "register_operand" "")
7618                  (match_operand:SI 2 "nonimmediate_operand" "")))
7619    (set (match_operand:SI 3 "register_operand" "")
7620         (umod:SI (match_dup 1) (match_dup 2)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "reload_completed"
7623   [(set (match_dup 3) (const_int 0))
7624    (parallel [(set (match_dup 0)
7625                    (udiv:SI (match_dup 1) (match_dup 2)))
7626               (set (match_dup 3)
7627                    (umod:SI (match_dup 1) (match_dup 2)))
7628               (use (match_dup 3))
7629               (clobber (reg:CC FLAGS_REG))])]
7630   "")
7631
7632 (define_expand "udivmodhi4"
7633   [(set (match_dup 4) (const_int 0))
7634    (parallel [(set (match_operand:HI 0 "register_operand" "")
7635                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7636                             (match_operand:HI 2 "nonimmediate_operand" "")))
7637               (set (match_operand:HI 3 "register_operand" "")
7638                    (umod:HI (match_dup 1) (match_dup 2)))
7639               (use (match_dup 4))
7640               (clobber (reg:CC FLAGS_REG))])]
7641   "TARGET_HIMODE_MATH"
7642   "operands[4] = gen_reg_rtx (HImode);")
7643
7644 (define_insn "*udivmodhi_noext"
7645   [(set (match_operand:HI 0 "register_operand" "=a")
7646         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648    (set (match_operand:HI 3 "register_operand" "=d")
7649         (umod:HI (match_dup 1) (match_dup 2)))
7650    (use (match_operand:HI 4 "register_operand" "3"))
7651    (clobber (reg:CC FLAGS_REG))]
7652   ""
7653   "div{w}\t%2"
7654   [(set_attr "type" "idiv")
7655    (set_attr "mode" "HI")])
7656
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate.  Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7661 ;
7662 ;(define_insn ""
7663 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7664 ;       (truncate:SI
7665 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7666 ;                  (zero_extend:DI
7667 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ;   (set (match_operand:SI 3 "register_operand" "=d")
7669 ;       (truncate:SI
7670 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ;   (clobber (reg:CC FLAGS_REG))]
7672 ;  ""
7673 ;  "div{l}\t{%2, %0|%0, %2}"
7674 ;  [(set_attr "type" "idiv")])
7675 \f
7676 ;;- Logical AND instructions
7677
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7680
7681 (define_insn "*testdi_1_rex64"
7682   [(set (reg FLAGS_REG)
7683         (compare
7684           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7686           (const_int 0)))]
7687   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7689   "@
7690    test{l}\t{%k1, %k0|%k0, %k1}
7691    test{l}\t{%k1, %k0|%k0, %k1}
7692    test{q}\t{%1, %0|%0, %1}
7693    test{q}\t{%1, %0|%0, %1}
7694    test{q}\t{%1, %0|%0, %1}"
7695   [(set_attr "type" "test")
7696    (set_attr "modrm" "0,1,0,1,1")
7697    (set_attr "mode" "SI,SI,DI,DI,DI")
7698    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7699
7700 (define_insn "testsi_1"
7701   [(set (reg FLAGS_REG)
7702         (compare
7703           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7705           (const_int 0)))]
7706   "ix86_match_ccmode (insn, CCNOmode)
7707    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708   "test{l}\t{%1, %0|%0, %1}"
7709   [(set_attr "type" "test")
7710    (set_attr "modrm" "0,1,1")
7711    (set_attr "mode" "SI")
7712    (set_attr "pent_pair" "uv,np,uv")])
7713
7714 (define_expand "testsi_ccno_1"
7715   [(set (reg:CCNO FLAGS_REG)
7716         (compare:CCNO
7717           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718                   (match_operand:SI 1 "nonmemory_operand" ""))
7719           (const_int 0)))]
7720   ""
7721   "")
7722
7723 (define_insn "*testhi_1"
7724   [(set (reg FLAGS_REG)
7725         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7727                  (const_int 0)))]
7728   "ix86_match_ccmode (insn, CCNOmode)
7729    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730   "test{w}\t{%1, %0|%0, %1}"
7731   [(set_attr "type" "test")
7732    (set_attr "modrm" "0,1,1")
7733    (set_attr "mode" "HI")
7734    (set_attr "pent_pair" "uv,np,uv")])
7735
7736 (define_expand "testqi_ccz_1"
7737   [(set (reg:CCZ FLAGS_REG)
7738         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739                              (match_operand:QI 1 "nonmemory_operand" ""))
7740                  (const_int 0)))]
7741   ""
7742   "")
7743
7744 (define_insn "*testqi_1_maybe_si"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:QI
7748             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7750           (const_int 0)))]
7751    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752     && ix86_match_ccmode (insn,
7753                          GET_CODE (operands[1]) == CONST_INT
7754                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7755 {
7756   if (which_alternative == 3)
7757     {
7758       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760       return "test{l}\t{%1, %k0|%k0, %1}";
7761     }
7762   return "test{b}\t{%1, %0|%0, %1}";
7763 }
7764   [(set_attr "type" "test")
7765    (set_attr "modrm" "0,1,1,1")
7766    (set_attr "mode" "QI,QI,QI,SI")
7767    (set_attr "pent_pair" "uv,np,uv,np")])
7768
7769 (define_insn "*testqi_1"
7770   [(set (reg FLAGS_REG)
7771         (compare
7772           (and:QI
7773             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774             (match_operand:QI 1 "general_operand" "n,n,qn"))
7775           (const_int 0)))]
7776   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777    && ix86_match_ccmode (insn, CCNOmode)"
7778   "test{b}\t{%1, %0|%0, %1}"
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,1")
7781    (set_attr "mode" "QI")
7782    (set_attr "pent_pair" "uv,np,uv")])
7783
7784 (define_expand "testqi_ext_ccno_0"
7785   [(set (reg:CCNO FLAGS_REG)
7786         (compare:CCNO
7787           (and:SI
7788             (zero_extract:SI
7789               (match_operand 0 "ext_register_operand" "")
7790               (const_int 8)
7791               (const_int 8))
7792             (match_operand 1 "const_int_operand" ""))
7793           (const_int 0)))]
7794   ""
7795   "")
7796
7797 (define_insn "*testqi_ext_0"
7798   [(set (reg FLAGS_REG)
7799         (compare
7800           (and:SI
7801             (zero_extract:SI
7802               (match_operand 0 "ext_register_operand" "Q")
7803               (const_int 8)
7804               (const_int 8))
7805             (match_operand 1 "const_int_operand" "n"))
7806           (const_int 0)))]
7807   "ix86_match_ccmode (insn, CCNOmode)"
7808   "test{b}\t{%1, %h0|%h0, %1}"
7809   [(set_attr "type" "test")
7810    (set_attr "mode" "QI")
7811    (set_attr "length_immediate" "1")
7812    (set_attr "pent_pair" "np")])
7813
7814 (define_insn "*testqi_ext_1"
7815   [(set (reg FLAGS_REG)
7816         (compare
7817           (and:SI
7818             (zero_extract:SI
7819               (match_operand 0 "ext_register_operand" "Q")
7820               (const_int 8)
7821               (const_int 8))
7822             (zero_extend:SI
7823               (match_operand:QI 1 "general_operand" "Qm")))
7824           (const_int 0)))]
7825   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827   "test{b}\t{%1, %h0|%h0, %1}"
7828   [(set_attr "type" "test")
7829    (set_attr "mode" "QI")])
7830
7831 (define_insn "*testqi_ext_1_rex64"
7832   [(set (reg FLAGS_REG)
7833         (compare
7834           (and:SI
7835             (zero_extract:SI
7836               (match_operand 0 "ext_register_operand" "Q")
7837               (const_int 8)
7838               (const_int 8))
7839             (zero_extend:SI
7840               (match_operand:QI 1 "register_operand" "Q")))
7841           (const_int 0)))]
7842   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843   "test{b}\t{%1, %h0|%h0, %1}"
7844   [(set_attr "type" "test")
7845    (set_attr "mode" "QI")])
7846
7847 (define_insn "*testqi_ext_2"
7848   [(set (reg FLAGS_REG)
7849         (compare
7850           (and:SI
7851             (zero_extract:SI
7852               (match_operand 0 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8))
7855             (zero_extract:SI
7856               (match_operand 1 "ext_register_operand" "Q")
7857               (const_int 8)
7858               (const_int 8)))
7859           (const_int 0)))]
7860   "ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%h1, %h0|%h0, %h1}"
7862   [(set_attr "type" "test")
7863    (set_attr "mode" "QI")])
7864
7865 ;; Combine likes to form bit extractions for some tests.  Humor it.
7866 (define_insn "*testqi_ext_3"
7867   [(set (reg FLAGS_REG)
7868         (compare (zero_extract:SI
7869                    (match_operand 0 "nonimmediate_operand" "rm")
7870                    (match_operand:SI 1 "const_int_operand" "")
7871                    (match_operand:SI 2 "const_int_operand" ""))
7872                  (const_int 0)))]
7873   "ix86_match_ccmode (insn, CCNOmode)
7874    && (GET_MODE (operands[0]) == SImode
7875        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876        || GET_MODE (operands[0]) == HImode
7877        || GET_MODE (operands[0]) == QImode)"
7878   "#")
7879
7880 (define_insn "*testqi_ext_3_rex64"
7881   [(set (reg FLAGS_REG)
7882         (compare (zero_extract:DI
7883                    (match_operand 0 "nonimmediate_operand" "rm")
7884                    (match_operand:DI 1 "const_int_operand" "")
7885                    (match_operand:DI 2 "const_int_operand" ""))
7886                  (const_int 0)))]
7887   "TARGET_64BIT
7888    && ix86_match_ccmode (insn, CCNOmode)
7889    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7890    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7891    /* Ensure that resulting mask is zero or sign extended operand.  */
7892    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894            && INTVAL (operands[1]) > 32))
7895    && (GET_MODE (operands[0]) == SImode
7896        || GET_MODE (operands[0]) == DImode
7897        || GET_MODE (operands[0]) == HImode
7898        || GET_MODE (operands[0]) == QImode)"
7899   "#")
7900
7901 (define_split
7902   [(set (match_operand 0 "flags_reg_operand" "")
7903         (match_operator 1 "compare_operator"
7904           [(zero_extract
7905              (match_operand 2 "nonimmediate_operand" "")
7906              (match_operand 3 "const_int_operand" "")
7907              (match_operand 4 "const_int_operand" ""))
7908            (const_int 0)]))]
7909   "ix86_match_ccmode (insn, CCNOmode)"
7910   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911 {
7912   rtx val = operands[2];
7913   HOST_WIDE_INT len = INTVAL (operands[3]);
7914   HOST_WIDE_INT pos = INTVAL (operands[4]);
7915   HOST_WIDE_INT mask;
7916   enum machine_mode mode, submode;
7917
7918   mode = GET_MODE (val);
7919   if (GET_CODE (val) == MEM)
7920     {
7921       /* ??? Combine likes to put non-volatile mem extractions in QImode
7922          no matter the size of the test.  So find a mode that works.  */
7923       if (! MEM_VOLATILE_P (val))
7924         {
7925           mode = smallest_mode_for_size (pos + len, MODE_INT);
7926           val = adjust_address (val, mode, 0);
7927         }
7928     }
7929   else if (GET_CODE (val) == SUBREG
7930            && (submode = GET_MODE (SUBREG_REG (val)),
7931                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932            && pos + len <= GET_MODE_BITSIZE (submode))
7933     {
7934       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7935       mode = submode;
7936       val = SUBREG_REG (val);
7937     }
7938   else if (mode == HImode && pos + len <= 8)
7939     {
7940       /* Small HImode tests can be converted to QImode.  */
7941       mode = QImode;
7942       val = gen_lowpart (QImode, val);
7943     }
7944
7945   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7946   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7947
7948   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7949 })
7950
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7955 ;; to QI regs.
7956 (define_split
7957   [(set (match_operand 0 "flags_reg_operand" "")
7958         (match_operator 1 "compare_operator"
7959           [(and (match_operand 2 "register_operand" "")
7960                 (match_operand 3 "const_int_operand" ""))
7961            (const_int 0)]))]
7962    "reload_completed
7963     && QI_REG_P (operands[2])
7964     && GET_MODE (operands[2]) != QImode
7965     && ((ix86_match_ccmode (insn, CCZmode)
7966          && !(INTVAL (operands[3]) & ~(255 << 8)))
7967         || (ix86_match_ccmode (insn, CCNOmode)
7968             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7969   [(set (match_dup 0)
7970         (match_op_dup 1
7971           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7972                    (match_dup 3))
7973            (const_int 0)]))]
7974   "operands[2] = gen_lowpart (SImode, operands[2]);
7975    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7976
7977 (define_split
7978   [(set (match_operand 0 "flags_reg_operand" "")
7979         (match_operator 1 "compare_operator"
7980           [(and (match_operand 2 "nonimmediate_operand" "")
7981                 (match_operand 3 "const_int_operand" ""))
7982            (const_int 0)]))]
7983    "reload_completed
7984     && GET_MODE (operands[2]) != QImode
7985     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986     && ((ix86_match_ccmode (insn, CCZmode)
7987          && !(INTVAL (operands[3]) & ~255))
7988         || (ix86_match_ccmode (insn, CCNOmode)
7989             && !(INTVAL (operands[3]) & ~127)))"
7990   [(set (match_dup 0)
7991         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7992                          (const_int 0)]))]
7993   "operands[2] = gen_lowpart (QImode, operands[2]);
7994    operands[3] = gen_lowpart (QImode, operands[3]);")
7995
7996
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers.  If this is considered useful,
7999 ;; it should be done with splitters.
8000
8001 (define_expand "anddi3"
8002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005    (clobber (reg:CC FLAGS_REG))]
8006   "TARGET_64BIT"
8007   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8008
8009 (define_insn "*anddi_1_rex64"
8010   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8015 {
8016   switch (get_attr_type (insn))
8017     {
8018     case TYPE_IMOVX:
8019       {
8020         enum machine_mode mode;
8021
8022         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023         if (INTVAL (operands[2]) == 0xff)
8024           mode = QImode;
8025         else
8026           {
8027             gcc_assert (INTVAL (operands[2]) == 0xffff);
8028             mode = HImode;
8029           }
8030         
8031         operands[1] = gen_lowpart (mode, operands[1]);
8032         if (mode == QImode)
8033           return "movz{bq|x}\t{%1,%0|%0, %1}";
8034         else
8035           return "movz{wq|x}\t{%1,%0|%0, %1}";
8036       }
8037
8038     default:
8039       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040       if (get_attr_mode (insn) == MODE_SI)
8041         return "and{l}\t{%k2, %k0|%k0, %k2}";
8042       else
8043         return "and{q}\t{%2, %0|%0, %2}";
8044     }
8045 }
8046   [(set_attr "type" "alu,alu,alu,imovx")
8047    (set_attr "length_immediate" "*,*,*,0")
8048    (set_attr "mode" "SI,DI,DI,DI")])
8049
8050 (define_insn "*anddi_2"
8051   [(set (reg FLAGS_REG)
8052         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054                  (const_int 0)))
8055    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056         (and:DI (match_dup 1) (match_dup 2)))]
8057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058    && ix86_binary_operator_ok (AND, DImode, operands)"
8059   "@
8060    and{l}\t{%k2, %k0|%k0, %k2}
8061    and{q}\t{%2, %0|%0, %2}
8062    and{q}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "SI,DI,DI")])
8065
8066 (define_expand "andsi3"
8067   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069                 (match_operand:SI 2 "general_operand" "")))
8070    (clobber (reg:CC FLAGS_REG))]
8071   ""
8072   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8073
8074 (define_insn "*andsi_1"
8075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "ix86_binary_operator_ok (AND, SImode, operands)"
8080 {
8081   switch (get_attr_type (insn))
8082     {
8083     case TYPE_IMOVX:
8084       {
8085         enum machine_mode mode;
8086
8087         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088         if (INTVAL (operands[2]) == 0xff)
8089           mode = QImode;
8090         else
8091           {
8092             gcc_assert (INTVAL (operands[2]) == 0xffff);
8093             mode = HImode;
8094           }
8095         
8096         operands[1] = gen_lowpart (mode, operands[1]);
8097         if (mode == QImode)
8098           return "movz{bl|x}\t{%1,%0|%0, %1}";
8099         else
8100           return "movz{wl|x}\t{%1,%0|%0, %1}";
8101       }
8102
8103     default:
8104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105       return "and{l}\t{%2, %0|%0, %2}";
8106     }
8107 }
8108   [(set_attr "type" "alu,alu,imovx")
8109    (set_attr "length_immediate" "*,*,0")
8110    (set_attr "mode" "SI")])
8111
8112 (define_split
8113   [(set (match_operand 0 "register_operand" "")
8114         (and (match_dup 0)
8115              (const_int -65536)))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119   "operands[1] = gen_lowpart (HImode, operands[0]);")
8120
8121 (define_split
8122   [(set (match_operand 0 "ext_register_operand" "")
8123         (and (match_dup 0)
8124              (const_int -256)))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128   "operands[1] = gen_lowpart (QImode, operands[0]);")
8129
8130 (define_split
8131   [(set (match_operand 0 "ext_register_operand" "")
8132         (and (match_dup 0)
8133              (const_int -65281)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136   [(parallel [(set (zero_extract:SI (match_dup 0)
8137                                     (const_int 8)
8138                                     (const_int 8))
8139                    (xor:SI 
8140                      (zero_extract:SI (match_dup 0)
8141                                       (const_int 8)
8142                                       (const_int 8))
8143                      (zero_extract:SI (match_dup 0)
8144                                       (const_int 8)
8145                                       (const_int 8))))
8146               (clobber (reg:CC FLAGS_REG))])]
8147   "operands[0] = gen_lowpart (SImode, operands[0]);")
8148
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151   [(set (match_operand:DI 0 "register_operand" "=r")
8152         (zero_extend:DI
8153           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154                   (match_operand:SI 2 "general_operand" "rim"))))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157   "and{l}\t{%2, %k0|%k0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI")])
8160
8161 (define_insn "*andsi_2"
8162   [(set (reg FLAGS_REG)
8163         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164                          (match_operand:SI 2 "general_operand" "rim,ri"))
8165                  (const_int 0)))
8166    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167         (and:SI (match_dup 1) (match_dup 2)))]
8168   "ix86_match_ccmode (insn, CCNOmode)
8169    && ix86_binary_operator_ok (AND, SImode, operands)"
8170   "and{l}\t{%2, %0|%0, %2}"
8171   [(set_attr "type" "alu")
8172    (set_attr "mode" "SI")])
8173
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176   [(set (reg FLAGS_REG)
8177         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178                          (match_operand:SI 2 "general_operand" "rim"))
8179                  (const_int 0)))
8180    (set (match_operand:DI 0 "register_operand" "=r")
8181         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183    && ix86_binary_operator_ok (AND, SImode, operands)"
8184   "and{l}\t{%2, %k0|%k0, %2}"
8185   [(set_attr "type" "alu")
8186    (set_attr "mode" "SI")])
8187
8188 (define_expand "andhi3"
8189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191                 (match_operand:HI 2 "general_operand" "")))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "TARGET_HIMODE_MATH"
8194   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8195
8196 (define_insn "*andhi_1"
8197   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "ix86_binary_operator_ok (AND, HImode, operands)"
8202 {
8203   switch (get_attr_type (insn))
8204     {
8205     case TYPE_IMOVX:
8206       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207       gcc_assert (INTVAL (operands[2]) == 0xff);
8208       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8209
8210     default:
8211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212
8213       return "and{w}\t{%2, %0|%0, %2}";
8214     }
8215 }
8216   [(set_attr "type" "alu,alu,imovx")
8217    (set_attr "length_immediate" "*,*,0")
8218    (set_attr "mode" "HI,HI,SI")])
8219
8220 (define_insn "*andhi_2"
8221   [(set (reg FLAGS_REG)
8222         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223                          (match_operand:HI 2 "general_operand" "rim,ri"))
8224                  (const_int 0)))
8225    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226         (and:HI (match_dup 1) (match_dup 2)))]
8227   "ix86_match_ccmode (insn, CCNOmode)
8228    && ix86_binary_operator_ok (AND, HImode, operands)"
8229   "and{w}\t{%2, %0|%0, %2}"
8230   [(set_attr "type" "alu")
8231    (set_attr "mode" "HI")])
8232
8233 (define_expand "andqi3"
8234   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236                 (match_operand:QI 2 "general_operand" "")))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "TARGET_QIMODE_MATH"
8239   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8240
8241 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8242 (define_insn "*andqi_1"
8243   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246    (clobber (reg:CC FLAGS_REG))]
8247   "ix86_binary_operator_ok (AND, QImode, operands)"
8248   "@
8249    and{b}\t{%2, %0|%0, %2}
8250    and{b}\t{%2, %0|%0, %2}
8251    and{l}\t{%k2, %k0|%k0, %k2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "QI,QI,SI")])
8254
8255 (define_insn "*andqi_1_slp"
8256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257         (and:QI (match_dup 0)
8258                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262   "and{b}\t{%1, %0|%0, %1}"
8263   [(set_attr "type" "alu1")
8264    (set_attr "mode" "QI")])
8265
8266 (define_insn "*andqi_2_maybe_si"
8267   [(set (reg FLAGS_REG)
8268         (compare (and:QI
8269                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8271                  (const_int 0)))
8272    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273         (and:QI (match_dup 1) (match_dup 2)))]
8274   "ix86_binary_operator_ok (AND, QImode, operands)
8275    && ix86_match_ccmode (insn,
8276                          GET_CODE (operands[2]) == CONST_INT
8277                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8278 {
8279   if (which_alternative == 2)
8280     {
8281       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283       return "and{l}\t{%2, %k0|%k0, %2}";
8284     }
8285   return "and{b}\t{%2, %0|%0, %2}";
8286 }
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_2"
8291   [(set (reg FLAGS_REG)
8292         (compare (and:QI
8293                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294                    (match_operand:QI 2 "general_operand" "qim,qi"))
8295                  (const_int 0)))
8296    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297         (and:QI (match_dup 1) (match_dup 2)))]
8298   "ix86_match_ccmode (insn, CCNOmode)
8299    && ix86_binary_operator_ok (AND, QImode, operands)"
8300   "and{b}\t{%2, %0|%0, %2}"
8301   [(set_attr "type" "alu")
8302    (set_attr "mode" "QI")])
8303
8304 (define_insn "*andqi_2_slp"
8305   [(set (reg FLAGS_REG)
8306         (compare (and:QI
8307                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8309                  (const_int 0)))
8310    (set (strict_low_part (match_dup 0))
8311         (and:QI (match_dup 0) (match_dup 1)))]
8312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313    && ix86_match_ccmode (insn, CCNOmode)
8314    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315   "and{b}\t{%1, %0|%0, %1}"
8316   [(set_attr "type" "alu1")
8317    (set_attr "mode" "QI")])
8318
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8322
8323 (define_insn "andqi_ext_0"
8324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325                          (const_int 8)
8326                          (const_int 8))
8327         (and:SI 
8328           (zero_extract:SI
8329             (match_operand 1 "ext_register_operand" "0")
8330             (const_int 8)
8331             (const_int 8))
8332           (match_operand 2 "const_int_operand" "n")))
8333    (clobber (reg:CC FLAGS_REG))]
8334   ""
8335   "and{b}\t{%2, %h0|%h0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "length_immediate" "1")
8338    (set_attr "mode" "QI")])
8339
8340 ;; Generated by peephole translating test to and.  This shows up
8341 ;; often in fp comparisons.
8342
8343 (define_insn "*andqi_ext_0_cc"
8344   [(set (reg FLAGS_REG)
8345         (compare
8346           (and:SI
8347             (zero_extract:SI
8348               (match_operand 1 "ext_register_operand" "0")
8349               (const_int 8)
8350               (const_int 8))
8351             (match_operand 2 "const_int_operand" "n"))
8352           (const_int 0)))
8353    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8354                          (const_int 8)
8355                          (const_int 8))
8356         (and:SI 
8357           (zero_extract:SI
8358             (match_dup 1)
8359             (const_int 8)
8360             (const_int 8))
8361           (match_dup 2)))]
8362   "ix86_match_ccmode (insn, CCNOmode)"
8363   "and{b}\t{%2, %h0|%h0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "length_immediate" "1")
8366    (set_attr "mode" "QI")])
8367
8368 (define_insn "*andqi_ext_1"
8369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370                          (const_int 8)
8371                          (const_int 8))
8372         (and:SI 
8373           (zero_extract:SI
8374             (match_operand 1 "ext_register_operand" "0")
8375             (const_int 8)
8376             (const_int 8))
8377           (zero_extend:SI
8378             (match_operand:QI 2 "general_operand" "Qm"))))
8379    (clobber (reg:CC FLAGS_REG))]
8380   "!TARGET_64BIT"
8381   "and{b}\t{%2, %h0|%h0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "length_immediate" "0")
8384    (set_attr "mode" "QI")])
8385
8386 (define_insn "*andqi_ext_1_rex64"
8387   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388                          (const_int 8)
8389                          (const_int 8))
8390         (and:SI 
8391           (zero_extract:SI
8392             (match_operand 1 "ext_register_operand" "0")
8393             (const_int 8)
8394             (const_int 8))
8395           (zero_extend:SI
8396             (match_operand 2 "ext_register_operand" "Q"))))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "TARGET_64BIT"
8399   "and{b}\t{%2, %h0|%h0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "length_immediate" "0")
8402    (set_attr "mode" "QI")])
8403
8404 (define_insn "*andqi_ext_2"
8405   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406                          (const_int 8)
8407                          (const_int 8))
8408         (and:SI
8409           (zero_extract:SI
8410             (match_operand 1 "ext_register_operand" "%0")
8411             (const_int 8)
8412             (const_int 8))
8413           (zero_extract:SI
8414             (match_operand 2 "ext_register_operand" "Q")
8415             (const_int 8)
8416             (const_int 8))))
8417    (clobber (reg:CC FLAGS_REG))]
8418   ""
8419   "and{b}\t{%h2, %h0|%h0, %h2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "length_immediate" "0")
8422    (set_attr "mode" "QI")])
8423
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8429 (define_split
8430   [(set (match_operand 0 "register_operand" "")
8431         (and (match_operand 1 "register_operand" "")
8432              (match_operand 2 "const_int_operand" "")))
8433    (clobber (reg:CC FLAGS_REG))]
8434    "reload_completed
8435     && QI_REG_P (operands[0])
8436     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437     && !(~INTVAL (operands[2]) & ~(255 << 8))
8438     && GET_MODE (operands[0]) != QImode"
8439   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440                    (and:SI (zero_extract:SI (match_dup 1)
8441                                             (const_int 8) (const_int 8))
8442                            (match_dup 2)))
8443               (clobber (reg:CC FLAGS_REG))])]
8444   "operands[0] = gen_lowpart (SImode, operands[0]);
8445    operands[1] = gen_lowpart (SImode, operands[1]);
8446    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8447
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8450 (define_split
8451   [(set (match_operand 0 "register_operand" "")
8452         (and (match_operand 1 "general_operand" "")
8453              (match_operand 2 "const_int_operand" "")))
8454    (clobber (reg:CC FLAGS_REG))]
8455    "reload_completed
8456     && ANY_QI_REG_P (operands[0])
8457     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458     && !(~INTVAL (operands[2]) & ~255)
8459     && !(INTVAL (operands[2]) & 128)
8460     && GET_MODE (operands[0]) != QImode"
8461   [(parallel [(set (strict_low_part (match_dup 0))
8462                    (and:QI (match_dup 1)
8463                            (match_dup 2)))
8464               (clobber (reg:CC FLAGS_REG))])]
8465   "operands[0] = gen_lowpart (QImode, operands[0]);
8466    operands[1] = gen_lowpart (QImode, operands[1]);
8467    operands[2] = gen_lowpart (QImode, operands[2]);")
8468 \f
8469 ;; Logical inclusive OR instructions
8470
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8473
8474 (define_expand "iordi3"
8475   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477                 (match_operand:DI 2 "x86_64_general_operand" "")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT"
8480   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8481
8482 (define_insn "*iordi_1_rex64"
8483   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "TARGET_64BIT
8488    && ix86_binary_operator_ok (IOR, DImode, operands)"
8489   "or{q}\t{%2, %0|%0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "mode" "DI")])
8492
8493 (define_insn "*iordi_2_rex64"
8494   [(set (reg FLAGS_REG)
8495         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8497                  (const_int 0)))
8498    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499         (ior:DI (match_dup 1) (match_dup 2)))]
8500   "TARGET_64BIT
8501    && ix86_match_ccmode (insn, CCNOmode)
8502    && ix86_binary_operator_ok (IOR, DImode, operands)"
8503   "or{q}\t{%2, %0|%0, %2}"
8504   [(set_attr "type" "alu")
8505    (set_attr "mode" "DI")])
8506
8507 (define_insn "*iordi_3_rex64"
8508   [(set (reg FLAGS_REG)
8509         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8511                  (const_int 0)))
8512    (clobber (match_scratch:DI 0 "=r"))]
8513   "TARGET_64BIT
8514    && ix86_match_ccmode (insn, CCNOmode)
8515    && ix86_binary_operator_ok (IOR, DImode, operands)"
8516   "or{q}\t{%2, %0|%0, %2}"
8517   [(set_attr "type" "alu")
8518    (set_attr "mode" "DI")])
8519
8520
8521 (define_expand "iorsi3"
8522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524                 (match_operand:SI 2 "general_operand" "")))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8528
8529 (define_insn "*iorsi_1"
8530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "ix86_binary_operator_ok (IOR, SImode, operands)"
8535   "or{l}\t{%2, %0|%0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "mode" "SI")])
8538
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541   [(set (match_operand:DI 0 "register_operand" "=rm")
8542         (zero_extend:DI
8543           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544                   (match_operand:SI 2 "general_operand" "rim"))))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547   "or{l}\t{%2, %k0|%k0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI")])
8550
8551 (define_insn "*iorsi_1_zext_imm"
8552   [(set (match_operand:DI 0 "register_operand" "=rm")
8553         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555    (clobber (reg:CC FLAGS_REG))]
8556   "TARGET_64BIT"
8557   "or{l}\t{%2, %k0|%k0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "SI")])
8560
8561 (define_insn "*iorsi_2"
8562   [(set (reg FLAGS_REG)
8563         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564                          (match_operand:SI 2 "general_operand" "rim,ri"))
8565                  (const_int 0)))
8566    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567         (ior:SI (match_dup 1) (match_dup 2)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && ix86_binary_operator_ok (IOR, SImode, operands)"
8570   "or{l}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577   [(set (reg FLAGS_REG)
8578         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                          (match_operand:SI 2 "general_operand" "rim"))
8580                  (const_int 0)))
8581    (set (match_operand:DI 0 "register_operand" "=r")
8582         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (IOR, SImode, operands)"
8585   "or{l}\t{%2, %k0|%k0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8588
8589 (define_insn "*iorsi_2_zext_imm"
8590   [(set (reg FLAGS_REG)
8591         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8593                  (const_int 0)))
8594    (set (match_operand:DI 0 "register_operand" "=r")
8595         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597    && ix86_binary_operator_ok (IOR, SImode, operands)"
8598   "or{l}\t{%2, %k0|%k0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "SI")])
8601
8602 (define_insn "*iorsi_3"
8603   [(set (reg FLAGS_REG)
8604         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605                          (match_operand:SI 2 "general_operand" "rim"))
8606                  (const_int 0)))
8607    (clobber (match_scratch:SI 0 "=r"))]
8608   "ix86_match_ccmode (insn, CCNOmode)
8609    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610   "or{l}\t{%2, %0|%0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "mode" "SI")])
8613
8614 (define_expand "iorhi3"
8615   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617                 (match_operand:HI 2 "general_operand" "")))
8618    (clobber (reg:CC FLAGS_REG))]
8619   "TARGET_HIMODE_MATH"
8620   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8621
8622 (define_insn "*iorhi_1"
8623   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "ix86_binary_operator_ok (IOR, HImode, operands)"
8628   "or{w}\t{%2, %0|%0, %2}"
8629   [(set_attr "type" "alu")
8630    (set_attr "mode" "HI")])
8631
8632 (define_insn "*iorhi_2"
8633   [(set (reg FLAGS_REG)
8634         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635                          (match_operand:HI 2 "general_operand" "rim,ri"))
8636                  (const_int 0)))
8637    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638         (ior:HI (match_dup 1) (match_dup 2)))]
8639   "ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (IOR, HImode, operands)"
8641   "or{w}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "HI")])
8644
8645 (define_insn "*iorhi_3"
8646   [(set (reg FLAGS_REG)
8647         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648                          (match_operand:HI 2 "general_operand" "rim"))
8649                  (const_int 0)))
8650    (clobber (match_scratch:HI 0 "=r"))]
8651   "ix86_match_ccmode (insn, CCNOmode)
8652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653   "or{w}\t{%2, %0|%0, %2}"
8654   [(set_attr "type" "alu")
8655    (set_attr "mode" "HI")])
8656
8657 (define_expand "iorqi3"
8658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660                 (match_operand:QI 2 "general_operand" "")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "TARGET_QIMODE_MATH"
8663   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8664
8665 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8666 (define_insn "*iorqi_1"
8667   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "ix86_binary_operator_ok (IOR, QImode, operands)"
8672   "@
8673    or{b}\t{%2, %0|%0, %2}
8674    or{b}\t{%2, %0|%0, %2}
8675    or{l}\t{%k2, %k0|%k0, %k2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "QI,QI,SI")])
8678
8679 (define_insn "*iorqi_1_slp"
8680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681         (ior:QI (match_dup 0)
8682                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683    (clobber (reg:CC FLAGS_REG))]
8684   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686   "or{b}\t{%1, %0|%0, %1}"
8687   [(set_attr "type" "alu1")
8688    (set_attr "mode" "QI")])
8689
8690 (define_insn "*iorqi_2"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693                          (match_operand:QI 2 "general_operand" "qim,qi"))
8694                  (const_int 0)))
8695    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696         (ior:QI (match_dup 1) (match_dup 2)))]
8697   "ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, QImode, operands)"
8699   "or{b}\t{%2, %0|%0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "QI")])
8702
8703 (define_insn "*iorqi_2_slp"
8704   [(set (reg FLAGS_REG)
8705         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706                          (match_operand:QI 1 "general_operand" "qim,qi"))
8707                  (const_int 0)))
8708    (set (strict_low_part (match_dup 0))
8709         (ior:QI (match_dup 0) (match_dup 1)))]
8710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711    && ix86_match_ccmode (insn, CCNOmode)
8712    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713   "or{b}\t{%1, %0|%0, %1}"
8714   [(set_attr "type" "alu1")
8715    (set_attr "mode" "QI")])
8716
8717 (define_insn "*iorqi_3"
8718   [(set (reg FLAGS_REG)
8719         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720                          (match_operand:QI 2 "general_operand" "qim"))
8721                  (const_int 0)))
8722    (clobber (match_scratch:QI 0 "=q"))]
8723   "ix86_match_ccmode (insn, CCNOmode)
8724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725   "or{b}\t{%2, %0|%0, %2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "QI")])
8728
8729 (define_insn "iorqi_ext_0"
8730   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731                          (const_int 8)
8732                          (const_int 8))
8733         (ior:SI 
8734           (zero_extract:SI
8735             (match_operand 1 "ext_register_operand" "0")
8736             (const_int 8)
8737             (const_int 8))
8738           (match_operand 2 "const_int_operand" "n")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741   "or{b}\t{%2, %h0|%h0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "length_immediate" "1")
8744    (set_attr "mode" "QI")])
8745
8746 (define_insn "*iorqi_ext_1"
8747   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748                          (const_int 8)
8749                          (const_int 8))
8750         (ior:SI 
8751           (zero_extract:SI
8752             (match_operand 1 "ext_register_operand" "0")
8753             (const_int 8)
8754             (const_int 8))
8755           (zero_extend:SI
8756             (match_operand:QI 2 "general_operand" "Qm"))))
8757    (clobber (reg:CC FLAGS_REG))]
8758   "!TARGET_64BIT
8759    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760   "or{b}\t{%2, %h0|%h0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "length_immediate" "0")
8763    (set_attr "mode" "QI")])
8764
8765 (define_insn "*iorqi_ext_1_rex64"
8766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767                          (const_int 8)
8768                          (const_int 8))
8769         (ior:SI 
8770           (zero_extract:SI
8771             (match_operand 1 "ext_register_operand" "0")
8772             (const_int 8)
8773             (const_int 8))
8774           (zero_extend:SI
8775             (match_operand 2 "ext_register_operand" "Q"))))
8776    (clobber (reg:CC FLAGS_REG))]
8777   "TARGET_64BIT
8778    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779   "or{b}\t{%2, %h0|%h0, %2}"
8780   [(set_attr "type" "alu")
8781    (set_attr "length_immediate" "0")
8782    (set_attr "mode" "QI")])
8783
8784 (define_insn "*iorqi_ext_2"
8785   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786                          (const_int 8)
8787                          (const_int 8))
8788         (ior:SI 
8789           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8790                            (const_int 8)
8791                            (const_int 8))
8792           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8793                            (const_int 8)
8794                            (const_int 8))))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797   "ior{b}\t{%h2, %h0|%h0, %h2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "length_immediate" "0")
8800    (set_attr "mode" "QI")])
8801
8802 (define_split
8803   [(set (match_operand 0 "register_operand" "")
8804         (ior (match_operand 1 "register_operand" "")
8805              (match_operand 2 "const_int_operand" "")))
8806    (clobber (reg:CC FLAGS_REG))]
8807    "reload_completed
8808     && QI_REG_P (operands[0])
8809     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810     && !(INTVAL (operands[2]) & ~(255 << 8))
8811     && GET_MODE (operands[0]) != QImode"
8812   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813                    (ior:SI (zero_extract:SI (match_dup 1)
8814                                             (const_int 8) (const_int 8))
8815                            (match_dup 2)))
8816               (clobber (reg:CC FLAGS_REG))])]
8817   "operands[0] = gen_lowpart (SImode, operands[0]);
8818    operands[1] = gen_lowpart (SImode, operands[1]);
8819    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8820
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8823 (define_split
8824   [(set (match_operand 0 "register_operand" "")
8825         (ior (match_operand 1 "general_operand" "")
8826              (match_operand 2 "const_int_operand" "")))
8827    (clobber (reg:CC FLAGS_REG))]
8828    "reload_completed
8829     && ANY_QI_REG_P (operands[0])
8830     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831     && !(INTVAL (operands[2]) & ~255)
8832     && (INTVAL (operands[2]) & 128)
8833     && GET_MODE (operands[0]) != QImode"
8834   [(parallel [(set (strict_low_part (match_dup 0))
8835                    (ior:QI (match_dup 1)
8836                            (match_dup 2)))
8837               (clobber (reg:CC FLAGS_REG))])]
8838   "operands[0] = gen_lowpart (QImode, operands[0]);
8839    operands[1] = gen_lowpart (QImode, operands[1]);
8840    operands[2] = gen_lowpart (QImode, operands[2]);")
8841 \f
8842 ;; Logical XOR instructions
8843
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8846
8847 (define_expand "xordi3"
8848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850                 (match_operand:DI 2 "x86_64_general_operand" "")))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "TARGET_64BIT"
8853   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8854
8855 (define_insn "*xordi_1_rex64"
8856   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859    (clobber (reg:CC FLAGS_REG))]
8860   "TARGET_64BIT
8861    && ix86_binary_operator_ok (XOR, DImode, operands)"
8862   "@
8863    xor{q}\t{%2, %0|%0, %2}
8864    xor{q}\t{%2, %0|%0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "DI,DI")])
8867
8868 (define_insn "*xordi_2_rex64"
8869   [(set (reg FLAGS_REG)
8870         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8872                  (const_int 0)))
8873    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874         (xor:DI (match_dup 1) (match_dup 2)))]
8875   "TARGET_64BIT
8876    && ix86_match_ccmode (insn, CCNOmode)
8877    && ix86_binary_operator_ok (XOR, DImode, operands)"
8878   "@
8879    xor{q}\t{%2, %0|%0, %2}
8880    xor{q}\t{%2, %0|%0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "mode" "DI,DI")])
8883
8884 (define_insn "*xordi_3_rex64"
8885   [(set (reg FLAGS_REG)
8886         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8888                  (const_int 0)))
8889    (clobber (match_scratch:DI 0 "=r"))]
8890   "TARGET_64BIT
8891    && ix86_match_ccmode (insn, CCNOmode)
8892    && ix86_binary_operator_ok (XOR, DImode, operands)"
8893   "xor{q}\t{%2, %0|%0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "mode" "DI")])
8896
8897 (define_expand "xorsi3"
8898   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900                 (match_operand:SI 2 "general_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   ""
8903   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8904
8905 (define_insn "*xorsi_1"
8906   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908                 (match_operand:SI 2 "general_operand" "ri,rm")))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "ix86_binary_operator_ok (XOR, SImode, operands)"
8911   "xor{l}\t{%2, %0|%0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918   [(set (match_operand:DI 0 "register_operand" "=r")
8919         (zero_extend:DI
8920           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921                   (match_operand:SI 2 "general_operand" "rim"))))
8922    (clobber (reg:CC FLAGS_REG))]
8923   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924   "xor{l}\t{%2, %k0|%k0, %2}"
8925   [(set_attr "type" "alu")
8926    (set_attr "mode" "SI")])
8927
8928 (define_insn "*xorsi_1_zext_imm"
8929   [(set (match_operand:DI 0 "register_operand" "=r")
8930         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934   "xor{l}\t{%2, %k0|%k0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "SI")])
8937
8938 (define_insn "*xorsi_2"
8939   [(set (reg FLAGS_REG)
8940         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941                          (match_operand:SI 2 "general_operand" "rim,ri"))
8942                  (const_int 0)))
8943    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944         (xor:SI (match_dup 1) (match_dup 2)))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && ix86_binary_operator_ok (XOR, SImode, operands)"
8947   "xor{l}\t{%2, %0|%0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "mode" "SI")])
8950
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954   [(set (reg FLAGS_REG)
8955         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                          (match_operand:SI 2 "general_operand" "rim"))
8957                  (const_int 0)))
8958    (set (match_operand:DI 0 "register_operand" "=r")
8959         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961    && ix86_binary_operator_ok (XOR, SImode, operands)"
8962   "xor{l}\t{%2, %k0|%k0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "SI")])
8965
8966 (define_insn "*xorsi_2_zext_imm"
8967   [(set (reg FLAGS_REG)
8968         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8970                  (const_int 0)))
8971    (set (match_operand:DI 0 "register_operand" "=r")
8972         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974    && ix86_binary_operator_ok (XOR, SImode, operands)"
8975   "xor{l}\t{%2, %k0|%k0, %2}"
8976   [(set_attr "type" "alu")
8977    (set_attr "mode" "SI")])
8978
8979 (define_insn "*xorsi_3"
8980   [(set (reg FLAGS_REG)
8981         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982                          (match_operand:SI 2 "general_operand" "rim"))
8983                  (const_int 0)))
8984    (clobber (match_scratch:SI 0 "=r"))]
8985   "ix86_match_ccmode (insn, CCNOmode)
8986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987   "xor{l}\t{%2, %0|%0, %2}"
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "SI")])
8990
8991 (define_expand "xorhi3"
8992   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994                 (match_operand:HI 2 "general_operand" "")))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "TARGET_HIMODE_MATH"
8997   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8998
8999 (define_insn "*xorhi_1"
9000   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "ix86_binary_operator_ok (XOR, HImode, operands)"
9005   "xor{w}\t{%2, %0|%0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "HI")])
9008
9009 (define_insn "*xorhi_2"
9010   [(set (reg FLAGS_REG)
9011         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012                          (match_operand:HI 2 "general_operand" "rim,ri"))
9013                  (const_int 0)))
9014    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015         (xor:HI (match_dup 1) (match_dup 2)))]
9016   "ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (XOR, HImode, operands)"
9018   "xor{w}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "HI")])
9021
9022 (define_insn "*xorhi_3"
9023   [(set (reg FLAGS_REG)
9024         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025                          (match_operand:HI 2 "general_operand" "rim"))
9026                  (const_int 0)))
9027    (clobber (match_scratch:HI 0 "=r"))]
9028   "ix86_match_ccmode (insn, CCNOmode)
9029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030   "xor{w}\t{%2, %0|%0, %2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "mode" "HI")])
9033
9034 (define_expand "xorqi3"
9035   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037                 (match_operand:QI 2 "general_operand" "")))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "TARGET_QIMODE_MATH"
9040   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9041
9042 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9043 (define_insn "*xorqi_1"
9044   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047    (clobber (reg:CC FLAGS_REG))]
9048   "ix86_binary_operator_ok (XOR, QImode, operands)"
9049   "@
9050    xor{b}\t{%2, %0|%0, %2}
9051    xor{b}\t{%2, %0|%0, %2}
9052    xor{l}\t{%k2, %k0|%k0, %k2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "QI,QI,SI")])
9055
9056 (define_insn "*xorqi_1_slp"
9057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058         (xor:QI (match_dup 0)
9059                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060    (clobber (reg:CC FLAGS_REG))]
9061   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063   "xor{b}\t{%1, %0|%0, %1}"
9064   [(set_attr "type" "alu1")
9065    (set_attr "mode" "QI")])
9066
9067 (define_insn "xorqi_ext_0"
9068   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9069                          (const_int 8)
9070                          (const_int 8))
9071         (xor:SI 
9072           (zero_extract:SI
9073             (match_operand 1 "ext_register_operand" "0")
9074             (const_int 8)
9075             (const_int 8))
9076           (match_operand 2 "const_int_operand" "n")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079   "xor{b}\t{%2, %h0|%h0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "length_immediate" "1")
9082    (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_ext_1"
9085   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9086                          (const_int 8)
9087                          (const_int 8))
9088         (xor:SI 
9089           (zero_extract:SI
9090             (match_operand 1 "ext_register_operand" "0")
9091             (const_int 8)
9092             (const_int 8))
9093           (zero_extend:SI
9094             (match_operand:QI 2 "general_operand" "Qm"))))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "!TARGET_64BIT
9097    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098   "xor{b}\t{%2, %h0|%h0, %2}"
9099   [(set_attr "type" "alu")
9100    (set_attr "length_immediate" "0")
9101    (set_attr "mode" "QI")])
9102
9103 (define_insn "*xorqi_ext_1_rex64"
9104   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105                          (const_int 8)
9106                          (const_int 8))
9107         (xor:SI 
9108           (zero_extract:SI
9109             (match_operand 1 "ext_register_operand" "0")
9110             (const_int 8)
9111             (const_int 8))
9112           (zero_extend:SI
9113             (match_operand 2 "ext_register_operand" "Q"))))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "TARGET_64BIT
9116    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117   "xor{b}\t{%2, %h0|%h0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "length_immediate" "0")
9120    (set_attr "mode" "QI")])
9121
9122 (define_insn "*xorqi_ext_2"
9123   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (xor:SI 
9127           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9128                            (const_int 8)
9129                            (const_int 8))
9130           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9131                            (const_int 8)
9132                            (const_int 8))))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135   "xor{b}\t{%h2, %h0|%h0, %h2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "length_immediate" "0")
9138    (set_attr "mode" "QI")])
9139
9140 (define_insn "*xorqi_cc_1"
9141   [(set (reg FLAGS_REG)
9142         (compare
9143           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144                   (match_operand:QI 2 "general_operand" "qim,qi"))
9145           (const_int 0)))
9146    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147         (xor:QI (match_dup 1) (match_dup 2)))]
9148   "ix86_match_ccmode (insn, CCNOmode)
9149    && ix86_binary_operator_ok (XOR, QImode, operands)"
9150   "xor{b}\t{%2, %0|%0, %2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI")])
9153
9154 (define_insn "*xorqi_2_slp"
9155   [(set (reg FLAGS_REG)
9156         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157                          (match_operand:QI 1 "general_operand" "qim,qi"))
9158                  (const_int 0)))
9159    (set (strict_low_part (match_dup 0))
9160         (xor:QI (match_dup 0) (match_dup 1)))]
9161   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162    && ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164   "xor{b}\t{%1, %0|%0, %1}"
9165   [(set_attr "type" "alu1")
9166    (set_attr "mode" "QI")])
9167
9168 (define_insn "*xorqi_cc_2"
9169   [(set (reg FLAGS_REG)
9170         (compare
9171           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172                   (match_operand:QI 2 "general_operand" "qim"))
9173           (const_int 0)))
9174    (clobber (match_scratch:QI 0 "=q"))]
9175   "ix86_match_ccmode (insn, CCNOmode)
9176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177   "xor{b}\t{%2, %0|%0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "mode" "QI")])
9180
9181 (define_insn "*xorqi_cc_ext_1"
9182   [(set (reg FLAGS_REG)
9183         (compare
9184           (xor:SI
9185             (zero_extract:SI
9186               (match_operand 1 "ext_register_operand" "0")
9187               (const_int 8)
9188               (const_int 8))
9189             (match_operand:QI 2 "general_operand" "qmn"))
9190           (const_int 0)))
9191    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9192                          (const_int 8)
9193                          (const_int 8))
9194         (xor:SI 
9195           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9196           (match_dup 2)))]
9197   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198   "xor{b}\t{%2, %h0|%h0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:SI
9206             (zero_extract:SI
9207               (match_operand 1 "ext_register_operand" "0")
9208               (const_int 8)
9209               (const_int 8))
9210             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9211           (const_int 0)))
9212    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI 
9216           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9217           (match_dup 2)))]
9218   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219   "xor{b}\t{%2, %h0|%h0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9222
9223 (define_expand "xorqi_cc_ext_1"
9224   [(parallel [
9225      (set (reg:CCNO FLAGS_REG)
9226           (compare:CCNO
9227             (xor:SI
9228               (zero_extract:SI
9229                 (match_operand 1 "ext_register_operand" "")
9230                 (const_int 8)
9231                 (const_int 8))
9232               (match_operand:QI 2 "general_operand" ""))
9233             (const_int 0)))
9234      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9235                            (const_int 8)
9236                            (const_int 8))
9237           (xor:SI 
9238             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9239             (match_dup 2)))])]
9240   ""
9241   "")
9242
9243 (define_split
9244   [(set (match_operand 0 "register_operand" "")
9245         (xor (match_operand 1 "register_operand" "")
9246              (match_operand 2 "const_int_operand" "")))
9247    (clobber (reg:CC FLAGS_REG))]
9248    "reload_completed
9249     && QI_REG_P (operands[0])
9250     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251     && !(INTVAL (operands[2]) & ~(255 << 8))
9252     && GET_MODE (operands[0]) != QImode"
9253   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254                    (xor:SI (zero_extract:SI (match_dup 1)
9255                                             (const_int 8) (const_int 8))
9256                            (match_dup 2)))
9257               (clobber (reg:CC FLAGS_REG))])]
9258   "operands[0] = gen_lowpart (SImode, operands[0]);
9259    operands[1] = gen_lowpart (SImode, operands[1]);
9260    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9261
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9264 (define_split
9265   [(set (match_operand 0 "register_operand" "")
9266         (xor (match_operand 1 "general_operand" "")
9267              (match_operand 2 "const_int_operand" "")))
9268    (clobber (reg:CC FLAGS_REG))]
9269    "reload_completed
9270     && ANY_QI_REG_P (operands[0])
9271     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272     && !(INTVAL (operands[2]) & ~255)
9273     && (INTVAL (operands[2]) & 128)
9274     && GET_MODE (operands[0]) != QImode"
9275   [(parallel [(set (strict_low_part (match_dup 0))
9276                    (xor:QI (match_dup 1)
9277                            (match_dup 2)))
9278               (clobber (reg:CC FLAGS_REG))])]
9279   "operands[0] = gen_lowpart (QImode, operands[0]);
9280    operands[1] = gen_lowpart (QImode, operands[1]);
9281    operands[2] = gen_lowpart (QImode, operands[2]);")
9282 \f
9283 ;; Negation instructions
9284
9285 (define_expand "negti2"
9286   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288               (clobber (reg:CC FLAGS_REG))])]
9289   "TARGET_64BIT"
9290   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9291
9292 (define_insn "*negti2_1"
9293   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295    (clobber (reg:CC FLAGS_REG))]
9296   "TARGET_64BIT
9297    && ix86_unary_operator_ok (NEG, TImode, operands)"
9298   "#")
9299
9300 (define_split
9301   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302         (neg:TI (match_operand:TI 1 "general_operand" "")))
9303    (clobber (reg:CC FLAGS_REG))]
9304   "TARGET_64BIT && reload_completed"
9305   [(parallel
9306     [(set (reg:CCZ FLAGS_REG)
9307           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308      (set (match_dup 0) (neg:DI (match_dup 2)))])
9309    (parallel
9310     [(set (match_dup 1)
9311           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9312                             (match_dup 3))
9313                    (const_int 0)))
9314      (clobber (reg:CC FLAGS_REG))])
9315    (parallel
9316     [(set (match_dup 1)
9317           (neg:DI (match_dup 1)))
9318      (clobber (reg:CC FLAGS_REG))])]
9319   "split_ti (operands+1, 1, operands+2, operands+3);
9320    split_ti (operands+0, 1, operands+0, operands+1);")
9321
9322 (define_expand "negdi2"
9323   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325               (clobber (reg:CC FLAGS_REG))])]
9326   ""
9327   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9328
9329 (define_insn "*negdi2_1"
9330   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "!TARGET_64BIT
9334    && ix86_unary_operator_ok (NEG, DImode, operands)"
9335   "#")
9336
9337 (define_split
9338   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339         (neg:DI (match_operand:DI 1 "general_operand" "")))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "!TARGET_64BIT && reload_completed"
9342   [(parallel
9343     [(set (reg:CCZ FLAGS_REG)
9344           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345      (set (match_dup 0) (neg:SI (match_dup 2)))])
9346    (parallel
9347     [(set (match_dup 1)
9348           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9349                             (match_dup 3))
9350                    (const_int 0)))
9351      (clobber (reg:CC FLAGS_REG))])
9352    (parallel
9353     [(set (match_dup 1)
9354           (neg:SI (match_dup 1)))
9355      (clobber (reg:CC FLAGS_REG))])]
9356   "split_di (operands+1, 1, operands+2, operands+3);
9357    split_di (operands+0, 1, operands+0, operands+1);")
9358
9359 (define_insn "*negdi2_1_rex64"
9360   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9364   "neg{q}\t%0"
9365   [(set_attr "type" "negnot")
9366    (set_attr "mode" "DI")])
9367
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9371
9372 (define_insn "*negdi2_cmpz_rex64"
9373   [(set (reg:CCZ FLAGS_REG)
9374         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9375                      (const_int 0)))
9376    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377         (neg:DI (match_dup 1)))]
9378   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9379   "neg{q}\t%0"
9380   [(set_attr "type" "negnot")
9381    (set_attr "mode" "DI")])
9382
9383
9384 (define_expand "negsi2"
9385   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9390
9391 (define_insn "*negsi2_1"
9392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "ix86_unary_operator_ok (NEG, SImode, operands)"
9396   "neg{l}\t%0"
9397   [(set_attr "type" "negnot")
9398    (set_attr "mode" "SI")])
9399
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402   [(set (match_operand:DI 0 "register_operand" "=r")
9403         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9404                                         (const_int 32)))
9405                      (const_int 32)))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9408   "neg{l}\t%k0"
9409   [(set_attr "type" "negnot")
9410    (set_attr "mode" "SI")])
9411
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9415
9416 (define_insn "*negsi2_cmpz"
9417   [(set (reg:CCZ FLAGS_REG)
9418         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9419                      (const_int 0)))
9420    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421         (neg:SI (match_dup 1)))]
9422   "ix86_unary_operator_ok (NEG, SImode, operands)"
9423   "neg{l}\t%0"
9424   [(set_attr "type" "negnot")
9425    (set_attr "mode" "SI")])
9426
9427 (define_insn "*negsi2_cmpz_zext"
9428   [(set (reg:CCZ FLAGS_REG)
9429         (compare:CCZ (lshiftrt:DI
9430                        (neg:DI (ashift:DI
9431                                  (match_operand:DI 1 "register_operand" "0")
9432                                  (const_int 32)))
9433                        (const_int 32))
9434                      (const_int 0)))
9435    (set (match_operand:DI 0 "register_operand" "=r")
9436         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9437                                         (const_int 32)))
9438                      (const_int 32)))]
9439   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9440   "neg{l}\t%k0"
9441   [(set_attr "type" "negnot")
9442    (set_attr "mode" "SI")])
9443
9444 (define_expand "neghi2"
9445   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447               (clobber (reg:CC FLAGS_REG))])]
9448   "TARGET_HIMODE_MATH"
9449   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9450
9451 (define_insn "*neghi2_1"
9452   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_unary_operator_ok (NEG, HImode, operands)"
9456   "neg{w}\t%0"
9457   [(set_attr "type" "negnot")
9458    (set_attr "mode" "HI")])
9459
9460 (define_insn "*neghi2_cmpz"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465         (neg:HI (match_dup 1)))]
9466   "ix86_unary_operator_ok (NEG, HImode, operands)"
9467   "neg{w}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "HI")])
9470
9471 (define_expand "negqi2"
9472   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474               (clobber (reg:CC FLAGS_REG))])]
9475   "TARGET_QIMODE_MATH"
9476   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9477
9478 (define_insn "*negqi2_1"
9479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "ix86_unary_operator_ok (NEG, QImode, operands)"
9483   "neg{b}\t%0"
9484   [(set_attr "type" "negnot")
9485    (set_attr "mode" "QI")])
9486
9487 (define_insn "*negqi2_cmpz"
9488   [(set (reg:CCZ FLAGS_REG)
9489         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9490                      (const_int 0)))
9491    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492         (neg:QI (match_dup 1)))]
9493   "ix86_unary_operator_ok (NEG, QImode, operands)"
9494   "neg{b}\t%0"
9495   [(set_attr "type" "negnot")
9496    (set_attr "mode" "QI")])
9497
9498 ;; Changing of sign for FP values is doable using integer unit too.
9499
9500 (define_expand "negsf2"
9501   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387 || TARGET_SSE_MATH"
9504   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9505
9506 (define_expand "abssf2"
9507   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509   "TARGET_80387 || TARGET_SSE_MATH"
9510   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9511
9512 (define_insn "*absnegsf2_mixed"
9513   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9514         (match_operator:SF 3 "absneg_operator"
9515           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9516    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9520   "#")
9521
9522 (define_insn "*absnegsf2_sse"
9523   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9524         (match_operator:SF 3 "absneg_operator"
9525           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9527    (clobber (reg:CC FLAGS_REG))]
9528   "TARGET_SSE_MATH
9529    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9530   "#")
9531
9532 (define_insn "*absnegsf2_i387"
9533   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534         (match_operator:SF 3 "absneg_operator"
9535           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536    (use (match_operand 2 "" ""))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "TARGET_80387 && !TARGET_SSE_MATH
9539    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9540   "#")
9541
9542 (define_expand "copysignsf3"
9543   [(match_operand:SF 0 "register_operand" "")
9544    (match_operand:SF 1 "nonmemory_operand" "")
9545    (match_operand:SF 2 "register_operand" "")]
9546   "TARGET_SSE_MATH"
9547 {
9548   ix86_expand_copysign (operands);
9549   DONE;
9550 })
9551
9552 (define_insn_and_split "copysignsf3_const"
9553   [(set (match_operand:SF 0 "register_operand"          "=x")
9554         (unspec:SF
9555           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9556            (match_operand:SF 2 "register_operand"       "0")
9557            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9558           UNSPEC_COPYSIGN))]
9559   "TARGET_SSE_MATH"
9560   "#"
9561   "&& reload_completed"
9562   [(const_int 0)]
9563 {
9564   ix86_split_copysign_const (operands);
9565   DONE;
9566 })
9567
9568 (define_insn "copysignsf3_var"
9569   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9570         (unspec:SF
9571           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9572            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9573            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9575           UNSPEC_COPYSIGN))
9576    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9577   "TARGET_SSE_MATH"
9578   "#")
9579
9580 (define_split
9581   [(set (match_operand:SF 0 "register_operand" "")
9582         (unspec:SF
9583           [(match_operand:SF 2 "register_operand" "")
9584            (match_operand:SF 3 "register_operand" "")
9585            (match_operand:V4SF 4 "" "")
9586            (match_operand:V4SF 5 "" "")]
9587           UNSPEC_COPYSIGN))
9588    (clobber (match_scratch:V4SF 1 ""))]
9589   "TARGET_SSE_MATH && reload_completed"
9590   [(const_int 0)]
9591 {
9592   ix86_split_copysign_var (operands);
9593   DONE;
9594 })
9595
9596 (define_expand "negdf2"
9597   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9601
9602 (define_expand "absdf2"
9603   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9607
9608 (define_insn "*absnegdf2_mixed"
9609   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9610         (match_operator:DF 3 "absneg_operator"
9611           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9612    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9616   "#")
9617
9618 (define_insn "*absnegdf2_sse"
9619   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9620         (match_operator:DF 3 "absneg_operator"
9621           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "TARGET_SSE2 && TARGET_SSE_MATH
9625    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9626   "#")
9627
9628 (define_insn "*absnegdf2_i387"
9629   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630         (match_operator:DF 3 "absneg_operator"
9631           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632    (use (match_operand 2 "" ""))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9636   "#")
9637
9638 (define_expand "copysigndf3"
9639   [(match_operand:DF 0 "register_operand" "")
9640    (match_operand:DF 1 "nonmemory_operand" "")
9641    (match_operand:DF 2 "register_operand" "")]
9642   "TARGET_SSE2 && TARGET_SSE_MATH"
9643 {
9644   ix86_expand_copysign (operands);
9645   DONE;
9646 })
9647
9648 (define_insn_and_split "copysigndf3_const"
9649   [(set (match_operand:DF 0 "register_operand"          "=x")
9650         (unspec:DF
9651           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9652            (match_operand:DF 2 "register_operand"       "0")
9653            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9654           UNSPEC_COPYSIGN))]
9655   "TARGET_SSE2 && TARGET_SSE_MATH"
9656   "#"
9657   "&& reload_completed"
9658   [(const_int 0)]
9659 {
9660   ix86_split_copysign_const (operands);
9661   DONE;
9662 })
9663
9664 (define_insn "copysigndf3_var"
9665   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9666         (unspec:DF
9667           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9668            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9669            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9671           UNSPEC_COPYSIGN))
9672    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9673   "TARGET_SSE2 && TARGET_SSE_MATH"
9674   "#")
9675
9676 (define_split
9677   [(set (match_operand:DF 0 "register_operand" "")
9678         (unspec:DF
9679           [(match_operand:DF 2 "register_operand" "")
9680            (match_operand:DF 3 "register_operand" "")
9681            (match_operand:V2DF 4 "" "")
9682            (match_operand:V2DF 5 "" "")]
9683           UNSPEC_COPYSIGN))
9684    (clobber (match_scratch:V2DF 1 ""))]
9685   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9686   [(const_int 0)]
9687 {
9688   ix86_split_copysign_var (operands);
9689   DONE;
9690 })
9691
9692 (define_expand "negxf2"
9693   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387"
9696   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9697
9698 (define_expand "absxf2"
9699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701   "TARGET_80387"
9702   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9703
9704 (define_insn "*absnegxf2_i387"
9705   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706         (match_operator:XF 3 "absneg_operator"
9707           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "TARGET_80387
9711    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9712   "#")
9713
9714 ;; Splitters for fp abs and neg.
9715
9716 (define_split
9717   [(set (match_operand 0 "fp_register_operand" "")
9718         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719    (use (match_operand 2 "" ""))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "reload_completed"
9722   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9723
9724 (define_split
9725   [(set (match_operand 0 "register_operand" "")
9726         (match_operator 3 "absneg_operator"
9727           [(match_operand 1 "register_operand" "")]))
9728    (use (match_operand 2 "nonimmediate_operand" ""))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "reload_completed && SSE_REG_P (operands[0])"
9731   [(set (match_dup 0) (match_dup 3))]
9732 {
9733   enum machine_mode mode = GET_MODE (operands[0]);
9734   enum machine_mode vmode = GET_MODE (operands[2]);
9735   rtx tmp;
9736   
9737   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739   if (operands_match_p (operands[0], operands[2]))
9740     {
9741       tmp = operands[1];
9742       operands[1] = operands[2];
9743       operands[2] = tmp;
9744     }
9745   if (GET_CODE (operands[3]) == ABS)
9746     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9747   else
9748     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9749   operands[3] = tmp;
9750 })
9751
9752 (define_split
9753   [(set (match_operand:SF 0 "register_operand" "")
9754         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755    (use (match_operand:V4SF 2 "" ""))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "reload_completed"
9758   [(parallel [(set (match_dup 0) (match_dup 1))
9759               (clobber (reg:CC FLAGS_REG))])]
9760
9761   rtx tmp;
9762   operands[0] = gen_lowpart (SImode, operands[0]);
9763   if (GET_CODE (operands[1]) == ABS)
9764     {
9765       tmp = gen_int_mode (0x7fffffff, SImode);
9766       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9767     }
9768   else
9769     {
9770       tmp = gen_int_mode (0x80000000, SImode);
9771       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9772     }
9773   operands[1] = tmp;
9774 })
9775
9776 (define_split
9777   [(set (match_operand:DF 0 "register_operand" "")
9778         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779    (use (match_operand 2 "" ""))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "reload_completed"
9782   [(parallel [(set (match_dup 0) (match_dup 1))
9783               (clobber (reg:CC FLAGS_REG))])]
9784 {
9785   rtx tmp;
9786   if (TARGET_64BIT)
9787     {
9788       tmp = gen_lowpart (DImode, operands[0]);
9789       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9790       operands[0] = tmp;
9791
9792       if (GET_CODE (operands[1]) == ABS)
9793         tmp = const0_rtx;
9794       else
9795         tmp = gen_rtx_NOT (DImode, tmp);
9796     }
9797   else
9798     {
9799       operands[0] = gen_highpart (SImode, operands[0]);
9800       if (GET_CODE (operands[1]) == ABS)
9801         {
9802           tmp = gen_int_mode (0x7fffffff, SImode);
9803           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9804         }
9805       else
9806         {
9807           tmp = gen_int_mode (0x80000000, SImode);
9808           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9809         }
9810     }
9811   operands[1] = tmp;
9812 })
9813
9814 (define_split
9815   [(set (match_operand:XF 0 "register_operand" "")
9816         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817    (use (match_operand 2 "" ""))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "reload_completed"
9820   [(parallel [(set (match_dup 0) (match_dup 1))
9821               (clobber (reg:CC FLAGS_REG))])]
9822 {
9823   rtx tmp;
9824   operands[0] = gen_rtx_REG (SImode,
9825                              true_regnum (operands[0])
9826                              + (TARGET_64BIT ? 1 : 2));
9827   if (GET_CODE (operands[1]) == ABS)
9828     {
9829       tmp = GEN_INT (0x7fff);
9830       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9831     }
9832   else
9833     {
9834       tmp = GEN_INT (0x8000);
9835       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836     }
9837   operands[1] = tmp;
9838 })
9839
9840 (define_split
9841   [(set (match_operand 0 "memory_operand" "")
9842         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843    (use (match_operand 2 "" ""))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "reload_completed"
9846   [(parallel [(set (match_dup 0) (match_dup 1))
9847               (clobber (reg:CC FLAGS_REG))])]
9848 {
9849   enum machine_mode mode = GET_MODE (operands[0]);
9850   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9851   rtx tmp;
9852
9853   operands[0] = adjust_address (operands[0], QImode, size - 1);
9854   if (GET_CODE (operands[1]) == ABS)
9855     {
9856       tmp = gen_int_mode (0x7f, QImode);
9857       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9858     }
9859   else
9860     {
9861       tmp = gen_int_mode (0x80, QImode);
9862       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9863     }
9864   operands[1] = tmp;
9865 })
9866
9867 ;; Conditionalize these after reload. If they match before reload, we 
9868 ;; lose the clobber and ability to use integer instructions.
9869
9870 (define_insn "*negsf2_1"
9871   [(set (match_operand:SF 0 "register_operand" "=f")
9872         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873   "TARGET_80387 && reload_completed"
9874   "fchs"
9875   [(set_attr "type" "fsgn")
9876    (set_attr "mode" "SF")])
9877
9878 (define_insn "*negdf2_1"
9879   [(set (match_operand:DF 0 "register_operand" "=f")
9880         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881   "TARGET_80387 && reload_completed"
9882   "fchs"
9883   [(set_attr "type" "fsgn")
9884    (set_attr "mode" "DF")])
9885
9886 (define_insn "*negxf2_1"
9887   [(set (match_operand:XF 0 "register_operand" "=f")
9888         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889   "TARGET_80387 && reload_completed"
9890   "fchs"
9891   [(set_attr "type" "fsgn")
9892    (set_attr "mode" "XF")])
9893
9894 (define_insn "*abssf2_1"
9895   [(set (match_operand:SF 0 "register_operand" "=f")
9896         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897   "TARGET_80387 && reload_completed"
9898   "fabs"
9899   [(set_attr "type" "fsgn")
9900    (set_attr "mode" "SF")])
9901
9902 (define_insn "*absdf2_1"
9903   [(set (match_operand:DF 0 "register_operand" "=f")
9904         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905   "TARGET_80387 && reload_completed"
9906   "fabs"
9907   [(set_attr "type" "fsgn")
9908    (set_attr "mode" "DF")])
9909
9910 (define_insn "*absxf2_1"
9911   [(set (match_operand:XF 0 "register_operand" "=f")
9912         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913   "TARGET_80387 && reload_completed"
9914   "fabs"
9915   [(set_attr "type" "fsgn")
9916    (set_attr "mode" "DF")])
9917
9918 (define_insn "*negextendsfdf2"
9919   [(set (match_operand:DF 0 "register_operand" "=f")
9920         (neg:DF (float_extend:DF
9921                   (match_operand:SF 1 "register_operand" "0"))))]
9922   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9926
9927 (define_insn "*negextenddfxf2"
9928   [(set (match_operand:XF 0 "register_operand" "=f")
9929         (neg:XF (float_extend:XF
9930                   (match_operand:DF 1 "register_operand" "0"))))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "XF")])
9935
9936 (define_insn "*negextendsfxf2"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (float_extend:XF
9939                   (match_operand:SF 1 "register_operand" "0"))))]
9940   "TARGET_80387"
9941   "fchs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "XF")])
9944
9945 (define_insn "*absextendsfdf2"
9946   [(set (match_operand:DF 0 "register_operand" "=f")
9947         (abs:DF (float_extend:DF
9948                   (match_operand:SF 1 "register_operand" "0"))))]
9949   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9950   "fabs"
9951   [(set_attr "type" "fsgn")
9952    (set_attr "mode" "DF")])
9953
9954 (define_insn "*absextenddfxf2"
9955   [(set (match_operand:XF 0 "register_operand" "=f")
9956         (abs:XF (float_extend:XF
9957           (match_operand:DF 1 "register_operand" "0"))))]
9958   "TARGET_80387"
9959   "fabs"
9960   [(set_attr "type" "fsgn")
9961    (set_attr "mode" "XF")])
9962
9963 (define_insn "*absextendsfxf2"
9964   [(set (match_operand:XF 0 "register_operand" "=f")
9965         (abs:XF (float_extend:XF
9966           (match_operand:SF 1 "register_operand" "0"))))]
9967   "TARGET_80387"
9968   "fabs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "XF")])
9971 \f
9972 ;; One complement instructions
9973
9974 (define_expand "one_cmpldi2"
9975   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9977   "TARGET_64BIT"
9978   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9979
9980 (define_insn "*one_cmpldi2_1_rex64"
9981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9984   "not{q}\t%0"
9985   [(set_attr "type" "negnot")
9986    (set_attr "mode" "DI")])
9987
9988 (define_insn "*one_cmpldi2_2_rex64"
9989   [(set (reg FLAGS_REG)
9990         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9991                  (const_int 0)))
9992    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993         (not:DI (match_dup 1)))]
9994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995    && ix86_unary_operator_ok (NOT, DImode, operands)"
9996   "#"
9997   [(set_attr "type" "alu1")
9998    (set_attr "mode" "DI")])
9999
10000 (define_split
10001   [(set (match_operand 0 "flags_reg_operand" "")
10002         (match_operator 2 "compare_operator"
10003           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10004            (const_int 0)]))
10005    (set (match_operand:DI 1 "nonimmediate_operand" "")
10006         (not:DI (match_dup 3)))]
10007   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008   [(parallel [(set (match_dup 0)
10009                    (match_op_dup 2
10010                      [(xor:DI (match_dup 3) (const_int -1))
10011                       (const_int 0)]))
10012               (set (match_dup 1)
10013                    (xor:DI (match_dup 3) (const_int -1)))])]
10014   "")
10015
10016 (define_expand "one_cmplsi2"
10017   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10019   ""
10020   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10021
10022 (define_insn "*one_cmplsi2_1"
10023   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025   "ix86_unary_operator_ok (NOT, SImode, operands)"
10026   "not{l}\t%0"
10027   [(set_attr "type" "negnot")
10028    (set_attr "mode" "SI")])
10029
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032   [(set (match_operand:DI 0 "register_operand" "=r")
10033         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10035   "not{l}\t%k0"
10036   [(set_attr "type" "negnot")
10037    (set_attr "mode" "SI")])
10038
10039 (define_insn "*one_cmplsi2_2"
10040   [(set (reg FLAGS_REG)
10041         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10042                  (const_int 0)))
10043    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044         (not:SI (match_dup 1)))]
10045   "ix86_match_ccmode (insn, CCNOmode)
10046    && ix86_unary_operator_ok (NOT, SImode, operands)"
10047   "#"
10048   [(set_attr "type" "alu1")
10049    (set_attr "mode" "SI")])
10050
10051 (define_split
10052   [(set (match_operand 0 "flags_reg_operand" "")
10053         (match_operator 2 "compare_operator"
10054           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10055            (const_int 0)]))
10056    (set (match_operand:SI 1 "nonimmediate_operand" "")
10057         (not:SI (match_dup 3)))]
10058   "ix86_match_ccmode (insn, CCNOmode)"
10059   [(parallel [(set (match_dup 0)
10060                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10061                                     (const_int 0)]))
10062               (set (match_dup 1)
10063                    (xor:SI (match_dup 3) (const_int -1)))])]
10064   "")
10065
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068   [(set (reg FLAGS_REG)
10069         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10070                  (const_int 0)))
10071    (set (match_operand:DI 0 "register_operand" "=r")
10072         (zero_extend:DI (not:SI (match_dup 1))))]
10073   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074    && ix86_unary_operator_ok (NOT, SImode, operands)"
10075   "#"
10076   [(set_attr "type" "alu1")
10077    (set_attr "mode" "SI")])
10078
10079 (define_split
10080   [(set (match_operand 0 "flags_reg_operand" "")
10081         (match_operator 2 "compare_operator"
10082           [(not:SI (match_operand:SI 3 "register_operand" ""))
10083            (const_int 0)]))
10084    (set (match_operand:DI 1 "register_operand" "")
10085         (zero_extend:DI (not:SI (match_dup 3))))]
10086   "ix86_match_ccmode (insn, CCNOmode)"
10087   [(parallel [(set (match_dup 0)
10088                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10089                                     (const_int 0)]))
10090               (set (match_dup 1)
10091                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10092   "")
10093
10094 (define_expand "one_cmplhi2"
10095   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097   "TARGET_HIMODE_MATH"
10098   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10099
10100 (define_insn "*one_cmplhi2_1"
10101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103   "ix86_unary_operator_ok (NOT, HImode, operands)"
10104   "not{w}\t%0"
10105   [(set_attr "type" "negnot")
10106    (set_attr "mode" "HI")])
10107
10108 (define_insn "*one_cmplhi2_2"
10109   [(set (reg FLAGS_REG)
10110         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10111                  (const_int 0)))
10112    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113         (not:HI (match_dup 1)))]
10114   "ix86_match_ccmode (insn, CCNOmode)
10115    && ix86_unary_operator_ok (NEG, HImode, operands)"
10116   "#"
10117   [(set_attr "type" "alu1")
10118    (set_attr "mode" "HI")])
10119
10120 (define_split
10121   [(set (match_operand 0 "flags_reg_operand" "")
10122         (match_operator 2 "compare_operator"
10123           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10124            (const_int 0)]))
10125    (set (match_operand:HI 1 "nonimmediate_operand" "")
10126         (not:HI (match_dup 3)))]
10127   "ix86_match_ccmode (insn, CCNOmode)"
10128   [(parallel [(set (match_dup 0)
10129                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10130                                     (const_int 0)]))
10131               (set (match_dup 1)
10132                    (xor:HI (match_dup 3) (const_int -1)))])]
10133   "")
10134
10135 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10136 (define_expand "one_cmplqi2"
10137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139   "TARGET_QIMODE_MATH"
10140   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10141
10142 (define_insn "*one_cmplqi2_1"
10143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145   "ix86_unary_operator_ok (NOT, QImode, operands)"
10146   "@
10147    not{b}\t%0
10148    not{l}\t%k0"
10149   [(set_attr "type" "negnot")
10150    (set_attr "mode" "QI,SI")])
10151
10152 (define_insn "*one_cmplqi2_2"
10153   [(set (reg FLAGS_REG)
10154         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10155                  (const_int 0)))
10156    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157         (not:QI (match_dup 1)))]
10158   "ix86_match_ccmode (insn, CCNOmode)
10159    && ix86_unary_operator_ok (NOT, QImode, operands)"
10160   "#"
10161   [(set_attr "type" "alu1")
10162    (set_attr "mode" "QI")])
10163
10164 (define_split
10165   [(set (match_operand 0 "flags_reg_operand" "")
10166         (match_operator 2 "compare_operator"
10167           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10168            (const_int 0)]))
10169    (set (match_operand:QI 1 "nonimmediate_operand" "")
10170         (not:QI (match_dup 3)))]
10171   "ix86_match_ccmode (insn, CCNOmode)"
10172   [(parallel [(set (match_dup 0)
10173                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10174                                     (const_int 0)]))
10175               (set (match_dup 1)
10176                    (xor:QI (match_dup 3) (const_int -1)))])]
10177   "")
10178 \f
10179 ;; Arithmetic shift instructions
10180
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10185 ;;
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10192 ;;
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10198 ;;
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10201 ;; than 31.
10202
10203 (define_expand "ashlti3"
10204   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10206                               (match_operand:QI 2 "nonmemory_operand" "")))
10207               (clobber (reg:CC FLAGS_REG))])]
10208   "TARGET_64BIT"
10209 {
10210   if (! immediate_operand (operands[2], QImode))
10211     {
10212       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10213       DONE;
10214     }
10215   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10216   DONE;
10217 })
10218
10219 (define_insn "ashlti3_1"
10220   [(set (match_operand:TI 0 "register_operand" "=r")
10221         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222                    (match_operand:QI 2 "register_operand" "c")))
10223    (clobber (match_scratch:DI 3 "=&r"))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "TARGET_64BIT"
10226   "#"
10227   [(set_attr "type" "multi")])
10228
10229 (define_insn "*ashlti3_2"
10230   [(set (match_operand:TI 0 "register_operand" "=r")
10231         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232                    (match_operand:QI 2 "immediate_operand" "O")))
10233    (clobber (reg:CC FLAGS_REG))]
10234   "TARGET_64BIT"
10235   "#"
10236   [(set_attr "type" "multi")])
10237
10238 (define_split
10239   [(set (match_operand:TI 0 "register_operand" "")
10240         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241                    (match_operand:QI 2 "register_operand" "")))
10242    (clobber (match_scratch:DI 3 ""))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "TARGET_64BIT && reload_completed"
10245   [(const_int 0)]
10246   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10247
10248 (define_split
10249   [(set (match_operand:TI 0 "register_operand" "")
10250         (ashift:TI (match_operand:TI 1 "register_operand" "")
10251                    (match_operand:QI 2 "immediate_operand" "")))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_64BIT && reload_completed"
10254   [(const_int 0)]
10255   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10256
10257 (define_insn "x86_64_shld"
10258   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259         (ior:DI (ashift:DI (match_dup 0)
10260                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262                   (minus:QI (const_int 64) (match_dup 2)))))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT"
10265   "@
10266    shld{q}\t{%2, %1, %0|%0, %1, %2}
10267    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268   [(set_attr "type" "ishift")
10269    (set_attr "prefix_0f" "1")
10270    (set_attr "mode" "DI")
10271    (set_attr "athlon_decode" "vector")])
10272
10273 (define_expand "x86_64_shift_adj"
10274   [(set (reg:CCZ FLAGS_REG)
10275         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10276                              (const_int 64))
10277                      (const_int 0)))
10278    (set (match_operand:DI 0 "register_operand" "")
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 1 "register_operand" "")
10281                          (match_dup 0)))
10282    (set (match_dup 1)
10283         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284                          (match_operand:DI 3 "register_operand" "r")
10285                          (match_dup 1)))]
10286   "TARGET_64BIT"
10287   "")
10288
10289 (define_expand "ashldi3"
10290   [(set (match_operand:DI 0 "shiftdi_operand" "")
10291         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292                    (match_operand:QI 2 "nonmemory_operand" "")))]
10293   ""
10294   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10295
10296 (define_insn "*ashldi3_1_rex64"
10297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10302 {
10303   switch (get_attr_type (insn))
10304     {
10305     case TYPE_ALU:
10306       gcc_assert (operands[2] == const1_rtx);
10307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308       return "add{q}\t{%0, %0|%0, %0}";
10309
10310     case TYPE_LEA:
10311       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313       operands[1] = gen_rtx_MULT (DImode, operands[1],
10314                                   GEN_INT (1 << INTVAL (operands[2])));
10315       return "lea{q}\t{%a1, %0|%0, %a1}";
10316
10317     default:
10318       if (REG_P (operands[2]))
10319         return "sal{q}\t{%b2, %0|%0, %b2}";
10320       else if (operands[2] == const1_rtx
10321                && (TARGET_SHIFT1 || optimize_size))
10322         return "sal{q}\t%0";
10323       else
10324         return "sal{q}\t{%2, %0|%0, %2}";
10325     }
10326 }
10327   [(set (attr "type")
10328      (cond [(eq_attr "alternative" "1")
10329               (const_string "lea")
10330             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10331                           (const_int 0))
10332                       (match_operand 0 "register_operand" ""))
10333                  (match_operand 2 "const1_operand" ""))
10334               (const_string "alu")
10335            ]
10336            (const_string "ishift")))
10337    (set_attr "mode" "DI")])
10338
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341   [(set (match_operand:DI 0 "register_operand" "")
10342         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343                    (match_operand:QI 2 "immediate_operand" "")))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT && reload_completed
10346    && true_regnum (operands[0]) != true_regnum (operands[1])"
10347   [(set (match_dup 0)
10348         (mult:DI (match_dup 1)
10349                  (match_dup 2)))]
10350   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10351
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags.  We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356   [(set (reg FLAGS_REG)
10357         (compare
10358           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359                      (match_operand:QI 2 "immediate_operand" "e"))
10360           (const_int 0)))
10361    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362         (ashift:DI (match_dup 1) (match_dup 2)))]
10363   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10365 {
10366   switch (get_attr_type (insn))
10367     {
10368     case TYPE_ALU:
10369       gcc_assert (operands[2] == const1_rtx);
10370       return "add{q}\t{%0, %0|%0, %0}";
10371
10372     default:
10373       if (REG_P (operands[2]))
10374         return "sal{q}\t{%b2, %0|%0, %b2}";
10375       else if (operands[2] == const1_rtx
10376                && (TARGET_SHIFT1 || optimize_size))
10377         return "sal{q}\t%0";
10378       else
10379         return "sal{q}\t{%2, %0|%0, %2}";
10380     }
10381 }
10382   [(set (attr "type")
10383      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10384                           (const_int 0))
10385                       (match_operand 0 "register_operand" ""))
10386                  (match_operand 2 "const1_operand" ""))
10387               (const_string "alu")
10388            ]
10389            (const_string "ishift")))
10390    (set_attr "mode" "DI")])
10391
10392 (define_insn "*ashldi3_1"
10393   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "!TARGET_64BIT"
10398   "#"
10399   [(set_attr "type" "multi")])
10400
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium.  But if
10403 ;; we have one handy, we won't turn it away.
10404 (define_peephole2
10405   [(match_scratch:SI 3 "r")
10406    (parallel [(set (match_operand:DI 0 "register_operand" "")
10407                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408                               (match_operand:QI 2 "nonmemory_operand" "")))
10409               (clobber (reg:CC FLAGS_REG))])
10410    (match_dup 3)]
10411   "!TARGET_64BIT && TARGET_CMOVE"
10412   [(const_int 0)]
10413   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10414
10415 (define_split
10416   [(set (match_operand:DI 0 "register_operand" "")
10417         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418                    (match_operand:QI 2 "nonmemory_operand" "")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10421   [(const_int 0)]
10422   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10423
10424 (define_insn "x86_shld_1"
10425   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10426         (ior:SI (ashift:SI (match_dup 0)
10427                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10428                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10429                   (minus:QI (const_int 32) (match_dup 2)))))
10430    (clobber (reg:CC FLAGS_REG))]
10431   ""
10432   "@
10433    shld{l}\t{%2, %1, %0|%0, %1, %2}
10434    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10435   [(set_attr "type" "ishift")
10436    (set_attr "prefix_0f" "1")
10437    (set_attr "mode" "SI")
10438    (set_attr "pent_pair" "np")
10439    (set_attr "athlon_decode" "vector")])
10440
10441 (define_expand "x86_shift_adj_1"
10442   [(set (reg:CCZ FLAGS_REG)
10443         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10444                              (const_int 32))
10445                      (const_int 0)))
10446    (set (match_operand:SI 0 "register_operand" "")
10447         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10448                          (match_operand:SI 1 "register_operand" "")
10449                          (match_dup 0)))
10450    (set (match_dup 1)
10451         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10452                          (match_operand:SI 3 "register_operand" "r")
10453                          (match_dup 1)))]
10454   "TARGET_CMOVE"
10455   "")
10456
10457 (define_expand "x86_shift_adj_2"
10458   [(use (match_operand:SI 0 "register_operand" ""))
10459    (use (match_operand:SI 1 "register_operand" ""))
10460    (use (match_operand:QI 2 "register_operand" ""))]
10461   ""
10462 {
10463   rtx label = gen_label_rtx ();
10464   rtx tmp;
10465
10466   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10467
10468   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10469   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10470   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10471                               gen_rtx_LABEL_REF (VOIDmode, label),
10472                               pc_rtx);
10473   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10474   JUMP_LABEL (tmp) = label;
10475
10476   emit_move_insn (operands[0], operands[1]);
10477   ix86_expand_clear (operands[1]);
10478
10479   emit_label (label);
10480   LABEL_NUSES (label) = 1;
10481
10482   DONE;
10483 })
10484
10485 (define_expand "ashlsi3"
10486   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10487         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10488                    (match_operand:QI 2 "nonmemory_operand" "")))
10489    (clobber (reg:CC FLAGS_REG))]
10490   ""
10491   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10492
10493 (define_insn "*ashlsi3_1"
10494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10495         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10496                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10499 {
10500   switch (get_attr_type (insn))
10501     {
10502     case TYPE_ALU:
10503       gcc_assert (operands[2] == const1_rtx);
10504       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10505       return "add{l}\t{%0, %0|%0, %0}";
10506
10507     case TYPE_LEA:
10508       return "#";
10509
10510     default:
10511       if (REG_P (operands[2]))
10512         return "sal{l}\t{%b2, %0|%0, %b2}";
10513       else if (operands[2] == const1_rtx
10514                && (TARGET_SHIFT1 || optimize_size))
10515         return "sal{l}\t%0";
10516       else
10517         return "sal{l}\t{%2, %0|%0, %2}";
10518     }
10519 }
10520   [(set (attr "type")
10521      (cond [(eq_attr "alternative" "1")
10522               (const_string "lea")
10523             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524                           (const_int 0))
10525                       (match_operand 0 "register_operand" ""))
10526                  (match_operand 2 "const1_operand" ""))
10527               (const_string "alu")
10528            ]
10529            (const_string "ishift")))
10530    (set_attr "mode" "SI")])
10531
10532 ;; Convert lea to the lea pattern to avoid flags dependency.
10533 (define_split
10534   [(set (match_operand 0 "register_operand" "")
10535         (ashift (match_operand 1 "index_register_operand" "")
10536                 (match_operand:QI 2 "const_int_operand" "")))
10537    (clobber (reg:CC FLAGS_REG))]
10538   "reload_completed
10539    && true_regnum (operands[0]) != true_regnum (operands[1])
10540    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10541   [(const_int 0)]
10542 {
10543   rtx pat;
10544   enum machine_mode mode = GET_MODE (operands[0]);
10545
10546   if (GET_MODE_SIZE (mode) < 4)
10547     operands[0] = gen_lowpart (SImode, operands[0]);
10548   if (mode != Pmode)
10549     operands[1] = gen_lowpart (Pmode, operands[1]);
10550   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10551
10552   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10553   if (Pmode != SImode)
10554     pat = gen_rtx_SUBREG (SImode, pat, 0);
10555   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10556   DONE;
10557 })
10558
10559 ;; Rare case of shifting RSP is handled by generating move and shift
10560 (define_split
10561   [(set (match_operand 0 "register_operand" "")
10562         (ashift (match_operand 1 "register_operand" "")
10563                 (match_operand:QI 2 "const_int_operand" "")))
10564    (clobber (reg:CC FLAGS_REG))]
10565   "reload_completed
10566    && true_regnum (operands[0]) != true_regnum (operands[1])"
10567   [(const_int 0)]
10568 {
10569   rtx pat, clob;
10570   emit_move_insn (operands[1], operands[0]);
10571   pat = gen_rtx_SET (VOIDmode, operands[0],
10572                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10573                                      operands[0], operands[2]));
10574   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10575   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10576   DONE;
10577 })
10578
10579 (define_insn "*ashlsi3_1_zext"
10580   [(set (match_operand:DI 0 "register_operand" "=r,r")
10581         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10582                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10583    (clobber (reg:CC FLAGS_REG))]
10584   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10585 {
10586   switch (get_attr_type (insn))
10587     {
10588     case TYPE_ALU:
10589       gcc_assert (operands[2] == const1_rtx);
10590       return "add{l}\t{%k0, %k0|%k0, %k0}";
10591
10592     case TYPE_LEA:
10593       return "#";
10594
10595     default:
10596       if (REG_P (operands[2]))
10597         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_size))
10600         return "sal{l}\t%k0";
10601       else
10602         return "sal{l}\t{%2, %k0|%k0, %2}";
10603     }
10604 }
10605   [(set (attr "type")
10606      (cond [(eq_attr "alternative" "1")
10607               (const_string "lea")
10608             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10609                      (const_int 0))
10610                  (match_operand 2 "const1_operand" ""))
10611               (const_string "alu")
10612            ]
10613            (const_string "ishift")))
10614    (set_attr "mode" "SI")])
10615
10616 ;; Convert lea to the lea pattern to avoid flags dependency.
10617 (define_split
10618   [(set (match_operand:DI 0 "register_operand" "")
10619         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10620                                 (match_operand:QI 2 "const_int_operand" ""))))
10621    (clobber (reg:CC FLAGS_REG))]
10622   "TARGET_64BIT && reload_completed
10623    && true_regnum (operands[0]) != true_regnum (operands[1])"
10624   [(set (match_dup 0) (zero_extend:DI
10625                         (subreg:SI (mult:SI (match_dup 1)
10626                                             (match_dup 2)) 0)))]
10627 {
10628   operands[1] = gen_lowpart (Pmode, operands[1]);
10629   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10630 })
10631
10632 ;; This pattern can't accept a variable shift count, since shifts by
10633 ;; zero don't affect the flags.  We assume that shifts by constant
10634 ;; zero are optimized away.
10635 (define_insn "*ashlsi3_cmp"
10636   [(set (reg FLAGS_REG)
10637         (compare
10638           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10639                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10640           (const_int 0)))
10641    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10642         (ashift:SI (match_dup 1) (match_dup 2)))]
10643   "ix86_match_ccmode (insn, CCGOCmode)
10644    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10645 {
10646   switch (get_attr_type (insn))
10647     {
10648     case TYPE_ALU:
10649       gcc_assert (operands[2] == const1_rtx);
10650       return "add{l}\t{%0, %0|%0, %0}";
10651
10652     default:
10653       if (REG_P (operands[2]))
10654         return "sal{l}\t{%b2, %0|%0, %b2}";
10655       else if (operands[2] == const1_rtx
10656                && (TARGET_SHIFT1 || optimize_size))
10657         return "sal{l}\t%0";
10658       else
10659         return "sal{l}\t{%2, %0|%0, %2}";
10660     }
10661 }
10662   [(set (attr "type")
10663      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10664                           (const_int 0))
10665                       (match_operand 0 "register_operand" ""))
10666                  (match_operand 2 "const1_operand" ""))
10667               (const_string "alu")
10668            ]
10669            (const_string "ishift")))
10670    (set_attr "mode" "SI")])
10671
10672 (define_insn "*ashlsi3_cmp_zext"
10673   [(set (reg FLAGS_REG)
10674         (compare
10675           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10676                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10677           (const_int 0)))
10678    (set (match_operand:DI 0 "register_operand" "=r")
10679         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10680   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10681    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       return "add{l}\t{%k0, %k0|%k0, %k0}";
10688
10689     default:
10690       if (REG_P (operands[2]))
10691         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10692       else if (operands[2] == const1_rtx
10693                && (TARGET_SHIFT1 || optimize_size))
10694         return "sal{l}\t%k0";
10695       else
10696         return "sal{l}\t{%2, %k0|%k0, %2}";
10697     }
10698 }
10699   [(set (attr "type")
10700      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10701                      (const_int 0))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "SI")])
10707
10708 (define_expand "ashlhi3"
10709   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10710         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10711                    (match_operand:QI 2 "nonmemory_operand" "")))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "TARGET_HIMODE_MATH"
10714   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10715
10716 (define_insn "*ashlhi3_1_lea"
10717   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10718         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10719                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "!TARGET_PARTIAL_REG_STALL
10722    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10723 {
10724   switch (get_attr_type (insn))
10725     {
10726     case TYPE_LEA:
10727       return "#";
10728     case TYPE_ALU:
10729       gcc_assert (operands[2] == const1_rtx);
10730       return "add{w}\t{%0, %0|%0, %0}";
10731
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{w}\t{%b2, %0|%0, %b2}";
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         return "sal{w}\t%0";
10738       else
10739         return "sal{w}\t{%2, %0|%0, %2}";
10740     }
10741 }
10742   [(set (attr "type")
10743      (cond [(eq_attr "alternative" "1")
10744               (const_string "lea")
10745             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746                           (const_int 0))
10747                       (match_operand 0 "register_operand" ""))
10748                  (match_operand 2 "const1_operand" ""))
10749               (const_string "alu")
10750            ]
10751            (const_string "ishift")))
10752    (set_attr "mode" "HI,SI")])
10753
10754 (define_insn "*ashlhi3_1"
10755   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10756         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10757                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10758    (clobber (reg:CC FLAGS_REG))]
10759   "TARGET_PARTIAL_REG_STALL
10760    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10761 {
10762   switch (get_attr_type (insn))
10763     {
10764     case TYPE_ALU:
10765       gcc_assert (operands[2] == const1_rtx);
10766       return "add{w}\t{%0, %0|%0, %0}";
10767
10768     default:
10769       if (REG_P (operands[2]))
10770         return "sal{w}\t{%b2, %0|%0, %b2}";
10771       else if (operands[2] == const1_rtx
10772                && (TARGET_SHIFT1 || optimize_size))
10773         return "sal{w}\t%0";
10774       else
10775         return "sal{w}\t{%2, %0|%0, %2}";
10776     }
10777 }
10778   [(set (attr "type")
10779      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10780                           (const_int 0))
10781                       (match_operand 0 "register_operand" ""))
10782                  (match_operand 2 "const1_operand" ""))
10783               (const_string "alu")
10784            ]
10785            (const_string "ishift")))
10786    (set_attr "mode" "HI")])
10787
10788 ;; This pattern can't accept a variable shift count, since shifts by
10789 ;; zero don't affect the flags.  We assume that shifts by constant
10790 ;; zero are optimized away.
10791 (define_insn "*ashlhi3_cmp"
10792   [(set (reg FLAGS_REG)
10793         (compare
10794           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10795                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10796           (const_int 0)))
10797    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10798         (ashift:HI (match_dup 1) (match_dup 2)))]
10799   "ix86_match_ccmode (insn, CCGOCmode)
10800    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10801 {
10802   switch (get_attr_type (insn))
10803     {
10804     case TYPE_ALU:
10805       gcc_assert (operands[2] == const1_rtx);
10806       return "add{w}\t{%0, %0|%0, %0}";
10807
10808     default:
10809       if (REG_P (operands[2]))
10810         return "sal{w}\t{%b2, %0|%0, %b2}";
10811       else if (operands[2] == const1_rtx
10812                && (TARGET_SHIFT1 || optimize_size))
10813         return "sal{w}\t%0";
10814       else
10815         return "sal{w}\t{%2, %0|%0, %2}";
10816     }
10817 }
10818   [(set (attr "type")
10819      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820                           (const_int 0))
10821                       (match_operand 0 "register_operand" ""))
10822                  (match_operand 2 "const1_operand" ""))
10823               (const_string "alu")
10824            ]
10825            (const_string "ishift")))
10826    (set_attr "mode" "HI")])
10827
10828 (define_expand "ashlqi3"
10829   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10830         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10831                    (match_operand:QI 2 "nonmemory_operand" "")))
10832    (clobber (reg:CC FLAGS_REG))]
10833   "TARGET_QIMODE_MATH"
10834   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10835
10836 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10837
10838 (define_insn "*ashlqi3_1_lea"
10839   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10840         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10841                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10842    (clobber (reg:CC FLAGS_REG))]
10843   "!TARGET_PARTIAL_REG_STALL
10844    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10845 {
10846   switch (get_attr_type (insn))
10847     {
10848     case TYPE_LEA:
10849       return "#";
10850     case TYPE_ALU:
10851       gcc_assert (operands[2] == const1_rtx);
10852       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10853         return "add{l}\t{%k0, %k0|%k0, %k0}";
10854       else
10855         return "add{b}\t{%0, %0|%0, %0}";
10856
10857     default:
10858       if (REG_P (operands[2]))
10859         {
10860           if (get_attr_mode (insn) == MODE_SI)
10861             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10862           else
10863             return "sal{b}\t{%b2, %0|%0, %b2}";
10864         }
10865       else if (operands[2] == const1_rtx
10866                && (TARGET_SHIFT1 || optimize_size))
10867         {
10868           if (get_attr_mode (insn) == MODE_SI)
10869             return "sal{l}\t%0";
10870           else
10871             return "sal{b}\t%0";
10872         }
10873       else
10874         {
10875           if (get_attr_mode (insn) == MODE_SI)
10876             return "sal{l}\t{%2, %k0|%k0, %2}";
10877           else
10878             return "sal{b}\t{%2, %0|%0, %2}";
10879         }
10880     }
10881 }
10882   [(set (attr "type")
10883      (cond [(eq_attr "alternative" "2")
10884               (const_string "lea")
10885             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886                           (const_int 0))
10887                       (match_operand 0 "register_operand" ""))
10888                  (match_operand 2 "const1_operand" ""))
10889               (const_string "alu")
10890            ]
10891            (const_string "ishift")))
10892    (set_attr "mode" "QI,SI,SI")])
10893
10894 (define_insn "*ashlqi3_1"
10895   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10896         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10897                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_PARTIAL_REG_STALL
10900    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10901 {
10902   switch (get_attr_type (insn))
10903     {
10904     case TYPE_ALU:
10905       gcc_assert (operands[2] == const1_rtx);
10906       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10907         return "add{l}\t{%k0, %k0|%k0, %k0}";
10908       else
10909         return "add{b}\t{%0, %0|%0, %0}";
10910
10911     default:
10912       if (REG_P (operands[2]))
10913         {
10914           if (get_attr_mode (insn) == MODE_SI)
10915             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10916           else
10917             return "sal{b}\t{%b2, %0|%0, %b2}";
10918         }
10919       else if (operands[2] == const1_rtx
10920                && (TARGET_SHIFT1 || optimize_size))
10921         {
10922           if (get_attr_mode (insn) == MODE_SI)
10923             return "sal{l}\t%0";
10924           else
10925             return "sal{b}\t%0";
10926         }
10927       else
10928         {
10929           if (get_attr_mode (insn) == MODE_SI)
10930             return "sal{l}\t{%2, %k0|%k0, %2}";
10931           else
10932             return "sal{b}\t{%2, %0|%0, %2}";
10933         }
10934     }
10935 }
10936   [(set (attr "type")
10937      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938                           (const_int 0))
10939                       (match_operand 0 "register_operand" ""))
10940                  (match_operand 2 "const1_operand" ""))
10941               (const_string "alu")
10942            ]
10943            (const_string "ishift")))
10944    (set_attr "mode" "QI,SI")])
10945
10946 ;; This pattern can't accept a variable shift count, since shifts by
10947 ;; zero don't affect the flags.  We assume that shifts by constant
10948 ;; zero are optimized away.
10949 (define_insn "*ashlqi3_cmp"
10950   [(set (reg FLAGS_REG)
10951         (compare
10952           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10953                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10954           (const_int 0)))
10955    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10956         (ashift:QI (match_dup 1) (match_dup 2)))]
10957   "ix86_match_ccmode (insn, CCGOCmode)
10958    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10959 {
10960   switch (get_attr_type (insn))
10961     {
10962     case TYPE_ALU:
10963       gcc_assert (operands[2] == const1_rtx);
10964       return "add{b}\t{%0, %0|%0, %0}";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{b}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{b}\t%0";
10972       else
10973         return "sal{b}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10978                           (const_int 0))
10979                       (match_operand 0 "register_operand" ""))
10980                  (match_operand 2 "const1_operand" ""))
10981               (const_string "alu")
10982            ]
10983            (const_string "ishift")))
10984    (set_attr "mode" "QI")])
10985
10986 ;; See comment above `ashldi3' about how this works.
10987
10988 (define_expand "ashrti3"
10989   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10990                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10991                                 (match_operand:QI 2 "nonmemory_operand" "")))
10992               (clobber (reg:CC FLAGS_REG))])]
10993   "TARGET_64BIT"
10994 {
10995   if (! immediate_operand (operands[2], QImode))
10996     {
10997       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10998       DONE;
10999     }
11000   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11001   DONE;
11002 })
11003
11004 (define_insn "ashrti3_1"
11005   [(set (match_operand:TI 0 "register_operand" "=r")
11006         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11007                      (match_operand:QI 2 "register_operand" "c")))
11008    (clobber (match_scratch:DI 3 "=&r"))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "TARGET_64BIT"
11011   "#"
11012   [(set_attr "type" "multi")])
11013
11014 (define_insn "*ashrti3_2"
11015   [(set (match_operand:TI 0 "register_operand" "=r")
11016         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11017                      (match_operand:QI 2 "immediate_operand" "O")))
11018    (clobber (reg:CC FLAGS_REG))]
11019   "TARGET_64BIT"
11020   "#"
11021   [(set_attr "type" "multi")])
11022
11023 (define_split
11024   [(set (match_operand:TI 0 "register_operand" "")
11025         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11026                      (match_operand:QI 2 "register_operand" "")))
11027    (clobber (match_scratch:DI 3 ""))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "TARGET_64BIT && reload_completed"
11030   [(const_int 0)]
11031   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11032
11033 (define_split
11034   [(set (match_operand:TI 0 "register_operand" "")
11035         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11036                      (match_operand:QI 2 "immediate_operand" "")))
11037    (clobber (reg:CC FLAGS_REG))]
11038   "TARGET_64BIT && reload_completed"
11039   [(const_int 0)]
11040   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11041
11042 (define_insn "x86_64_shrd"
11043   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11044         (ior:DI (ashiftrt:DI (match_dup 0)
11045                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11046                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11047                   (minus:QI (const_int 64) (match_dup 2)))))
11048    (clobber (reg:CC FLAGS_REG))]
11049   "TARGET_64BIT"
11050   "@
11051    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11052    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11053   [(set_attr "type" "ishift")
11054    (set_attr "prefix_0f" "1")
11055    (set_attr "mode" "DI")
11056    (set_attr "athlon_decode" "vector")])
11057
11058 (define_expand "ashrdi3"
11059   [(set (match_operand:DI 0 "shiftdi_operand" "")
11060         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11061                      (match_operand:QI 2 "nonmemory_operand" "")))]
11062   ""
11063   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11064
11065 (define_insn "*ashrdi3_63_rex64"
11066   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11067         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11068                      (match_operand:DI 2 "const_int_operand" "i,i")))
11069    (clobber (reg:CC FLAGS_REG))]
11070   "TARGET_64BIT && INTVAL (operands[2]) == 63
11071    && (TARGET_USE_CLTD || optimize_size)
11072    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11073   "@
11074    {cqto|cqo}
11075    sar{q}\t{%2, %0|%0, %2}"
11076   [(set_attr "type" "imovx,ishift")
11077    (set_attr "prefix_0f" "0,*")
11078    (set_attr "length_immediate" "0,*")
11079    (set_attr "modrm" "0,1")
11080    (set_attr "mode" "DI")])
11081
11082 (define_insn "*ashrdi3_1_one_bit_rex64"
11083   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11084         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11085                      (match_operand:QI 2 "const1_operand" "")))
11086    (clobber (reg:CC FLAGS_REG))]
11087   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11088    && (TARGET_SHIFT1 || optimize_size)"
11089   "sar{q}\t%0"
11090   [(set_attr "type" "ishift")
11091    (set (attr "length") 
11092      (if_then_else (match_operand:DI 0 "register_operand" "") 
11093         (const_string "2")
11094         (const_string "*")))])
11095
11096 (define_insn "*ashrdi3_1_rex64"
11097   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11098         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11099                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11100    (clobber (reg:CC FLAGS_REG))]
11101   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11102   "@
11103    sar{q}\t{%2, %0|%0, %2}
11104    sar{q}\t{%b2, %0|%0, %b2}"
11105   [(set_attr "type" "ishift")
11106    (set_attr "mode" "DI")])
11107
11108 ;; This pattern can't accept a variable shift count, since shifts by
11109 ;; zero don't affect the flags.  We assume that shifts by constant
11110 ;; zero are optimized away.
11111 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11112   [(set (reg FLAGS_REG)
11113         (compare
11114           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11115                        (match_operand:QI 2 "const1_operand" ""))
11116           (const_int 0)))
11117    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11118         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11119   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11120    && (TARGET_SHIFT1 || optimize_size)
11121    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11122   "sar{q}\t%0"
11123   [(set_attr "type" "ishift")
11124    (set (attr "length") 
11125      (if_then_else (match_operand:DI 0 "register_operand" "") 
11126         (const_string "2")
11127         (const_string "*")))])
11128
11129 ;; This pattern can't accept a variable shift count, since shifts by
11130 ;; zero don't affect the flags.  We assume that shifts by constant
11131 ;; zero are optimized away.
11132 (define_insn "*ashrdi3_cmp_rex64"
11133   [(set (reg FLAGS_REG)
11134         (compare
11135           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11136                        (match_operand:QI 2 "const_int_operand" "n"))
11137           (const_int 0)))
11138    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11139         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11140   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11141    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11142   "sar{q}\t{%2, %0|%0, %2}"
11143   [(set_attr "type" "ishift")
11144    (set_attr "mode" "DI")])
11145
11146 (define_insn "*ashrdi3_1"
11147   [(set (match_operand:DI 0 "register_operand" "=r")
11148         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11149                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11150    (clobber (reg:CC FLAGS_REG))]
11151   "!TARGET_64BIT"
11152   "#"
11153   [(set_attr "type" "multi")])
11154
11155 ;; By default we don't ask for a scratch register, because when DImode
11156 ;; values are manipulated, registers are already at a premium.  But if
11157 ;; we have one handy, we won't turn it away.
11158 (define_peephole2
11159   [(match_scratch:SI 3 "r")
11160    (parallel [(set (match_operand:DI 0 "register_operand" "")
11161                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11162                                 (match_operand:QI 2 "nonmemory_operand" "")))
11163               (clobber (reg:CC FLAGS_REG))])
11164    (match_dup 3)]
11165   "!TARGET_64BIT && TARGET_CMOVE"
11166   [(const_int 0)]
11167   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11168
11169 (define_split
11170   [(set (match_operand:DI 0 "register_operand" "")
11171         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11172                      (match_operand:QI 2 "nonmemory_operand" "")))
11173    (clobber (reg:CC FLAGS_REG))]
11174   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11175   [(const_int 0)]
11176   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11177
11178 (define_insn "x86_shrd_1"
11179   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11180         (ior:SI (ashiftrt:SI (match_dup 0)
11181                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11182                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11183                   (minus:QI (const_int 32) (match_dup 2)))))
11184    (clobber (reg:CC FLAGS_REG))]
11185   ""
11186   "@
11187    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11188    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11189   [(set_attr "type" "ishift")
11190    (set_attr "prefix_0f" "1")
11191    (set_attr "pent_pair" "np")
11192    (set_attr "mode" "SI")])
11193
11194 (define_expand "x86_shift_adj_3"
11195   [(use (match_operand:SI 0 "register_operand" ""))
11196    (use (match_operand:SI 1 "register_operand" ""))
11197    (use (match_operand:QI 2 "register_operand" ""))]
11198   ""
11199 {
11200   rtx label = gen_label_rtx ();
11201   rtx tmp;
11202
11203   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11204
11205   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208                               gen_rtx_LABEL_REF (VOIDmode, label),
11209                               pc_rtx);
11210   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211   JUMP_LABEL (tmp) = label;
11212
11213   emit_move_insn (operands[0], operands[1]);
11214   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11215
11216   emit_label (label);
11217   LABEL_NUSES (label) = 1;
11218
11219   DONE;
11220 })
11221
11222 (define_insn "ashrsi3_31"
11223   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11224         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11225                      (match_operand:SI 2 "const_int_operand" "i,i")))
11226    (clobber (reg:CC FLAGS_REG))]
11227   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11228    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11229   "@
11230    {cltd|cdq}
11231    sar{l}\t{%2, %0|%0, %2}"
11232   [(set_attr "type" "imovx,ishift")
11233    (set_attr "prefix_0f" "0,*")
11234    (set_attr "length_immediate" "0,*")
11235    (set_attr "modrm" "0,1")
11236    (set_attr "mode" "SI")])
11237
11238 (define_insn "*ashrsi3_31_zext"
11239   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11240         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11241                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11242    (clobber (reg:CC FLAGS_REG))]
11243   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11244    && INTVAL (operands[2]) == 31
11245    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11246   "@
11247    {cltd|cdq}
11248    sar{l}\t{%2, %k0|%k0, %2}"
11249   [(set_attr "type" "imovx,ishift")
11250    (set_attr "prefix_0f" "0,*")
11251    (set_attr "length_immediate" "0,*")
11252    (set_attr "modrm" "0,1")
11253    (set_attr "mode" "SI")])
11254
11255 (define_expand "ashrsi3"
11256   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11257         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11258                      (match_operand:QI 2 "nonmemory_operand" "")))
11259    (clobber (reg:CC FLAGS_REG))]
11260   ""
11261   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11262
11263 (define_insn "*ashrsi3_1_one_bit"
11264   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11265         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11266                      (match_operand:QI 2 "const1_operand" "")))
11267    (clobber (reg:CC FLAGS_REG))]
11268   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11269    && (TARGET_SHIFT1 || optimize_size)"
11270   "sar{l}\t%0"
11271   [(set_attr "type" "ishift")
11272    (set (attr "length") 
11273      (if_then_else (match_operand:SI 0 "register_operand" "") 
11274         (const_string "2")
11275         (const_string "*")))])
11276
11277 (define_insn "*ashrsi3_1_one_bit_zext"
11278   [(set (match_operand:DI 0 "register_operand" "=r")
11279         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11280                                      (match_operand:QI 2 "const1_operand" ""))))
11281    (clobber (reg:CC FLAGS_REG))]
11282   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11283    && (TARGET_SHIFT1 || optimize_size)"
11284   "sar{l}\t%k0"
11285   [(set_attr "type" "ishift")
11286    (set_attr "length" "2")])
11287
11288 (define_insn "*ashrsi3_1"
11289   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11290         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11291                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11292    (clobber (reg:CC FLAGS_REG))]
11293   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11294   "@
11295    sar{l}\t{%2, %0|%0, %2}
11296    sar{l}\t{%b2, %0|%0, %b2}"
11297   [(set_attr "type" "ishift")
11298    (set_attr "mode" "SI")])
11299
11300 (define_insn "*ashrsi3_1_zext"
11301   [(set (match_operand:DI 0 "register_operand" "=r,r")
11302         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11303                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11306   "@
11307    sar{l}\t{%2, %k0|%k0, %2}
11308    sar{l}\t{%b2, %k0|%k0, %b2}"
11309   [(set_attr "type" "ishift")
11310    (set_attr "mode" "SI")])
11311
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags.  We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*ashrsi3_one_bit_cmp"
11316   [(set (reg FLAGS_REG)
11317         (compare
11318           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11319                        (match_operand:QI 2 "const1_operand" ""))
11320           (const_int 0)))
11321    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11322         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11323   "ix86_match_ccmode (insn, CCGOCmode)
11324    && (TARGET_SHIFT1 || optimize_size)
11325    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11326   "sar{l}\t%0"
11327   [(set_attr "type" "ishift")
11328    (set (attr "length") 
11329      (if_then_else (match_operand:SI 0 "register_operand" "") 
11330         (const_string "2")
11331         (const_string "*")))])
11332
11333 (define_insn "*ashrsi3_one_bit_cmp_zext"
11334   [(set (reg FLAGS_REG)
11335         (compare
11336           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11337                        (match_operand:QI 2 "const1_operand" ""))
11338           (const_int 0)))
11339    (set (match_operand:DI 0 "register_operand" "=r")
11340         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11341   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11342    && (TARGET_SHIFT1 || optimize_size)
11343    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11344   "sar{l}\t%k0"
11345   [(set_attr "type" "ishift")
11346    (set_attr "length" "2")])
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrsi3_cmp"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11356           (const_int 0)))
11357    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11359   "ix86_match_ccmode (insn, CCGOCmode)
11360    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11361   "sar{l}\t{%2, %0|%0, %2}"
11362   [(set_attr "type" "ishift")
11363    (set_attr "mode" "SI")])
11364
11365 (define_insn "*ashrsi3_cmp_zext"
11366   [(set (reg FLAGS_REG)
11367         (compare
11368           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11369                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11370           (const_int 0)))
11371    (set (match_operand:DI 0 "register_operand" "=r")
11372         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11373   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11374    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11375   "sar{l}\t{%2, %k0|%k0, %2}"
11376   [(set_attr "type" "ishift")
11377    (set_attr "mode" "SI")])
11378
11379 (define_expand "ashrhi3"
11380   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11381         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11382                      (match_operand:QI 2 "nonmemory_operand" "")))
11383    (clobber (reg:CC FLAGS_REG))]
11384   "TARGET_HIMODE_MATH"
11385   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11386
11387 (define_insn "*ashrhi3_1_one_bit"
11388   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11389         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11390                      (match_operand:QI 2 "const1_operand" "")))
11391    (clobber (reg:CC FLAGS_REG))]
11392   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11393    && (TARGET_SHIFT1 || optimize_size)"
11394   "sar{w}\t%0"
11395   [(set_attr "type" "ishift")
11396    (set (attr "length") 
11397      (if_then_else (match_operand 0 "register_operand" "") 
11398         (const_string "2")
11399         (const_string "*")))])
11400
11401 (define_insn "*ashrhi3_1"
11402   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11403         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11404                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11407   "@
11408    sar{w}\t{%2, %0|%0, %2}
11409    sar{w}\t{%b2, %0|%0, %b2}"
11410   [(set_attr "type" "ishift")
11411    (set_attr "mode" "HI")])
11412
11413 ;; This pattern can't accept a variable shift count, since shifts by
11414 ;; zero don't affect the flags.  We assume that shifts by constant
11415 ;; zero are optimized away.
11416 (define_insn "*ashrhi3_one_bit_cmp"
11417   [(set (reg FLAGS_REG)
11418         (compare
11419           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11420                        (match_operand:QI 2 "const1_operand" ""))
11421           (const_int 0)))
11422    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11423         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11424   "ix86_match_ccmode (insn, CCGOCmode)
11425    && (TARGET_SHIFT1 || optimize_size)
11426    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11427   "sar{w}\t%0"
11428   [(set_attr "type" "ishift")
11429    (set (attr "length") 
11430      (if_then_else (match_operand 0 "register_operand" "") 
11431         (const_string "2")
11432         (const_string "*")))])
11433
11434 ;; This pattern can't accept a variable shift count, since shifts by
11435 ;; zero don't affect the flags.  We assume that shifts by constant
11436 ;; zero are optimized away.
11437 (define_insn "*ashrhi3_cmp"
11438   [(set (reg FLAGS_REG)
11439         (compare
11440           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11441                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11442           (const_int 0)))
11443    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11444         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11445   "ix86_match_ccmode (insn, CCGOCmode)
11446    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11447   "sar{w}\t{%2, %0|%0, %2}"
11448   [(set_attr "type" "ishift")
11449    (set_attr "mode" "HI")])
11450
11451 (define_expand "ashrqi3"
11452   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11453         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11454                      (match_operand:QI 2 "nonmemory_operand" "")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "TARGET_QIMODE_MATH"
11457   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11458
11459 (define_insn "*ashrqi3_1_one_bit"
11460   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11461         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11462                      (match_operand:QI 2 "const1_operand" "")))
11463    (clobber (reg:CC FLAGS_REG))]
11464   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11465    && (TARGET_SHIFT1 || optimize_size)"
11466   "sar{b}\t%0"
11467   [(set_attr "type" "ishift")
11468    (set (attr "length") 
11469      (if_then_else (match_operand 0 "register_operand" "") 
11470         (const_string "2")
11471         (const_string "*")))])
11472
11473 (define_insn "*ashrqi3_1_one_bit_slp"
11474   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11475         (ashiftrt:QI (match_dup 0)
11476                      (match_operand:QI 1 "const1_operand" "")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11479    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11480    && (TARGET_SHIFT1 || optimize_size)"
11481   "sar{b}\t%0"
11482   [(set_attr "type" "ishift1")
11483    (set (attr "length") 
11484      (if_then_else (match_operand 0 "register_operand" "") 
11485         (const_string "2")
11486         (const_string "*")))])
11487
11488 (define_insn "*ashrqi3_1"
11489   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11490         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11491                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11494   "@
11495    sar{b}\t{%2, %0|%0, %2}
11496    sar{b}\t{%b2, %0|%0, %b2}"
11497   [(set_attr "type" "ishift")
11498    (set_attr "mode" "QI")])
11499
11500 (define_insn "*ashrqi3_1_slp"
11501   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11502         (ashiftrt:QI (match_dup 0)
11503                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11504    (clobber (reg:CC FLAGS_REG))]
11505   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11506    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11507   "@
11508    sar{b}\t{%1, %0|%0, %1}
11509    sar{b}\t{%b1, %0|%0, %b1}"
11510   [(set_attr "type" "ishift1")
11511    (set_attr "mode" "QI")])
11512
11513 ;; This pattern can't accept a variable shift count, since shifts by
11514 ;; zero don't affect the flags.  We assume that shifts by constant
11515 ;; zero are optimized away.
11516 (define_insn "*ashrqi3_one_bit_cmp"
11517   [(set (reg FLAGS_REG)
11518         (compare
11519           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11520                        (match_operand:QI 2 "const1_operand" "I"))
11521           (const_int 0)))
11522    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11523         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11524   "ix86_match_ccmode (insn, CCGOCmode)
11525    && (TARGET_SHIFT1 || optimize_size)
11526    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11527   "sar{b}\t%0"
11528   [(set_attr "type" "ishift")
11529    (set (attr "length") 
11530      (if_then_else (match_operand 0 "register_operand" "") 
11531         (const_string "2")
11532         (const_string "*")))])
11533
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags.  We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*ashrqi3_cmp"
11538   [(set (reg FLAGS_REG)
11539         (compare
11540           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11541                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11542           (const_int 0)))
11543    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11544         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11545   "ix86_match_ccmode (insn, CCGOCmode)
11546    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11547   "sar{b}\t{%2, %0|%0, %2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "QI")])
11550 \f
11551 ;; Logical shift instructions
11552
11553 ;; See comment above `ashldi3' about how this works.
11554
11555 (define_expand "lshrti3"
11556   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11557                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11558                                 (match_operand:QI 2 "nonmemory_operand" "")))
11559               (clobber (reg:CC FLAGS_REG))])]
11560   "TARGET_64BIT"
11561 {
11562   if (! immediate_operand (operands[2], QImode))
11563     {
11564       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11565       DONE;
11566     }
11567   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11568   DONE;
11569 })
11570
11571 (define_insn "lshrti3_1"
11572   [(set (match_operand:TI 0 "register_operand" "=r")
11573         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11574                      (match_operand:QI 2 "register_operand" "c")))
11575    (clobber (match_scratch:DI 3 "=&r"))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_64BIT"
11578   "#"
11579   [(set_attr "type" "multi")])
11580
11581 (define_insn "*lshrti3_2"
11582   [(set (match_operand:TI 0 "register_operand" "=r")
11583         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11584                      (match_operand:QI 2 "immediate_operand" "O")))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "TARGET_64BIT"
11587   "#"
11588   [(set_attr "type" "multi")])
11589
11590 (define_split 
11591   [(set (match_operand:TI 0 "register_operand" "")
11592         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11593                      (match_operand:QI 2 "register_operand" "")))
11594    (clobber (match_scratch:DI 3 ""))
11595    (clobber (reg:CC FLAGS_REG))]
11596   "TARGET_64BIT && reload_completed"
11597   [(const_int 0)]
11598   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11599
11600 (define_split 
11601   [(set (match_operand:TI 0 "register_operand" "")
11602         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11603                      (match_operand:QI 2 "immediate_operand" "")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "TARGET_64BIT && reload_completed"
11606   [(const_int 0)]
11607   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11608
11609 (define_expand "lshrdi3"
11610   [(set (match_operand:DI 0 "shiftdi_operand" "")
11611         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11612                      (match_operand:QI 2 "nonmemory_operand" "")))]
11613   ""
11614   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11615
11616 (define_insn "*lshrdi3_1_one_bit_rex64"
11617   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11618         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11619                      (match_operand:QI 2 "const1_operand" "")))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11622    && (TARGET_SHIFT1 || optimize_size)"
11623   "shr{q}\t%0"
11624   [(set_attr "type" "ishift")
11625    (set (attr "length") 
11626      (if_then_else (match_operand:DI 0 "register_operand" "") 
11627         (const_string "2")
11628         (const_string "*")))])
11629
11630 (define_insn "*lshrdi3_1_rex64"
11631   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11632         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11633                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11636   "@
11637    shr{q}\t{%2, %0|%0, %2}
11638    shr{q}\t{%b2, %0|%0, %b2}"
11639   [(set_attr "type" "ishift")
11640    (set_attr "mode" "DI")])
11641
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags.  We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11652         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11653   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11654    && (TARGET_SHIFT1 || optimize_size)
11655    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11656   "shr{q}\t%0"
11657   [(set_attr "type" "ishift")
11658    (set (attr "length") 
11659      (if_then_else (match_operand:DI 0 "register_operand" "") 
11660         (const_string "2")
11661         (const_string "*")))])
11662
11663 ;; This pattern can't accept a variable shift count, since shifts by
11664 ;; zero don't affect the flags.  We assume that shifts by constant
11665 ;; zero are optimized away.
11666 (define_insn "*lshrdi3_cmp_rex64"
11667   [(set (reg FLAGS_REG)
11668         (compare
11669           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11670                        (match_operand:QI 2 "const_int_operand" "e"))
11671           (const_int 0)))
11672    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11673         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11674   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11675    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11676   "shr{q}\t{%2, %0|%0, %2}"
11677   [(set_attr "type" "ishift")
11678    (set_attr "mode" "DI")])
11679
11680 (define_insn "*lshrdi3_1"
11681   [(set (match_operand:DI 0 "register_operand" "=r")
11682         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11683                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11684    (clobber (reg:CC FLAGS_REG))]
11685   "!TARGET_64BIT"
11686   "#"
11687   [(set_attr "type" "multi")])
11688
11689 ;; By default we don't ask for a scratch register, because when DImode
11690 ;; values are manipulated, registers are already at a premium.  But if
11691 ;; we have one handy, we won't turn it away.
11692 (define_peephole2
11693   [(match_scratch:SI 3 "r")
11694    (parallel [(set (match_operand:DI 0 "register_operand" "")
11695                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11696                                 (match_operand:QI 2 "nonmemory_operand" "")))
11697               (clobber (reg:CC FLAGS_REG))])
11698    (match_dup 3)]
11699   "!TARGET_64BIT && TARGET_CMOVE"
11700   [(const_int 0)]
11701   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11702
11703 (define_split 
11704   [(set (match_operand:DI 0 "register_operand" "")
11705         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11706                      (match_operand:QI 2 "nonmemory_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11709   [(const_int 0)]
11710   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11711
11712 (define_expand "lshrsi3"
11713   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11714         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11715                      (match_operand:QI 2 "nonmemory_operand" "")))
11716    (clobber (reg:CC FLAGS_REG))]
11717   ""
11718   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11719
11720 (define_insn "*lshrsi3_1_one_bit"
11721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11722         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11723                      (match_operand:QI 2 "const1_operand" "")))
11724    (clobber (reg:CC FLAGS_REG))]
11725   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11726    && (TARGET_SHIFT1 || optimize_size)"
11727   "shr{l}\t%0"
11728   [(set_attr "type" "ishift")
11729    (set (attr "length") 
11730      (if_then_else (match_operand:SI 0 "register_operand" "") 
11731         (const_string "2")
11732         (const_string "*")))])
11733
11734 (define_insn "*lshrsi3_1_one_bit_zext"
11735   [(set (match_operand:DI 0 "register_operand" "=r")
11736         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11737                      (match_operand:QI 2 "const1_operand" "")))
11738    (clobber (reg:CC FLAGS_REG))]
11739   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11740    && (TARGET_SHIFT1 || optimize_size)"
11741   "shr{l}\t%k0"
11742   [(set_attr "type" "ishift")
11743    (set_attr "length" "2")])
11744
11745 (define_insn "*lshrsi3_1"
11746   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11747         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11748                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11749    (clobber (reg:CC FLAGS_REG))]
11750   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11751   "@
11752    shr{l}\t{%2, %0|%0, %2}
11753    shr{l}\t{%b2, %0|%0, %b2}"
11754   [(set_attr "type" "ishift")
11755    (set_attr "mode" "SI")])
11756
11757 (define_insn "*lshrsi3_1_zext"
11758   [(set (match_operand:DI 0 "register_operand" "=r,r")
11759         (zero_extend:DI
11760           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11761                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11764   "@
11765    shr{l}\t{%2, %k0|%k0, %2}
11766    shr{l}\t{%b2, %k0|%k0, %b2}"
11767   [(set_attr "type" "ishift")
11768    (set_attr "mode" "SI")])
11769
11770 ;; This pattern can't accept a variable shift count, since shifts by
11771 ;; zero don't affect the flags.  We assume that shifts by constant
11772 ;; zero are optimized away.
11773 (define_insn "*lshrsi3_one_bit_cmp"
11774   [(set (reg FLAGS_REG)
11775         (compare
11776           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11777                        (match_operand:QI 2 "const1_operand" ""))
11778           (const_int 0)))
11779    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11780         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11781   "ix86_match_ccmode (insn, CCGOCmode)
11782    && (TARGET_SHIFT1 || optimize_size)
11783    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11784   "shr{l}\t%0"
11785   [(set_attr "type" "ishift")
11786    (set (attr "length") 
11787      (if_then_else (match_operand:SI 0 "register_operand" "") 
11788         (const_string "2")
11789         (const_string "*")))])
11790
11791 (define_insn "*lshrsi3_cmp_one_bit_zext"
11792   [(set (reg FLAGS_REG)
11793         (compare
11794           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11795                        (match_operand:QI 2 "const1_operand" ""))
11796           (const_int 0)))
11797    (set (match_operand:DI 0 "register_operand" "=r")
11798         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11799   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11800    && (TARGET_SHIFT1 || optimize_size)
11801    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802   "shr{l}\t%k0"
11803   [(set_attr "type" "ishift")
11804    (set_attr "length" "2")])
11805
11806 ;; This pattern can't accept a variable shift count, since shifts by
11807 ;; zero don't affect the flags.  We assume that shifts by constant
11808 ;; zero are optimized away.
11809 (define_insn "*lshrsi3_cmp"
11810   [(set (reg FLAGS_REG)
11811         (compare
11812           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11813                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11814           (const_int 0)))
11815    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11816         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11817   "ix86_match_ccmode (insn, CCGOCmode)
11818    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11819   "shr{l}\t{%2, %0|%0, %2}"
11820   [(set_attr "type" "ishift")
11821    (set_attr "mode" "SI")])
11822
11823 (define_insn "*lshrsi3_cmp_zext"
11824   [(set (reg FLAGS_REG)
11825         (compare
11826           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11827                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11828           (const_int 0)))
11829    (set (match_operand:DI 0 "register_operand" "=r")
11830         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11831   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11832    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11833   "shr{l}\t{%2, %k0|%k0, %2}"
11834   [(set_attr "type" "ishift")
11835    (set_attr "mode" "SI")])
11836
11837 (define_expand "lshrhi3"
11838   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11839         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11840                      (match_operand:QI 2 "nonmemory_operand" "")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "TARGET_HIMODE_MATH"
11843   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11844
11845 (define_insn "*lshrhi3_1_one_bit"
11846   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11847         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11848                      (match_operand:QI 2 "const1_operand" "")))
11849    (clobber (reg:CC FLAGS_REG))]
11850   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11851    && (TARGET_SHIFT1 || optimize_size)"
11852   "shr{w}\t%0"
11853   [(set_attr "type" "ishift")
11854    (set (attr "length") 
11855      (if_then_else (match_operand 0 "register_operand" "") 
11856         (const_string "2")
11857         (const_string "*")))])
11858
11859 (define_insn "*lshrhi3_1"
11860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11861         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11862                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11863    (clobber (reg:CC FLAGS_REG))]
11864   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11865   "@
11866    shr{w}\t{%2, %0|%0, %2}
11867    shr{w}\t{%b2, %0|%0, %b2}"
11868   [(set_attr "type" "ishift")
11869    (set_attr "mode" "HI")])
11870
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags.  We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*lshrhi3_one_bit_cmp"
11875   [(set (reg FLAGS_REG)
11876         (compare
11877           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11878                        (match_operand:QI 2 "const1_operand" ""))
11879           (const_int 0)))
11880    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11881         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11882   "ix86_match_ccmode (insn, CCGOCmode)
11883    && (TARGET_SHIFT1 || optimize_size)
11884    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11885   "shr{w}\t%0"
11886   [(set_attr "type" "ishift")
11887    (set (attr "length") 
11888      (if_then_else (match_operand:SI 0 "register_operand" "") 
11889         (const_string "2")
11890         (const_string "*")))])
11891
11892 ;; This pattern can't accept a variable shift count, since shifts by
11893 ;; zero don't affect the flags.  We assume that shifts by constant
11894 ;; zero are optimized away.
11895 (define_insn "*lshrhi3_cmp"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900           (const_int 0)))
11901    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11902         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11903   "ix86_match_ccmode (insn, CCGOCmode)
11904    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905   "shr{w}\t{%2, %0|%0, %2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11908
11909 (define_expand "lshrqi3"
11910   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11911         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11912                      (match_operand:QI 2 "nonmemory_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "TARGET_QIMODE_MATH"
11915   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11916
11917 (define_insn "*lshrqi3_1_one_bit"
11918   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11919         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11920                      (match_operand:QI 2 "const1_operand" "")))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11923    && (TARGET_SHIFT1 || optimize_size)"
11924   "shr{b}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set (attr "length") 
11927      (if_then_else (match_operand 0 "register_operand" "") 
11928         (const_string "2")
11929         (const_string "*")))])
11930
11931 (define_insn "*lshrqi3_1_one_bit_slp"
11932   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11933         (lshiftrt:QI (match_dup 0)
11934                      (match_operand:QI 1 "const1_operand" "")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11937    && (TARGET_SHIFT1 || optimize_size)"
11938   "shr{b}\t%0"
11939   [(set_attr "type" "ishift1")
11940    (set (attr "length") 
11941      (if_then_else (match_operand 0 "register_operand" "") 
11942         (const_string "2")
11943         (const_string "*")))])
11944
11945 (define_insn "*lshrqi3_1"
11946   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11947         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11948                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11951   "@
11952    shr{b}\t{%2, %0|%0, %2}
11953    shr{b}\t{%b2, %0|%0, %b2}"
11954   [(set_attr "type" "ishift")
11955    (set_attr "mode" "QI")])
11956
11957 (define_insn "*lshrqi3_1_slp"
11958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11959         (lshiftrt:QI (match_dup 0)
11960                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11963    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11964   "@
11965    shr{b}\t{%1, %0|%0, %1}
11966    shr{b}\t{%b1, %0|%0, %b1}"
11967   [(set_attr "type" "ishift1")
11968    (set_attr "mode" "QI")])
11969
11970 ;; This pattern can't accept a variable shift count, since shifts by
11971 ;; zero don't affect the flags.  We assume that shifts by constant
11972 ;; zero are optimized away.
11973 (define_insn "*lshrqi2_one_bit_cmp"
11974   [(set (reg FLAGS_REG)
11975         (compare
11976           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11977                        (match_operand:QI 2 "const1_operand" ""))
11978           (const_int 0)))
11979    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11980         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11981   "ix86_match_ccmode (insn, CCGOCmode)
11982    && (TARGET_SHIFT1 || optimize_size)
11983    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11984   "shr{b}\t%0"
11985   [(set_attr "type" "ishift")
11986    (set (attr "length") 
11987      (if_then_else (match_operand:SI 0 "register_operand" "") 
11988         (const_string "2")
11989         (const_string "*")))])
11990
11991 ;; This pattern can't accept a variable shift count, since shifts by
11992 ;; zero don't affect the flags.  We assume that shifts by constant
11993 ;; zero are optimized away.
11994 (define_insn "*lshrqi2_cmp"
11995   [(set (reg FLAGS_REG)
11996         (compare
11997           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11998                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11999           (const_int 0)))
12000    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12001         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12002   "ix86_match_ccmode (insn, CCGOCmode)
12003    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12004   "shr{b}\t{%2, %0|%0, %2}"
12005   [(set_attr "type" "ishift")
12006    (set_attr "mode" "QI")])
12007 \f
12008 ;; Rotate instructions
12009
12010 (define_expand "rotldi3"
12011   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12012         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12013                    (match_operand:QI 2 "nonmemory_operand" "")))
12014    (clobber (reg:CC FLAGS_REG))]
12015   "TARGET_64BIT"
12016   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12017
12018 (define_insn "*rotlsi3_1_one_bit_rex64"
12019   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12021                    (match_operand:QI 2 "const1_operand" "")))
12022    (clobber (reg:CC FLAGS_REG))]
12023   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12024    && (TARGET_SHIFT1 || optimize_size)"
12025   "rol{q}\t%0"
12026   [(set_attr "type" "rotate")
12027    (set (attr "length") 
12028      (if_then_else (match_operand:DI 0 "register_operand" "") 
12029         (const_string "2")
12030         (const_string "*")))])
12031
12032 (define_insn "*rotldi3_1_rex64"
12033   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12034         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12035                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12036    (clobber (reg:CC FLAGS_REG))]
12037   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12038   "@
12039    rol{q}\t{%2, %0|%0, %2}
12040    rol{q}\t{%b2, %0|%0, %b2}"
12041   [(set_attr "type" "rotate")
12042    (set_attr "mode" "DI")])
12043
12044 (define_expand "rotlsi3"
12045   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12046         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12047                    (match_operand:QI 2 "nonmemory_operand" "")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   ""
12050   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12051
12052 (define_insn "*rotlsi3_1_one_bit"
12053   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12054         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12055                    (match_operand:QI 2 "const1_operand" "")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12058    && (TARGET_SHIFT1 || optimize_size)"
12059   "rol{l}\t%0"
12060   [(set_attr "type" "rotate")
12061    (set (attr "length") 
12062      (if_then_else (match_operand:SI 0 "register_operand" "") 
12063         (const_string "2")
12064         (const_string "*")))])
12065
12066 (define_insn "*rotlsi3_1_one_bit_zext"
12067   [(set (match_operand:DI 0 "register_operand" "=r")
12068         (zero_extend:DI
12069           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12070                      (match_operand:QI 2 "const1_operand" ""))))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12073    && (TARGET_SHIFT1 || optimize_size)"
12074   "rol{l}\t%k0"
12075   [(set_attr "type" "rotate")
12076    (set_attr "length" "2")])
12077
12078 (define_insn "*rotlsi3_1"
12079   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12080         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12081                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12082    (clobber (reg:CC FLAGS_REG))]
12083   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12084   "@
12085    rol{l}\t{%2, %0|%0, %2}
12086    rol{l}\t{%b2, %0|%0, %b2}"
12087   [(set_attr "type" "rotate")
12088    (set_attr "mode" "SI")])
12089
12090 (define_insn "*rotlsi3_1_zext"
12091   [(set (match_operand:DI 0 "register_operand" "=r,r")
12092         (zero_extend:DI
12093           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12094                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12097   "@
12098    rol{l}\t{%2, %k0|%k0, %2}
12099    rol{l}\t{%b2, %k0|%k0, %b2}"
12100   [(set_attr "type" "rotate")
12101    (set_attr "mode" "SI")])
12102
12103 (define_expand "rotlhi3"
12104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12105         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12106                    (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_HIMODE_MATH"
12109   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12110
12111 (define_insn "*rotlhi3_1_one_bit"
12112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12113         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12114                    (match_operand:QI 2 "const1_operand" "")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12117    && (TARGET_SHIFT1 || optimize_size)"
12118   "rol{w}\t%0"
12119   [(set_attr "type" "rotate")
12120    (set (attr "length") 
12121      (if_then_else (match_operand 0 "register_operand" "") 
12122         (const_string "2")
12123         (const_string "*")))])
12124
12125 (define_insn "*rotlhi3_1"
12126   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12127         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12128                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12131   "@
12132    rol{w}\t{%2, %0|%0, %2}
12133    rol{w}\t{%b2, %0|%0, %b2}"
12134   [(set_attr "type" "rotate")
12135    (set_attr "mode" "HI")])
12136
12137 (define_expand "rotlqi3"
12138   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12139         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12140                    (match_operand:QI 2 "nonmemory_operand" "")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "TARGET_QIMODE_MATH"
12143   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12144
12145 (define_insn "*rotlqi3_1_one_bit_slp"
12146   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12147         (rotate:QI (match_dup 0)
12148                    (match_operand:QI 1 "const1_operand" "")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12151    && (TARGET_SHIFT1 || optimize_size)"
12152   "rol{b}\t%0"
12153   [(set_attr "type" "rotate1")
12154    (set (attr "length") 
12155      (if_then_else (match_operand 0 "register_operand" "") 
12156         (const_string "2")
12157         (const_string "*")))])
12158
12159 (define_insn "*rotlqi3_1_one_bit"
12160   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12161         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12162                    (match_operand:QI 2 "const1_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12165    && (TARGET_SHIFT1 || optimize_size)"
12166   "rol{b}\t%0"
12167   [(set_attr "type" "rotate")
12168    (set (attr "length") 
12169      (if_then_else (match_operand 0 "register_operand" "") 
12170         (const_string "2")
12171         (const_string "*")))])
12172
12173 (define_insn "*rotlqi3_1_slp"
12174   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12175         (rotate:QI (match_dup 0)
12176                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12177    (clobber (reg:CC FLAGS_REG))]
12178   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12179    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12180   "@
12181    rol{b}\t{%1, %0|%0, %1}
12182    rol{b}\t{%b1, %0|%0, %b1}"
12183   [(set_attr "type" "rotate1")
12184    (set_attr "mode" "QI")])
12185
12186 (define_insn "*rotlqi3_1"
12187   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190    (clobber (reg:CC FLAGS_REG))]
12191   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12192   "@
12193    rol{b}\t{%2, %0|%0, %2}
12194    rol{b}\t{%b2, %0|%0, %b2}"
12195   [(set_attr "type" "rotate")
12196    (set_attr "mode" "QI")])
12197
12198 (define_expand "rotrdi3"
12199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12200         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12201                      (match_operand:QI 2 "nonmemory_operand" "")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "TARGET_64BIT"
12204   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12205
12206 (define_insn "*rotrdi3_1_one_bit_rex64"
12207   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12208         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12209                      (match_operand:QI 2 "const1_operand" "")))
12210    (clobber (reg:CC FLAGS_REG))]
12211   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12212    && (TARGET_SHIFT1 || optimize_size)"
12213   "ror{q}\t%0"
12214   [(set_attr "type" "rotate")
12215    (set (attr "length") 
12216      (if_then_else (match_operand:DI 0 "register_operand" "") 
12217         (const_string "2")
12218         (const_string "*")))])
12219
12220 (define_insn "*rotrdi3_1_rex64"
12221   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12222         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12223                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12224    (clobber (reg:CC FLAGS_REG))]
12225   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12226   "@
12227    ror{q}\t{%2, %0|%0, %2}
12228    ror{q}\t{%b2, %0|%0, %b2}"
12229   [(set_attr "type" "rotate")
12230    (set_attr "mode" "DI")])
12231
12232 (define_expand "rotrsi3"
12233   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12234         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12235                      (match_operand:QI 2 "nonmemory_operand" "")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   ""
12238   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12239
12240 (define_insn "*rotrsi3_1_one_bit"
12241   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12242         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243                      (match_operand:QI 2 "const1_operand" "")))
12244    (clobber (reg:CC FLAGS_REG))]
12245   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12246    && (TARGET_SHIFT1 || optimize_size)"
12247   "ror{l}\t%0"
12248   [(set_attr "type" "rotate")
12249    (set (attr "length") 
12250      (if_then_else (match_operand:SI 0 "register_operand" "") 
12251         (const_string "2")
12252         (const_string "*")))])
12253
12254 (define_insn "*rotrsi3_1_one_bit_zext"
12255   [(set (match_operand:DI 0 "register_operand" "=r")
12256         (zero_extend:DI
12257           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12258                        (match_operand:QI 2 "const1_operand" ""))))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12261    && (TARGET_SHIFT1 || optimize_size)"
12262   "ror{l}\t%k0"
12263   [(set_attr "type" "rotate")
12264    (set (attr "length") 
12265      (if_then_else (match_operand:SI 0 "register_operand" "") 
12266         (const_string "2")
12267         (const_string "*")))])
12268
12269 (define_insn "*rotrsi3_1"
12270   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12271         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12272                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273    (clobber (reg:CC FLAGS_REG))]
12274   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12275   "@
12276    ror{l}\t{%2, %0|%0, %2}
12277    ror{l}\t{%b2, %0|%0, %b2}"
12278   [(set_attr "type" "rotate")
12279    (set_attr "mode" "SI")])
12280
12281 (define_insn "*rotrsi3_1_zext"
12282   [(set (match_operand:DI 0 "register_operand" "=r,r")
12283         (zero_extend:DI
12284           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12285                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12288   "@
12289    ror{l}\t{%2, %k0|%k0, %2}
12290    ror{l}\t{%b2, %k0|%k0, %b2}"
12291   [(set_attr "type" "rotate")
12292    (set_attr "mode" "SI")])
12293
12294 (define_expand "rotrhi3"
12295   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12296         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12297                      (match_operand:QI 2 "nonmemory_operand" "")))
12298    (clobber (reg:CC FLAGS_REG))]
12299   "TARGET_HIMODE_MATH"
12300   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12301
12302 (define_insn "*rotrhi3_one_bit"
12303   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12304         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12305                      (match_operand:QI 2 "const1_operand" "")))
12306    (clobber (reg:CC FLAGS_REG))]
12307   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12308    && (TARGET_SHIFT1 || optimize_size)"
12309   "ror{w}\t%0"
12310   [(set_attr "type" "rotate")
12311    (set (attr "length") 
12312      (if_then_else (match_operand 0 "register_operand" "") 
12313         (const_string "2")
12314         (const_string "*")))])
12315
12316 (define_insn "*rotrhi3"
12317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12318         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12319                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12322   "@
12323    ror{w}\t{%2, %0|%0, %2}
12324    ror{w}\t{%b2, %0|%0, %b2}"
12325   [(set_attr "type" "rotate")
12326    (set_attr "mode" "HI")])
12327
12328 (define_expand "rotrqi3"
12329   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12330         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12331                      (match_operand:QI 2 "nonmemory_operand" "")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_QIMODE_MATH"
12334   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12335
12336 (define_insn "*rotrqi3_1_one_bit"
12337   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12338         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12339                      (match_operand:QI 2 "const1_operand" "")))
12340    (clobber (reg:CC FLAGS_REG))]
12341   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12342    && (TARGET_SHIFT1 || optimize_size)"
12343   "ror{b}\t%0"
12344   [(set_attr "type" "rotate")
12345    (set (attr "length") 
12346      (if_then_else (match_operand 0 "register_operand" "") 
12347         (const_string "2")
12348         (const_string "*")))])
12349
12350 (define_insn "*rotrqi3_1_one_bit_slp"
12351   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12352         (rotatert:QI (match_dup 0)
12353                      (match_operand:QI 1 "const1_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12356    && (TARGET_SHIFT1 || optimize_size)"
12357   "ror{b}\t%0"
12358   [(set_attr "type" "rotate1")
12359    (set (attr "length") 
12360      (if_then_else (match_operand 0 "register_operand" "") 
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*rotrqi3_1"
12365   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12366         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12367                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12370   "@
12371    ror{b}\t{%2, %0|%0, %2}
12372    ror{b}\t{%b2, %0|%0, %b2}"
12373   [(set_attr "type" "rotate")
12374    (set_attr "mode" "QI")])
12375
12376 (define_insn "*rotrqi3_1_slp"
12377   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12378         (rotatert:QI (match_dup 0)
12379                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12382    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12383   "@
12384    ror{b}\t{%1, %0|%0, %1}
12385    ror{b}\t{%b1, %0|%0, %b1}"
12386   [(set_attr "type" "rotate1")
12387    (set_attr "mode" "QI")])
12388 \f
12389 ;; Bit set / bit test instructions
12390
12391 (define_expand "extv"
12392   [(set (match_operand:SI 0 "register_operand" "")
12393         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12394                          (match_operand:SI 2 "immediate_operand" "")
12395                          (match_operand:SI 3 "immediate_operand" "")))]
12396   ""
12397 {
12398   /* Handle extractions from %ah et al.  */
12399   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12400     FAIL;
12401
12402   /* From mips.md: extract_bit_field doesn't verify that our source
12403      matches the predicate, so check it again here.  */
12404   if (! ext_register_operand (operands[1], VOIDmode))
12405     FAIL;
12406 })
12407
12408 (define_expand "extzv"
12409   [(set (match_operand:SI 0 "register_operand" "")
12410         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12411                          (match_operand:SI 2 "immediate_operand" "")
12412                          (match_operand:SI 3 "immediate_operand" "")))]
12413   ""
12414 {
12415   /* Handle extractions from %ah et al.  */
12416   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12417     FAIL;
12418
12419   /* From mips.md: extract_bit_field doesn't verify that our source
12420      matches the predicate, so check it again here.  */
12421   if (! ext_register_operand (operands[1], VOIDmode))
12422     FAIL;
12423 })
12424
12425 (define_expand "insv"
12426   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12427                       (match_operand 1 "immediate_operand" "")
12428                       (match_operand 2 "immediate_operand" ""))
12429         (match_operand 3 "register_operand" ""))]
12430   ""
12431 {
12432   /* Handle extractions from %ah et al.  */
12433   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12434     FAIL;
12435
12436   /* From mips.md: insert_bit_field doesn't verify that our source
12437      matches the predicate, so check it again here.  */
12438   if (! ext_register_operand (operands[0], VOIDmode))
12439     FAIL;
12440
12441   if (TARGET_64BIT)
12442     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12443   else
12444     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12445
12446   DONE;
12447 })
12448
12449 ;; %%% bts, btr, btc, bt.
12450 ;; In general these instructions are *slow* when applied to memory,
12451 ;; since they enforce atomic operation.  When applied to registers,
12452 ;; it depends on the cpu implementation.  They're never faster than
12453 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12454 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12455 ;; within the instruction itself, so operating on bits in the high
12456 ;; 32-bits of a register becomes easier.
12457 ;;
12458 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12459 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12460 ;; negdf respectively, so they can never be disabled entirely.
12461
12462 (define_insn "*btsq"
12463   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12464                          (const_int 1)
12465                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12466         (const_int 1))
12467    (clobber (reg:CC FLAGS_REG))]
12468   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12469   "bts{q} %1,%0"
12470   [(set_attr "type" "alu1")])
12471
12472 (define_insn "*btrq"
12473   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12474                          (const_int 1)
12475                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12476         (const_int 0))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12479   "btr{q} %1,%0"
12480   [(set_attr "type" "alu1")])
12481
12482 (define_insn "*btcq"
12483   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12484                          (const_int 1)
12485                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12486         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12487    (clobber (reg:CC FLAGS_REG))]
12488   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12489   "btc{q} %1,%0"
12490   [(set_attr "type" "alu1")])
12491
12492 ;; Allow Nocona to avoid these instructions if a register is available.
12493
12494 (define_peephole2
12495   [(match_scratch:DI 2 "r")
12496    (parallel [(set (zero_extract:DI
12497                      (match_operand:DI 0 "register_operand" "")
12498                      (const_int 1)
12499                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12500                    (const_int 1))
12501               (clobber (reg:CC FLAGS_REG))])]
12502   "TARGET_64BIT && !TARGET_USE_BT"
12503   [(const_int 0)]
12504 {
12505   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12506   rtx op1;
12507
12508   if (HOST_BITS_PER_WIDE_INT >= 64)
12509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12510   else if (i < HOST_BITS_PER_WIDE_INT)
12511     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12512   else
12513     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12514
12515   op1 = immed_double_const (lo, hi, DImode);
12516   if (i >= 31)
12517     {
12518       emit_move_insn (operands[2], op1);
12519       op1 = operands[2];
12520     }
12521
12522   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12523   DONE;
12524 })
12525
12526 (define_peephole2
12527   [(match_scratch:DI 2 "r")
12528    (parallel [(set (zero_extract:DI
12529                      (match_operand:DI 0 "register_operand" "")
12530                      (const_int 1)
12531                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12532                    (const_int 0))
12533               (clobber (reg:CC FLAGS_REG))])]
12534   "TARGET_64BIT && !TARGET_USE_BT"
12535   [(const_int 0)]
12536 {
12537   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12538   rtx op1;
12539
12540   if (HOST_BITS_PER_WIDE_INT >= 64)
12541     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12542   else if (i < HOST_BITS_PER_WIDE_INT)
12543     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12544   else
12545     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12546
12547   op1 = immed_double_const (~lo, ~hi, DImode);
12548   if (i >= 32)
12549     {
12550       emit_move_insn (operands[2], op1);
12551       op1 = operands[2];
12552     }
12553
12554   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12555   DONE;
12556 })
12557
12558 (define_peephole2
12559   [(match_scratch:DI 2 "r")
12560    (parallel [(set (zero_extract:DI
12561                      (match_operand:DI 0 "register_operand" "")
12562                      (const_int 1)
12563                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12564               (not:DI (zero_extract:DI
12565                         (match_dup 0) (const_int 1) (match_dup 1))))
12566               (clobber (reg:CC FLAGS_REG))])]
12567   "TARGET_64BIT && !TARGET_USE_BT"
12568   [(const_int 0)]
12569 {
12570   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12571   rtx op1;
12572
12573   if (HOST_BITS_PER_WIDE_INT >= 64)
12574     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12575   else if (i < HOST_BITS_PER_WIDE_INT)
12576     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12577   else
12578     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12579
12580   op1 = immed_double_const (lo, hi, DImode);
12581   if (i >= 31)
12582     {
12583       emit_move_insn (operands[2], op1);
12584       op1 = operands[2];
12585     }
12586
12587   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12588   DONE;
12589 })
12590 \f
12591 ;; Store-flag instructions.
12592
12593 ;; For all sCOND expanders, also expand the compare or test insn that
12594 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12595
12596 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12597 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12598 ;; way, which can later delete the movzx if only QImode is needed.
12599
12600 (define_expand "seq"
12601   [(set (match_operand:QI 0 "register_operand" "")
12602         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12603   ""
12604   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12605
12606 (define_expand "sne"
12607   [(set (match_operand:QI 0 "register_operand" "")
12608         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12609   ""
12610   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12611
12612 (define_expand "sgt"
12613   [(set (match_operand:QI 0 "register_operand" "")
12614         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12615   ""
12616   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12617
12618 (define_expand "sgtu"
12619   [(set (match_operand:QI 0 "register_operand" "")
12620         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12621   ""
12622   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12623
12624 (define_expand "slt"
12625   [(set (match_operand:QI 0 "register_operand" "")
12626         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12627   ""
12628   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12629
12630 (define_expand "sltu"
12631   [(set (match_operand:QI 0 "register_operand" "")
12632         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12633   ""
12634   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12635
12636 (define_expand "sge"
12637   [(set (match_operand:QI 0 "register_operand" "")
12638         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12639   ""
12640   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12641
12642 (define_expand "sgeu"
12643   [(set (match_operand:QI 0 "register_operand" "")
12644         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12645   ""
12646   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12647
12648 (define_expand "sle"
12649   [(set (match_operand:QI 0 "register_operand" "")
12650         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12651   ""
12652   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12653
12654 (define_expand "sleu"
12655   [(set (match_operand:QI 0 "register_operand" "")
12656         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12657   ""
12658   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12659
12660 (define_expand "sunordered"
12661   [(set (match_operand:QI 0 "register_operand" "")
12662         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12663   "TARGET_80387 || TARGET_SSE"
12664   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12665
12666 (define_expand "sordered"
12667   [(set (match_operand:QI 0 "register_operand" "")
12668         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12669   "TARGET_80387"
12670   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12671
12672 (define_expand "suneq"
12673   [(set (match_operand:QI 0 "register_operand" "")
12674         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12675   "TARGET_80387 || TARGET_SSE"
12676   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12677
12678 (define_expand "sunge"
12679   [(set (match_operand:QI 0 "register_operand" "")
12680         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12681   "TARGET_80387 || TARGET_SSE"
12682   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12683
12684 (define_expand "sungt"
12685   [(set (match_operand:QI 0 "register_operand" "")
12686         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12687   "TARGET_80387 || TARGET_SSE"
12688   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12689
12690 (define_expand "sunle"
12691   [(set (match_operand:QI 0 "register_operand" "")
12692         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12693   "TARGET_80387 || TARGET_SSE"
12694   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12695
12696 (define_expand "sunlt"
12697   [(set (match_operand:QI 0 "register_operand" "")
12698         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12699   "TARGET_80387 || TARGET_SSE"
12700   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12701
12702 (define_expand "sltgt"
12703   [(set (match_operand:QI 0 "register_operand" "")
12704         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12705   "TARGET_80387 || TARGET_SSE"
12706   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12707
12708 (define_insn "*setcc_1"
12709   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12710         (match_operator:QI 1 "ix86_comparison_operator"
12711           [(reg FLAGS_REG) (const_int 0)]))]
12712   ""
12713   "set%C1\t%0"
12714   [(set_attr "type" "setcc")
12715    (set_attr "mode" "QI")])
12716
12717 (define_insn "*setcc_2"
12718   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12719         (match_operator:QI 1 "ix86_comparison_operator"
12720           [(reg FLAGS_REG) (const_int 0)]))]
12721   ""
12722   "set%C1\t%0"
12723   [(set_attr "type" "setcc")
12724    (set_attr "mode" "QI")])
12725
12726 ;; In general it is not safe to assume too much about CCmode registers,
12727 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12728 ;; conditions this is safe on x86, so help combine not create
12729 ;;
12730 ;;      seta    %al
12731 ;;      testb   %al, %al
12732 ;;      sete    %al
12733
12734 (define_split 
12735   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12736         (ne:QI (match_operator 1 "ix86_comparison_operator"
12737                  [(reg FLAGS_REG) (const_int 0)])
12738             (const_int 0)))]
12739   ""
12740   [(set (match_dup 0) (match_dup 1))]
12741 {
12742   PUT_MODE (operands[1], QImode);
12743 })
12744
12745 (define_split 
12746   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12747         (ne:QI (match_operator 1 "ix86_comparison_operator"
12748                  [(reg FLAGS_REG) (const_int 0)])
12749             (const_int 0)))]
12750   ""
12751   [(set (match_dup 0) (match_dup 1))]
12752 {
12753   PUT_MODE (operands[1], QImode);
12754 })
12755
12756 (define_split 
12757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12758         (eq:QI (match_operator 1 "ix86_comparison_operator"
12759                  [(reg FLAGS_REG) (const_int 0)])
12760             (const_int 0)))]
12761   ""
12762   [(set (match_dup 0) (match_dup 1))]
12763 {
12764   rtx new_op1 = copy_rtx (operands[1]);
12765   operands[1] = new_op1;
12766   PUT_MODE (new_op1, QImode);
12767   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12768                                              GET_MODE (XEXP (new_op1, 0))));
12769
12770   /* Make sure that (a) the CCmode we have for the flags is strong
12771      enough for the reversed compare or (b) we have a valid FP compare.  */
12772   if (! ix86_comparison_operator (new_op1, VOIDmode))
12773     FAIL;
12774 })
12775
12776 (define_split 
12777   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12778         (eq:QI (match_operator 1 "ix86_comparison_operator"
12779                  [(reg FLAGS_REG) (const_int 0)])
12780             (const_int 0)))]
12781   ""
12782   [(set (match_dup 0) (match_dup 1))]
12783 {
12784   rtx new_op1 = copy_rtx (operands[1]);
12785   operands[1] = new_op1;
12786   PUT_MODE (new_op1, QImode);
12787   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12788                                              GET_MODE (XEXP (new_op1, 0))));
12789
12790   /* Make sure that (a) the CCmode we have for the flags is strong
12791      enough for the reversed compare or (b) we have a valid FP compare.  */
12792   if (! ix86_comparison_operator (new_op1, VOIDmode))
12793     FAIL;
12794 })
12795
12796 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12797 ;; subsequent logical operations are used to imitate conditional moves.
12798 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12799 ;; it directly.
12800
12801 (define_insn "*sse_setccsf"
12802   [(set (match_operand:SF 0 "register_operand" "=x")
12803         (match_operator:SF 1 "sse_comparison_operator"
12804           [(match_operand:SF 2 "register_operand" "0")
12805            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12806   "TARGET_SSE"
12807   "cmp%D1ss\t{%3, %0|%0, %3}"
12808   [(set_attr "type" "ssecmp")
12809    (set_attr "mode" "SF")])
12810
12811 (define_insn "*sse_setccdf"
12812   [(set (match_operand:DF 0 "register_operand" "=Y")
12813         (match_operator:DF 1 "sse_comparison_operator"
12814           [(match_operand:DF 2 "register_operand" "0")
12815            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12816   "TARGET_SSE2"
12817   "cmp%D1sd\t{%3, %0|%0, %3}"
12818   [(set_attr "type" "ssecmp")
12819    (set_attr "mode" "DF")])
12820 \f
12821 ;; Basic conditional jump instructions.
12822 ;; We ignore the overflow flag for signed branch instructions.
12823
12824 ;; For all bCOND expanders, also expand the compare or test insn that
12825 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12826
12827 (define_expand "beq"
12828   [(set (pc)
12829         (if_then_else (match_dup 1)
12830                       (label_ref (match_operand 0 "" ""))
12831                       (pc)))]
12832   ""
12833   "ix86_expand_branch (EQ, operands[0]); DONE;")
12834
12835 (define_expand "bne"
12836   [(set (pc)
12837         (if_then_else (match_dup 1)
12838                       (label_ref (match_operand 0 "" ""))
12839                       (pc)))]
12840   ""
12841   "ix86_expand_branch (NE, operands[0]); DONE;")
12842
12843 (define_expand "bgt"
12844   [(set (pc)
12845         (if_then_else (match_dup 1)
12846                       (label_ref (match_operand 0 "" ""))
12847                       (pc)))]
12848   ""
12849   "ix86_expand_branch (GT, operands[0]); DONE;")
12850
12851 (define_expand "bgtu"
12852   [(set (pc)
12853         (if_then_else (match_dup 1)
12854                       (label_ref (match_operand 0 "" ""))
12855                       (pc)))]
12856   ""
12857   "ix86_expand_branch (GTU, operands[0]); DONE;")
12858
12859 (define_expand "blt"
12860   [(set (pc)
12861         (if_then_else (match_dup 1)
12862                       (label_ref (match_operand 0 "" ""))
12863                       (pc)))]
12864   ""
12865   "ix86_expand_branch (LT, operands[0]); DONE;")
12866
12867 (define_expand "bltu"
12868   [(set (pc)
12869         (if_then_else (match_dup 1)
12870                       (label_ref (match_operand 0 "" ""))
12871                       (pc)))]
12872   ""
12873   "ix86_expand_branch (LTU, operands[0]); DONE;")
12874
12875 (define_expand "bge"
12876   [(set (pc)
12877         (if_then_else (match_dup 1)
12878                       (label_ref (match_operand 0 "" ""))
12879                       (pc)))]
12880   ""
12881   "ix86_expand_branch (GE, operands[0]); DONE;")
12882
12883 (define_expand "bgeu"
12884   [(set (pc)
12885         (if_then_else (match_dup 1)
12886                       (label_ref (match_operand 0 "" ""))
12887                       (pc)))]
12888   ""
12889   "ix86_expand_branch (GEU, operands[0]); DONE;")
12890
12891 (define_expand "ble"
12892   [(set (pc)
12893         (if_then_else (match_dup 1)
12894                       (label_ref (match_operand 0 "" ""))
12895                       (pc)))]
12896   ""
12897   "ix86_expand_branch (LE, operands[0]); DONE;")
12898
12899 (define_expand "bleu"
12900   [(set (pc)
12901         (if_then_else (match_dup 1)
12902                       (label_ref (match_operand 0 "" ""))
12903                       (pc)))]
12904   ""
12905   "ix86_expand_branch (LEU, operands[0]); DONE;")
12906
12907 (define_expand "bunordered"
12908   [(set (pc)
12909         (if_then_else (match_dup 1)
12910                       (label_ref (match_operand 0 "" ""))
12911                       (pc)))]
12912   "TARGET_80387 || TARGET_SSE_MATH"
12913   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12914
12915 (define_expand "bordered"
12916   [(set (pc)
12917         (if_then_else (match_dup 1)
12918                       (label_ref (match_operand 0 "" ""))
12919                       (pc)))]
12920   "TARGET_80387 || TARGET_SSE_MATH"
12921   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12922
12923 (define_expand "buneq"
12924   [(set (pc)
12925         (if_then_else (match_dup 1)
12926                       (label_ref (match_operand 0 "" ""))
12927                       (pc)))]
12928   "TARGET_80387 || TARGET_SSE_MATH"
12929   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12930
12931 (define_expand "bunge"
12932   [(set (pc)
12933         (if_then_else (match_dup 1)
12934                       (label_ref (match_operand 0 "" ""))
12935                       (pc)))]
12936   "TARGET_80387 || TARGET_SSE_MATH"
12937   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12938
12939 (define_expand "bungt"
12940   [(set (pc)
12941         (if_then_else (match_dup 1)
12942                       (label_ref (match_operand 0 "" ""))
12943                       (pc)))]
12944   "TARGET_80387 || TARGET_SSE_MATH"
12945   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12946
12947 (define_expand "bunle"
12948   [(set (pc)
12949         (if_then_else (match_dup 1)
12950                       (label_ref (match_operand 0 "" ""))
12951                       (pc)))]
12952   "TARGET_80387 || TARGET_SSE_MATH"
12953   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12954
12955 (define_expand "bunlt"
12956   [(set (pc)
12957         (if_then_else (match_dup 1)
12958                       (label_ref (match_operand 0 "" ""))
12959                       (pc)))]
12960   "TARGET_80387 || TARGET_SSE_MATH"
12961   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12962
12963 (define_expand "bltgt"
12964   [(set (pc)
12965         (if_then_else (match_dup 1)
12966                       (label_ref (match_operand 0 "" ""))
12967                       (pc)))]
12968   "TARGET_80387 || TARGET_SSE_MATH"
12969   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12970
12971 (define_insn "*jcc_1"
12972   [(set (pc)
12973         (if_then_else (match_operator 1 "ix86_comparison_operator"
12974                                       [(reg FLAGS_REG) (const_int 0)])
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "%+j%C1\t%l0"
12979   [(set_attr "type" "ibr")
12980    (set_attr "modrm" "0")
12981    (set (attr "length")
12982            (if_then_else (and (ge (minus (match_dup 0) (pc))
12983                                   (const_int -126))
12984                               (lt (minus (match_dup 0) (pc))
12985                                   (const_int 128)))
12986              (const_int 2)
12987              (const_int 6)))])
12988
12989 (define_insn "*jcc_2"
12990   [(set (pc)
12991         (if_then_else (match_operator 1 "ix86_comparison_operator"
12992                                       [(reg FLAGS_REG) (const_int 0)])
12993                       (pc)
12994                       (label_ref (match_operand 0 "" ""))))]
12995   ""
12996   "%+j%c1\t%l0"
12997   [(set_attr "type" "ibr")
12998    (set_attr "modrm" "0")
12999    (set (attr "length")
13000            (if_then_else (and (ge (minus (match_dup 0) (pc))
13001                                   (const_int -126))
13002                               (lt (minus (match_dup 0) (pc))
13003                                   (const_int 128)))
13004              (const_int 2)
13005              (const_int 6)))])
13006
13007 ;; In general it is not safe to assume too much about CCmode registers,
13008 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13009 ;; conditions this is safe on x86, so help combine not create
13010 ;;
13011 ;;      seta    %al
13012 ;;      testb   %al, %al
13013 ;;      je      Lfoo
13014
13015 (define_split 
13016   [(set (pc)
13017         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13018                                       [(reg FLAGS_REG) (const_int 0)])
13019                           (const_int 0))
13020                       (label_ref (match_operand 1 "" ""))
13021                       (pc)))]
13022   ""
13023   [(set (pc)
13024         (if_then_else (match_dup 0)
13025                       (label_ref (match_dup 1))
13026                       (pc)))]
13027 {
13028   PUT_MODE (operands[0], VOIDmode);
13029 })
13030   
13031 (define_split 
13032   [(set (pc)
13033         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13034                                       [(reg FLAGS_REG) (const_int 0)])
13035                           (const_int 0))
13036                       (label_ref (match_operand 1 "" ""))
13037                       (pc)))]
13038   ""
13039   [(set (pc)
13040         (if_then_else (match_dup 0)
13041                       (label_ref (match_dup 1))
13042                       (pc)))]
13043 {
13044   rtx new_op0 = copy_rtx (operands[0]);
13045   operands[0] = new_op0;
13046   PUT_MODE (new_op0, VOIDmode);
13047   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13048                                              GET_MODE (XEXP (new_op0, 0))));
13049
13050   /* Make sure that (a) the CCmode we have for the flags is strong
13051      enough for the reversed compare or (b) we have a valid FP compare.  */
13052   if (! ix86_comparison_operator (new_op0, VOIDmode))
13053     FAIL;
13054 })
13055
13056 ;; Define combination compare-and-branch fp compare instructions to use
13057 ;; during early optimization.  Splitting the operation apart early makes
13058 ;; for bad code when we want to reverse the operation.
13059
13060 (define_insn "*fp_jcc_1_mixed"
13061   [(set (pc)
13062         (if_then_else (match_operator 0 "comparison_operator"
13063                         [(match_operand 1 "register_operand" "f#x,x#f")
13064                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13065           (label_ref (match_operand 3 "" ""))
13066           (pc)))
13067    (clobber (reg:CCFP FPSR_REG))
13068    (clobber (reg:CCFP FLAGS_REG))]
13069   "TARGET_MIX_SSE_I387
13070    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13071    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13072    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13073   "#")
13074
13075 (define_insn "*fp_jcc_1_sse"
13076   [(set (pc)
13077         (if_then_else (match_operator 0 "comparison_operator"
13078                         [(match_operand 1 "register_operand" "x")
13079                          (match_operand 2 "nonimmediate_operand" "xm")])
13080           (label_ref (match_operand 3 "" ""))
13081           (pc)))
13082    (clobber (reg:CCFP FPSR_REG))
13083    (clobber (reg:CCFP FLAGS_REG))]
13084   "TARGET_SSE_MATH
13085    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13086    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13087    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13088   "#")
13089
13090 (define_insn "*fp_jcc_1_387"
13091   [(set (pc)
13092         (if_then_else (match_operator 0 "comparison_operator"
13093                         [(match_operand 1 "register_operand" "f")
13094                          (match_operand 2 "register_operand" "f")])
13095           (label_ref (match_operand 3 "" ""))
13096           (pc)))
13097    (clobber (reg:CCFP FPSR_REG))
13098    (clobber (reg:CCFP FLAGS_REG))]
13099   "TARGET_CMOVE && TARGET_80387
13100    && FLOAT_MODE_P (GET_MODE (operands[1]))
13101    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13102    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13103   "#")
13104
13105 (define_insn "*fp_jcc_2_mixed"
13106   [(set (pc)
13107         (if_then_else (match_operator 0 "comparison_operator"
13108                         [(match_operand 1 "register_operand" "f#x,x#f")
13109                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13110           (pc)
13111           (label_ref (match_operand 3 "" ""))))
13112    (clobber (reg:CCFP FPSR_REG))
13113    (clobber (reg:CCFP FLAGS_REG))]
13114   "TARGET_MIX_SSE_I387
13115    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13116    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13117    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13118   "#")
13119
13120 (define_insn "*fp_jcc_2_sse"
13121   [(set (pc)
13122         (if_then_else (match_operator 0 "comparison_operator"
13123                         [(match_operand 1 "register_operand" "x")
13124                          (match_operand 2 "nonimmediate_operand" "xm")])
13125           (pc)
13126           (label_ref (match_operand 3 "" ""))))
13127    (clobber (reg:CCFP FPSR_REG))
13128    (clobber (reg:CCFP FLAGS_REG))]
13129   "TARGET_SSE_MATH
13130    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13131    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13132    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13133   "#")
13134
13135 (define_insn "*fp_jcc_2_387"
13136   [(set (pc)
13137         (if_then_else (match_operator 0 "comparison_operator"
13138                         [(match_operand 1 "register_operand" "f")
13139                          (match_operand 2 "register_operand" "f")])
13140           (pc)
13141           (label_ref (match_operand 3 "" ""))))
13142    (clobber (reg:CCFP FPSR_REG))
13143    (clobber (reg:CCFP FLAGS_REG))]
13144   "TARGET_CMOVE && TARGET_80387
13145    && FLOAT_MODE_P (GET_MODE (operands[1]))
13146    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13148   "#")
13149
13150 (define_insn "*fp_jcc_3_387"
13151   [(set (pc)
13152         (if_then_else (match_operator 0 "comparison_operator"
13153                         [(match_operand 1 "register_operand" "f")
13154                          (match_operand 2 "nonimmediate_operand" "fm")])
13155           (label_ref (match_operand 3 "" ""))
13156           (pc)))
13157    (clobber (reg:CCFP FPSR_REG))
13158    (clobber (reg:CCFP FLAGS_REG))
13159    (clobber (match_scratch:HI 4 "=a"))]
13160   "TARGET_80387
13161    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13162    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13163    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13164    && SELECT_CC_MODE (GET_CODE (operands[0]),
13165                       operands[1], operands[2]) == CCFPmode
13166    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13167   "#")
13168
13169 (define_insn "*fp_jcc_4_387"
13170   [(set (pc)
13171         (if_then_else (match_operator 0 "comparison_operator"
13172                         [(match_operand 1 "register_operand" "f")
13173                          (match_operand 2 "nonimmediate_operand" "fm")])
13174           (pc)
13175           (label_ref (match_operand 3 "" ""))))
13176    (clobber (reg:CCFP FPSR_REG))
13177    (clobber (reg:CCFP FLAGS_REG))
13178    (clobber (match_scratch:HI 4 "=a"))]
13179   "TARGET_80387
13180    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13181    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13183    && SELECT_CC_MODE (GET_CODE (operands[0]),
13184                       operands[1], operands[2]) == CCFPmode
13185    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186   "#")
13187
13188 (define_insn "*fp_jcc_5_387"
13189   [(set (pc)
13190         (if_then_else (match_operator 0 "comparison_operator"
13191                         [(match_operand 1 "register_operand" "f")
13192                          (match_operand 2 "register_operand" "f")])
13193           (label_ref (match_operand 3 "" ""))
13194           (pc)))
13195    (clobber (reg:CCFP FPSR_REG))
13196    (clobber (reg:CCFP FLAGS_REG))
13197    (clobber (match_scratch:HI 4 "=a"))]
13198   "TARGET_80387
13199    && FLOAT_MODE_P (GET_MODE (operands[1]))
13200    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13202   "#")
13203
13204 (define_insn "*fp_jcc_6_387"
13205   [(set (pc)
13206         (if_then_else (match_operator 0 "comparison_operator"
13207                         [(match_operand 1 "register_operand" "f")
13208                          (match_operand 2 "register_operand" "f")])
13209           (pc)
13210           (label_ref (match_operand 3 "" ""))))
13211    (clobber (reg:CCFP FPSR_REG))
13212    (clobber (reg:CCFP FLAGS_REG))
13213    (clobber (match_scratch:HI 4 "=a"))]
13214   "TARGET_80387
13215    && FLOAT_MODE_P (GET_MODE (operands[1]))
13216    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13218   "#")
13219
13220 (define_insn "*fp_jcc_7_387"
13221   [(set (pc)
13222         (if_then_else (match_operator 0 "comparison_operator"
13223                         [(match_operand 1 "register_operand" "f")
13224                          (match_operand 2 "const0_operand" "X")])
13225           (label_ref (match_operand 3 "" ""))
13226           (pc)))
13227    (clobber (reg:CCFP FPSR_REG))
13228    (clobber (reg:CCFP FLAGS_REG))
13229    (clobber (match_scratch:HI 4 "=a"))]
13230   "TARGET_80387
13231    && FLOAT_MODE_P (GET_MODE (operands[1]))
13232    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13234    && SELECT_CC_MODE (GET_CODE (operands[0]),
13235                       operands[1], operands[2]) == CCFPmode
13236    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13237   "#")
13238
13239 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13240 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13241 ;; with a precedence over other operators and is always put in the first
13242 ;; place. Swap condition and operands to match ficom instruction.
13243
13244 (define_insn "*fp_jcc_8<mode>_387"
13245   [(set (pc)
13246         (if_then_else (match_operator 0 "comparison_operator"
13247                         [(match_operator 1 "float_operator"
13248                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13249                            (match_operand 3 "register_operand" "f,f")])
13250           (label_ref (match_operand 4 "" ""))
13251           (pc)))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))
13254    (clobber (match_scratch:HI 5 "=a,a"))]
13255   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13256    && FLOAT_MODE_P (GET_MODE (operands[3]))
13257    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13258    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13259    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13260    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13261   "#")
13262
13263 (define_split
13264   [(set (pc)
13265         (if_then_else (match_operator 0 "comparison_operator"
13266                         [(match_operand 1 "register_operand" "")
13267                          (match_operand 2 "nonimmediate_operand" "")])
13268           (match_operand 3 "" "")
13269           (match_operand 4 "" "")))
13270    (clobber (reg:CCFP FPSR_REG))
13271    (clobber (reg:CCFP FLAGS_REG))]
13272   "reload_completed"
13273   [(const_int 0)]
13274 {
13275   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13276                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13277   DONE;
13278 })
13279
13280 (define_split
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "")
13284                          (match_operand 2 "general_operand" "")])
13285           (match_operand 3 "" "")
13286           (match_operand 4 "" "")))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 5 "=a"))]
13290   "reload_completed"
13291   [(const_int 0)]
13292 {
13293   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13294                         operands[3], operands[4], operands[5], NULL_RTX);
13295   DONE;
13296 })
13297
13298 (define_split
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operator 1 "float_operator"
13302                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13303                            (match_operand 3 "register_operand" "")])
13304           (match_operand 4 "" "")
13305           (match_operand 5 "" "")))
13306    (clobber (reg:CCFP FPSR_REG))
13307    (clobber (reg:CCFP FLAGS_REG))
13308    (clobber (match_scratch:HI 6 "=a"))]
13309   "reload_completed"
13310   [(const_int 0)]
13311 {
13312   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13313   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13314                         operands[3], operands[7],
13315                         operands[4], operands[5], operands[6], NULL_RTX);
13316   DONE;
13317 })
13318
13319 ;; %%% Kill this when reload knows how to do it.
13320 (define_split
13321   [(set (pc)
13322         (if_then_else (match_operator 0 "comparison_operator"
13323                         [(match_operator 1 "float_operator"
13324                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13325                            (match_operand 3 "register_operand" "")])
13326           (match_operand 4 "" "")
13327           (match_operand 5 "" "")))
13328    (clobber (reg:CCFP FPSR_REG))
13329    (clobber (reg:CCFP FLAGS_REG))
13330    (clobber (match_scratch:HI 6 "=a"))]
13331   "reload_completed"
13332   [(const_int 0)]
13333 {
13334   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13335   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13336   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13337                         operands[3], operands[7],
13338                         operands[4], operands[5], operands[6], operands[2]);
13339   DONE;
13340 })
13341 \f
13342 ;; Unconditional and other jump instructions
13343
13344 (define_insn "jump"
13345   [(set (pc)
13346         (label_ref (match_operand 0 "" "")))]
13347   ""
13348   "jmp\t%l0"
13349   [(set_attr "type" "ibr")
13350    (set (attr "length")
13351            (if_then_else (and (ge (minus (match_dup 0) (pc))
13352                                   (const_int -126))
13353                               (lt (minus (match_dup 0) (pc))
13354                                   (const_int 128)))
13355              (const_int 2)
13356              (const_int 5)))
13357    (set_attr "modrm" "0")])
13358
13359 (define_expand "indirect_jump"
13360   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13361   ""
13362   "")
13363
13364 (define_insn "*indirect_jump"
13365   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13366   "!TARGET_64BIT"
13367   "jmp\t%A0"
13368   [(set_attr "type" "ibr")
13369    (set_attr "length_immediate" "0")])
13370
13371 (define_insn "*indirect_jump_rtx64"
13372   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13373   "TARGET_64BIT"
13374   "jmp\t%A0"
13375   [(set_attr "type" "ibr")
13376    (set_attr "length_immediate" "0")])
13377
13378 (define_expand "tablejump"
13379   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13380               (use (label_ref (match_operand 1 "" "")))])]
13381   ""
13382 {
13383   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13384      relative.  Convert the relative address to an absolute address.  */
13385   if (flag_pic)
13386     {
13387       rtx op0, op1;
13388       enum rtx_code code;
13389
13390       if (TARGET_64BIT)
13391         {
13392           code = PLUS;
13393           op0 = operands[0];
13394           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13395         }
13396       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13397         {
13398           code = PLUS;
13399           op0 = operands[0];
13400           op1 = pic_offset_table_rtx;
13401         }
13402       else
13403         {
13404           code = MINUS;
13405           op0 = pic_offset_table_rtx;
13406           op1 = operands[0];
13407         }
13408
13409       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13410                                          OPTAB_DIRECT);
13411     }
13412 })
13413
13414 (define_insn "*tablejump_1"
13415   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13416    (use (label_ref (match_operand 1 "" "")))]
13417   "!TARGET_64BIT"
13418   "jmp\t%A0"
13419   [(set_attr "type" "ibr")
13420    (set_attr "length_immediate" "0")])
13421
13422 (define_insn "*tablejump_1_rtx64"
13423   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13424    (use (label_ref (match_operand 1 "" "")))]
13425   "TARGET_64BIT"
13426   "jmp\t%A0"
13427   [(set_attr "type" "ibr")
13428    (set_attr "length_immediate" "0")])
13429 \f
13430 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13431
13432 (define_peephole2
13433   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13434    (set (match_operand:QI 1 "register_operand" "")
13435         (match_operator:QI 2 "ix86_comparison_operator"
13436           [(reg FLAGS_REG) (const_int 0)]))
13437    (set (match_operand 3 "q_regs_operand" "")
13438         (zero_extend (match_dup 1)))]
13439   "(peep2_reg_dead_p (3, operands[1])
13440     || operands_match_p (operands[1], operands[3]))
13441    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13442   [(set (match_dup 4) (match_dup 0))
13443    (set (strict_low_part (match_dup 5))
13444         (match_dup 2))]
13445 {
13446   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13447   operands[5] = gen_lowpart (QImode, operands[3]);
13448   ix86_expand_clear (operands[3]);
13449 })
13450
13451 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13452
13453 (define_peephole2
13454   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13455    (set (match_operand:QI 1 "register_operand" "")
13456         (match_operator:QI 2 "ix86_comparison_operator"
13457           [(reg FLAGS_REG) (const_int 0)]))
13458    (parallel [(set (match_operand 3 "q_regs_operand" "")
13459                    (zero_extend (match_dup 1)))
13460               (clobber (reg:CC FLAGS_REG))])]
13461   "(peep2_reg_dead_p (3, operands[1])
13462     || operands_match_p (operands[1], operands[3]))
13463    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13464   [(set (match_dup 4) (match_dup 0))
13465    (set (strict_low_part (match_dup 5))
13466         (match_dup 2))]
13467 {
13468   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13469   operands[5] = gen_lowpart (QImode, operands[3]);
13470   ix86_expand_clear (operands[3]);
13471 })
13472 \f
13473 ;; Call instructions.
13474
13475 ;; The predicates normally associated with named expanders are not properly
13476 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13477 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13478
13479 ;; Call subroutine returning no value.
13480
13481 (define_expand "call_pop"
13482   [(parallel [(call (match_operand:QI 0 "" "")
13483                     (match_operand:SI 1 "" ""))
13484               (set (reg:SI SP_REG)
13485                    (plus:SI (reg:SI SP_REG)
13486                             (match_operand:SI 3 "" "")))])]
13487   "!TARGET_64BIT"
13488 {
13489   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13490   DONE;
13491 })
13492
13493 (define_insn "*call_pop_0"
13494   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13495          (match_operand:SI 1 "" ""))
13496    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13497                             (match_operand:SI 2 "immediate_operand" "")))]
13498   "!TARGET_64BIT"
13499 {
13500   if (SIBLING_CALL_P (insn))
13501     return "jmp\t%P0";
13502   else
13503     return "call\t%P0";
13504 }
13505   [(set_attr "type" "call")])
13506   
13507 (define_insn "*call_pop_1"
13508   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13509          (match_operand:SI 1 "" ""))
13510    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13511                             (match_operand:SI 2 "immediate_operand" "i")))]
13512   "!TARGET_64BIT"
13513 {
13514   if (constant_call_address_operand (operands[0], Pmode))
13515     {
13516       if (SIBLING_CALL_P (insn))
13517         return "jmp\t%P0";
13518       else
13519         return "call\t%P0";
13520     }
13521   if (SIBLING_CALL_P (insn))
13522     return "jmp\t%A0";
13523   else
13524     return "call\t%A0";
13525 }
13526   [(set_attr "type" "call")])
13527
13528 (define_expand "call"
13529   [(call (match_operand:QI 0 "" "")
13530          (match_operand 1 "" ""))
13531    (use (match_operand 2 "" ""))]
13532   ""
13533 {
13534   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13535   DONE;
13536 })
13537
13538 (define_expand "sibcall"
13539   [(call (match_operand:QI 0 "" "")
13540          (match_operand 1 "" ""))
13541    (use (match_operand 2 "" ""))]
13542   ""
13543 {
13544   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13545   DONE;
13546 })
13547
13548 (define_insn "*call_0"
13549   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13550          (match_operand 1 "" ""))]
13551   ""
13552 {
13553   if (SIBLING_CALL_P (insn))
13554     return "jmp\t%P0";
13555   else
13556     return "call\t%P0";
13557 }
13558   [(set_attr "type" "call")])
13559
13560 (define_insn "*call_1"
13561   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13562          (match_operand 1 "" ""))]
13563   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13564 {
13565   if (constant_call_address_operand (operands[0], Pmode))
13566     return "call\t%P0";
13567   return "call\t%A0";
13568 }
13569   [(set_attr "type" "call")])
13570
13571 (define_insn "*sibcall_1"
13572   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13573          (match_operand 1 "" ""))]
13574   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13575 {
13576   if (constant_call_address_operand (operands[0], Pmode))
13577     return "jmp\t%P0";
13578   return "jmp\t%A0";
13579 }
13580   [(set_attr "type" "call")])
13581
13582 (define_insn "*call_1_rex64"
13583   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13584          (match_operand 1 "" ""))]
13585   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13586 {
13587   if (constant_call_address_operand (operands[0], Pmode))
13588     return "call\t%P0";
13589   return "call\t%A0";
13590 }
13591   [(set_attr "type" "call")])
13592
13593 (define_insn "*sibcall_1_rex64"
13594   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13595          (match_operand 1 "" ""))]
13596   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13597   "jmp\t%P0"
13598   [(set_attr "type" "call")])
13599
13600 (define_insn "*sibcall_1_rex64_v"
13601   [(call (mem:QI (reg:DI 40))
13602          (match_operand 0 "" ""))]
13603   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13604   "jmp\t*%%r11"
13605   [(set_attr "type" "call")])
13606
13607
13608 ;; Call subroutine, returning value in operand 0
13609
13610 (define_expand "call_value_pop"
13611   [(parallel [(set (match_operand 0 "" "")
13612                    (call (match_operand:QI 1 "" "")
13613                          (match_operand:SI 2 "" "")))
13614               (set (reg:SI SP_REG)
13615                    (plus:SI (reg:SI SP_REG)
13616                             (match_operand:SI 4 "" "")))])]
13617   "!TARGET_64BIT"
13618 {
13619   ix86_expand_call (operands[0], operands[1], operands[2],
13620                     operands[3], operands[4], 0);
13621   DONE;
13622 })
13623
13624 (define_expand "call_value"
13625   [(set (match_operand 0 "" "")
13626         (call (match_operand:QI 1 "" "")
13627               (match_operand:SI 2 "" "")))
13628    (use (match_operand:SI 3 "" ""))]
13629   ;; Operand 2 not used on the i386.
13630   ""
13631 {
13632   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13633   DONE;
13634 })
13635
13636 (define_expand "sibcall_value"
13637   [(set (match_operand 0 "" "")
13638         (call (match_operand:QI 1 "" "")
13639               (match_operand:SI 2 "" "")))
13640    (use (match_operand:SI 3 "" ""))]
13641   ;; Operand 2 not used on the i386.
13642   ""
13643 {
13644   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13645   DONE;
13646 })
13647
13648 ;; Call subroutine returning any type.
13649
13650 (define_expand "untyped_call"
13651   [(parallel [(call (match_operand 0 "" "")
13652                     (const_int 0))
13653               (match_operand 1 "" "")
13654               (match_operand 2 "" "")])]
13655   ""
13656 {
13657   int i;
13658
13659   /* In order to give reg-stack an easier job in validating two
13660      coprocessor registers as containing a possible return value,
13661      simply pretend the untyped call returns a complex long double
13662      value.  */
13663
13664   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13665                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13666                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13667                     NULL, 0);
13668
13669   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13670     {
13671       rtx set = XVECEXP (operands[2], 0, i);
13672       emit_move_insn (SET_DEST (set), SET_SRC (set));
13673     }
13674
13675   /* The optimizer does not know that the call sets the function value
13676      registers we stored in the result block.  We avoid problems by
13677      claiming that all hard registers are used and clobbered at this
13678      point.  */
13679   emit_insn (gen_blockage (const0_rtx));
13680
13681   DONE;
13682 })
13683 \f
13684 ;; Prologue and epilogue instructions
13685
13686 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13687 ;; all of memory.  This blocks insns from being moved across this point.
13688
13689 (define_insn "blockage"
13690   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13691   ""
13692   ""
13693   [(set_attr "length" "0")])
13694
13695 ;; Insn emitted into the body of a function to return from a function.
13696 ;; This is only done if the function's epilogue is known to be simple.
13697 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13698
13699 (define_expand "return"
13700   [(return)]
13701   "ix86_can_use_return_insn_p ()"
13702 {
13703   if (current_function_pops_args)
13704     {
13705       rtx popc = GEN_INT (current_function_pops_args);
13706       emit_jump_insn (gen_return_pop_internal (popc));
13707       DONE;
13708     }
13709 })
13710
13711 (define_insn "return_internal"
13712   [(return)]
13713   "reload_completed"
13714   "ret"
13715   [(set_attr "length" "1")
13716    (set_attr "length_immediate" "0")
13717    (set_attr "modrm" "0")])
13718
13719 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13720 ;; instruction Athlon and K8 have.
13721
13722 (define_insn "return_internal_long"
13723   [(return)
13724    (unspec [(const_int 0)] UNSPEC_REP)]
13725   "reload_completed"
13726   "rep {;} ret"
13727   [(set_attr "length" "1")
13728    (set_attr "length_immediate" "0")
13729    (set_attr "prefix_rep" "1")
13730    (set_attr "modrm" "0")])
13731
13732 (define_insn "return_pop_internal"
13733   [(return)
13734    (use (match_operand:SI 0 "const_int_operand" ""))]
13735   "reload_completed"
13736   "ret\t%0"
13737   [(set_attr "length" "3")
13738    (set_attr "length_immediate" "2")
13739    (set_attr "modrm" "0")])
13740
13741 (define_insn "return_indirect_internal"
13742   [(return)
13743    (use (match_operand:SI 0 "register_operand" "r"))]
13744   "reload_completed"
13745   "jmp\t%A0"
13746   [(set_attr "type" "ibr")
13747    (set_attr "length_immediate" "0")])
13748
13749 (define_insn "nop"
13750   [(const_int 0)]
13751   ""
13752   "nop"
13753   [(set_attr "length" "1")
13754    (set_attr "length_immediate" "0")
13755    (set_attr "modrm" "0")])
13756
13757 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13758 ;; branch prediction penalty for the third jump in a 16-byte
13759 ;; block on K8.
13760
13761 (define_insn "align"
13762   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13763   ""
13764 {
13765 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13766   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13767 #else
13768   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13769      The align insn is used to avoid 3 jump instructions in the row to improve
13770      branch prediction and the benefits hardly outweight the cost of extra 8
13771      nops on the average inserted by full alignment pseudo operation.  */
13772 #endif
13773   return "";
13774 }
13775   [(set_attr "length" "16")])
13776
13777 (define_expand "prologue"
13778   [(const_int 1)]
13779   ""
13780   "ix86_expand_prologue (); DONE;")
13781
13782 (define_insn "set_got"
13783   [(set (match_operand:SI 0 "register_operand" "=r")
13784         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13785    (clobber (reg:CC FLAGS_REG))]
13786   "!TARGET_64BIT"
13787   { return output_set_got (operands[0]); }
13788   [(set_attr "type" "multi")
13789    (set_attr "length" "12")])
13790
13791 (define_insn "set_got_rex64"
13792   [(set (match_operand:DI 0 "register_operand" "=r")
13793         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13794   "TARGET_64BIT"
13795   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13796   [(set_attr "type" "lea")
13797    (set_attr "length" "6")])
13798
13799 (define_expand "epilogue"
13800   [(const_int 1)]
13801   ""
13802   "ix86_expand_epilogue (1); DONE;")
13803
13804 (define_expand "sibcall_epilogue"
13805   [(const_int 1)]
13806   ""
13807   "ix86_expand_epilogue (0); DONE;")
13808
13809 (define_expand "eh_return"
13810   [(use (match_operand 0 "register_operand" ""))]
13811   ""
13812 {
13813   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13814
13815   /* Tricky bit: we write the address of the handler to which we will
13816      be returning into someone else's stack frame, one word below the
13817      stack address we wish to restore.  */
13818   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13819   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13820   tmp = gen_rtx_MEM (Pmode, tmp);
13821   emit_move_insn (tmp, ra);
13822
13823   if (Pmode == SImode)
13824     emit_jump_insn (gen_eh_return_si (sa));
13825   else
13826     emit_jump_insn (gen_eh_return_di (sa));
13827   emit_barrier ();
13828   DONE;
13829 })
13830
13831 (define_insn_and_split "eh_return_si"
13832   [(set (pc) 
13833         (unspec [(match_operand:SI 0 "register_operand" "c")]
13834                  UNSPEC_EH_RETURN))]
13835   "!TARGET_64BIT"
13836   "#"
13837   "reload_completed"
13838   [(const_int 1)]
13839   "ix86_expand_epilogue (2); DONE;")
13840
13841 (define_insn_and_split "eh_return_di"
13842   [(set (pc) 
13843         (unspec [(match_operand:DI 0 "register_operand" "c")]
13844                  UNSPEC_EH_RETURN))]
13845   "TARGET_64BIT"
13846   "#"
13847   "reload_completed"
13848   [(const_int 1)]
13849   "ix86_expand_epilogue (2); DONE;")
13850
13851 (define_insn "leave"
13852   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13853    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13854    (clobber (mem:BLK (scratch)))]
13855   "!TARGET_64BIT"
13856   "leave"
13857   [(set_attr "type" "leave")])
13858
13859 (define_insn "leave_rex64"
13860   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13861    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13862    (clobber (mem:BLK (scratch)))]
13863   "TARGET_64BIT"
13864   "leave"
13865   [(set_attr "type" "leave")])
13866 \f
13867 (define_expand "ffssi2"
13868   [(parallel
13869      [(set (match_operand:SI 0 "register_operand" "") 
13870            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13871       (clobber (match_scratch:SI 2 ""))
13872       (clobber (reg:CC FLAGS_REG))])]
13873   ""
13874   "")
13875
13876 (define_insn_and_split "*ffs_cmove"
13877   [(set (match_operand:SI 0 "register_operand" "=r") 
13878         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13879    (clobber (match_scratch:SI 2 "=&r"))
13880    (clobber (reg:CC FLAGS_REG))]
13881   "TARGET_CMOVE"
13882   "#"
13883   "&& reload_completed"
13884   [(set (match_dup 2) (const_int -1))
13885    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13886               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13887    (set (match_dup 0) (if_then_else:SI
13888                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13889                         (match_dup 2)
13890                         (match_dup 0)))
13891    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13892               (clobber (reg:CC FLAGS_REG))])]
13893   "")
13894
13895 (define_insn_and_split "*ffs_no_cmove"
13896   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13897         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13898    (clobber (match_scratch:SI 2 "=&q"))
13899    (clobber (reg:CC FLAGS_REG))]
13900   ""
13901   "#"
13902   "reload_completed"
13903   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13904               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13905    (set (strict_low_part (match_dup 3))
13906         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13907    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13908               (clobber (reg:CC FLAGS_REG))])
13909    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13910               (clobber (reg:CC FLAGS_REG))])
13911    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13912               (clobber (reg:CC FLAGS_REG))])]
13913 {
13914   operands[3] = gen_lowpart (QImode, operands[2]);
13915   ix86_expand_clear (operands[2]);
13916 })
13917
13918 (define_insn "*ffssi_1"
13919   [(set (reg:CCZ FLAGS_REG)
13920         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13921                      (const_int 0)))
13922    (set (match_operand:SI 0 "register_operand" "=r")
13923         (ctz:SI (match_dup 1)))]
13924   ""
13925   "bsf{l}\t{%1, %0|%0, %1}"
13926   [(set_attr "prefix_0f" "1")])
13927
13928 (define_expand "ffsdi2"
13929   [(parallel
13930      [(set (match_operand:DI 0 "register_operand" "") 
13931            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13932       (clobber (match_scratch:DI 2 ""))
13933       (clobber (reg:CC FLAGS_REG))])]
13934   "TARGET_64BIT && TARGET_CMOVE"
13935   "")
13936
13937 (define_insn_and_split "*ffs_rex64"
13938   [(set (match_operand:DI 0 "register_operand" "=r") 
13939         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13940    (clobber (match_scratch:DI 2 "=&r"))
13941    (clobber (reg:CC FLAGS_REG))]
13942   "TARGET_64BIT && TARGET_CMOVE"
13943   "#"
13944   "&& reload_completed"
13945   [(set (match_dup 2) (const_int -1))
13946    (parallel [(set (reg:CCZ FLAGS_REG)
13947                    (compare:CCZ (match_dup 1) (const_int 0)))
13948               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13949    (set (match_dup 0) (if_then_else:DI
13950                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13951                         (match_dup 2)
13952                         (match_dup 0)))
13953    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13954               (clobber (reg:CC FLAGS_REG))])]
13955   "")
13956
13957 (define_insn "*ffsdi_1"
13958   [(set (reg:CCZ FLAGS_REG)
13959         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13960                      (const_int 0)))
13961    (set (match_operand:DI 0 "register_operand" "=r")
13962         (ctz:DI (match_dup 1)))]
13963   "TARGET_64BIT"
13964   "bsf{q}\t{%1, %0|%0, %1}"
13965   [(set_attr "prefix_0f" "1")])
13966
13967 (define_insn "ctzsi2"
13968   [(set (match_operand:SI 0 "register_operand" "=r")
13969         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970    (clobber (reg:CC FLAGS_REG))]
13971   ""
13972   "bsf{l}\t{%1, %0|%0, %1}"
13973   [(set_attr "prefix_0f" "1")])
13974
13975 (define_insn "ctzdi2"
13976   [(set (match_operand:DI 0 "register_operand" "=r")
13977         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13978    (clobber (reg:CC FLAGS_REG))]
13979   "TARGET_64BIT"
13980   "bsf{q}\t{%1, %0|%0, %1}"
13981   [(set_attr "prefix_0f" "1")])
13982
13983 (define_expand "clzsi2"
13984   [(parallel
13985      [(set (match_operand:SI 0 "register_operand" "")
13986            (minus:SI (const_int 31)
13987                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13988       (clobber (reg:CC FLAGS_REG))])
13989    (parallel
13990      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13991       (clobber (reg:CC FLAGS_REG))])]
13992   ""
13993   "")
13994
13995 (define_insn "*bsr"
13996   [(set (match_operand:SI 0 "register_operand" "=r")
13997         (minus:SI (const_int 31)
13998                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13999    (clobber (reg:CC FLAGS_REG))]
14000   ""
14001   "bsr{l}\t{%1, %0|%0, %1}"
14002   [(set_attr "prefix_0f" "1")])
14003
14004 (define_expand "clzdi2"
14005   [(parallel
14006      [(set (match_operand:DI 0 "register_operand" "")
14007            (minus:DI (const_int 63)
14008                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14009       (clobber (reg:CC FLAGS_REG))])
14010    (parallel
14011      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14012       (clobber (reg:CC FLAGS_REG))])]
14013   "TARGET_64BIT"
14014   "")
14015
14016 (define_insn "*bsr_rex64"
14017   [(set (match_operand:DI 0 "register_operand" "=r")
14018         (minus:DI (const_int 63)
14019                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14020    (clobber (reg:CC FLAGS_REG))]
14021   "TARGET_64BIT"
14022   "bsr{q}\t{%1, %0|%0, %1}"
14023   [(set_attr "prefix_0f" "1")])
14024 \f
14025 ;; Thread-local storage patterns for ELF.
14026 ;;
14027 ;; Note that these code sequences must appear exactly as shown
14028 ;; in order to allow linker relaxation.
14029
14030 (define_insn "*tls_global_dynamic_32_gnu"
14031   [(set (match_operand:SI 0 "register_operand" "=a")
14032         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14033                     (match_operand:SI 2 "tls_symbolic_operand" "")
14034                     (match_operand:SI 3 "call_insn_operand" "")]
14035                     UNSPEC_TLS_GD))
14036    (clobber (match_scratch:SI 4 "=d"))
14037    (clobber (match_scratch:SI 5 "=c"))
14038    (clobber (reg:CC FLAGS_REG))]
14039   "!TARGET_64BIT && TARGET_GNU_TLS"
14040   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14041   [(set_attr "type" "multi")
14042    (set_attr "length" "12")])
14043
14044 (define_insn "*tls_global_dynamic_32_sun"
14045   [(set (match_operand:SI 0 "register_operand" "=a")
14046         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14047                     (match_operand:SI 2 "tls_symbolic_operand" "")
14048                     (match_operand:SI 3 "call_insn_operand" "")]
14049                     UNSPEC_TLS_GD))
14050    (clobber (match_scratch:SI 4 "=d"))
14051    (clobber (match_scratch:SI 5 "=c"))
14052    (clobber (reg:CC FLAGS_REG))]
14053   "!TARGET_64BIT && TARGET_SUN_TLS"
14054   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14055         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14056   [(set_attr "type" "multi")
14057    (set_attr "length" "14")])
14058
14059 (define_expand "tls_global_dynamic_32"
14060   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14061                    (unspec:SI
14062                     [(match_dup 2)
14063                      (match_operand:SI 1 "tls_symbolic_operand" "")
14064                      (match_dup 3)]
14065                     UNSPEC_TLS_GD))
14066               (clobber (match_scratch:SI 4 ""))
14067               (clobber (match_scratch:SI 5 ""))
14068               (clobber (reg:CC FLAGS_REG))])]
14069   ""
14070 {
14071   if (flag_pic)
14072     operands[2] = pic_offset_table_rtx;
14073   else
14074     {
14075       operands[2] = gen_reg_rtx (Pmode);
14076       emit_insn (gen_set_got (operands[2]));
14077     }
14078   operands[3] = ix86_tls_get_addr ();
14079 })
14080
14081 (define_insn "*tls_global_dynamic_64"
14082   [(set (match_operand:DI 0 "register_operand" "=a")
14083         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14084                       (match_operand:DI 3 "" "")))
14085    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14086               UNSPEC_TLS_GD)]
14087   "TARGET_64BIT"
14088   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14089   [(set_attr "type" "multi")
14090    (set_attr "length" "16")])
14091
14092 (define_expand "tls_global_dynamic_64"
14093   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14094                    (call (mem:QI (match_dup 2)) (const_int 0)))
14095               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14096                          UNSPEC_TLS_GD)])]
14097   ""
14098 {
14099   operands[2] = ix86_tls_get_addr ();
14100 })
14101
14102 (define_insn "*tls_local_dynamic_base_32_gnu"
14103   [(set (match_operand:SI 0 "register_operand" "=a")
14104         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14105                     (match_operand:SI 2 "call_insn_operand" "")]
14106                    UNSPEC_TLS_LD_BASE))
14107    (clobber (match_scratch:SI 3 "=d"))
14108    (clobber (match_scratch:SI 4 "=c"))
14109    (clobber (reg:CC FLAGS_REG))]
14110   "!TARGET_64BIT && TARGET_GNU_TLS"
14111   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14112   [(set_attr "type" "multi")
14113    (set_attr "length" "11")])
14114
14115 (define_insn "*tls_local_dynamic_base_32_sun"
14116   [(set (match_operand:SI 0 "register_operand" "=a")
14117         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14118                     (match_operand:SI 2 "call_insn_operand" "")]
14119                    UNSPEC_TLS_LD_BASE))
14120    (clobber (match_scratch:SI 3 "=d"))
14121    (clobber (match_scratch:SI 4 "=c"))
14122    (clobber (reg:CC FLAGS_REG))]
14123   "!TARGET_64BIT && TARGET_SUN_TLS"
14124   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14125         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14126   [(set_attr "type" "multi")
14127    (set_attr "length" "13")])
14128
14129 (define_expand "tls_local_dynamic_base_32"
14130   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14131                    (unspec:SI [(match_dup 1) (match_dup 2)]
14132                               UNSPEC_TLS_LD_BASE))
14133               (clobber (match_scratch:SI 3 ""))
14134               (clobber (match_scratch:SI 4 ""))
14135               (clobber (reg:CC FLAGS_REG))])]
14136   ""
14137 {
14138   if (flag_pic)
14139     operands[1] = pic_offset_table_rtx;
14140   else
14141     {
14142       operands[1] = gen_reg_rtx (Pmode);
14143       emit_insn (gen_set_got (operands[1]));
14144     }
14145   operands[2] = ix86_tls_get_addr ();
14146 })
14147
14148 (define_insn "*tls_local_dynamic_base_64"
14149   [(set (match_operand:DI 0 "register_operand" "=a")
14150         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14151                       (match_operand:DI 2 "" "")))
14152    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14153   "TARGET_64BIT"
14154   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14155   [(set_attr "type" "multi")
14156    (set_attr "length" "12")])
14157
14158 (define_expand "tls_local_dynamic_base_64"
14159   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14160                    (call (mem:QI (match_dup 1)) (const_int 0)))
14161               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14162   ""
14163 {
14164   operands[1] = ix86_tls_get_addr ();
14165 })
14166
14167 ;; Local dynamic of a single variable is a lose.  Show combine how
14168 ;; to convert that back to global dynamic.
14169
14170 (define_insn_and_split "*tls_local_dynamic_32_once"
14171   [(set (match_operand:SI 0 "register_operand" "=a")
14172         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14173                              (match_operand:SI 2 "call_insn_operand" "")]
14174                             UNSPEC_TLS_LD_BASE)
14175                  (const:SI (unspec:SI
14176                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14177                             UNSPEC_DTPOFF))))
14178    (clobber (match_scratch:SI 4 "=d"))
14179    (clobber (match_scratch:SI 5 "=c"))
14180    (clobber (reg:CC FLAGS_REG))]
14181   ""
14182   "#"
14183   ""
14184   [(parallel [(set (match_dup 0)
14185                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14186                               UNSPEC_TLS_GD))
14187               (clobber (match_dup 4))
14188               (clobber (match_dup 5))
14189               (clobber (reg:CC FLAGS_REG))])]
14190   "")
14191
14192 ;; Load and add the thread base pointer from %gs:0.
14193
14194 (define_insn "*load_tp_si"
14195   [(set (match_operand:SI 0 "register_operand" "=r")
14196         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14197   "!TARGET_64BIT"
14198   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14199   [(set_attr "type" "imov")
14200    (set_attr "modrm" "0")
14201    (set_attr "length" "7")
14202    (set_attr "memory" "load")
14203    (set_attr "imm_disp" "false")])
14204
14205 (define_insn "*add_tp_si"
14206   [(set (match_operand:SI 0 "register_operand" "=r")
14207         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14208                  (match_operand:SI 1 "register_operand" "0")))
14209    (clobber (reg:CC FLAGS_REG))]
14210   "!TARGET_64BIT"
14211   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14212   [(set_attr "type" "alu")
14213    (set_attr "modrm" "0")
14214    (set_attr "length" "7")
14215    (set_attr "memory" "load")
14216    (set_attr "imm_disp" "false")])
14217
14218 (define_insn "*load_tp_di"
14219   [(set (match_operand:DI 0 "register_operand" "=r")
14220         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14221   "TARGET_64BIT"
14222   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14223   [(set_attr "type" "imov")
14224    (set_attr "modrm" "0")
14225    (set_attr "length" "7")
14226    (set_attr "memory" "load")
14227    (set_attr "imm_disp" "false")])
14228
14229 (define_insn "*add_tp_di"
14230   [(set (match_operand:DI 0 "register_operand" "=r")
14231         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14232                  (match_operand:DI 1 "register_operand" "0")))
14233    (clobber (reg:CC FLAGS_REG))]
14234   "TARGET_64BIT"
14235   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14236   [(set_attr "type" "alu")
14237    (set_attr "modrm" "0")
14238    (set_attr "length" "7")
14239    (set_attr "memory" "load")
14240    (set_attr "imm_disp" "false")])
14241 \f
14242 ;; These patterns match the binary 387 instructions for addM3, subM3,
14243 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14244 ;; SFmode.  The first is the normal insn, the second the same insn but
14245 ;; with one operand a conversion, and the third the same insn but with
14246 ;; the other operand a conversion.  The conversion may be SFmode or
14247 ;; SImode if the target mode DFmode, but only SImode if the target mode
14248 ;; is SFmode.
14249
14250 ;; Gcc is slightly more smart about handling normal two address instructions
14251 ;; so use special patterns for add and mull.
14252
14253 (define_insn "*fop_sf_comm_mixed"
14254   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14255         (match_operator:SF 3 "binary_fp_operator"
14256                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14257                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14258   "TARGET_MIX_SSE_I387
14259    && COMMUTATIVE_ARITH_P (operands[3])
14260    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14261   "* return output_387_binary_op (insn, operands);"
14262   [(set (attr "type") 
14263         (if_then_else (eq_attr "alternative" "1")
14264            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14265               (const_string "ssemul")
14266               (const_string "sseadd"))
14267            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14268               (const_string "fmul")
14269               (const_string "fop"))))
14270    (set_attr "mode" "SF")])
14271
14272 (define_insn "*fop_sf_comm_sse"
14273   [(set (match_operand:SF 0 "register_operand" "=x")
14274         (match_operator:SF 3 "binary_fp_operator"
14275                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14276                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14277   "TARGET_SSE_MATH
14278    && COMMUTATIVE_ARITH_P (operands[3])
14279    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14280   "* return output_387_binary_op (insn, operands);"
14281   [(set (attr "type") 
14282         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14283            (const_string "ssemul")
14284            (const_string "sseadd")))
14285    (set_attr "mode" "SF")])
14286
14287 (define_insn "*fop_sf_comm_i387"
14288   [(set (match_operand:SF 0 "register_operand" "=f")
14289         (match_operator:SF 3 "binary_fp_operator"
14290                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14291                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14292   "TARGET_80387
14293    && COMMUTATIVE_ARITH_P (operands[3])
14294    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14295   "* return output_387_binary_op (insn, operands);"
14296   [(set (attr "type") 
14297         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14298            (const_string "fmul")
14299            (const_string "fop")))
14300    (set_attr "mode" "SF")])
14301
14302 (define_insn "*fop_sf_1_mixed"
14303   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14304         (match_operator:SF 3 "binary_fp_operator"
14305                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14306                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14307   "TARGET_MIX_SSE_I387
14308    && !COMMUTATIVE_ARITH_P (operands[3])
14309    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14310   "* return output_387_binary_op (insn, operands);"
14311   [(set (attr "type") 
14312         (cond [(and (eq_attr "alternative" "2")
14313                     (match_operand:SF 3 "mult_operator" ""))
14314                  (const_string "ssemul")
14315                (and (eq_attr "alternative" "2")
14316                     (match_operand:SF 3 "div_operator" ""))
14317                  (const_string "ssediv")
14318                (eq_attr "alternative" "2")
14319                  (const_string "sseadd")
14320                (match_operand:SF 3 "mult_operator" "") 
14321                  (const_string "fmul")
14322                (match_operand:SF 3 "div_operator" "") 
14323                  (const_string "fdiv")
14324               ]
14325               (const_string "fop")))
14326    (set_attr "mode" "SF")])
14327
14328 (define_insn "*fop_sf_1_sse"
14329   [(set (match_operand:SF 0 "register_operand" "=x")
14330         (match_operator:SF 3 "binary_fp_operator"
14331                         [(match_operand:SF 1 "register_operand" "0")
14332                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14333   "TARGET_SSE_MATH
14334    && !COMMUTATIVE_ARITH_P (operands[3])"
14335   "* return output_387_binary_op (insn, operands);"
14336   [(set (attr "type") 
14337         (cond [(match_operand:SF 3 "mult_operator" "")
14338                  (const_string "ssemul")
14339                (match_operand:SF 3 "div_operator" "")
14340                  (const_string "ssediv")
14341               ]
14342               (const_string "sseadd")))
14343    (set_attr "mode" "SF")])
14344
14345 ;; This pattern is not fully shadowed by the pattern above.
14346 (define_insn "*fop_sf_1_i387"
14347   [(set (match_operand:SF 0 "register_operand" "=f,f")
14348         (match_operator:SF 3 "binary_fp_operator"
14349                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14350                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14351   "TARGET_80387 && !TARGET_SSE_MATH
14352    && !COMMUTATIVE_ARITH_P (operands[3])
14353    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type") 
14356         (cond [(match_operand:SF 3 "mult_operator" "") 
14357                  (const_string "fmul")
14358                (match_operand:SF 3 "div_operator" "") 
14359                  (const_string "fdiv")
14360               ]
14361               (const_string "fop")))
14362    (set_attr "mode" "SF")])
14363
14364 ;; ??? Add SSE splitters for these!
14365 (define_insn "*fop_sf_2<mode>_i387"
14366   [(set (match_operand:SF 0 "register_operand" "=f,f")
14367         (match_operator:SF 3 "binary_fp_operator"
14368           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14369            (match_operand:SF 2 "register_operand" "0,0")]))]
14370   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14371   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14372   [(set (attr "type") 
14373         (cond [(match_operand:SF 3 "mult_operator" "") 
14374                  (const_string "fmul")
14375                (match_operand:SF 3 "div_operator" "") 
14376                  (const_string "fdiv")
14377               ]
14378               (const_string "fop")))
14379    (set_attr "fp_int_src" "true")
14380    (set_attr "mode" "<MODE>")])
14381
14382 (define_insn "*fop_sf_3<mode>_i387"
14383   [(set (match_operand:SF 0 "register_operand" "=f,f")
14384         (match_operator:SF 3 "binary_fp_operator"
14385           [(match_operand:SF 1 "register_operand" "0,0")
14386            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14387   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14388   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14389   [(set (attr "type") 
14390         (cond [(match_operand:SF 3 "mult_operator" "") 
14391                  (const_string "fmul")
14392                (match_operand:SF 3 "div_operator" "") 
14393                  (const_string "fdiv")
14394               ]
14395               (const_string "fop")))
14396    (set_attr "fp_int_src" "true")
14397    (set_attr "mode" "<MODE>")])
14398
14399 (define_insn "*fop_df_comm_mixed"
14400   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14401         (match_operator:DF 3 "binary_fp_operator"
14402                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14403                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14404   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14405    && COMMUTATIVE_ARITH_P (operands[3])
14406    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407   "* return output_387_binary_op (insn, operands);"
14408   [(set (attr "type") 
14409         (if_then_else (eq_attr "alternative" "1")
14410            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14411               (const_string "ssemul")
14412               (const_string "sseadd"))
14413            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14414               (const_string "fmul")
14415               (const_string "fop"))))
14416    (set_attr "mode" "DF")])
14417
14418 (define_insn "*fop_df_comm_sse"
14419   [(set (match_operand:DF 0 "register_operand" "=Y")
14420         (match_operator:DF 3 "binary_fp_operator"
14421                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14422                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14423   "TARGET_SSE2 && TARGET_SSE_MATH
14424    && COMMUTATIVE_ARITH_P (operands[3])
14425    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14426   "* return output_387_binary_op (insn, operands);"
14427   [(set (attr "type") 
14428         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14429            (const_string "ssemul")
14430            (const_string "sseadd")))
14431    (set_attr "mode" "DF")])
14432
14433 (define_insn "*fop_df_comm_i387"
14434   [(set (match_operand:DF 0 "register_operand" "=f")
14435         (match_operator:DF 3 "binary_fp_operator"
14436                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14437                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14438   "TARGET_80387
14439    && COMMUTATIVE_ARITH_P (operands[3])
14440    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14441   "* return output_387_binary_op (insn, operands);"
14442   [(set (attr "type") 
14443         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14444            (const_string "fmul")
14445            (const_string "fop")))
14446    (set_attr "mode" "DF")])
14447
14448 (define_insn "*fop_df_1_mixed"
14449   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14450         (match_operator:DF 3 "binary_fp_operator"
14451                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14452                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14453   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14454    && !COMMUTATIVE_ARITH_P (operands[3])
14455    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14456   "* return output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (cond [(and (eq_attr "alternative" "2")
14459                     (match_operand:SF 3 "mult_operator" ""))
14460                  (const_string "ssemul")
14461                (and (eq_attr "alternative" "2")
14462                     (match_operand:SF 3 "div_operator" ""))
14463                  (const_string "ssediv")
14464                (eq_attr "alternative" "2")
14465                  (const_string "sseadd")
14466                (match_operand:DF 3 "mult_operator" "") 
14467                  (const_string "fmul")
14468                (match_operand:DF 3 "div_operator" "") 
14469                  (const_string "fdiv")
14470               ]
14471               (const_string "fop")))
14472    (set_attr "mode" "DF")])
14473
14474 (define_insn "*fop_df_1_sse"
14475   [(set (match_operand:DF 0 "register_operand" "=Y")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "register_operand" "0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14479   "TARGET_SSE2 && TARGET_SSE_MATH
14480    && !COMMUTATIVE_ARITH_P (operands[3])"
14481   "* return output_387_binary_op (insn, operands);"
14482   [(set_attr "mode" "DF")
14483    (set (attr "type") 
14484         (cond [(match_operand:SF 3 "mult_operator" "")
14485                  (const_string "ssemul")
14486                (match_operand:SF 3 "div_operator" "")
14487                  (const_string "ssediv")
14488               ]
14489               (const_string "sseadd")))])
14490
14491 ;; This pattern is not fully shadowed by the pattern above.
14492 (define_insn "*fop_df_1_i387"
14493   [(set (match_operand:DF 0 "register_operand" "=f,f")
14494         (match_operator:DF 3 "binary_fp_operator"
14495                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14496                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14497   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14498    && !COMMUTATIVE_ARITH_P (operands[3])
14499    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14500   "* return output_387_binary_op (insn, operands);"
14501   [(set (attr "type") 
14502         (cond [(match_operand:DF 3 "mult_operator" "") 
14503                  (const_string "fmul")
14504                (match_operand:DF 3 "div_operator" "")
14505                  (const_string "fdiv")
14506               ]
14507               (const_string "fop")))
14508    (set_attr "mode" "DF")])
14509
14510 ;; ??? Add SSE splitters for these!
14511 (define_insn "*fop_df_2<mode>_i387"
14512   [(set (match_operand:DF 0 "register_operand" "=f,f")
14513         (match_operator:DF 3 "binary_fp_operator"
14514            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14515             (match_operand:DF 2 "register_operand" "0,0")]))]
14516   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14517    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14518   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519   [(set (attr "type") 
14520         (cond [(match_operand:DF 3 "mult_operator" "") 
14521                  (const_string "fmul")
14522                (match_operand:DF 3 "div_operator" "") 
14523                  (const_string "fdiv")
14524               ]
14525               (const_string "fop")))
14526    (set_attr "fp_int_src" "true")
14527    (set_attr "mode" "<MODE>")])
14528
14529 (define_insn "*fop_df_3<mode>_i387"
14530   [(set (match_operand:DF 0 "register_operand" "=f,f")
14531         (match_operator:DF 3 "binary_fp_operator"
14532            [(match_operand:DF 1 "register_operand" "0,0")
14533             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14534   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14535    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14536   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14537   [(set (attr "type") 
14538         (cond [(match_operand:DF 3 "mult_operator" "") 
14539                  (const_string "fmul")
14540                (match_operand:DF 3 "div_operator" "") 
14541                  (const_string "fdiv")
14542               ]
14543               (const_string "fop")))
14544    (set_attr "fp_int_src" "true")
14545    (set_attr "mode" "<MODE>")])
14546
14547 (define_insn "*fop_df_4_i387"
14548   [(set (match_operand:DF 0 "register_operand" "=f,f")
14549         (match_operator:DF 3 "binary_fp_operator"
14550            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14551             (match_operand:DF 2 "register_operand" "0,f")]))]
14552   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14553    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14554   "* return output_387_binary_op (insn, operands);"
14555   [(set (attr "type") 
14556         (cond [(match_operand:DF 3 "mult_operator" "") 
14557                  (const_string "fmul")
14558                (match_operand:DF 3 "div_operator" "") 
14559                  (const_string "fdiv")
14560               ]
14561               (const_string "fop")))
14562    (set_attr "mode" "SF")])
14563
14564 (define_insn "*fop_df_5_i387"
14565   [(set (match_operand:DF 0 "register_operand" "=f,f")
14566         (match_operator:DF 3 "binary_fp_operator"
14567           [(match_operand:DF 1 "register_operand" "0,f")
14568            (float_extend:DF
14569             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14570   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14571   "* return output_387_binary_op (insn, operands);"
14572   [(set (attr "type") 
14573         (cond [(match_operand:DF 3 "mult_operator" "") 
14574                  (const_string "fmul")
14575                (match_operand:DF 3 "div_operator" "") 
14576                  (const_string "fdiv")
14577               ]
14578               (const_string "fop")))
14579    (set_attr "mode" "SF")])
14580
14581 (define_insn "*fop_df_6_i387"
14582   [(set (match_operand:DF 0 "register_operand" "=f,f")
14583         (match_operator:DF 3 "binary_fp_operator"
14584           [(float_extend:DF
14585             (match_operand:SF 1 "register_operand" "0,f"))
14586            (float_extend:DF
14587             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14588   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14589   "* return output_387_binary_op (insn, operands);"
14590   [(set (attr "type") 
14591         (cond [(match_operand:DF 3 "mult_operator" "") 
14592                  (const_string "fmul")
14593                (match_operand:DF 3 "div_operator" "") 
14594                  (const_string "fdiv")
14595               ]
14596               (const_string "fop")))
14597    (set_attr "mode" "SF")])
14598
14599 (define_insn "*fop_xf_comm_i387"
14600   [(set (match_operand:XF 0 "register_operand" "=f")
14601         (match_operator:XF 3 "binary_fp_operator"
14602                         [(match_operand:XF 1 "register_operand" "%0")
14603                          (match_operand:XF 2 "register_operand" "f")]))]
14604   "TARGET_80387
14605    && COMMUTATIVE_ARITH_P (operands[3])"
14606   "* return output_387_binary_op (insn, operands);"
14607   [(set (attr "type") 
14608         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14609            (const_string "fmul")
14610            (const_string "fop")))
14611    (set_attr "mode" "XF")])
14612
14613 (define_insn "*fop_xf_1_i387"
14614   [(set (match_operand:XF 0 "register_operand" "=f,f")
14615         (match_operator:XF 3 "binary_fp_operator"
14616                         [(match_operand:XF 1 "register_operand" "0,f")
14617                          (match_operand:XF 2 "register_operand" "f,0")]))]
14618   "TARGET_80387
14619    && !COMMUTATIVE_ARITH_P (operands[3])"
14620   "* return output_387_binary_op (insn, operands);"
14621   [(set (attr "type") 
14622         (cond [(match_operand:XF 3 "mult_operator" "") 
14623                  (const_string "fmul")
14624                (match_operand:XF 3 "div_operator" "") 
14625                  (const_string "fdiv")
14626               ]
14627               (const_string "fop")))
14628    (set_attr "mode" "XF")])
14629
14630 (define_insn "*fop_xf_2<mode>_i387"
14631   [(set (match_operand:XF 0 "register_operand" "=f,f")
14632         (match_operator:XF 3 "binary_fp_operator"
14633            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14634             (match_operand:XF 2 "register_operand" "0,0")]))]
14635   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14636   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14637   [(set (attr "type") 
14638         (cond [(match_operand:XF 3 "mult_operator" "") 
14639                  (const_string "fmul")
14640                (match_operand:XF 3 "div_operator" "") 
14641                  (const_string "fdiv")
14642               ]
14643               (const_string "fop")))
14644    (set_attr "fp_int_src" "true")
14645    (set_attr "mode" "<MODE>")])
14646
14647 (define_insn "*fop_xf_3<mode>_i387"
14648   [(set (match_operand:XF 0 "register_operand" "=f,f")
14649         (match_operator:XF 3 "binary_fp_operator"
14650           [(match_operand:XF 1 "register_operand" "0,0")
14651            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14652   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14653   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(match_operand:XF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:XF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "fp_int_src" "true")
14662    (set_attr "mode" "<MODE>")])
14663
14664 (define_insn "*fop_xf_4_i387"
14665   [(set (match_operand:XF 0 "register_operand" "=f,f")
14666         (match_operator:XF 3 "binary_fp_operator"
14667            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14668             (match_operand:XF 2 "register_operand" "0,f")]))]
14669   "TARGET_80387"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:XF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:XF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14679
14680 (define_insn "*fop_xf_5_i387"
14681   [(set (match_operand:XF 0 "register_operand" "=f,f")
14682         (match_operator:XF 3 "binary_fp_operator"
14683           [(match_operand:XF 1 "register_operand" "0,f")
14684            (float_extend:XF
14685             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14686   "TARGET_80387"
14687   "* return output_387_binary_op (insn, operands);"
14688   [(set (attr "type") 
14689         (cond [(match_operand:XF 3 "mult_operator" "") 
14690                  (const_string "fmul")
14691                (match_operand:XF 3 "div_operator" "") 
14692                  (const_string "fdiv")
14693               ]
14694               (const_string "fop")))
14695    (set_attr "mode" "SF")])
14696
14697 (define_insn "*fop_xf_6_i387"
14698   [(set (match_operand:XF 0 "register_operand" "=f,f")
14699         (match_operator:XF 3 "binary_fp_operator"
14700           [(float_extend:XF
14701             (match_operand 1 "register_operand" "0,f"))
14702            (float_extend:XF
14703             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14704   "TARGET_80387"
14705   "* return output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "mode" "SF")])
14714
14715 (define_split
14716   [(set (match_operand 0 "register_operand" "")
14717         (match_operator 3 "binary_fp_operator"
14718            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14719             (match_operand 2 "register_operand" "")]))]
14720   "TARGET_80387 && reload_completed
14721    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14722   [(const_int 0)]
14723
14724   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14725   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14726   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14727                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14728                                           GET_MODE (operands[3]),
14729                                           operands[4],
14730                                           operands[2])));
14731   ix86_free_from_memory (GET_MODE (operands[1]));
14732   DONE;
14733 })
14734
14735 (define_split
14736   [(set (match_operand 0 "register_operand" "")
14737         (match_operator 3 "binary_fp_operator"
14738            [(match_operand 1 "register_operand" "")
14739             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14740   "TARGET_80387 && reload_completed
14741    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14742   [(const_int 0)]
14743 {
14744   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14745   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14746   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14747                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14748                                           GET_MODE (operands[3]),
14749                                           operands[1],
14750                                           operands[4])));
14751   ix86_free_from_memory (GET_MODE (operands[2]));
14752   DONE;
14753 })
14754 \f
14755 ;; FPU special functions.
14756
14757 (define_expand "sqrtsf2"
14758   [(set (match_operand:SF 0 "register_operand" "")
14759         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14760   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14761 {
14762   if (!TARGET_SSE_MATH)
14763     operands[1] = force_reg (SFmode, operands[1]);
14764 })
14765
14766 (define_insn "*sqrtsf2_mixed"
14767   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14768         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14769   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14770   "@
14771    fsqrt
14772    sqrtss\t{%1, %0|%0, %1}"
14773   [(set_attr "type" "fpspc,sse")
14774    (set_attr "mode" "SF,SF")
14775    (set_attr "athlon_decode" "direct,*")])
14776
14777 (define_insn "*sqrtsf2_sse"
14778   [(set (match_operand:SF 0 "register_operand" "=x")
14779         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14780   "TARGET_SSE_MATH"
14781   "sqrtss\t{%1, %0|%0, %1}"
14782   [(set_attr "type" "sse")
14783    (set_attr "mode" "SF")
14784    (set_attr "athlon_decode" "*")])
14785
14786 (define_insn "*sqrtsf2_i387"
14787   [(set (match_operand:SF 0 "register_operand" "=f")
14788         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14789   "TARGET_USE_FANCY_MATH_387"
14790   "fsqrt"
14791   [(set_attr "type" "fpspc")
14792    (set_attr "mode" "SF")
14793    (set_attr "athlon_decode" "direct")])
14794
14795 (define_expand "sqrtdf2"
14796   [(set (match_operand:DF 0 "register_operand" "")
14797         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14798   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14799 {
14800   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14801     operands[1] = force_reg (DFmode, operands[1]);
14802 })
14803
14804 (define_insn "*sqrtdf2_mixed"
14805   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14806         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14807   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14808   "@
14809    fsqrt
14810    sqrtsd\t{%1, %0|%0, %1}"
14811   [(set_attr "type" "fpspc,sse")
14812    (set_attr "mode" "DF,DF")
14813    (set_attr "athlon_decode" "direct,*")])
14814
14815 (define_insn "*sqrtdf2_sse"
14816   [(set (match_operand:DF 0 "register_operand" "=Y")
14817         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14818   "TARGET_SSE2 && TARGET_SSE_MATH"
14819   "sqrtsd\t{%1, %0|%0, %1}"
14820   [(set_attr "type" "sse")
14821    (set_attr "mode" "DF")
14822    (set_attr "athlon_decode" "*")])
14823
14824 (define_insn "*sqrtdf2_i387"
14825   [(set (match_operand:DF 0 "register_operand" "=f")
14826         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14827   "TARGET_USE_FANCY_MATH_387"
14828   "fsqrt"
14829   [(set_attr "type" "fpspc")
14830    (set_attr "mode" "DF")
14831    (set_attr "athlon_decode" "direct")])
14832
14833 (define_insn "*sqrtextendsfdf2_i387"
14834   [(set (match_operand:DF 0 "register_operand" "=f")
14835         (sqrt:DF (float_extend:DF
14836                   (match_operand:SF 1 "register_operand" "0"))))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14839   "fsqrt"
14840   [(set_attr "type" "fpspc")
14841    (set_attr "mode" "DF")
14842    (set_attr "athlon_decode" "direct")])
14843
14844 (define_insn "sqrtxf2"
14845   [(set (match_operand:XF 0 "register_operand" "=f")
14846         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14847   "TARGET_USE_FANCY_MATH_387 
14848    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14849   "fsqrt"
14850   [(set_attr "type" "fpspc")
14851    (set_attr "mode" "XF")
14852    (set_attr "athlon_decode" "direct")])
14853
14854 (define_insn "*sqrtextendsfxf2_i387"
14855   [(set (match_operand:XF 0 "register_operand" "=f")
14856         (sqrt:XF (float_extend:XF
14857                   (match_operand:SF 1 "register_operand" "0"))))]
14858   "TARGET_USE_FANCY_MATH_387"
14859   "fsqrt"
14860   [(set_attr "type" "fpspc")
14861    (set_attr "mode" "XF")
14862    (set_attr "athlon_decode" "direct")])
14863
14864 (define_insn "*sqrtextenddfxf2_i387"
14865   [(set (match_operand:XF 0 "register_operand" "=f")
14866         (sqrt:XF (float_extend:XF
14867                   (match_operand:DF 1 "register_operand" "0"))))]
14868   "TARGET_USE_FANCY_MATH_387"
14869   "fsqrt"
14870   [(set_attr "type" "fpspc")
14871    (set_attr "mode" "XF")
14872    (set_attr "athlon_decode" "direct")])
14873
14874 (define_insn "fpremxf4"
14875   [(set (match_operand:XF 0 "register_operand" "=f")
14876         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14877                     (match_operand:XF 3 "register_operand" "1")]
14878                    UNSPEC_FPREM_F))
14879    (set (match_operand:XF 1 "register_operand" "=u")
14880         (unspec:XF [(match_dup 2) (match_dup 3)]
14881                    UNSPEC_FPREM_U))
14882    (set (reg:CCFP FPSR_REG)
14883         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14884   "TARGET_USE_FANCY_MATH_387
14885    && flag_unsafe_math_optimizations"
14886   "fprem"
14887   [(set_attr "type" "fpspc")
14888    (set_attr "mode" "XF")])
14889
14890 (define_expand "fmodsf3"
14891   [(use (match_operand:SF 0 "register_operand" ""))
14892    (use (match_operand:SF 1 "register_operand" ""))
14893    (use (match_operand:SF 2 "register_operand" ""))]
14894   "TARGET_USE_FANCY_MATH_387
14895    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14896    && flag_unsafe_math_optimizations"
14897 {
14898   rtx label = gen_label_rtx ();
14899
14900   rtx op1 = gen_reg_rtx (XFmode);
14901   rtx op2 = gen_reg_rtx (XFmode);
14902
14903   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14904   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14905
14906   emit_label (label);
14907
14908   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14909   ix86_emit_fp_unordered_jump (label);
14910
14911   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14912   DONE;
14913 })
14914
14915 (define_expand "fmoddf3"
14916   [(use (match_operand:DF 0 "register_operand" ""))
14917    (use (match_operand:DF 1 "register_operand" ""))
14918    (use (match_operand:DF 2 "register_operand" ""))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14921    && flag_unsafe_math_optimizations"
14922 {
14923   rtx label = gen_label_rtx ();
14924
14925   rtx op1 = gen_reg_rtx (XFmode);
14926   rtx op2 = gen_reg_rtx (XFmode);
14927
14928   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14929   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14930
14931   emit_label (label);
14932
14933   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14934   ix86_emit_fp_unordered_jump (label);
14935
14936   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14937   DONE;
14938 })
14939
14940 (define_expand "fmodxf3"
14941   [(use (match_operand:XF 0 "register_operand" ""))
14942    (use (match_operand:XF 1 "register_operand" ""))
14943    (use (match_operand:XF 2 "register_operand" ""))]
14944   "TARGET_USE_FANCY_MATH_387
14945    && flag_unsafe_math_optimizations"
14946 {
14947   rtx label = gen_label_rtx ();
14948
14949   emit_label (label);
14950
14951   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14952                            operands[1], operands[2]));
14953   ix86_emit_fp_unordered_jump (label);
14954
14955   emit_move_insn (operands[0], operands[1]);
14956   DONE;
14957 })
14958
14959 (define_insn "fprem1xf4"
14960   [(set (match_operand:XF 0 "register_operand" "=f")
14961         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14962                     (match_operand:XF 3 "register_operand" "1")]
14963                    UNSPEC_FPREM1_F))
14964    (set (match_operand:XF 1 "register_operand" "=u")
14965         (unspec:XF [(match_dup 2) (match_dup 3)]
14966                    UNSPEC_FPREM1_U))
14967    (set (reg:CCFP FPSR_REG)
14968         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14969   "TARGET_USE_FANCY_MATH_387
14970    && flag_unsafe_math_optimizations"
14971   "fprem1"
14972   [(set_attr "type" "fpspc")
14973    (set_attr "mode" "XF")])
14974
14975 (define_expand "dremsf3"
14976   [(use (match_operand:SF 0 "register_operand" ""))
14977    (use (match_operand:SF 1 "register_operand" ""))
14978    (use (match_operand:SF 2 "register_operand" ""))]
14979   "TARGET_USE_FANCY_MATH_387
14980    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14981    && flag_unsafe_math_optimizations"
14982 {
14983   rtx label = gen_label_rtx ();
14984
14985   rtx op1 = gen_reg_rtx (XFmode);
14986   rtx op2 = gen_reg_rtx (XFmode);
14987
14988   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14989   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14990
14991   emit_label (label);
14992
14993   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14994   ix86_emit_fp_unordered_jump (label);
14995
14996   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14997   DONE;
14998 })
14999
15000 (define_expand "dremdf3"
15001   [(use (match_operand:DF 0 "register_operand" ""))
15002    (use (match_operand:DF 1 "register_operand" ""))
15003    (use (match_operand:DF 2 "register_operand" ""))]
15004   "TARGET_USE_FANCY_MATH_387
15005    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15006    && flag_unsafe_math_optimizations"
15007 {
15008   rtx label = gen_label_rtx ();
15009
15010   rtx op1 = gen_reg_rtx (XFmode);
15011   rtx op2 = gen_reg_rtx (XFmode);
15012
15013   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15014   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15015
15016   emit_label (label);
15017
15018   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15019   ix86_emit_fp_unordered_jump (label);
15020
15021   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15022   DONE;
15023 })
15024
15025 (define_expand "dremxf3"
15026   [(use (match_operand:XF 0 "register_operand" ""))
15027    (use (match_operand:XF 1 "register_operand" ""))
15028    (use (match_operand:XF 2 "register_operand" ""))]
15029   "TARGET_USE_FANCY_MATH_387
15030    && flag_unsafe_math_optimizations"
15031 {
15032   rtx label = gen_label_rtx ();
15033
15034   emit_label (label);
15035
15036   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15037                             operands[1], operands[2]));
15038   ix86_emit_fp_unordered_jump (label);
15039
15040   emit_move_insn (operands[0], operands[1]);
15041   DONE;
15042 })
15043
15044 (define_insn "*sindf2"
15045   [(set (match_operand:DF 0 "register_operand" "=f")
15046         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15049    && flag_unsafe_math_optimizations"
15050   "fsin"
15051   [(set_attr "type" "fpspc")
15052    (set_attr "mode" "DF")])
15053
15054 (define_insn "*sinsf2"
15055   [(set (match_operand:SF 0 "register_operand" "=f")
15056         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15057   "TARGET_USE_FANCY_MATH_387
15058    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15059    && flag_unsafe_math_optimizations"
15060   "fsin"
15061   [(set_attr "type" "fpspc")
15062    (set_attr "mode" "SF")])
15063
15064 (define_insn "*sinextendsfdf2"
15065   [(set (match_operand:DF 0 "register_operand" "=f")
15066         (unspec:DF [(float_extend:DF
15067                      (match_operand:SF 1 "register_operand" "0"))]
15068                    UNSPEC_SIN))]
15069   "TARGET_USE_FANCY_MATH_387
15070    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15071    && flag_unsafe_math_optimizations"
15072   "fsin"
15073   [(set_attr "type" "fpspc")
15074    (set_attr "mode" "DF")])
15075
15076 (define_insn "*sinxf2"
15077   [(set (match_operand:XF 0 "register_operand" "=f")
15078         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15079   "TARGET_USE_FANCY_MATH_387
15080    && flag_unsafe_math_optimizations"
15081   "fsin"
15082   [(set_attr "type" "fpspc")
15083    (set_attr "mode" "XF")])
15084
15085 (define_insn "*cosdf2"
15086   [(set (match_operand:DF 0 "register_operand" "=f")
15087         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15088   "TARGET_USE_FANCY_MATH_387
15089    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15090    && flag_unsafe_math_optimizations"
15091   "fcos"
15092   [(set_attr "type" "fpspc")
15093    (set_attr "mode" "DF")])
15094
15095 (define_insn "*cossf2"
15096   [(set (match_operand:SF 0 "register_operand" "=f")
15097         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15100    && flag_unsafe_math_optimizations"
15101   "fcos"
15102   [(set_attr "type" "fpspc")
15103    (set_attr "mode" "SF")])
15104
15105 (define_insn "*cosextendsfdf2"
15106   [(set (match_operand:DF 0 "register_operand" "=f")
15107         (unspec:DF [(float_extend:DF
15108                      (match_operand:SF 1 "register_operand" "0"))]
15109                    UNSPEC_COS))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15112    && flag_unsafe_math_optimizations"
15113   "fcos"
15114   [(set_attr "type" "fpspc")
15115    (set_attr "mode" "DF")])
15116
15117 (define_insn "*cosxf2"
15118   [(set (match_operand:XF 0 "register_operand" "=f")
15119         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15120   "TARGET_USE_FANCY_MATH_387
15121    && flag_unsafe_math_optimizations"
15122   "fcos"
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "XF")])
15125
15126 ;; With sincos pattern defined, sin and cos builtin function will be
15127 ;; expanded to sincos pattern with one of its outputs left unused. 
15128 ;; Cse pass  will detected, if two sincos patterns can be combined,
15129 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15130 ;; depending on the unused output.
15131
15132 (define_insn "sincosdf3"
15133   [(set (match_operand:DF 0 "register_operand" "=f")
15134         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15135                    UNSPEC_SINCOS_COS))
15136    (set (match_operand:DF 1 "register_operand" "=u")
15137         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15138   "TARGET_USE_FANCY_MATH_387
15139    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15140    && flag_unsafe_math_optimizations"
15141   "fsincos"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "DF")])
15144
15145 (define_split
15146   [(set (match_operand:DF 0 "register_operand" "")
15147         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15148                    UNSPEC_SINCOS_COS))
15149    (set (match_operand:DF 1 "register_operand" "")
15150         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15151   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15152    && !reload_completed && !reload_in_progress"
15153   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15154   "")
15155
15156 (define_split
15157   [(set (match_operand:DF 0 "register_operand" "")
15158         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15159                    UNSPEC_SINCOS_COS))
15160    (set (match_operand:DF 1 "register_operand" "")
15161         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15162   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15163    && !reload_completed && !reload_in_progress"
15164   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15165   "")
15166
15167 (define_insn "sincossf3"
15168   [(set (match_operand:SF 0 "register_operand" "=f")
15169         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15170                    UNSPEC_SINCOS_COS))
15171    (set (match_operand:SF 1 "register_operand" "=u")
15172         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15175    && flag_unsafe_math_optimizations"
15176   "fsincos"
15177   [(set_attr "type" "fpspc")
15178    (set_attr "mode" "SF")])
15179
15180 (define_split
15181   [(set (match_operand:SF 0 "register_operand" "")
15182         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15183                    UNSPEC_SINCOS_COS))
15184    (set (match_operand:SF 1 "register_operand" "")
15185         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15186   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15187    && !reload_completed && !reload_in_progress"
15188   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15189   "")
15190
15191 (define_split
15192   [(set (match_operand:SF 0 "register_operand" "")
15193         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15194                    UNSPEC_SINCOS_COS))
15195    (set (match_operand:SF 1 "register_operand" "")
15196         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15197   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15198    && !reload_completed && !reload_in_progress"
15199   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15200   "")
15201
15202 (define_insn "*sincosextendsfdf3"
15203   [(set (match_operand:DF 0 "register_operand" "=f")
15204         (unspec:DF [(float_extend:DF
15205                      (match_operand:SF 2 "register_operand" "0"))]
15206                    UNSPEC_SINCOS_COS))
15207    (set (match_operand:DF 1 "register_operand" "=u")
15208         (unspec:DF [(float_extend:DF
15209                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15210   "TARGET_USE_FANCY_MATH_387
15211    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15212    && flag_unsafe_math_optimizations"
15213   "fsincos"
15214   [(set_attr "type" "fpspc")
15215    (set_attr "mode" "DF")])
15216
15217 (define_split
15218   [(set (match_operand:DF 0 "register_operand" "")
15219         (unspec:DF [(float_extend:DF
15220                      (match_operand:SF 2 "register_operand" ""))]
15221                    UNSPEC_SINCOS_COS))
15222    (set (match_operand:DF 1 "register_operand" "")
15223         (unspec:DF [(float_extend:DF
15224                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15225   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15226    && !reload_completed && !reload_in_progress"
15227   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15228                                    (match_dup 2))] UNSPEC_SIN))]
15229   "")
15230
15231 (define_split
15232   [(set (match_operand:DF 0 "register_operand" "")
15233         (unspec:DF [(float_extend:DF
15234                      (match_operand:SF 2 "register_operand" ""))]
15235                    UNSPEC_SINCOS_COS))
15236    (set (match_operand:DF 1 "register_operand" "")
15237         (unspec:DF [(float_extend:DF
15238                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15239   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15240    && !reload_completed && !reload_in_progress"
15241   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15242                                    (match_dup 2))] UNSPEC_COS))]
15243   "")
15244
15245 (define_insn "sincosxf3"
15246   [(set (match_operand:XF 0 "register_operand" "=f")
15247         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15248                    UNSPEC_SINCOS_COS))
15249    (set (match_operand:XF 1 "register_operand" "=u")
15250         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15251   "TARGET_USE_FANCY_MATH_387
15252    && flag_unsafe_math_optimizations"
15253   "fsincos"
15254   [(set_attr "type" "fpspc")
15255    (set_attr "mode" "XF")])
15256
15257 (define_split
15258   [(set (match_operand:XF 0 "register_operand" "")
15259         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15260                    UNSPEC_SINCOS_COS))
15261    (set (match_operand:XF 1 "register_operand" "")
15262         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15263   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15264    && !reload_completed && !reload_in_progress"
15265   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15266   "")
15267
15268 (define_split
15269   [(set (match_operand:XF 0 "register_operand" "")
15270         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15271                    UNSPEC_SINCOS_COS))
15272    (set (match_operand:XF 1 "register_operand" "")
15273         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15274   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15275    && !reload_completed && !reload_in_progress"
15276   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15277   "")
15278
15279 (define_insn "*tandf3_1"
15280   [(set (match_operand:DF 0 "register_operand" "=f")
15281         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15282                    UNSPEC_TAN_ONE))
15283    (set (match_operand:DF 1 "register_operand" "=u")
15284         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15285   "TARGET_USE_FANCY_MATH_387
15286    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15287    && flag_unsafe_math_optimizations"
15288   "fptan"
15289   [(set_attr "type" "fpspc")
15290    (set_attr "mode" "DF")])
15291
15292 ;; optimize sequence: fptan
15293 ;;                    fstp    %st(0)
15294 ;;                    fld1
15295 ;; into fptan insn.
15296
15297 (define_peephole2
15298   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15299                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15300                              UNSPEC_TAN_ONE))
15301              (set (match_operand:DF 1 "register_operand" "")
15302                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15303    (set (match_dup 0)
15304         (match_operand:DF 3 "immediate_operand" ""))]
15305   "standard_80387_constant_p (operands[3]) == 2"
15306   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15307              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15308   "")
15309
15310 (define_expand "tandf2"
15311   [(parallel [(set (match_dup 2)
15312                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15313                               UNSPEC_TAN_ONE))
15314               (set (match_operand:DF 0 "register_operand" "")
15315                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15316   "TARGET_USE_FANCY_MATH_387
15317    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15318    && flag_unsafe_math_optimizations"
15319 {
15320   operands[2] = gen_reg_rtx (DFmode);
15321 })
15322
15323 (define_insn "*tansf3_1"
15324   [(set (match_operand:SF 0 "register_operand" "=f")
15325         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15326                    UNSPEC_TAN_ONE))
15327    (set (match_operand:SF 1 "register_operand" "=u")
15328         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15331    && flag_unsafe_math_optimizations"
15332   "fptan"
15333   [(set_attr "type" "fpspc")
15334    (set_attr "mode" "SF")])
15335
15336 ;; optimize sequence: fptan
15337 ;;                    fstp    %st(0)
15338 ;;                    fld1
15339 ;; into fptan insn.
15340
15341 (define_peephole2
15342   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15343                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15344                              UNSPEC_TAN_ONE))
15345              (set (match_operand:SF 1 "register_operand" "")
15346                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15347    (set (match_dup 0)
15348         (match_operand:SF 3 "immediate_operand" ""))]
15349   "standard_80387_constant_p (operands[3]) == 2"
15350   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15351              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15352   "")
15353
15354 (define_expand "tansf2"
15355   [(parallel [(set (match_dup 2)
15356                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15357                               UNSPEC_TAN_ONE))
15358               (set (match_operand:SF 0 "register_operand" "")
15359                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15360   "TARGET_USE_FANCY_MATH_387
15361    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations"
15363 {
15364   operands[2] = gen_reg_rtx (SFmode);
15365 })
15366
15367 (define_insn "*tanxf3_1"
15368   [(set (match_operand:XF 0 "register_operand" "=f")
15369         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15370                    UNSPEC_TAN_ONE))
15371    (set (match_operand:XF 1 "register_operand" "=u")
15372         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15373   "TARGET_USE_FANCY_MATH_387
15374    && flag_unsafe_math_optimizations"
15375   "fptan"
15376   [(set_attr "type" "fpspc")
15377    (set_attr "mode" "XF")])
15378
15379 ;; optimize sequence: fptan
15380 ;;                    fstp    %st(0)
15381 ;;                    fld1
15382 ;; into fptan insn.
15383
15384 (define_peephole2
15385   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15386                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15387                              UNSPEC_TAN_ONE))
15388              (set (match_operand:XF 1 "register_operand" "")
15389                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15390    (set (match_dup 0)
15391         (match_operand:XF 3 "immediate_operand" ""))]
15392   "standard_80387_constant_p (operands[3]) == 2"
15393   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15394              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15395   "")
15396
15397 (define_expand "tanxf2"
15398   [(parallel [(set (match_dup 2)
15399                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15400                               UNSPEC_TAN_ONE))
15401               (set (match_operand:XF 0 "register_operand" "")
15402                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations"
15405 {
15406   operands[2] = gen_reg_rtx (XFmode);
15407 })
15408
15409 (define_insn "atan2df3_1"
15410   [(set (match_operand:DF 0 "register_operand" "=f")
15411         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15412                     (match_operand:DF 1 "register_operand" "u")]
15413                    UNSPEC_FPATAN))
15414    (clobber (match_scratch:DF 3 "=1"))]
15415   "TARGET_USE_FANCY_MATH_387
15416    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15417    && flag_unsafe_math_optimizations"
15418   "fpatan"
15419   [(set_attr "type" "fpspc")
15420    (set_attr "mode" "DF")])
15421
15422 (define_expand "atan2df3"
15423   [(use (match_operand:DF 0 "register_operand" ""))
15424    (use (match_operand:DF 2 "register_operand" ""))
15425    (use (match_operand:DF 1 "register_operand" ""))]
15426   "TARGET_USE_FANCY_MATH_387
15427    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15428    && flag_unsafe_math_optimizations"
15429 {
15430   rtx copy = gen_reg_rtx (DFmode);
15431   emit_move_insn (copy, operands[1]);
15432   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15433   DONE;
15434 })
15435
15436 (define_expand "atandf2"
15437   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15438                    (unspec:DF [(match_dup 2)
15439                                (match_operand:DF 1 "register_operand" "")]
15440                     UNSPEC_FPATAN))
15441               (clobber (match_scratch:DF 3 ""))])]
15442   "TARGET_USE_FANCY_MATH_387
15443    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15444    && flag_unsafe_math_optimizations"
15445 {
15446   operands[2] = gen_reg_rtx (DFmode);
15447   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15448 })
15449
15450 (define_insn "atan2sf3_1"
15451   [(set (match_operand:SF 0 "register_operand" "=f")
15452         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15453                     (match_operand:SF 1 "register_operand" "u")]
15454                    UNSPEC_FPATAN))
15455    (clobber (match_scratch:SF 3 "=1"))]
15456   "TARGET_USE_FANCY_MATH_387
15457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15458    && flag_unsafe_math_optimizations"
15459   "fpatan"
15460   [(set_attr "type" "fpspc")
15461    (set_attr "mode" "SF")])
15462
15463 (define_expand "atan2sf3"
15464   [(use (match_operand:SF 0 "register_operand" ""))
15465    (use (match_operand:SF 2 "register_operand" ""))
15466    (use (match_operand:SF 1 "register_operand" ""))]
15467   "TARGET_USE_FANCY_MATH_387
15468    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15469    && flag_unsafe_math_optimizations"
15470 {
15471   rtx copy = gen_reg_rtx (SFmode);
15472   emit_move_insn (copy, operands[1]);
15473   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15474   DONE;
15475 })
15476
15477 (define_expand "atansf2"
15478   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15479                    (unspec:SF [(match_dup 2)
15480                                (match_operand:SF 1 "register_operand" "")]
15481                     UNSPEC_FPATAN))
15482               (clobber (match_scratch:SF 3 ""))])]
15483   "TARGET_USE_FANCY_MATH_387
15484    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15485    && flag_unsafe_math_optimizations"
15486 {
15487   operands[2] = gen_reg_rtx (SFmode);
15488   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15489 })
15490
15491 (define_insn "atan2xf3_1"
15492   [(set (match_operand:XF 0 "register_operand" "=f")
15493         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15494                     (match_operand:XF 1 "register_operand" "u")]
15495                    UNSPEC_FPATAN))
15496    (clobber (match_scratch:XF 3 "=1"))]
15497   "TARGET_USE_FANCY_MATH_387
15498    && flag_unsafe_math_optimizations"
15499   "fpatan"
15500   [(set_attr "type" "fpspc")
15501    (set_attr "mode" "XF")])
15502
15503 (define_expand "atan2xf3"
15504   [(use (match_operand:XF 0 "register_operand" ""))
15505    (use (match_operand:XF 2 "register_operand" ""))
15506    (use (match_operand:XF 1 "register_operand" ""))]
15507   "TARGET_USE_FANCY_MATH_387
15508    && flag_unsafe_math_optimizations"
15509 {
15510   rtx copy = gen_reg_rtx (XFmode);
15511   emit_move_insn (copy, operands[1]);
15512   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15513   DONE;
15514 })
15515
15516 (define_expand "atanxf2"
15517   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15518                    (unspec:XF [(match_dup 2)
15519                                (match_operand:XF 1 "register_operand" "")]
15520                     UNSPEC_FPATAN))
15521               (clobber (match_scratch:XF 3 ""))])]
15522   "TARGET_USE_FANCY_MATH_387
15523    && flag_unsafe_math_optimizations"
15524 {
15525   operands[2] = gen_reg_rtx (XFmode);
15526   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15527 })
15528
15529 (define_expand "asindf2"
15530   [(set (match_dup 2)
15531         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15532    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15533    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15534    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15535    (parallel [(set (match_dup 7)
15536                    (unspec:XF [(match_dup 6) (match_dup 2)]
15537                               UNSPEC_FPATAN))
15538               (clobber (match_scratch:XF 8 ""))])
15539    (set (match_operand:DF 0 "register_operand" "")
15540         (float_truncate:DF (match_dup 7)))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations"
15544 {
15545   int i;
15546
15547   for (i=2; i<8; i++)
15548     operands[i] = gen_reg_rtx (XFmode);
15549
15550   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15551 })
15552
15553 (define_expand "asinsf2"
15554   [(set (match_dup 2)
15555         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15556    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15557    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15558    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15559    (parallel [(set (match_dup 7)
15560                    (unspec:XF [(match_dup 6) (match_dup 2)]
15561                               UNSPEC_FPATAN))
15562               (clobber (match_scratch:XF 8 ""))])
15563    (set (match_operand:SF 0 "register_operand" "")
15564         (float_truncate:SF (match_dup 7)))]
15565   "TARGET_USE_FANCY_MATH_387
15566    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15567    && flag_unsafe_math_optimizations"
15568 {
15569   int i;
15570
15571   for (i=2; i<8; i++)
15572     operands[i] = gen_reg_rtx (XFmode);
15573
15574   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15575 })
15576
15577 (define_expand "asinxf2"
15578   [(set (match_dup 2)
15579         (mult:XF (match_operand:XF 1 "register_operand" "")
15580                  (match_dup 1)))
15581    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15582    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15583    (parallel [(set (match_operand:XF 0 "register_operand" "")
15584                    (unspec:XF [(match_dup 5) (match_dup 1)]
15585                               UNSPEC_FPATAN))
15586               (clobber (match_scratch:XF 6 ""))])]
15587   "TARGET_USE_FANCY_MATH_387
15588    && flag_unsafe_math_optimizations"
15589 {
15590   int i;
15591
15592   for (i=2; i<6; i++)
15593     operands[i] = gen_reg_rtx (XFmode);
15594
15595   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15596 })
15597
15598 (define_expand "acosdf2"
15599   [(set (match_dup 2)
15600         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15601    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15602    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15603    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15604    (parallel [(set (match_dup 7)
15605                    (unspec:XF [(match_dup 2) (match_dup 6)]
15606                               UNSPEC_FPATAN))
15607               (clobber (match_scratch:XF 8 ""))])
15608    (set (match_operand:DF 0 "register_operand" "")
15609         (float_truncate:DF (match_dup 7)))]
15610   "TARGET_USE_FANCY_MATH_387
15611    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15612    && flag_unsafe_math_optimizations"
15613 {
15614   int i;
15615
15616   for (i=2; i<8; i++)
15617     operands[i] = gen_reg_rtx (XFmode);
15618
15619   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15620 })
15621
15622 (define_expand "acossf2"
15623   [(set (match_dup 2)
15624         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15625    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15626    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15627    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15628    (parallel [(set (match_dup 7)
15629                    (unspec:XF [(match_dup 2) (match_dup 6)]
15630                               UNSPEC_FPATAN))
15631               (clobber (match_scratch:XF 8 ""))])
15632    (set (match_operand:SF 0 "register_operand" "")
15633         (float_truncate:SF (match_dup 7)))]
15634   "TARGET_USE_FANCY_MATH_387
15635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15636    && flag_unsafe_math_optimizations"
15637 {
15638   int i;
15639
15640   for (i=2; i<8; i++)
15641     operands[i] = gen_reg_rtx (XFmode);
15642
15643   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15644 })
15645
15646 (define_expand "acosxf2"
15647   [(set (match_dup 2)
15648         (mult:XF (match_operand:XF 1 "register_operand" "")
15649                  (match_dup 1)))
15650    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15651    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15652    (parallel [(set (match_operand:XF 0 "register_operand" "")
15653                    (unspec:XF [(match_dup 1) (match_dup 5)]
15654                               UNSPEC_FPATAN))
15655               (clobber (match_scratch:XF 6 ""))])]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_unsafe_math_optimizations"
15658 {
15659   int i;
15660
15661   for (i=2; i<6; i++)
15662     operands[i] = gen_reg_rtx (XFmode);
15663
15664   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15665 })
15666
15667 (define_insn "fyl2x_xf3"
15668   [(set (match_operand:XF 0 "register_operand" "=f")
15669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15670                     (match_operand:XF 1 "register_operand" "u")]
15671                    UNSPEC_FYL2X))
15672    (clobber (match_scratch:XF 3 "=1"))]
15673   "TARGET_USE_FANCY_MATH_387
15674    && flag_unsafe_math_optimizations"
15675   "fyl2x"
15676   [(set_attr "type" "fpspc")
15677    (set_attr "mode" "XF")])
15678
15679 (define_expand "logsf2"
15680   [(set (match_dup 2)
15681         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15682    (parallel [(set (match_dup 4)
15683                    (unspec:XF [(match_dup 2)
15684                                (match_dup 3)] UNSPEC_FYL2X))
15685               (clobber (match_scratch:XF 5 ""))])
15686    (set (match_operand:SF 0 "register_operand" "")
15687         (float_truncate:SF (match_dup 4)))]
15688   "TARGET_USE_FANCY_MATH_387
15689    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15690    && flag_unsafe_math_optimizations"
15691 {
15692   rtx temp;
15693
15694   operands[2] = gen_reg_rtx (XFmode);
15695   operands[3] = gen_reg_rtx (XFmode);
15696   operands[4] = gen_reg_rtx (XFmode);
15697
15698   temp = standard_80387_constant_rtx (4); /* fldln2 */
15699   emit_move_insn (operands[3], temp);
15700 })
15701
15702 (define_expand "logdf2"
15703   [(set (match_dup 2)
15704         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15705    (parallel [(set (match_dup 4)
15706                    (unspec:XF [(match_dup 2)
15707                                (match_dup 3)] UNSPEC_FYL2X))
15708               (clobber (match_scratch:XF 5 ""))])
15709    (set (match_operand:DF 0 "register_operand" "")
15710         (float_truncate:DF (match_dup 4)))]
15711   "TARGET_USE_FANCY_MATH_387
15712    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15713    && flag_unsafe_math_optimizations"
15714 {
15715   rtx temp;
15716
15717   operands[2] = gen_reg_rtx (XFmode);
15718   operands[3] = gen_reg_rtx (XFmode);
15719   operands[4] = gen_reg_rtx (XFmode);
15720
15721   temp = standard_80387_constant_rtx (4); /* fldln2 */
15722   emit_move_insn (operands[3], temp);
15723 })
15724
15725 (define_expand "logxf2"
15726   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15727                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15728                                (match_dup 2)] UNSPEC_FYL2X))
15729               (clobber (match_scratch:XF 3 ""))])]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15732 {
15733   rtx temp;
15734
15735   operands[2] = gen_reg_rtx (XFmode);
15736   temp = standard_80387_constant_rtx (4); /* fldln2 */
15737   emit_move_insn (operands[2], temp);
15738 })
15739
15740 (define_expand "log10sf2"
15741   [(set (match_dup 2)
15742         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15743    (parallel [(set (match_dup 4)
15744                    (unspec:XF [(match_dup 2)
15745                                (match_dup 3)] UNSPEC_FYL2X))
15746               (clobber (match_scratch:XF 5 ""))])
15747    (set (match_operand:SF 0 "register_operand" "")
15748         (float_truncate:SF (match_dup 4)))]
15749   "TARGET_USE_FANCY_MATH_387
15750    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15751    && flag_unsafe_math_optimizations"
15752 {
15753   rtx temp;
15754
15755   operands[2] = gen_reg_rtx (XFmode);
15756   operands[3] = gen_reg_rtx (XFmode);
15757   operands[4] = gen_reg_rtx (XFmode);
15758
15759   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15760   emit_move_insn (operands[3], temp);
15761 })
15762
15763 (define_expand "log10df2"
15764   [(set (match_dup 2)
15765         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15766    (parallel [(set (match_dup 4)
15767                    (unspec:XF [(match_dup 2)
15768                                (match_dup 3)] UNSPEC_FYL2X))
15769               (clobber (match_scratch:XF 5 ""))])
15770    (set (match_operand:DF 0 "register_operand" "")
15771         (float_truncate:DF (match_dup 4)))]
15772   "TARGET_USE_FANCY_MATH_387
15773    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15774    && flag_unsafe_math_optimizations"
15775 {
15776   rtx temp;
15777
15778   operands[2] = gen_reg_rtx (XFmode);
15779   operands[3] = gen_reg_rtx (XFmode);
15780   operands[4] = gen_reg_rtx (XFmode);
15781
15782   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15783   emit_move_insn (operands[3], temp);
15784 })
15785
15786 (define_expand "log10xf2"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15789                                (match_dup 2)] UNSPEC_FYL2X))
15790               (clobber (match_scratch:XF 3 ""))])]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15793 {
15794   rtx temp;
15795
15796   operands[2] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15798   emit_move_insn (operands[2], temp);
15799 })
15800
15801 (define_expand "log2sf2"
15802   [(set (match_dup 2)
15803         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15804    (parallel [(set (match_dup 4)
15805                    (unspec:XF [(match_dup 2)
15806                                (match_dup 3)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 5 ""))])
15808    (set (match_operand:SF 0 "register_operand" "")
15809         (float_truncate:SF (match_dup 4)))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813 {
15814   operands[2] = gen_reg_rtx (XFmode);
15815   operands[3] = gen_reg_rtx (XFmode);
15816   operands[4] = gen_reg_rtx (XFmode);
15817
15818   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15819 })
15820
15821 (define_expand "log2df2"
15822   [(set (match_dup 2)
15823         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15824    (parallel [(set (match_dup 4)
15825                    (unspec:XF [(match_dup 2)
15826                                (match_dup 3)] UNSPEC_FYL2X))
15827               (clobber (match_scratch:XF 5 ""))])
15828    (set (match_operand:DF 0 "register_operand" "")
15829         (float_truncate:DF (match_dup 4)))]
15830   "TARGET_USE_FANCY_MATH_387
15831    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15832    && flag_unsafe_math_optimizations"
15833 {
15834   operands[2] = gen_reg_rtx (XFmode);
15835   operands[3] = gen_reg_rtx (XFmode);
15836   operands[4] = gen_reg_rtx (XFmode);
15837
15838   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15839 })
15840
15841 (define_expand "log2xf2"
15842   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15843                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15844                                (match_dup 2)] UNSPEC_FYL2X))
15845               (clobber (match_scratch:XF 3 ""))])]
15846   "TARGET_USE_FANCY_MATH_387
15847    && flag_unsafe_math_optimizations"
15848 {
15849   operands[2] = gen_reg_rtx (XFmode);
15850   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15851 })
15852
15853 (define_insn "fyl2xp1_xf3"
15854   [(set (match_operand:XF 0 "register_operand" "=f")
15855         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15856                     (match_operand:XF 1 "register_operand" "u")]
15857                    UNSPEC_FYL2XP1))
15858    (clobber (match_scratch:XF 3 "=1"))]
15859   "TARGET_USE_FANCY_MATH_387
15860    && flag_unsafe_math_optimizations"
15861   "fyl2xp1"
15862   [(set_attr "type" "fpspc")
15863    (set_attr "mode" "XF")])
15864
15865 (define_expand "log1psf2"
15866   [(use (match_operand:SF 0 "register_operand" ""))
15867    (use (match_operand:SF 1 "register_operand" ""))]
15868   "TARGET_USE_FANCY_MATH_387
15869    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15870    && flag_unsafe_math_optimizations"
15871 {
15872   rtx op0 = gen_reg_rtx (XFmode);
15873   rtx op1 = gen_reg_rtx (XFmode);
15874
15875   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15876   ix86_emit_i387_log1p (op0, op1);
15877   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15878   DONE;
15879 })
15880
15881 (define_expand "log1pdf2"
15882   [(use (match_operand:DF 0 "register_operand" ""))
15883    (use (match_operand:DF 1 "register_operand" ""))]
15884   "TARGET_USE_FANCY_MATH_387
15885    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15886    && flag_unsafe_math_optimizations"
15887 {
15888   rtx op0 = gen_reg_rtx (XFmode);
15889   rtx op1 = gen_reg_rtx (XFmode);
15890
15891   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15892   ix86_emit_i387_log1p (op0, op1);
15893   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15894   DONE;
15895 })
15896
15897 (define_expand "log1pxf2"
15898   [(use (match_operand:XF 0 "register_operand" ""))
15899    (use (match_operand:XF 1 "register_operand" ""))]
15900   "TARGET_USE_FANCY_MATH_387
15901    && flag_unsafe_math_optimizations"
15902 {
15903   ix86_emit_i387_log1p (operands[0], operands[1]);
15904   DONE;
15905 })
15906
15907 (define_insn "*fxtractxf3"
15908   [(set (match_operand:XF 0 "register_operand" "=f")
15909         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15910                    UNSPEC_XTRACT_FRACT))
15911    (set (match_operand:XF 1 "register_operand" "=u")
15912         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15913   "TARGET_USE_FANCY_MATH_387
15914    && flag_unsafe_math_optimizations"
15915   "fxtract"
15916   [(set_attr "type" "fpspc")
15917    (set_attr "mode" "XF")])
15918
15919 (define_expand "logbsf2"
15920   [(set (match_dup 2)
15921         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15922    (parallel [(set (match_dup 3)
15923                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15924               (set (match_dup 4)
15925                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15926    (set (match_operand:SF 0 "register_operand" "")
15927         (float_truncate:SF (match_dup 4)))]
15928   "TARGET_USE_FANCY_MATH_387
15929    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15930    && flag_unsafe_math_optimizations"
15931 {
15932   operands[2] = gen_reg_rtx (XFmode);
15933   operands[3] = gen_reg_rtx (XFmode);
15934   operands[4] = gen_reg_rtx (XFmode);
15935 })
15936
15937 (define_expand "logbdf2"
15938   [(set (match_dup 2)
15939         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15940    (parallel [(set (match_dup 3)
15941                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15942               (set (match_dup 4)
15943                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15944    (set (match_operand:DF 0 "register_operand" "")
15945         (float_truncate:DF (match_dup 4)))]
15946   "TARGET_USE_FANCY_MATH_387
15947    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15948    && flag_unsafe_math_optimizations"
15949 {
15950   operands[2] = gen_reg_rtx (XFmode);
15951   operands[3] = gen_reg_rtx (XFmode);
15952   operands[4] = gen_reg_rtx (XFmode);
15953 })
15954
15955 (define_expand "logbxf2"
15956   [(parallel [(set (match_dup 2)
15957                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15958                               UNSPEC_XTRACT_FRACT))
15959               (set (match_operand:XF 0 "register_operand" "")
15960                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15961   "TARGET_USE_FANCY_MATH_387
15962    && flag_unsafe_math_optimizations"
15963 {
15964   operands[2] = gen_reg_rtx (XFmode);
15965 })
15966
15967 (define_expand "ilogbsi2"
15968   [(parallel [(set (match_dup 2)
15969                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15970                               UNSPEC_XTRACT_FRACT))
15971               (set (match_operand:XF 3 "register_operand" "")
15972                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15973    (parallel [(set (match_operand:SI 0 "register_operand" "")
15974                    (fix:SI (match_dup 3)))
15975               (clobber (reg:CC FLAGS_REG))])]
15976   "TARGET_USE_FANCY_MATH_387
15977    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15978    && flag_unsafe_math_optimizations"
15979 {
15980   operands[2] = gen_reg_rtx (XFmode);
15981   operands[3] = gen_reg_rtx (XFmode);
15982 })
15983
15984 (define_insn "*f2xm1xf2"
15985   [(set (match_operand:XF 0 "register_operand" "=f")
15986         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15987          UNSPEC_F2XM1))]
15988   "TARGET_USE_FANCY_MATH_387
15989    && flag_unsafe_math_optimizations"
15990   "f2xm1"
15991   [(set_attr "type" "fpspc")
15992    (set_attr "mode" "XF")])
15993
15994 (define_insn "*fscalexf4"
15995   [(set (match_operand:XF 0 "register_operand" "=f")
15996         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15997                     (match_operand:XF 3 "register_operand" "1")]
15998                    UNSPEC_FSCALE_FRACT))
15999    (set (match_operand:XF 1 "register_operand" "=u")
16000         (unspec:XF [(match_dup 2) (match_dup 3)]
16001                    UNSPEC_FSCALE_EXP))]
16002   "TARGET_USE_FANCY_MATH_387
16003    && flag_unsafe_math_optimizations"
16004   "fscale"
16005   [(set_attr "type" "fpspc")
16006    (set_attr "mode" "XF")])
16007
16008 (define_expand "expsf2"
16009   [(set (match_dup 2)
16010         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16011    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16012    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16013    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16014    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16015    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16016    (parallel [(set (match_dup 10)
16017                    (unspec:XF [(match_dup 9) (match_dup 5)]
16018                               UNSPEC_FSCALE_FRACT))
16019               (set (match_dup 11)
16020                    (unspec:XF [(match_dup 9) (match_dup 5)]
16021                               UNSPEC_FSCALE_EXP))])
16022    (set (match_operand:SF 0 "register_operand" "")
16023         (float_truncate:SF (match_dup 10)))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16026    && flag_unsafe_math_optimizations"
16027 {
16028   rtx temp;
16029   int i;
16030
16031   for (i=2; i<12; i++)
16032     operands[i] = gen_reg_rtx (XFmode);
16033   temp = standard_80387_constant_rtx (5); /* fldl2e */
16034   emit_move_insn (operands[3], temp);
16035   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16036 })
16037
16038 (define_expand "expdf2"
16039   [(set (match_dup 2)
16040         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16041    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16042    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16043    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16044    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16045    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16046    (parallel [(set (match_dup 10)
16047                    (unspec:XF [(match_dup 9) (match_dup 5)]
16048                               UNSPEC_FSCALE_FRACT))
16049               (set (match_dup 11)
16050                    (unspec:XF [(match_dup 9) (match_dup 5)]
16051                               UNSPEC_FSCALE_EXP))])
16052    (set (match_operand:DF 0 "register_operand" "")
16053         (float_truncate:DF (match_dup 10)))]
16054   "TARGET_USE_FANCY_MATH_387
16055    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16056    && flag_unsafe_math_optimizations"
16057 {
16058   rtx temp;
16059   int i;
16060
16061   for (i=2; i<12; i++)
16062     operands[i] = gen_reg_rtx (XFmode);
16063   temp = standard_80387_constant_rtx (5); /* fldl2e */
16064   emit_move_insn (operands[3], temp);
16065   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16066 })
16067
16068 (define_expand "expxf2"
16069   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16070                                (match_dup 2)))
16071    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16072    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16073    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16074    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16075    (parallel [(set (match_operand:XF 0 "register_operand" "")
16076                    (unspec:XF [(match_dup 8) (match_dup 4)]
16077                               UNSPEC_FSCALE_FRACT))
16078               (set (match_dup 9)
16079                    (unspec:XF [(match_dup 8) (match_dup 4)]
16080                               UNSPEC_FSCALE_EXP))])]
16081   "TARGET_USE_FANCY_MATH_387
16082    && flag_unsafe_math_optimizations"
16083 {
16084   rtx temp;
16085   int i;
16086
16087   for (i=2; i<10; i++)
16088     operands[i] = gen_reg_rtx (XFmode);
16089   temp = standard_80387_constant_rtx (5); /* fldl2e */
16090   emit_move_insn (operands[2], temp);
16091   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16092 })
16093
16094 (define_expand "exp10sf2"
16095   [(set (match_dup 2)
16096         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16097    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16098    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16099    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16100    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16101    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16102    (parallel [(set (match_dup 10)
16103                    (unspec:XF [(match_dup 9) (match_dup 5)]
16104                               UNSPEC_FSCALE_FRACT))
16105               (set (match_dup 11)
16106                    (unspec:XF [(match_dup 9) (match_dup 5)]
16107                               UNSPEC_FSCALE_EXP))])
16108    (set (match_operand:SF 0 "register_operand" "")
16109         (float_truncate:SF (match_dup 10)))]
16110   "TARGET_USE_FANCY_MATH_387
16111    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16112    && flag_unsafe_math_optimizations"
16113 {
16114   rtx temp;
16115   int i;
16116
16117   for (i=2; i<12; i++)
16118     operands[i] = gen_reg_rtx (XFmode);
16119   temp = standard_80387_constant_rtx (6); /* fldl2t */
16120   emit_move_insn (operands[3], temp);
16121   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16122 })
16123
16124 (define_expand "exp10df2"
16125   [(set (match_dup 2)
16126         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16127    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16128    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16129    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16130    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16131    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16132    (parallel [(set (match_dup 10)
16133                    (unspec:XF [(match_dup 9) (match_dup 5)]
16134                               UNSPEC_FSCALE_FRACT))
16135               (set (match_dup 11)
16136                    (unspec:XF [(match_dup 9) (match_dup 5)]
16137                               UNSPEC_FSCALE_EXP))])
16138    (set (match_operand:DF 0 "register_operand" "")
16139         (float_truncate:DF (match_dup 10)))]
16140   "TARGET_USE_FANCY_MATH_387
16141    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16142    && flag_unsafe_math_optimizations"
16143 {
16144   rtx temp;
16145   int i;
16146
16147   for (i=2; i<12; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149   temp = standard_80387_constant_rtx (6); /* fldl2t */
16150   emit_move_insn (operands[3], temp);
16151   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16152 })
16153
16154 (define_expand "exp10xf2"
16155   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16156                                (match_dup 2)))
16157    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16158    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16159    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16160    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16161    (parallel [(set (match_operand:XF 0 "register_operand" "")
16162                    (unspec:XF [(match_dup 8) (match_dup 4)]
16163                               UNSPEC_FSCALE_FRACT))
16164               (set (match_dup 9)
16165                    (unspec:XF [(match_dup 8) (match_dup 4)]
16166                               UNSPEC_FSCALE_EXP))])]
16167   "TARGET_USE_FANCY_MATH_387
16168    && flag_unsafe_math_optimizations"
16169 {
16170   rtx temp;
16171   int i;
16172
16173   for (i=2; i<10; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16175   temp = standard_80387_constant_rtx (6); /* fldl2t */
16176   emit_move_insn (operands[2], temp);
16177   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16178 })
16179
16180 (define_expand "exp2sf2"
16181   [(set (match_dup 2)
16182         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16183    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16184    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16185    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16186    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16187    (parallel [(set (match_dup 8)
16188                    (unspec:XF [(match_dup 7) (match_dup 3)]
16189                               UNSPEC_FSCALE_FRACT))
16190               (set (match_dup 9)
16191                    (unspec:XF [(match_dup 7) (match_dup 3)]
16192                               UNSPEC_FSCALE_EXP))])
16193    (set (match_operand:SF 0 "register_operand" "")
16194         (float_truncate:SF (match_dup 8)))]
16195   "TARGET_USE_FANCY_MATH_387
16196    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16197    && flag_unsafe_math_optimizations"
16198 {
16199   int i;
16200
16201   for (i=2; i<10; i++)
16202     operands[i] = gen_reg_rtx (XFmode);
16203   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16204 })
16205
16206 (define_expand "exp2df2"
16207   [(set (match_dup 2)
16208         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16209    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16210    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16211    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16212    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16213    (parallel [(set (match_dup 8)
16214                    (unspec:XF [(match_dup 7) (match_dup 3)]
16215                               UNSPEC_FSCALE_FRACT))
16216               (set (match_dup 9)
16217                    (unspec:XF [(match_dup 7) (match_dup 3)]
16218                               UNSPEC_FSCALE_EXP))])
16219    (set (match_operand:DF 0 "register_operand" "")
16220         (float_truncate:DF (match_dup 8)))]
16221   "TARGET_USE_FANCY_MATH_387
16222    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16223    && flag_unsafe_math_optimizations"
16224 {
16225   int i;
16226
16227   for (i=2; i<10; i++)
16228     operands[i] = gen_reg_rtx (XFmode);
16229   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16230 })
16231
16232 (define_expand "exp2xf2"
16233   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16234    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16235    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16236    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16237    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16238    (parallel [(set (match_operand:XF 0 "register_operand" "")
16239                    (unspec:XF [(match_dup 7) (match_dup 3)]
16240                               UNSPEC_FSCALE_FRACT))
16241               (set (match_dup 8)
16242                    (unspec:XF [(match_dup 7) (match_dup 3)]
16243                               UNSPEC_FSCALE_EXP))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   int i;
16248
16249   for (i=2; i<9; i++)
16250     operands[i] = gen_reg_rtx (XFmode);
16251   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16252 })
16253
16254 (define_expand "expm1df2"
16255   [(set (match_dup 2)
16256         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16257    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16258    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16259    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16260    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16261    (parallel [(set (match_dup 8)
16262                    (unspec:XF [(match_dup 7) (match_dup 5)]
16263                               UNSPEC_FSCALE_FRACT))
16264                    (set (match_dup 9)
16265                    (unspec:XF [(match_dup 7) (match_dup 5)]
16266                               UNSPEC_FSCALE_EXP))])
16267    (parallel [(set (match_dup 11)
16268                    (unspec:XF [(match_dup 10) (match_dup 9)]
16269                               UNSPEC_FSCALE_FRACT))
16270               (set (match_dup 12)
16271                    (unspec:XF [(match_dup 10) (match_dup 9)]
16272                               UNSPEC_FSCALE_EXP))])
16273    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16274    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16275    (set (match_operand:DF 0 "register_operand" "")
16276         (float_truncate:DF (match_dup 14)))]
16277   "TARGET_USE_FANCY_MATH_387
16278    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16279    && flag_unsafe_math_optimizations"
16280 {
16281   rtx temp;
16282   int i;
16283
16284   for (i=2; i<15; i++)
16285     operands[i] = gen_reg_rtx (XFmode);
16286   temp = standard_80387_constant_rtx (5); /* fldl2e */
16287   emit_move_insn (operands[3], temp);
16288   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16289 })
16290
16291 (define_expand "expm1sf2"
16292   [(set (match_dup 2)
16293         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16294    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16295    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16296    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16297    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16298    (parallel [(set (match_dup 8)
16299                    (unspec:XF [(match_dup 7) (match_dup 5)]
16300                               UNSPEC_FSCALE_FRACT))
16301                    (set (match_dup 9)
16302                    (unspec:XF [(match_dup 7) (match_dup 5)]
16303                               UNSPEC_FSCALE_EXP))])
16304    (parallel [(set (match_dup 11)
16305                    (unspec:XF [(match_dup 10) (match_dup 9)]
16306                               UNSPEC_FSCALE_FRACT))
16307               (set (match_dup 12)
16308                    (unspec:XF [(match_dup 10) (match_dup 9)]
16309                               UNSPEC_FSCALE_EXP))])
16310    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16311    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16312    (set (match_operand:SF 0 "register_operand" "")
16313         (float_truncate:SF (match_dup 14)))]
16314   "TARGET_USE_FANCY_MATH_387
16315    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16316    && flag_unsafe_math_optimizations"
16317 {
16318   rtx temp;
16319   int i;
16320
16321   for (i=2; i<15; i++)
16322     operands[i] = gen_reg_rtx (XFmode);
16323   temp = standard_80387_constant_rtx (5); /* fldl2e */
16324   emit_move_insn (operands[3], temp);
16325   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16326 })
16327
16328 (define_expand "expm1xf2"
16329   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16330                                (match_dup 2)))
16331    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16332    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16333    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16334    (parallel [(set (match_dup 7)
16335                    (unspec:XF [(match_dup 6) (match_dup 4)]
16336                               UNSPEC_FSCALE_FRACT))
16337                    (set (match_dup 8)
16338                    (unspec:XF [(match_dup 6) (match_dup 4)]
16339                               UNSPEC_FSCALE_EXP))])
16340    (parallel [(set (match_dup 10)
16341                    (unspec:XF [(match_dup 9) (match_dup 8)]
16342                               UNSPEC_FSCALE_FRACT))
16343               (set (match_dup 11)
16344                    (unspec:XF [(match_dup 9) (match_dup 8)]
16345                               UNSPEC_FSCALE_EXP))])
16346    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16347    (set (match_operand:XF 0 "register_operand" "")
16348         (plus:XF (match_dup 12) (match_dup 7)))]
16349   "TARGET_USE_FANCY_MATH_387
16350    && flag_unsafe_math_optimizations"
16351 {
16352   rtx temp;
16353   int i;
16354
16355   for (i=2; i<13; i++)
16356     operands[i] = gen_reg_rtx (XFmode);
16357   temp = standard_80387_constant_rtx (5); /* fldl2e */
16358   emit_move_insn (operands[2], temp);
16359   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16360 })
16361
16362 (define_expand "ldexpdf3"
16363   [(set (match_dup 3)
16364         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16365    (set (match_dup 4)
16366         (float:XF (match_operand:SI 2 "register_operand" "")))
16367    (parallel [(set (match_dup 5)
16368                    (unspec:XF [(match_dup 3) (match_dup 4)]
16369                               UNSPEC_FSCALE_FRACT))
16370               (set (match_dup 6)
16371                    (unspec:XF [(match_dup 3) (match_dup 4)]
16372                               UNSPEC_FSCALE_EXP))])
16373    (set (match_operand:DF 0 "register_operand" "")
16374         (float_truncate:DF (match_dup 5)))]
16375   "TARGET_USE_FANCY_MATH_387
16376    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16377    && flag_unsafe_math_optimizations"
16378 {
16379   int i;
16380
16381   for (i=3; i<7; i++)
16382     operands[i] = gen_reg_rtx (XFmode);
16383 })
16384
16385 (define_expand "ldexpsf3"
16386   [(set (match_dup 3)
16387         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16388    (set (match_dup 4)
16389         (float:XF (match_operand:SI 2 "register_operand" "")))
16390    (parallel [(set (match_dup 5)
16391                    (unspec:XF [(match_dup 3) (match_dup 4)]
16392                               UNSPEC_FSCALE_FRACT))
16393               (set (match_dup 6)
16394                    (unspec:XF [(match_dup 3) (match_dup 4)]
16395                               UNSPEC_FSCALE_EXP))])
16396    (set (match_operand:SF 0 "register_operand" "")
16397         (float_truncate:SF (match_dup 5)))]
16398   "TARGET_USE_FANCY_MATH_387
16399    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16400    && flag_unsafe_math_optimizations"
16401 {
16402   int i;
16403
16404   for (i=3; i<7; i++)
16405     operands[i] = gen_reg_rtx (XFmode);
16406 })
16407
16408 (define_expand "ldexpxf3"
16409   [(set (match_dup 3)
16410         (float:XF (match_operand:SI 2 "register_operand" "")))
16411    (parallel [(set (match_operand:XF 0 " register_operand" "")
16412                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16413                                (match_dup 3)]
16414                               UNSPEC_FSCALE_FRACT))
16415               (set (match_dup 4)
16416                    (unspec:XF [(match_dup 1) (match_dup 3)]
16417                               UNSPEC_FSCALE_EXP))])]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420 {
16421   int i;
16422
16423   for (i=3; i<5; i++)
16424     operands[i] = gen_reg_rtx (XFmode);
16425 })
16426 \f
16427
16428 (define_insn "frndintxf2"
16429   [(set (match_operand:XF 0 "register_operand" "=f")
16430         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16431          UNSPEC_FRNDINT))]
16432   "TARGET_USE_FANCY_MATH_387
16433    && flag_unsafe_math_optimizations"
16434   "frndint"
16435   [(set_attr "type" "fpspc")
16436    (set_attr "mode" "XF")])
16437
16438 (define_expand "rintdf2"
16439   [(use (match_operand:DF 0 "register_operand" ""))
16440    (use (match_operand:DF 1 "register_operand" ""))]
16441   "TARGET_USE_FANCY_MATH_387
16442    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16443    && flag_unsafe_math_optimizations"
16444 {
16445   rtx op0 = gen_reg_rtx (XFmode);
16446   rtx op1 = gen_reg_rtx (XFmode);
16447
16448   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16449   emit_insn (gen_frndintxf2 (op0, op1));
16450
16451   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16452   DONE;
16453 })
16454
16455 (define_expand "rintsf2"
16456   [(use (match_operand:SF 0 "register_operand" ""))
16457    (use (match_operand:SF 1 "register_operand" ""))]
16458   "TARGET_USE_FANCY_MATH_387
16459    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16460    && flag_unsafe_math_optimizations"
16461 {
16462   rtx op0 = gen_reg_rtx (XFmode);
16463   rtx op1 = gen_reg_rtx (XFmode);
16464
16465   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16466   emit_insn (gen_frndintxf2 (op0, op1));
16467
16468   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16469   DONE;
16470 })
16471
16472 (define_expand "rintxf2"
16473   [(use (match_operand:XF 0 "register_operand" ""))
16474    (use (match_operand:XF 1 "register_operand" ""))]
16475   "TARGET_USE_FANCY_MATH_387
16476    && flag_unsafe_math_optimizations"
16477 {
16478   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16479   DONE;
16480 })
16481
16482 (define_insn "fistdi2"
16483   [(set (match_operand:DI 0 "memory_operand" "=m")
16484         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16485          UNSPEC_FIST))
16486    (clobber (match_scratch:XF 2 "=&1f"))]
16487   "TARGET_USE_FANCY_MATH_387
16488    && flag_unsafe_math_optimizations"
16489   "* return output_fix_trunc (insn, operands, 0);"
16490   [(set_attr "type" "fpspc")
16491    (set_attr "mode" "DI")])
16492
16493 (define_insn "fistdi2_with_temp"
16494   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16495         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16496          UNSPEC_FIST))
16497    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16498    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16499   "TARGET_USE_FANCY_MATH_387
16500    && flag_unsafe_math_optimizations"
16501   "#"
16502   [(set_attr "type" "fpspc")
16503    (set_attr "mode" "DI")])
16504
16505 (define_split 
16506   [(set (match_operand:DI 0 "register_operand" "")
16507         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16508          UNSPEC_FIST))
16509    (clobber (match_operand:DI 2 "memory_operand" ""))
16510    (clobber (match_scratch 3 ""))]
16511   "reload_completed"
16512   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16513               (clobber (match_dup 3))])
16514    (set (match_dup 0) (match_dup 2))]
16515   "")
16516
16517 (define_split 
16518   [(set (match_operand:DI 0 "memory_operand" "")
16519         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16520          UNSPEC_FIST))
16521    (clobber (match_operand:DI 2 "memory_operand" ""))
16522    (clobber (match_scratch 3 ""))]
16523   "reload_completed"
16524   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16525               (clobber (match_dup 3))])]
16526   "")
16527
16528 (define_insn "fist<mode>2"
16529   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16530         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16531          UNSPEC_FIST))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && flag_unsafe_math_optimizations"
16534   "* return output_fix_trunc (insn, operands, 0);"
16535   [(set_attr "type" "fpspc")
16536    (set_attr "mode" "<MODE>")])
16537
16538 (define_insn "fist<mode>2_with_temp"
16539   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16540         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16541          UNSPEC_FIST))
16542    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16543   "TARGET_USE_FANCY_MATH_387
16544    && flag_unsafe_math_optimizations"
16545   "#"
16546   [(set_attr "type" "fpspc")
16547    (set_attr "mode" "<MODE>")])
16548
16549 (define_split 
16550   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16551         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16552          UNSPEC_FIST))
16553    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16554   "reload_completed"
16555   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16556                        UNSPEC_FIST))
16557    (set (match_dup 0) (match_dup 2))]
16558   "")
16559
16560 (define_split 
16561   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16562         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16563          UNSPEC_FIST))
16564    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16565   "reload_completed"
16566   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16567                        UNSPEC_FIST))]
16568   "")
16569
16570 (define_expand "lrint<mode>2"
16571   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16572    (use (match_operand:XF 1 "register_operand" ""))]
16573   "TARGET_USE_FANCY_MATH_387
16574    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16575    && flag_unsafe_math_optimizations"
16576 {
16577   if (memory_operand (operands[0], VOIDmode))
16578     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16579   else
16580     {
16581       rtx op = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16582       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16583                                             op));
16584     }
16585   DONE;
16586 })
16587
16588 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16589 (define_insn_and_split "frndintxf2_floor"
16590   [(set (match_operand:XF 0 "register_operand" "=f")
16591         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16592          UNSPEC_FRNDINT_FLOOR))
16593    (clobber (reg:CC FLAGS_REG))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations
16596    && !(reload_completed || reload_in_progress)"
16597   "#"
16598   "&& 1"
16599   [(const_int 0)]
16600 {
16601   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16602
16603   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16604   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16605
16606   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16607                                         operands[2], operands[3]));
16608   DONE;
16609 }
16610   [(set_attr "type" "frndint")
16611    (set_attr "i387_cw" "floor")
16612    (set_attr "mode" "XF")])
16613
16614 (define_insn "frndintxf2_floor_i387"
16615   [(set (match_operand:XF 0 "register_operand" "=f")
16616         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16617          UNSPEC_FRNDINT_FLOOR))
16618    (use (match_operand:HI 2 "memory_operand" "m"))
16619    (use (match_operand:HI 3 "memory_operand" "m"))]
16620   "TARGET_USE_FANCY_MATH_387
16621    && flag_unsafe_math_optimizations"
16622   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16623   [(set_attr "type" "frndint")
16624    (set_attr "i387_cw" "floor")
16625    (set_attr "mode" "XF")])
16626
16627 (define_expand "floorxf2"
16628   [(use (match_operand:XF 0 "register_operand" ""))
16629    (use (match_operand:XF 1 "register_operand" ""))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && flag_unsafe_math_optimizations"
16632 {
16633   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16634   DONE;
16635 })
16636
16637 (define_expand "floordf2"
16638   [(use (match_operand:DF 0 "register_operand" ""))
16639    (use (match_operand:DF 1 "register_operand" ""))]
16640   "TARGET_USE_FANCY_MATH_387
16641    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16642    && flag_unsafe_math_optimizations"
16643 {
16644   rtx op0 = gen_reg_rtx (XFmode);
16645   rtx op1 = gen_reg_rtx (XFmode);
16646
16647   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16648   emit_insn (gen_frndintxf2_floor (op0, op1));
16649
16650   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16651   DONE;
16652 })
16653
16654 (define_expand "floorsf2"
16655   [(use (match_operand:SF 0 "register_operand" ""))
16656    (use (match_operand:SF 1 "register_operand" ""))]
16657   "TARGET_USE_FANCY_MATH_387
16658    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16659    && flag_unsafe_math_optimizations"
16660 {
16661   rtx op0 = gen_reg_rtx (XFmode);
16662   rtx op1 = gen_reg_rtx (XFmode);
16663
16664   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16665   emit_insn (gen_frndintxf2_floor (op0, op1));
16666
16667   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16668   DONE;
16669 })
16670
16671 (define_insn_and_split "*fist<mode>2_floor_1"
16672   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16673         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16674          UNSPEC_FIST_FLOOR))
16675    (clobber (reg:CC FLAGS_REG))]
16676   "TARGET_USE_FANCY_MATH_387
16677    && flag_unsafe_math_optimizations
16678    && !(reload_completed || reload_in_progress)"
16679   "#"
16680   "&& 1"
16681   [(const_int 0)]
16682 {
16683   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16684
16685   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16686   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16687   if (memory_operand (operands[0], VOIDmode))
16688     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16689                                       operands[2], operands[3]));
16690   else
16691     {
16692       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16693       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16694                                                   operands[2], operands[3],
16695                                                   operands[4]));
16696     }
16697   DONE;
16698 }
16699   [(set_attr "type" "fistp")
16700    (set_attr "i387_cw" "floor")
16701    (set_attr "mode" "<MODE>")])
16702
16703 (define_insn "fistdi2_floor"
16704   [(set (match_operand:DI 0 "memory_operand" "=m")
16705         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16706          UNSPEC_FIST_FLOOR))
16707    (use (match_operand:HI 2 "memory_operand" "m"))
16708    (use (match_operand:HI 3 "memory_operand" "m"))
16709    (clobber (match_scratch:XF 4 "=&1f"))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations"
16712   "* return output_fix_trunc (insn, operands, 0);"
16713   [(set_attr "type" "fistp")
16714    (set_attr "i387_cw" "floor")
16715    (set_attr "mode" "DI")])
16716
16717 (define_insn "fistdi2_floor_with_temp"
16718   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16719         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16720          UNSPEC_FIST_FLOOR))
16721    (use (match_operand:HI 2 "memory_operand" "m,m"))
16722    (use (match_operand:HI 3 "memory_operand" "m,m"))
16723    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16724    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && flag_unsafe_math_optimizations"
16727   "#"
16728   [(set_attr "type" "fistp")
16729    (set_attr "i387_cw" "floor")
16730    (set_attr "mode" "DI")])
16731
16732 (define_split 
16733   [(set (match_operand:DI 0 "register_operand" "")
16734         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16735          UNSPEC_FIST_FLOOR))
16736    (use (match_operand:HI 2 "memory_operand" ""))
16737    (use (match_operand:HI 3 "memory_operand" ""))
16738    (clobber (match_operand:DI 4 "memory_operand" ""))
16739    (clobber (match_scratch 5 ""))]
16740   "reload_completed"
16741   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16742               (use (match_dup 2))
16743               (use (match_dup 3))
16744               (clobber (match_dup 5))])
16745    (set (match_dup 0) (match_dup 4))]
16746   "")
16747
16748 (define_split 
16749   [(set (match_operand:DI 0 "memory_operand" "")
16750         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16751          UNSPEC_FIST_FLOOR))
16752    (use (match_operand:HI 2 "memory_operand" ""))
16753    (use (match_operand:HI 3 "memory_operand" ""))
16754    (clobber (match_operand:DI 4 "memory_operand" ""))
16755    (clobber (match_scratch 5 ""))]
16756   "reload_completed"
16757   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16758               (use (match_dup 2))
16759               (use (match_dup 3))
16760               (clobber (match_dup 5))])]
16761   "")
16762
16763 (define_insn "fist<mode>2_floor"
16764   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16765         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16766          UNSPEC_FIST_FLOOR))
16767    (use (match_operand:HI 2 "memory_operand" "m"))
16768    (use (match_operand:HI 3 "memory_operand" "m"))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && flag_unsafe_math_optimizations"
16771   "* return output_fix_trunc (insn, operands, 0);"
16772   [(set_attr "type" "fistp")
16773    (set_attr "i387_cw" "floor")
16774    (set_attr "mode" "<MODE>")])
16775
16776 (define_insn "fist<mode>2_floor_with_temp"
16777   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16778         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16779          UNSPEC_FIST_FLOOR))
16780    (use (match_operand:HI 2 "memory_operand" "m,m"))
16781    (use (match_operand:HI 3 "memory_operand" "m,m"))
16782    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16783   "TARGET_USE_FANCY_MATH_387
16784    && flag_unsafe_math_optimizations"
16785   "#"
16786   [(set_attr "type" "fistp")
16787    (set_attr "i387_cw" "floor")
16788    (set_attr "mode" "<MODE>")])
16789
16790 (define_split 
16791   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16792         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16793          UNSPEC_FIST_FLOOR))
16794    (use (match_operand:HI 2 "memory_operand" ""))
16795    (use (match_operand:HI 3 "memory_operand" ""))
16796    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16797   "reload_completed"
16798   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16799                                   UNSPEC_FIST_FLOOR))
16800               (use (match_dup 2))
16801               (use (match_dup 3))])
16802    (set (match_dup 0) (match_dup 4))]
16803   "")
16804
16805 (define_split 
16806   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16807         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16808          UNSPEC_FIST_FLOOR))
16809    (use (match_operand:HI 2 "memory_operand" ""))
16810    (use (match_operand:HI 3 "memory_operand" ""))
16811    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16812   "reload_completed"
16813   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16814                                   UNSPEC_FIST_FLOOR))
16815               (use (match_dup 2))
16816               (use (match_dup 3))])]
16817   "")
16818
16819 (define_expand "lfloor<mode>2"
16820   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16821                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16822                     UNSPEC_FIST_FLOOR))
16823               (clobber (reg:CC FLAGS_REG))])]
16824   "TARGET_USE_FANCY_MATH_387
16825    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16826    && flag_unsafe_math_optimizations"
16827   "")
16828
16829 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16830 (define_insn_and_split "frndintxf2_ceil"
16831   [(set (match_operand:XF 0 "register_operand" "=f")
16832         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16833          UNSPEC_FRNDINT_CEIL))
16834    (clobber (reg:CC FLAGS_REG))]
16835   "TARGET_USE_FANCY_MATH_387
16836    && flag_unsafe_math_optimizations
16837    && !(reload_completed || reload_in_progress)"
16838   "#"
16839   "&& 1"
16840   [(const_int 0)]
16841 {
16842   ix86_optimize_mode_switching[I387_CEIL] = 1;
16843
16844   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16845   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16846
16847   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16848                                        operands[2], operands[3]));
16849   DONE;
16850 }
16851   [(set_attr "type" "frndint")
16852    (set_attr "i387_cw" "ceil")
16853    (set_attr "mode" "XF")])
16854
16855 (define_insn "frndintxf2_ceil_i387"
16856   [(set (match_operand:XF 0 "register_operand" "=f")
16857         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16858          UNSPEC_FRNDINT_CEIL))
16859    (use (match_operand:HI 2 "memory_operand" "m"))
16860    (use (match_operand:HI 3 "memory_operand" "m"))]
16861   "TARGET_USE_FANCY_MATH_387
16862    && flag_unsafe_math_optimizations"
16863   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16864   [(set_attr "type" "frndint")
16865    (set_attr "i387_cw" "ceil")
16866    (set_attr "mode" "XF")])
16867
16868 (define_expand "ceilxf2"
16869   [(use (match_operand:XF 0 "register_operand" ""))
16870    (use (match_operand:XF 1 "register_operand" ""))]
16871   "TARGET_USE_FANCY_MATH_387
16872    && flag_unsafe_math_optimizations"
16873 {
16874   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16875   DONE;
16876 })
16877
16878 (define_expand "ceildf2"
16879   [(use (match_operand:DF 0 "register_operand" ""))
16880    (use (match_operand:DF 1 "register_operand" ""))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16883    && flag_unsafe_math_optimizations"
16884 {
16885   rtx op0 = gen_reg_rtx (XFmode);
16886   rtx op1 = gen_reg_rtx (XFmode);
16887
16888   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16889   emit_insn (gen_frndintxf2_ceil (op0, op1));
16890
16891   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16892   DONE;
16893 })
16894
16895 (define_expand "ceilsf2"
16896   [(use (match_operand:SF 0 "register_operand" ""))
16897    (use (match_operand:SF 1 "register_operand" ""))]
16898   "TARGET_USE_FANCY_MATH_387
16899    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16900    && flag_unsafe_math_optimizations"
16901 {
16902   rtx op0 = gen_reg_rtx (XFmode);
16903   rtx op1 = gen_reg_rtx (XFmode);
16904
16905   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16906   emit_insn (gen_frndintxf2_ceil (op0, op1));
16907
16908   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16909   DONE;
16910 })
16911
16912 (define_insn_and_split "*fist<mode>2_ceil_1"
16913   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16914         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16915          UNSPEC_FIST_CEIL))
16916    (clobber (reg:CC FLAGS_REG))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && flag_unsafe_math_optimizations
16919    && !(reload_completed || reload_in_progress)"
16920   "#"
16921   "&& 1"
16922   [(const_int 0)]
16923 {
16924   ix86_optimize_mode_switching[I387_CEIL] = 1;
16925
16926   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16927   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16928   if (memory_operand (operands[0], VOIDmode))
16929     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16930                                      operands[2], operands[3]));
16931   else
16932     {
16933       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16934       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16935                                                  operands[2], operands[3],
16936                                                  operands[4]));
16937     }
16938   DONE;
16939 }
16940   [(set_attr "type" "fistp")
16941    (set_attr "i387_cw" "ceil")
16942    (set_attr "mode" "<MODE>")])
16943
16944 (define_insn "fistdi2_ceil"
16945   [(set (match_operand:DI 0 "memory_operand" "=m")
16946         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16947          UNSPEC_FIST_CEIL))
16948    (use (match_operand:HI 2 "memory_operand" "m"))
16949    (use (match_operand:HI 3 "memory_operand" "m"))
16950    (clobber (match_scratch:XF 4 "=&1f"))]
16951   "TARGET_USE_FANCY_MATH_387
16952    && flag_unsafe_math_optimizations"
16953   "* return output_fix_trunc (insn, operands, 0);"
16954   [(set_attr "type" "fistp")
16955    (set_attr "i387_cw" "ceil")
16956    (set_attr "mode" "DI")])
16957
16958 (define_insn "fistdi2_ceil_with_temp"
16959   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16960         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16961          UNSPEC_FIST_CEIL))
16962    (use (match_operand:HI 2 "memory_operand" "m,m"))
16963    (use (match_operand:HI 3 "memory_operand" "m,m"))
16964    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16965    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16966   "TARGET_USE_FANCY_MATH_387
16967    && flag_unsafe_math_optimizations"
16968   "#"
16969   [(set_attr "type" "fistp")
16970    (set_attr "i387_cw" "ceil")
16971    (set_attr "mode" "DI")])
16972
16973 (define_split 
16974   [(set (match_operand:DI 0 "register_operand" "")
16975         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16976          UNSPEC_FIST_CEIL))
16977    (use (match_operand:HI 2 "memory_operand" ""))
16978    (use (match_operand:HI 3 "memory_operand" ""))
16979    (clobber (match_operand:DI 4 "memory_operand" ""))
16980    (clobber (match_scratch 5 ""))]
16981   "reload_completed"
16982   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16983               (use (match_dup 2))
16984               (use (match_dup 3))
16985               (clobber (match_dup 5))])
16986    (set (match_dup 0) (match_dup 4))]
16987   "")
16988
16989 (define_split 
16990   [(set (match_operand:DI 0 "memory_operand" "")
16991         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16992          UNSPEC_FIST_CEIL))
16993    (use (match_operand:HI 2 "memory_operand" ""))
16994    (use (match_operand:HI 3 "memory_operand" ""))
16995    (clobber (match_operand:DI 4 "memory_operand" ""))
16996    (clobber (match_scratch 5 ""))]
16997   "reload_completed"
16998   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16999               (use (match_dup 2))
17000               (use (match_dup 3))
17001               (clobber (match_dup 5))])]
17002   "")
17003
17004 (define_insn "fist<mode>2_ceil"
17005   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17006         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17007          UNSPEC_FIST_CEIL))
17008    (use (match_operand:HI 2 "memory_operand" "m"))
17009    (use (match_operand:HI 3 "memory_operand" "m"))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && flag_unsafe_math_optimizations"
17012   "* return output_fix_trunc (insn, operands, 0);"
17013   [(set_attr "type" "fistp")
17014    (set_attr "i387_cw" "ceil")
17015    (set_attr "mode" "<MODE>")])
17016
17017 (define_insn "fist<mode>2_ceil_with_temp"
17018   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17019         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17020          UNSPEC_FIST_CEIL))
17021    (use (match_operand:HI 2 "memory_operand" "m,m"))
17022    (use (match_operand:HI 3 "memory_operand" "m,m"))
17023    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17024   "TARGET_USE_FANCY_MATH_387
17025    && flag_unsafe_math_optimizations"
17026   "#"
17027   [(set_attr "type" "fistp")
17028    (set_attr "i387_cw" "ceil")
17029    (set_attr "mode" "<MODE>")])
17030
17031 (define_split 
17032   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17033         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17034          UNSPEC_FIST_CEIL))
17035    (use (match_operand:HI 2 "memory_operand" ""))
17036    (use (match_operand:HI 3 "memory_operand" ""))
17037    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17038   "reload_completed"
17039   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17040                                   UNSPEC_FIST_CEIL))
17041               (use (match_dup 2))
17042               (use (match_dup 3))])
17043    (set (match_dup 0) (match_dup 4))]
17044   "")
17045
17046 (define_split 
17047   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17048         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17049          UNSPEC_FIST_CEIL))
17050    (use (match_operand:HI 2 "memory_operand" ""))
17051    (use (match_operand:HI 3 "memory_operand" ""))
17052    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17053   "reload_completed"
17054   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17055                                   UNSPEC_FIST_CEIL))
17056               (use (match_dup 2))
17057               (use (match_dup 3))])]
17058   "")
17059
17060 (define_expand "lceil<mode>2"
17061   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17062                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17063                     UNSPEC_FIST_CEIL))
17064               (clobber (reg:CC FLAGS_REG))])]
17065   "TARGET_USE_FANCY_MATH_387
17066    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17067    && flag_unsafe_math_optimizations"
17068   "")
17069
17070 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17071 (define_insn_and_split "frndintxf2_trunc"
17072   [(set (match_operand:XF 0 "register_operand" "=f")
17073         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17074          UNSPEC_FRNDINT_TRUNC))
17075    (clobber (reg:CC FLAGS_REG))]
17076   "TARGET_USE_FANCY_MATH_387
17077    && flag_unsafe_math_optimizations
17078    && !(reload_completed || reload_in_progress)"
17079   "#"
17080   "&& 1"
17081   [(const_int 0)]
17082 {
17083   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17084
17085   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17086   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17087
17088   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17089                                         operands[2], operands[3]));
17090   DONE;
17091 }
17092   [(set_attr "type" "frndint")
17093    (set_attr "i387_cw" "trunc")
17094    (set_attr "mode" "XF")])
17095
17096 (define_insn "frndintxf2_trunc_i387"
17097   [(set (match_operand:XF 0 "register_operand" "=f")
17098         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17099          UNSPEC_FRNDINT_TRUNC))
17100    (use (match_operand:HI 2 "memory_operand" "m"))
17101    (use (match_operand:HI 3 "memory_operand" "m"))]
17102   "TARGET_USE_FANCY_MATH_387
17103    && flag_unsafe_math_optimizations"
17104   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17105   [(set_attr "type" "frndint")
17106    (set_attr "i387_cw" "trunc")
17107    (set_attr "mode" "XF")])
17108
17109 (define_expand "btruncxf2"
17110   [(use (match_operand:XF 0 "register_operand" ""))
17111    (use (match_operand:XF 1 "register_operand" ""))]
17112   "TARGET_USE_FANCY_MATH_387
17113    && flag_unsafe_math_optimizations"
17114 {
17115   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17116   DONE;
17117 })
17118
17119 (define_expand "btruncdf2"
17120   [(use (match_operand:DF 0 "register_operand" ""))
17121    (use (match_operand:DF 1 "register_operand" ""))]
17122   "TARGET_USE_FANCY_MATH_387
17123    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17124    && flag_unsafe_math_optimizations"
17125 {
17126   rtx op0 = gen_reg_rtx (XFmode);
17127   rtx op1 = gen_reg_rtx (XFmode);
17128
17129   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17130   emit_insn (gen_frndintxf2_trunc (op0, op1));
17131
17132   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17133   DONE;
17134 })
17135
17136 (define_expand "btruncsf2"
17137   [(use (match_operand:SF 0 "register_operand" ""))
17138    (use (match_operand:SF 1 "register_operand" ""))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17141    && flag_unsafe_math_optimizations"
17142 {
17143   rtx op0 = gen_reg_rtx (XFmode);
17144   rtx op1 = gen_reg_rtx (XFmode);
17145
17146   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17147   emit_insn (gen_frndintxf2_trunc (op0, op1));
17148
17149   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17150   DONE;
17151 })
17152
17153 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17154 (define_insn_and_split "frndintxf2_mask_pm"
17155   [(set (match_operand:XF 0 "register_operand" "=f")
17156         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17157          UNSPEC_FRNDINT_MASK_PM))
17158    (clobber (reg:CC FLAGS_REG))]
17159   "TARGET_USE_FANCY_MATH_387
17160    && flag_unsafe_math_optimizations
17161    && !(reload_completed || reload_in_progress)"
17162   "#"
17163   "&& 1"
17164   [(const_int 0)]
17165 {
17166   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17167
17168   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17169   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17170
17171   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17172                                           operands[2], operands[3]));
17173   DONE;
17174 }
17175   [(set_attr "type" "frndint")
17176    (set_attr "i387_cw" "mask_pm")
17177    (set_attr "mode" "XF")])
17178
17179 (define_insn "frndintxf2_mask_pm_i387"
17180   [(set (match_operand:XF 0 "register_operand" "=f")
17181         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17182          UNSPEC_FRNDINT_MASK_PM))
17183    (use (match_operand:HI 2 "memory_operand" "m"))
17184    (use (match_operand:HI 3 "memory_operand" "m"))]
17185   "TARGET_USE_FANCY_MATH_387
17186    && flag_unsafe_math_optimizations"
17187   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17188   [(set_attr "type" "frndint")
17189    (set_attr "i387_cw" "mask_pm")
17190    (set_attr "mode" "XF")])
17191
17192 (define_expand "nearbyintxf2"
17193   [(use (match_operand:XF 0 "register_operand" ""))
17194    (use (match_operand:XF 1 "register_operand" ""))]
17195   "TARGET_USE_FANCY_MATH_387
17196    && flag_unsafe_math_optimizations"
17197 {
17198   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17199
17200   DONE;
17201 })
17202
17203 (define_expand "nearbyintdf2"
17204   [(use (match_operand:DF 0 "register_operand" ""))
17205    (use (match_operand:DF 1 "register_operand" ""))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17208    && flag_unsafe_math_optimizations"
17209 {
17210   rtx op0 = gen_reg_rtx (XFmode);
17211   rtx op1 = gen_reg_rtx (XFmode);
17212
17213   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17214   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17215
17216   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17217   DONE;
17218 })
17219
17220 (define_expand "nearbyintsf2"
17221   [(use (match_operand:SF 0 "register_operand" ""))
17222    (use (match_operand:SF 1 "register_operand" ""))]
17223   "TARGET_USE_FANCY_MATH_387
17224    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17225    && flag_unsafe_math_optimizations"
17226 {
17227   rtx op0 = gen_reg_rtx (XFmode);
17228   rtx op1 = gen_reg_rtx (XFmode);
17229
17230   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17231   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17232
17233   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17234   DONE;
17235 })
17236
17237 \f
17238 ;; Block operation instructions
17239
17240 (define_insn "cld"
17241  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17242  ""
17243  "cld"
17244   [(set_attr "type" "cld")])
17245
17246 (define_expand "movmemsi"
17247   [(use (match_operand:BLK 0 "memory_operand" ""))
17248    (use (match_operand:BLK 1 "memory_operand" ""))
17249    (use (match_operand:SI 2 "nonmemory_operand" ""))
17250    (use (match_operand:SI 3 "const_int_operand" ""))]
17251   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17252 {
17253  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17254    DONE;
17255  else
17256    FAIL;
17257 })
17258
17259 (define_expand "movmemdi"
17260   [(use (match_operand:BLK 0 "memory_operand" ""))
17261    (use (match_operand:BLK 1 "memory_operand" ""))
17262    (use (match_operand:DI 2 "nonmemory_operand" ""))
17263    (use (match_operand:DI 3 "const_int_operand" ""))]
17264   "TARGET_64BIT"
17265 {
17266  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17267    DONE;
17268  else
17269    FAIL;
17270 })
17271
17272 ;; Most CPUs don't like single string operations
17273 ;; Handle this case here to simplify previous expander.
17274
17275 (define_expand "strmov"
17276   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17277    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17278    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17279               (clobber (reg:CC FLAGS_REG))])
17280    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17281               (clobber (reg:CC FLAGS_REG))])]
17282   ""
17283 {
17284   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17285
17286   /* If .md ever supports :P for Pmode, these can be directly
17287      in the pattern above.  */
17288   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17289   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17290
17291   if (TARGET_SINGLE_STRINGOP || optimize_size)
17292     {
17293       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17294                                       operands[2], operands[3],
17295                                       operands[5], operands[6]));
17296       DONE;
17297     }
17298
17299   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17300 })
17301
17302 (define_expand "strmov_singleop"
17303   [(parallel [(set (match_operand 1 "memory_operand" "")
17304                    (match_operand 3 "memory_operand" ""))
17305               (set (match_operand 0 "register_operand" "")
17306                    (match_operand 4 "" ""))
17307               (set (match_operand 2 "register_operand" "")
17308                    (match_operand 5 "" ""))
17309               (use (reg:SI DIRFLAG_REG))])]
17310   "TARGET_SINGLE_STRINGOP || optimize_size"
17311   "")
17312
17313 (define_insn "*strmovdi_rex_1"
17314   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17315         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17316    (set (match_operand:DI 0 "register_operand" "=D")
17317         (plus:DI (match_dup 2)
17318                  (const_int 8)))
17319    (set (match_operand:DI 1 "register_operand" "=S")
17320         (plus:DI (match_dup 3)
17321                  (const_int 8)))
17322    (use (reg:SI DIRFLAG_REG))]
17323   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17324   "movsq"
17325   [(set_attr "type" "str")
17326    (set_attr "mode" "DI")
17327    (set_attr "memory" "both")])
17328
17329 (define_insn "*strmovsi_1"
17330   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17331         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17332    (set (match_operand:SI 0 "register_operand" "=D")
17333         (plus:SI (match_dup 2)
17334                  (const_int 4)))
17335    (set (match_operand:SI 1 "register_operand" "=S")
17336         (plus:SI (match_dup 3)
17337                  (const_int 4)))
17338    (use (reg:SI DIRFLAG_REG))]
17339   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17340   "{movsl|movsd}"
17341   [(set_attr "type" "str")
17342    (set_attr "mode" "SI")
17343    (set_attr "memory" "both")])
17344
17345 (define_insn "*strmovsi_rex_1"
17346   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17347         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17348    (set (match_operand:DI 0 "register_operand" "=D")
17349         (plus:DI (match_dup 2)
17350                  (const_int 4)))
17351    (set (match_operand:DI 1 "register_operand" "=S")
17352         (plus:DI (match_dup 3)
17353                  (const_int 4)))
17354    (use (reg:SI DIRFLAG_REG))]
17355   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17356   "{movsl|movsd}"
17357   [(set_attr "type" "str")
17358    (set_attr "mode" "SI")
17359    (set_attr "memory" "both")])
17360
17361 (define_insn "*strmovhi_1"
17362   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17363         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17364    (set (match_operand:SI 0 "register_operand" "=D")
17365         (plus:SI (match_dup 2)
17366                  (const_int 2)))
17367    (set (match_operand:SI 1 "register_operand" "=S")
17368         (plus:SI (match_dup 3)
17369                  (const_int 2)))
17370    (use (reg:SI DIRFLAG_REG))]
17371   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17372   "movsw"
17373   [(set_attr "type" "str")
17374    (set_attr "memory" "both")
17375    (set_attr "mode" "HI")])
17376
17377 (define_insn "*strmovhi_rex_1"
17378   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17379         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17380    (set (match_operand:DI 0 "register_operand" "=D")
17381         (plus:DI (match_dup 2)
17382                  (const_int 2)))
17383    (set (match_operand:DI 1 "register_operand" "=S")
17384         (plus:DI (match_dup 3)
17385                  (const_int 2)))
17386    (use (reg:SI DIRFLAG_REG))]
17387   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17388   "movsw"
17389   [(set_attr "type" "str")
17390    (set_attr "memory" "both")
17391    (set_attr "mode" "HI")])
17392
17393 (define_insn "*strmovqi_1"
17394   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17395         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17396    (set (match_operand:SI 0 "register_operand" "=D")
17397         (plus:SI (match_dup 2)
17398                  (const_int 1)))
17399    (set (match_operand:SI 1 "register_operand" "=S")
17400         (plus:SI (match_dup 3)
17401                  (const_int 1)))
17402    (use (reg:SI DIRFLAG_REG))]
17403   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17404   "movsb"
17405   [(set_attr "type" "str")
17406    (set_attr "memory" "both")
17407    (set_attr "mode" "QI")])
17408
17409 (define_insn "*strmovqi_rex_1"
17410   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17411         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17412    (set (match_operand:DI 0 "register_operand" "=D")
17413         (plus:DI (match_dup 2)
17414                  (const_int 1)))
17415    (set (match_operand:DI 1 "register_operand" "=S")
17416         (plus:DI (match_dup 3)
17417                  (const_int 1)))
17418    (use (reg:SI DIRFLAG_REG))]
17419   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17420   "movsb"
17421   [(set_attr "type" "str")
17422    (set_attr "memory" "both")
17423    (set_attr "mode" "QI")])
17424
17425 (define_expand "rep_mov"
17426   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17427               (set (match_operand 0 "register_operand" "")
17428                    (match_operand 5 "" ""))
17429               (set (match_operand 2 "register_operand" "")
17430                    (match_operand 6 "" ""))
17431               (set (match_operand 1 "memory_operand" "")
17432                    (match_operand 3 "memory_operand" ""))
17433               (use (match_dup 4))
17434               (use (reg:SI DIRFLAG_REG))])]
17435   ""
17436   "")
17437
17438 (define_insn "*rep_movdi_rex64"
17439   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17440    (set (match_operand:DI 0 "register_operand" "=D") 
17441         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17442                             (const_int 3))
17443                  (match_operand:DI 3 "register_operand" "0")))
17444    (set (match_operand:DI 1 "register_operand" "=S") 
17445         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17446                  (match_operand:DI 4 "register_operand" "1")))
17447    (set (mem:BLK (match_dup 3))
17448         (mem:BLK (match_dup 4)))
17449    (use (match_dup 5))
17450    (use (reg:SI DIRFLAG_REG))]
17451   "TARGET_64BIT"
17452   "{rep\;movsq|rep movsq}"
17453   [(set_attr "type" "str")
17454    (set_attr "prefix_rep" "1")
17455    (set_attr "memory" "both")
17456    (set_attr "mode" "DI")])
17457
17458 (define_insn "*rep_movsi"
17459   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17460    (set (match_operand:SI 0 "register_operand" "=D") 
17461         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17462                             (const_int 2))
17463                  (match_operand:SI 3 "register_operand" "0")))
17464    (set (match_operand:SI 1 "register_operand" "=S") 
17465         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17466                  (match_operand:SI 4 "register_operand" "1")))
17467    (set (mem:BLK (match_dup 3))
17468         (mem:BLK (match_dup 4)))
17469    (use (match_dup 5))
17470    (use (reg:SI DIRFLAG_REG))]
17471   "!TARGET_64BIT"
17472   "{rep\;movsl|rep movsd}"
17473   [(set_attr "type" "str")
17474    (set_attr "prefix_rep" "1")
17475    (set_attr "memory" "both")
17476    (set_attr "mode" "SI")])
17477
17478 (define_insn "*rep_movsi_rex64"
17479   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17480    (set (match_operand:DI 0 "register_operand" "=D") 
17481         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17482                             (const_int 2))
17483                  (match_operand:DI 3 "register_operand" "0")))
17484    (set (match_operand:DI 1 "register_operand" "=S") 
17485         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17486                  (match_operand:DI 4 "register_operand" "1")))
17487    (set (mem:BLK (match_dup 3))
17488         (mem:BLK (match_dup 4)))
17489    (use (match_dup 5))
17490    (use (reg:SI DIRFLAG_REG))]
17491   "TARGET_64BIT"
17492   "{rep\;movsl|rep movsd}"
17493   [(set_attr "type" "str")
17494    (set_attr "prefix_rep" "1")
17495    (set_attr "memory" "both")
17496    (set_attr "mode" "SI")])
17497
17498 (define_insn "*rep_movqi"
17499   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17500    (set (match_operand:SI 0 "register_operand" "=D") 
17501         (plus:SI (match_operand:SI 3 "register_operand" "0")
17502                  (match_operand:SI 5 "register_operand" "2")))
17503    (set (match_operand:SI 1 "register_operand" "=S") 
17504         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17505    (set (mem:BLK (match_dup 3))
17506         (mem:BLK (match_dup 4)))
17507    (use (match_dup 5))
17508    (use (reg:SI DIRFLAG_REG))]
17509   "!TARGET_64BIT"
17510   "{rep\;movsb|rep movsb}"
17511   [(set_attr "type" "str")
17512    (set_attr "prefix_rep" "1")
17513    (set_attr "memory" "both")
17514    (set_attr "mode" "SI")])
17515
17516 (define_insn "*rep_movqi_rex64"
17517   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17518    (set (match_operand:DI 0 "register_operand" "=D") 
17519         (plus:DI (match_operand:DI 3 "register_operand" "0")
17520                  (match_operand:DI 5 "register_operand" "2")))
17521    (set (match_operand:DI 1 "register_operand" "=S") 
17522         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17523    (set (mem:BLK (match_dup 3))
17524         (mem:BLK (match_dup 4)))
17525    (use (match_dup 5))
17526    (use (reg:SI DIRFLAG_REG))]
17527   "TARGET_64BIT"
17528   "{rep\;movsb|rep movsb}"
17529   [(set_attr "type" "str")
17530    (set_attr "prefix_rep" "1")
17531    (set_attr "memory" "both")
17532    (set_attr "mode" "SI")])
17533
17534 (define_expand "setmemsi"
17535    [(use (match_operand:BLK 0 "memory_operand" ""))
17536     (use (match_operand:SI 1 "nonmemory_operand" ""))
17537     (use (match_operand 2 "const_int_operand" ""))
17538     (use (match_operand 3 "const_int_operand" ""))]
17539   ""
17540 {
17541  /* If value to set is not zero, use the library routine.  */
17542  if (operands[2] != const0_rtx)
17543    FAIL;
17544
17545  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17546    DONE;
17547  else
17548    FAIL;
17549 })
17550
17551 (define_expand "setmemdi"
17552    [(use (match_operand:BLK 0 "memory_operand" ""))
17553     (use (match_operand:DI 1 "nonmemory_operand" ""))
17554     (use (match_operand 2 "const_int_operand" ""))
17555     (use (match_operand 3 "const_int_operand" ""))]
17556   "TARGET_64BIT"
17557 {
17558  /* If value to set is not zero, use the library routine.  */
17559  if (operands[2] != const0_rtx)
17560    FAIL;
17561
17562  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17563    DONE;
17564  else
17565    FAIL;
17566 })
17567
17568 ;; Most CPUs don't like single string operations
17569 ;; Handle this case here to simplify previous expander.
17570
17571 (define_expand "strset"
17572   [(set (match_operand 1 "memory_operand" "")
17573         (match_operand 2 "register_operand" ""))
17574    (parallel [(set (match_operand 0 "register_operand" "")
17575                    (match_dup 3))
17576               (clobber (reg:CC FLAGS_REG))])]
17577   ""
17578 {
17579   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17580     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17581
17582   /* If .md ever supports :P for Pmode, this can be directly
17583      in the pattern above.  */
17584   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17585                               GEN_INT (GET_MODE_SIZE (GET_MODE
17586                                                       (operands[2]))));
17587   if (TARGET_SINGLE_STRINGOP || optimize_size)
17588     {
17589       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17590                                       operands[3]));
17591       DONE;
17592     }
17593 })
17594
17595 (define_expand "strset_singleop"
17596   [(parallel [(set (match_operand 1 "memory_operand" "")
17597                    (match_operand 2 "register_operand" ""))
17598               (set (match_operand 0 "register_operand" "")
17599                    (match_operand 3 "" ""))
17600               (use (reg:SI DIRFLAG_REG))])]
17601   "TARGET_SINGLE_STRINGOP || optimize_size"
17602   "")
17603
17604 (define_insn "*strsetdi_rex_1"
17605   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17606         (match_operand:DI 2 "register_operand" "a"))
17607    (set (match_operand:DI 0 "register_operand" "=D")
17608         (plus:DI (match_dup 1)
17609                  (const_int 8)))
17610    (use (reg:SI DIRFLAG_REG))]
17611   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17612   "stosq"
17613   [(set_attr "type" "str")
17614    (set_attr "memory" "store")
17615    (set_attr "mode" "DI")])
17616
17617 (define_insn "*strsetsi_1"
17618   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17619         (match_operand:SI 2 "register_operand" "a"))
17620    (set (match_operand:SI 0 "register_operand" "=D")
17621         (plus:SI (match_dup 1)
17622                  (const_int 4)))
17623    (use (reg:SI DIRFLAG_REG))]
17624   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17625   "{stosl|stosd}"
17626   [(set_attr "type" "str")
17627    (set_attr "memory" "store")
17628    (set_attr "mode" "SI")])
17629
17630 (define_insn "*strsetsi_rex_1"
17631   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17632         (match_operand:SI 2 "register_operand" "a"))
17633    (set (match_operand:DI 0 "register_operand" "=D")
17634         (plus:DI (match_dup 1)
17635                  (const_int 4)))
17636    (use (reg:SI DIRFLAG_REG))]
17637   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17638   "{stosl|stosd}"
17639   [(set_attr "type" "str")
17640    (set_attr "memory" "store")
17641    (set_attr "mode" "SI")])
17642
17643 (define_insn "*strsethi_1"
17644   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17645         (match_operand:HI 2 "register_operand" "a"))
17646    (set (match_operand:SI 0 "register_operand" "=D")
17647         (plus:SI (match_dup 1)
17648                  (const_int 2)))
17649    (use (reg:SI DIRFLAG_REG))]
17650   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17651   "stosw"
17652   [(set_attr "type" "str")
17653    (set_attr "memory" "store")
17654    (set_attr "mode" "HI")])
17655
17656 (define_insn "*strsethi_rex_1"
17657   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17658         (match_operand:HI 2 "register_operand" "a"))
17659    (set (match_operand:DI 0 "register_operand" "=D")
17660         (plus:DI (match_dup 1)
17661                  (const_int 2)))
17662    (use (reg:SI DIRFLAG_REG))]
17663   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17664   "stosw"
17665   [(set_attr "type" "str")
17666    (set_attr "memory" "store")
17667    (set_attr "mode" "HI")])
17668
17669 (define_insn "*strsetqi_1"
17670   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17671         (match_operand:QI 2 "register_operand" "a"))
17672    (set (match_operand:SI 0 "register_operand" "=D")
17673         (plus:SI (match_dup 1)
17674                  (const_int 1)))
17675    (use (reg:SI DIRFLAG_REG))]
17676   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17677   "stosb"
17678   [(set_attr "type" "str")
17679    (set_attr "memory" "store")
17680    (set_attr "mode" "QI")])
17681
17682 (define_insn "*strsetqi_rex_1"
17683   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17684         (match_operand:QI 2 "register_operand" "a"))
17685    (set (match_operand:DI 0 "register_operand" "=D")
17686         (plus:DI (match_dup 1)
17687                  (const_int 1)))
17688    (use (reg:SI DIRFLAG_REG))]
17689   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17690   "stosb"
17691   [(set_attr "type" "str")
17692    (set_attr "memory" "store")
17693    (set_attr "mode" "QI")])
17694
17695 (define_expand "rep_stos"
17696   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17697               (set (match_operand 0 "register_operand" "")
17698                    (match_operand 4 "" ""))
17699               (set (match_operand 2 "memory_operand" "") (const_int 0))
17700               (use (match_operand 3 "register_operand" ""))
17701               (use (match_dup 1))
17702               (use (reg:SI DIRFLAG_REG))])]
17703   ""
17704   "")
17705
17706 (define_insn "*rep_stosdi_rex64"
17707   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17708    (set (match_operand:DI 0 "register_operand" "=D") 
17709         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17710                             (const_int 3))
17711                  (match_operand:DI 3 "register_operand" "0")))
17712    (set (mem:BLK (match_dup 3))
17713         (const_int 0))
17714    (use (match_operand:DI 2 "register_operand" "a"))
17715    (use (match_dup 4))
17716    (use (reg:SI DIRFLAG_REG))]
17717   "TARGET_64BIT"
17718   "{rep\;stosq|rep stosq}"
17719   [(set_attr "type" "str")
17720    (set_attr "prefix_rep" "1")
17721    (set_attr "memory" "store")
17722    (set_attr "mode" "DI")])
17723
17724 (define_insn "*rep_stossi"
17725   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17726    (set (match_operand:SI 0 "register_operand" "=D") 
17727         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17728                             (const_int 2))
17729                  (match_operand:SI 3 "register_operand" "0")))
17730    (set (mem:BLK (match_dup 3))
17731         (const_int 0))
17732    (use (match_operand:SI 2 "register_operand" "a"))
17733    (use (match_dup 4))
17734    (use (reg:SI DIRFLAG_REG))]
17735   "!TARGET_64BIT"
17736   "{rep\;stosl|rep stosd}"
17737   [(set_attr "type" "str")
17738    (set_attr "prefix_rep" "1")
17739    (set_attr "memory" "store")
17740    (set_attr "mode" "SI")])
17741
17742 (define_insn "*rep_stossi_rex64"
17743   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17744    (set (match_operand:DI 0 "register_operand" "=D") 
17745         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17746                             (const_int 2))
17747                  (match_operand:DI 3 "register_operand" "0")))
17748    (set (mem:BLK (match_dup 3))
17749         (const_int 0))
17750    (use (match_operand:SI 2 "register_operand" "a"))
17751    (use (match_dup 4))
17752    (use (reg:SI DIRFLAG_REG))]
17753   "TARGET_64BIT"
17754   "{rep\;stosl|rep stosd}"
17755   [(set_attr "type" "str")
17756    (set_attr "prefix_rep" "1")
17757    (set_attr "memory" "store")
17758    (set_attr "mode" "SI")])
17759
17760 (define_insn "*rep_stosqi"
17761   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17762    (set (match_operand:SI 0 "register_operand" "=D") 
17763         (plus:SI (match_operand:SI 3 "register_operand" "0")
17764                  (match_operand:SI 4 "register_operand" "1")))
17765    (set (mem:BLK (match_dup 3))
17766         (const_int 0))
17767    (use (match_operand:QI 2 "register_operand" "a"))
17768    (use (match_dup 4))
17769    (use (reg:SI DIRFLAG_REG))]
17770   "!TARGET_64BIT"
17771   "{rep\;stosb|rep stosb}"
17772   [(set_attr "type" "str")
17773    (set_attr "prefix_rep" "1")
17774    (set_attr "memory" "store")
17775    (set_attr "mode" "QI")])
17776
17777 (define_insn "*rep_stosqi_rex64"
17778   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17779    (set (match_operand:DI 0 "register_operand" "=D") 
17780         (plus:DI (match_operand:DI 3 "register_operand" "0")
17781                  (match_operand:DI 4 "register_operand" "1")))
17782    (set (mem:BLK (match_dup 3))
17783         (const_int 0))
17784    (use (match_operand:QI 2 "register_operand" "a"))
17785    (use (match_dup 4))
17786    (use (reg:SI DIRFLAG_REG))]
17787   "TARGET_64BIT"
17788   "{rep\;stosb|rep stosb}"
17789   [(set_attr "type" "str")
17790    (set_attr "prefix_rep" "1")
17791    (set_attr "memory" "store")
17792    (set_attr "mode" "QI")])
17793
17794 (define_expand "cmpstrnsi"
17795   [(set (match_operand:SI 0 "register_operand" "")
17796         (compare:SI (match_operand:BLK 1 "general_operand" "")
17797                     (match_operand:BLK 2 "general_operand" "")))
17798    (use (match_operand 3 "general_operand" ""))
17799    (use (match_operand 4 "immediate_operand" ""))]
17800   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17801 {
17802   rtx addr1, addr2, out, outlow, count, countreg, align;
17803
17804   /* Can't use this if the user has appropriated esi or edi.  */
17805   if (global_regs[4] || global_regs[5])
17806     FAIL;
17807
17808   out = operands[0];
17809   if (GET_CODE (out) != REG)
17810     out = gen_reg_rtx (SImode);
17811
17812   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17813   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17814   if (addr1 != XEXP (operands[1], 0))
17815     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17816   if (addr2 != XEXP (operands[2], 0))
17817     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17818
17819   count = operands[3];
17820   countreg = ix86_zero_extend_to_Pmode (count);
17821
17822   /* %%% Iff we are testing strict equality, we can use known alignment
17823      to good advantage.  This may be possible with combine, particularly
17824      once cc0 is dead.  */
17825   align = operands[4];
17826
17827   emit_insn (gen_cld ());
17828   if (GET_CODE (count) == CONST_INT)
17829     {
17830       if (INTVAL (count) == 0)
17831         {
17832           emit_move_insn (operands[0], const0_rtx);
17833           DONE;
17834         }
17835       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17836                                      operands[1], operands[2]));
17837     }
17838   else
17839     {
17840       if (TARGET_64BIT)
17841         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17842       else
17843         emit_insn (gen_cmpsi_1 (countreg, countreg));
17844       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17845                                   operands[1], operands[2]));
17846     }
17847
17848   outlow = gen_lowpart (QImode, out);
17849   emit_insn (gen_cmpintqi (outlow));
17850   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17851
17852   if (operands[0] != out)
17853     emit_move_insn (operands[0], out);
17854
17855   DONE;
17856 })
17857
17858 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17859
17860 (define_expand "cmpintqi"
17861   [(set (match_dup 1)
17862         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17863    (set (match_dup 2)
17864         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17865    (parallel [(set (match_operand:QI 0 "register_operand" "")
17866                    (minus:QI (match_dup 1)
17867                              (match_dup 2)))
17868               (clobber (reg:CC FLAGS_REG))])]
17869   ""
17870   "operands[1] = gen_reg_rtx (QImode);
17871    operands[2] = gen_reg_rtx (QImode);")
17872
17873 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17874 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17875
17876 (define_expand "cmpstrnqi_nz_1"
17877   [(parallel [(set (reg:CC FLAGS_REG)
17878                    (compare:CC (match_operand 4 "memory_operand" "")
17879                                (match_operand 5 "memory_operand" "")))
17880               (use (match_operand 2 "register_operand" ""))
17881               (use (match_operand:SI 3 "immediate_operand" ""))
17882               (use (reg:SI DIRFLAG_REG))
17883               (clobber (match_operand 0 "register_operand" ""))
17884               (clobber (match_operand 1 "register_operand" ""))
17885               (clobber (match_dup 2))])]
17886   ""
17887   "")
17888
17889 (define_insn "*cmpstrnqi_nz_1"
17890   [(set (reg:CC FLAGS_REG)
17891         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17892                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17893    (use (match_operand:SI 6 "register_operand" "2"))
17894    (use (match_operand:SI 3 "immediate_operand" "i"))
17895    (use (reg:SI DIRFLAG_REG))
17896    (clobber (match_operand:SI 0 "register_operand" "=S"))
17897    (clobber (match_operand:SI 1 "register_operand" "=D"))
17898    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17899   "!TARGET_64BIT"
17900   "repz{\;| }cmpsb"
17901   [(set_attr "type" "str")
17902    (set_attr "mode" "QI")
17903    (set_attr "prefix_rep" "1")])
17904
17905 (define_insn "*cmpstrnqi_nz_rex_1"
17906   [(set (reg:CC FLAGS_REG)
17907         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17908                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17909    (use (match_operand:DI 6 "register_operand" "2"))
17910    (use (match_operand:SI 3 "immediate_operand" "i"))
17911    (use (reg:SI DIRFLAG_REG))
17912    (clobber (match_operand:DI 0 "register_operand" "=S"))
17913    (clobber (match_operand:DI 1 "register_operand" "=D"))
17914    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17915   "TARGET_64BIT"
17916   "repz{\;| }cmpsb"
17917   [(set_attr "type" "str")
17918    (set_attr "mode" "QI")
17919    (set_attr "prefix_rep" "1")])
17920
17921 ;; The same, but the count is not known to not be zero.
17922
17923 (define_expand "cmpstrnqi_1"
17924   [(parallel [(set (reg:CC FLAGS_REG)
17925                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17926                                      (const_int 0))
17927                   (compare:CC (match_operand 4 "memory_operand" "")
17928                               (match_operand 5 "memory_operand" ""))
17929                   (const_int 0)))
17930               (use (match_operand:SI 3 "immediate_operand" ""))
17931               (use (reg:CC FLAGS_REG))
17932               (use (reg:SI DIRFLAG_REG))
17933               (clobber (match_operand 0 "register_operand" ""))
17934               (clobber (match_operand 1 "register_operand" ""))
17935               (clobber (match_dup 2))])]
17936   ""
17937   "")
17938
17939 (define_insn "*cmpstrnqi_1"
17940   [(set (reg:CC FLAGS_REG)
17941         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17942                              (const_int 0))
17943           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17944                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17945           (const_int 0)))
17946    (use (match_operand:SI 3 "immediate_operand" "i"))
17947    (use (reg:CC FLAGS_REG))
17948    (use (reg:SI DIRFLAG_REG))
17949    (clobber (match_operand:SI 0 "register_operand" "=S"))
17950    (clobber (match_operand:SI 1 "register_operand" "=D"))
17951    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17952   "!TARGET_64BIT"
17953   "repz{\;| }cmpsb"
17954   [(set_attr "type" "str")
17955    (set_attr "mode" "QI")
17956    (set_attr "prefix_rep" "1")])
17957
17958 (define_insn "*cmpstrnqi_rex_1"
17959   [(set (reg:CC FLAGS_REG)
17960         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17961                              (const_int 0))
17962           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17963                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17964           (const_int 0)))
17965    (use (match_operand:SI 3 "immediate_operand" "i"))
17966    (use (reg:CC FLAGS_REG))
17967    (use (reg:SI DIRFLAG_REG))
17968    (clobber (match_operand:DI 0 "register_operand" "=S"))
17969    (clobber (match_operand:DI 1 "register_operand" "=D"))
17970    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17971   "TARGET_64BIT"
17972   "repz{\;| }cmpsb"
17973   [(set_attr "type" "str")
17974    (set_attr "mode" "QI")
17975    (set_attr "prefix_rep" "1")])
17976
17977 (define_expand "strlensi"
17978   [(set (match_operand:SI 0 "register_operand" "")
17979         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17980                     (match_operand:QI 2 "immediate_operand" "")
17981                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17982   ""
17983 {
17984  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17985    DONE;
17986  else
17987    FAIL;
17988 })
17989
17990 (define_expand "strlendi"
17991   [(set (match_operand:DI 0 "register_operand" "")
17992         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17993                     (match_operand:QI 2 "immediate_operand" "")
17994                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17995   ""
17996 {
17997  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17998    DONE;
17999  else
18000    FAIL;
18001 })
18002
18003 (define_expand "strlenqi_1"
18004   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18005               (use (reg:SI DIRFLAG_REG))
18006               (clobber (match_operand 1 "register_operand" ""))
18007               (clobber (reg:CC FLAGS_REG))])]
18008   ""
18009   "")
18010
18011 (define_insn "*strlenqi_1"
18012   [(set (match_operand:SI 0 "register_operand" "=&c")
18013         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18014                     (match_operand:QI 2 "register_operand" "a")
18015                     (match_operand:SI 3 "immediate_operand" "i")
18016                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18017    (use (reg:SI DIRFLAG_REG))
18018    (clobber (match_operand:SI 1 "register_operand" "=D"))
18019    (clobber (reg:CC FLAGS_REG))]
18020   "!TARGET_64BIT"
18021   "repnz{\;| }scasb"
18022   [(set_attr "type" "str")
18023    (set_attr "mode" "QI")
18024    (set_attr "prefix_rep" "1")])
18025
18026 (define_insn "*strlenqi_rex_1"
18027   [(set (match_operand:DI 0 "register_operand" "=&c")
18028         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18029                     (match_operand:QI 2 "register_operand" "a")
18030                     (match_operand:DI 3 "immediate_operand" "i")
18031                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18032    (use (reg:SI DIRFLAG_REG))
18033    (clobber (match_operand:DI 1 "register_operand" "=D"))
18034    (clobber (reg:CC FLAGS_REG))]
18035   "TARGET_64BIT"
18036   "repnz{\;| }scasb"
18037   [(set_attr "type" "str")
18038    (set_attr "mode" "QI")
18039    (set_attr "prefix_rep" "1")])
18040
18041 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18042 ;; handled in combine, but it is not currently up to the task.
18043 ;; When used for their truth value, the cmpstrn* expanders generate
18044 ;; code like this:
18045 ;;
18046 ;;   repz cmpsb
18047 ;;   seta       %al
18048 ;;   setb       %dl
18049 ;;   cmpb       %al, %dl
18050 ;;   jcc        label
18051 ;;
18052 ;; The intermediate three instructions are unnecessary.
18053
18054 ;; This one handles cmpstrn*_nz_1...
18055 (define_peephole2
18056   [(parallel[
18057      (set (reg:CC FLAGS_REG)
18058           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18059                       (mem:BLK (match_operand 5 "register_operand" ""))))
18060      (use (match_operand 6 "register_operand" ""))
18061      (use (match_operand:SI 3 "immediate_operand" ""))
18062      (use (reg:SI DIRFLAG_REG))
18063      (clobber (match_operand 0 "register_operand" ""))
18064      (clobber (match_operand 1 "register_operand" ""))
18065      (clobber (match_operand 2 "register_operand" ""))])
18066    (set (match_operand:QI 7 "register_operand" "")
18067         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18068    (set (match_operand:QI 8 "register_operand" "")
18069         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18070    (set (reg FLAGS_REG)
18071         (compare (match_dup 7) (match_dup 8)))
18072   ]
18073   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18074   [(parallel[
18075      (set (reg:CC FLAGS_REG)
18076           (compare:CC (mem:BLK (match_dup 4))
18077                       (mem:BLK (match_dup 5))))
18078      (use (match_dup 6))
18079      (use (match_dup 3))
18080      (use (reg:SI DIRFLAG_REG))
18081      (clobber (match_dup 0))
18082      (clobber (match_dup 1))
18083      (clobber (match_dup 2))])]
18084   "")
18085
18086 ;; ...and this one handles cmpstrn*_1.
18087 (define_peephole2
18088   [(parallel[
18089      (set (reg:CC FLAGS_REG)
18090           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18091                                (const_int 0))
18092             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18093                         (mem:BLK (match_operand 5 "register_operand" "")))
18094             (const_int 0)))
18095      (use (match_operand:SI 3 "immediate_operand" ""))
18096      (use (reg:CC FLAGS_REG))
18097      (use (reg:SI DIRFLAG_REG))
18098      (clobber (match_operand 0 "register_operand" ""))
18099      (clobber (match_operand 1 "register_operand" ""))
18100      (clobber (match_operand 2 "register_operand" ""))])
18101    (set (match_operand:QI 7 "register_operand" "")
18102         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18103    (set (match_operand:QI 8 "register_operand" "")
18104         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18105    (set (reg FLAGS_REG)
18106         (compare (match_dup 7) (match_dup 8)))
18107   ]
18108   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18109   [(parallel[
18110      (set (reg:CC FLAGS_REG)
18111           (if_then_else:CC (ne (match_dup 6)
18112                                (const_int 0))
18113             (compare:CC (mem:BLK (match_dup 4))
18114                         (mem:BLK (match_dup 5)))
18115             (const_int 0)))
18116      (use (match_dup 3))
18117      (use (reg:CC FLAGS_REG))
18118      (use (reg:SI DIRFLAG_REG))
18119      (clobber (match_dup 0))
18120      (clobber (match_dup 1))
18121      (clobber (match_dup 2))])]
18122   "")
18123
18124
18125 \f
18126 ;; Conditional move instructions.
18127
18128 (define_expand "movdicc"
18129   [(set (match_operand:DI 0 "register_operand" "")
18130         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18131                          (match_operand:DI 2 "general_operand" "")
18132                          (match_operand:DI 3 "general_operand" "")))]
18133   "TARGET_64BIT"
18134   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18135
18136 (define_insn "x86_movdicc_0_m1_rex64"
18137   [(set (match_operand:DI 0 "register_operand" "=r")
18138         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18139           (const_int -1)
18140           (const_int 0)))
18141    (clobber (reg:CC FLAGS_REG))]
18142   "TARGET_64BIT"
18143   "sbb{q}\t%0, %0"
18144   ; Since we don't have the proper number of operands for an alu insn,
18145   ; fill in all the blanks.
18146   [(set_attr "type" "alu")
18147    (set_attr "pent_pair" "pu")
18148    (set_attr "memory" "none")
18149    (set_attr "imm_disp" "false")
18150    (set_attr "mode" "DI")
18151    (set_attr "length_immediate" "0")])
18152
18153 (define_insn "*movdicc_c_rex64"
18154   [(set (match_operand:DI 0 "register_operand" "=r,r")
18155         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18156                                 [(reg FLAGS_REG) (const_int 0)])
18157                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18158                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18159   "TARGET_64BIT && TARGET_CMOVE
18160    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18161   "@
18162    cmov%O2%C1\t{%2, %0|%0, %2}
18163    cmov%O2%c1\t{%3, %0|%0, %3}"
18164   [(set_attr "type" "icmov")
18165    (set_attr "mode" "DI")])
18166
18167 (define_expand "movsicc"
18168   [(set (match_operand:SI 0 "register_operand" "")
18169         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18170                          (match_operand:SI 2 "general_operand" "")
18171                          (match_operand:SI 3 "general_operand" "")))]
18172   ""
18173   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18174
18175 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18176 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18177 ;; So just document what we're doing explicitly.
18178
18179 (define_insn "x86_movsicc_0_m1"
18180   [(set (match_operand:SI 0 "register_operand" "=r")
18181         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18182           (const_int -1)
18183           (const_int 0)))
18184    (clobber (reg:CC FLAGS_REG))]
18185   ""
18186   "sbb{l}\t%0, %0"
18187   ; Since we don't have the proper number of operands for an alu insn,
18188   ; fill in all the blanks.
18189   [(set_attr "type" "alu")
18190    (set_attr "pent_pair" "pu")
18191    (set_attr "memory" "none")
18192    (set_attr "imm_disp" "false")
18193    (set_attr "mode" "SI")
18194    (set_attr "length_immediate" "0")])
18195
18196 (define_insn "*movsicc_noc"
18197   [(set (match_operand:SI 0 "register_operand" "=r,r")
18198         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18199                                 [(reg FLAGS_REG) (const_int 0)])
18200                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18201                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18202   "TARGET_CMOVE
18203    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18204   "@
18205    cmov%O2%C1\t{%2, %0|%0, %2}
18206    cmov%O2%c1\t{%3, %0|%0, %3}"
18207   [(set_attr "type" "icmov")
18208    (set_attr "mode" "SI")])
18209
18210 (define_expand "movhicc"
18211   [(set (match_operand:HI 0 "register_operand" "")
18212         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18213                          (match_operand:HI 2 "general_operand" "")
18214                          (match_operand:HI 3 "general_operand" "")))]
18215   "TARGET_HIMODE_MATH"
18216   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18217
18218 (define_insn "*movhicc_noc"
18219   [(set (match_operand:HI 0 "register_operand" "=r,r")
18220         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18221                                 [(reg FLAGS_REG) (const_int 0)])
18222                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18223                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18224   "TARGET_CMOVE
18225    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18226   "@
18227    cmov%O2%C1\t{%2, %0|%0, %2}
18228    cmov%O2%c1\t{%3, %0|%0, %3}"
18229   [(set_attr "type" "icmov")
18230    (set_attr "mode" "HI")])
18231
18232 (define_expand "movqicc"
18233   [(set (match_operand:QI 0 "register_operand" "")
18234         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18235                          (match_operand:QI 2 "general_operand" "")
18236                          (match_operand:QI 3 "general_operand" "")))]
18237   "TARGET_QIMODE_MATH"
18238   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18239
18240 (define_insn_and_split "*movqicc_noc"
18241   [(set (match_operand:QI 0 "register_operand" "=r,r")
18242         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18243                                 [(match_operand 4 "flags_reg_operand" "")
18244                                  (const_int 0)])
18245                       (match_operand:QI 2 "register_operand" "r,0")
18246                       (match_operand:QI 3 "register_operand" "0,r")))]
18247   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18248   "#"
18249   "&& reload_completed"
18250   [(set (match_dup 0)
18251         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18252                       (match_dup 2)
18253                       (match_dup 3)))]
18254   "operands[0] = gen_lowpart (SImode, operands[0]);
18255    operands[2] = gen_lowpart (SImode, operands[2]);
18256    operands[3] = gen_lowpart (SImode, operands[3]);"
18257   [(set_attr "type" "icmov")
18258    (set_attr "mode" "SI")])
18259
18260 (define_expand "movsfcc"
18261   [(set (match_operand:SF 0 "register_operand" "")
18262         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18263                          (match_operand:SF 2 "register_operand" "")
18264                          (match_operand:SF 3 "register_operand" "")))]
18265   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18266   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18267
18268 (define_insn "*movsfcc_1_387"
18269   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18270         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18271                                 [(reg FLAGS_REG) (const_int 0)])
18272                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18273                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18274   "TARGET_80387 && TARGET_CMOVE
18275    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18276   "@
18277    fcmov%F1\t{%2, %0|%0, %2}
18278    fcmov%f1\t{%3, %0|%0, %3}
18279    cmov%O2%C1\t{%2, %0|%0, %2}
18280    cmov%O2%c1\t{%3, %0|%0, %3}"
18281   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18282    (set_attr "mode" "SF,SF,SI,SI")])
18283
18284 (define_expand "movdfcc"
18285   [(set (match_operand:DF 0 "register_operand" "")
18286         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18287                          (match_operand:DF 2 "register_operand" "")
18288                          (match_operand:DF 3 "register_operand" "")))]
18289   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18290   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18291
18292 (define_insn "*movdfcc_1"
18293   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18294         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18295                                 [(reg FLAGS_REG) (const_int 0)])
18296                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18297                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18298   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18299    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18300   "@
18301    fcmov%F1\t{%2, %0|%0, %2}
18302    fcmov%f1\t{%3, %0|%0, %3}
18303    #
18304    #"
18305   [(set_attr "type" "fcmov,fcmov,multi,multi")
18306    (set_attr "mode" "DF")])
18307
18308 (define_insn "*movdfcc_1_rex64"
18309   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18310         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18311                                 [(reg FLAGS_REG) (const_int 0)])
18312                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18313                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18314   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18315    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18316   "@
18317    fcmov%F1\t{%2, %0|%0, %2}
18318    fcmov%f1\t{%3, %0|%0, %3}
18319    cmov%O2%C1\t{%2, %0|%0, %2}
18320    cmov%O2%c1\t{%3, %0|%0, %3}"
18321   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18322    (set_attr "mode" "DF")])
18323
18324 (define_split
18325   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18326         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18327                                 [(match_operand 4 "flags_reg_operand" "")
18328                                  (const_int 0)])
18329                       (match_operand:DF 2 "nonimmediate_operand" "")
18330                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18331   "!TARGET_64BIT && reload_completed"
18332   [(set (match_dup 2)
18333         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18334                       (match_dup 5)
18335                       (match_dup 7)))
18336    (set (match_dup 3)
18337         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18338                       (match_dup 6)
18339                       (match_dup 8)))]
18340   "split_di (operands+2, 1, operands+5, operands+6);
18341    split_di (operands+3, 1, operands+7, operands+8);
18342    split_di (operands, 1, operands+2, operands+3);")
18343
18344 (define_expand "movxfcc"
18345   [(set (match_operand:XF 0 "register_operand" "")
18346         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18347                          (match_operand:XF 2 "register_operand" "")
18348                          (match_operand:XF 3 "register_operand" "")))]
18349   "TARGET_80387 && TARGET_CMOVE"
18350   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18351
18352 (define_insn "*movxfcc_1"
18353   [(set (match_operand:XF 0 "register_operand" "=f,f")
18354         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18355                                 [(reg FLAGS_REG) (const_int 0)])
18356                       (match_operand:XF 2 "register_operand" "f,0")
18357                       (match_operand:XF 3 "register_operand" "0,f")))]
18358   "TARGET_80387 && TARGET_CMOVE"
18359   "@
18360    fcmov%F1\t{%2, %0|%0, %2}
18361    fcmov%f1\t{%3, %0|%0, %3}"
18362   [(set_attr "type" "fcmov")
18363    (set_attr "mode" "XF")])
18364
18365 ;; These versions of the min/max patterns are intentionally ignorant of
18366 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18367 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18368 ;; are undefined in this condition, we're certain this is correct.
18369
18370 (define_insn "sminsf3"
18371   [(set (match_operand:SF 0 "register_operand" "=x")
18372         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18373                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18374   "TARGET_SSE_MATH"
18375   "minss\t{%2, %0|%0, %2}"
18376   [(set_attr "type" "sseadd")
18377    (set_attr "mode" "SF")])
18378
18379 (define_insn "smaxsf3"
18380   [(set (match_operand:SF 0 "register_operand" "=x")
18381         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18382                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18383   "TARGET_SSE_MATH"
18384   "maxss\t{%2, %0|%0, %2}"
18385   [(set_attr "type" "sseadd")
18386    (set_attr "mode" "SF")])
18387
18388 (define_insn "smindf3"
18389   [(set (match_operand:DF 0 "register_operand" "=x")
18390         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18391                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18392   "TARGET_SSE2 && TARGET_SSE_MATH"
18393   "minsd\t{%2, %0|%0, %2}"
18394   [(set_attr "type" "sseadd")
18395    (set_attr "mode" "DF")])
18396
18397 (define_insn "smaxdf3"
18398   [(set (match_operand:DF 0 "register_operand" "=x")
18399         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18400                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18401   "TARGET_SSE2 && TARGET_SSE_MATH"
18402   "maxsd\t{%2, %0|%0, %2}"
18403   [(set_attr "type" "sseadd")
18404    (set_attr "mode" "DF")])
18405
18406 ;; These versions of the min/max patterns implement exactly the operations
18407 ;;   min = (op1 < op2 ? op1 : op2)
18408 ;;   max = (!(op1 < op2) ? op1 : op2)
18409 ;; Their operands are not commutative, and thus they may be used in the
18410 ;; presence of -0.0 and NaN.
18411
18412 (define_insn "*ieee_sminsf3"
18413   [(set (match_operand:SF 0 "register_operand" "=x")
18414         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18415                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18416                    UNSPEC_IEEE_MIN))]
18417   "TARGET_SSE_MATH"
18418   "minss\t{%2, %0|%0, %2}"
18419   [(set_attr "type" "sseadd")
18420    (set_attr "mode" "SF")])
18421
18422 (define_insn "*ieee_smaxsf3"
18423   [(set (match_operand:SF 0 "register_operand" "=x")
18424         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18425                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18426                    UNSPEC_IEEE_MAX))]
18427   "TARGET_SSE_MATH"
18428   "maxss\t{%2, %0|%0, %2}"
18429   [(set_attr "type" "sseadd")
18430    (set_attr "mode" "SF")])
18431
18432 (define_insn "*ieee_smindf3"
18433   [(set (match_operand:DF 0 "register_operand" "=x")
18434         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18435                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18436                    UNSPEC_IEEE_MIN))]
18437   "TARGET_SSE2 && TARGET_SSE_MATH"
18438   "minsd\t{%2, %0|%0, %2}"
18439   [(set_attr "type" "sseadd")
18440    (set_attr "mode" "DF")])
18441
18442 (define_insn "*ieee_smaxdf3"
18443   [(set (match_operand:DF 0 "register_operand" "=x")
18444         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18445                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18446                    UNSPEC_IEEE_MAX))]
18447   "TARGET_SSE2 && TARGET_SSE_MATH"
18448   "maxsd\t{%2, %0|%0, %2}"
18449   [(set_attr "type" "sseadd")
18450    (set_attr "mode" "DF")])
18451
18452 ;; Conditional addition patterns
18453 (define_expand "addqicc"
18454   [(match_operand:QI 0 "register_operand" "")
18455    (match_operand 1 "comparison_operator" "")
18456    (match_operand:QI 2 "register_operand" "")
18457    (match_operand:QI 3 "const_int_operand" "")]
18458   ""
18459   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18460
18461 (define_expand "addhicc"
18462   [(match_operand:HI 0 "register_operand" "")
18463    (match_operand 1 "comparison_operator" "")
18464    (match_operand:HI 2 "register_operand" "")
18465    (match_operand:HI 3 "const_int_operand" "")]
18466   ""
18467   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18468
18469 (define_expand "addsicc"
18470   [(match_operand:SI 0 "register_operand" "")
18471    (match_operand 1 "comparison_operator" "")
18472    (match_operand:SI 2 "register_operand" "")
18473    (match_operand:SI 3 "const_int_operand" "")]
18474   ""
18475   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18476
18477 (define_expand "adddicc"
18478   [(match_operand:DI 0 "register_operand" "")
18479    (match_operand 1 "comparison_operator" "")
18480    (match_operand:DI 2 "register_operand" "")
18481    (match_operand:DI 3 "const_int_operand" "")]
18482   "TARGET_64BIT"
18483   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18484
18485 \f
18486 ;; Misc patterns (?)
18487
18488 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18489 ;; Otherwise there will be nothing to keep
18490 ;; 
18491 ;; [(set (reg ebp) (reg esp))]
18492 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18493 ;;  (clobber (eflags)]
18494 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18495 ;;
18496 ;; in proper program order.
18497 (define_insn "pro_epilogue_adjust_stack_1"
18498   [(set (match_operand:SI 0 "register_operand" "=r,r")
18499         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18500                  (match_operand:SI 2 "immediate_operand" "i,i")))
18501    (clobber (reg:CC FLAGS_REG))
18502    (clobber (mem:BLK (scratch)))]
18503   "!TARGET_64BIT"
18504 {
18505   switch (get_attr_type (insn))
18506     {
18507     case TYPE_IMOV:
18508       return "mov{l}\t{%1, %0|%0, %1}";
18509
18510     case TYPE_ALU:
18511       if (GET_CODE (operands[2]) == CONST_INT
18512           && (INTVAL (operands[2]) == 128
18513               || (INTVAL (operands[2]) < 0
18514                   && INTVAL (operands[2]) != -128)))
18515         {
18516           operands[2] = GEN_INT (-INTVAL (operands[2]));
18517           return "sub{l}\t{%2, %0|%0, %2}";
18518         }
18519       return "add{l}\t{%2, %0|%0, %2}";
18520
18521     case TYPE_LEA:
18522       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18523       return "lea{l}\t{%a2, %0|%0, %a2}";
18524
18525     default:
18526       gcc_unreachable ();
18527     }
18528 }
18529   [(set (attr "type")
18530         (cond [(eq_attr "alternative" "0")
18531                  (const_string "alu")
18532                (match_operand:SI 2 "const0_operand" "")
18533                  (const_string "imov")
18534               ]
18535               (const_string "lea")))
18536    (set_attr "mode" "SI")])
18537
18538 (define_insn "pro_epilogue_adjust_stack_rex64"
18539   [(set (match_operand:DI 0 "register_operand" "=r,r")
18540         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18541                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18542    (clobber (reg:CC FLAGS_REG))
18543    (clobber (mem:BLK (scratch)))]
18544   "TARGET_64BIT"
18545 {
18546   switch (get_attr_type (insn))
18547     {
18548     case TYPE_IMOV:
18549       return "mov{q}\t{%1, %0|%0, %1}";
18550
18551     case TYPE_ALU:
18552       if (GET_CODE (operands[2]) == CONST_INT
18553           /* Avoid overflows.  */
18554           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18555           && (INTVAL (operands[2]) == 128
18556               || (INTVAL (operands[2]) < 0
18557                   && INTVAL (operands[2]) != -128)))
18558         {
18559           operands[2] = GEN_INT (-INTVAL (operands[2]));
18560           return "sub{q}\t{%2, %0|%0, %2}";
18561         }
18562       return "add{q}\t{%2, %0|%0, %2}";
18563
18564     case TYPE_LEA:
18565       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18566       return "lea{q}\t{%a2, %0|%0, %a2}";
18567
18568     default:
18569       gcc_unreachable ();
18570     }
18571 }
18572   [(set (attr "type")
18573         (cond [(eq_attr "alternative" "0")
18574                  (const_string "alu")
18575                (match_operand:DI 2 "const0_operand" "")
18576                  (const_string "imov")
18577               ]
18578               (const_string "lea")))
18579    (set_attr "mode" "DI")])
18580
18581 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18582   [(set (match_operand:DI 0 "register_operand" "=r,r")
18583         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18584                  (match_operand:DI 3 "immediate_operand" "i,i")))
18585    (use (match_operand:DI 2 "register_operand" "r,r"))
18586    (clobber (reg:CC FLAGS_REG))
18587    (clobber (mem:BLK (scratch)))]
18588   "TARGET_64BIT"
18589 {
18590   switch (get_attr_type (insn))
18591     {
18592     case TYPE_ALU:
18593       return "add{q}\t{%2, %0|%0, %2}";
18594
18595     case TYPE_LEA:
18596       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18597       return "lea{q}\t{%a2, %0|%0, %a2}";
18598
18599     default:
18600       gcc_unreachable ();
18601     }
18602 }
18603   [(set_attr "type" "alu,lea")
18604    (set_attr "mode" "DI")])
18605
18606 (define_expand "allocate_stack_worker"
18607   [(match_operand:SI 0 "register_operand" "")]
18608   "TARGET_STACK_PROBE"
18609 {
18610   if (reload_completed)
18611     {
18612       if (TARGET_64BIT)
18613         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18614       else
18615         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18616     }
18617   else
18618     {
18619       if (TARGET_64BIT)
18620         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18621       else
18622         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18623     }
18624   DONE;
18625 })
18626
18627 (define_insn "allocate_stack_worker_1"
18628   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18629     UNSPECV_STACK_PROBE)
18630    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18631    (clobber (match_scratch:SI 1 "=0"))
18632    (clobber (reg:CC FLAGS_REG))]
18633   "!TARGET_64BIT && TARGET_STACK_PROBE"
18634   "call\t__alloca"
18635   [(set_attr "type" "multi")
18636    (set_attr "length" "5")])
18637
18638 (define_expand "allocate_stack_worker_postreload"
18639   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18640                                     UNSPECV_STACK_PROBE)
18641               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18642               (clobber (match_dup 0))
18643               (clobber (reg:CC FLAGS_REG))])]
18644   ""
18645   "")
18646
18647 (define_insn "allocate_stack_worker_rex64"
18648   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18649     UNSPECV_STACK_PROBE)
18650    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18651    (clobber (match_scratch:DI 1 "=0"))
18652    (clobber (reg:CC FLAGS_REG))]
18653   "TARGET_64BIT && TARGET_STACK_PROBE"
18654   "call\t__alloca"
18655   [(set_attr "type" "multi")
18656    (set_attr "length" "5")])
18657
18658 (define_expand "allocate_stack_worker_rex64_postreload"
18659   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18660                                     UNSPECV_STACK_PROBE)
18661               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18662               (clobber (match_dup 0))
18663               (clobber (reg:CC FLAGS_REG))])]
18664   ""
18665   "")
18666
18667 (define_expand "allocate_stack"
18668   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18669                    (minus:SI (reg:SI SP_REG)
18670                              (match_operand:SI 1 "general_operand" "")))
18671               (clobber (reg:CC FLAGS_REG))])
18672    (parallel [(set (reg:SI SP_REG)
18673                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18674               (clobber (reg:CC FLAGS_REG))])]
18675   "TARGET_STACK_PROBE"
18676 {
18677 #ifdef CHECK_STACK_LIMIT
18678   if (GET_CODE (operands[1]) == CONST_INT
18679       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18680     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18681                            operands[1]));
18682   else 
18683 #endif
18684     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18685                                                             operands[1])));
18686
18687   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18688   DONE;
18689 })
18690
18691 (define_expand "builtin_setjmp_receiver"
18692   [(label_ref (match_operand 0 "" ""))]
18693   "!TARGET_64BIT && flag_pic"
18694 {
18695   emit_insn (gen_set_got (pic_offset_table_rtx));
18696   DONE;
18697 })
18698 \f
18699 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18700
18701 (define_split
18702   [(set (match_operand 0 "register_operand" "")
18703         (match_operator 3 "promotable_binary_operator"
18704            [(match_operand 1 "register_operand" "")
18705             (match_operand 2 "aligned_operand" "")]))
18706    (clobber (reg:CC FLAGS_REG))]
18707   "! TARGET_PARTIAL_REG_STALL && reload_completed
18708    && ((GET_MODE (operands[0]) == HImode 
18709         && ((!optimize_size && !TARGET_FAST_PREFIX)
18710             || GET_CODE (operands[2]) != CONST_INT
18711             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18712        || (GET_MODE (operands[0]) == QImode 
18713            && (TARGET_PROMOTE_QImode || optimize_size)))"
18714   [(parallel [(set (match_dup 0)
18715                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18716               (clobber (reg:CC FLAGS_REG))])]
18717   "operands[0] = gen_lowpart (SImode, operands[0]);
18718    operands[1] = gen_lowpart (SImode, operands[1]);
18719    if (GET_CODE (operands[3]) != ASHIFT)
18720      operands[2] = gen_lowpart (SImode, operands[2]);
18721    PUT_MODE (operands[3], SImode);")
18722
18723 ; Promote the QImode tests, as i386 has encoding of the AND
18724 ; instruction with 32-bit sign-extended immediate and thus the
18725 ; instruction size is unchanged, except in the %eax case for
18726 ; which it is increased by one byte, hence the ! optimize_size.
18727 (define_split
18728   [(set (match_operand 0 "flags_reg_operand" "")
18729         (match_operator 2 "compare_operator"
18730           [(and (match_operand 3 "aligned_operand" "")
18731                 (match_operand 4 "const_int_operand" ""))
18732            (const_int 0)]))
18733    (set (match_operand 1 "register_operand" "")
18734         (and (match_dup 3) (match_dup 4)))]
18735   "! TARGET_PARTIAL_REG_STALL && reload_completed
18736    /* Ensure that the operand will remain sign-extended immediate.  */
18737    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18738    && ! optimize_size
18739    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18740        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18741   [(parallel [(set (match_dup 0)
18742                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18743                                     (const_int 0)]))
18744               (set (match_dup 1)
18745                    (and:SI (match_dup 3) (match_dup 4)))])]
18746 {
18747   operands[4]
18748     = gen_int_mode (INTVAL (operands[4])
18749                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18750   operands[1] = gen_lowpart (SImode, operands[1]);
18751   operands[3] = gen_lowpart (SImode, operands[3]);
18752 })
18753
18754 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18755 ; the TEST instruction with 32-bit sign-extended immediate and thus
18756 ; the instruction size would at least double, which is not what we
18757 ; want even with ! optimize_size.
18758 (define_split
18759   [(set (match_operand 0 "flags_reg_operand" "")
18760         (match_operator 1 "compare_operator"
18761           [(and (match_operand:HI 2 "aligned_operand" "")
18762                 (match_operand:HI 3 "const_int_operand" ""))
18763            (const_int 0)]))]
18764   "! TARGET_PARTIAL_REG_STALL && reload_completed
18765    /* Ensure that the operand will remain sign-extended immediate.  */
18766    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18767    && ! TARGET_FAST_PREFIX
18768    && ! optimize_size"
18769   [(set (match_dup 0)
18770         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18771                          (const_int 0)]))]
18772 {
18773   operands[3]
18774     = gen_int_mode (INTVAL (operands[3])
18775                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18776   operands[2] = gen_lowpart (SImode, operands[2]);
18777 })
18778
18779 (define_split
18780   [(set (match_operand 0 "register_operand" "")
18781         (neg (match_operand 1 "register_operand" "")))
18782    (clobber (reg:CC FLAGS_REG))]
18783   "! TARGET_PARTIAL_REG_STALL && reload_completed
18784    && (GET_MODE (operands[0]) == HImode
18785        || (GET_MODE (operands[0]) == QImode 
18786            && (TARGET_PROMOTE_QImode || optimize_size)))"
18787   [(parallel [(set (match_dup 0)
18788                    (neg:SI (match_dup 1)))
18789               (clobber (reg:CC FLAGS_REG))])]
18790   "operands[0] = gen_lowpart (SImode, operands[0]);
18791    operands[1] = gen_lowpart (SImode, operands[1]);")
18792
18793 (define_split
18794   [(set (match_operand 0 "register_operand" "")
18795         (not (match_operand 1 "register_operand" "")))]
18796   "! TARGET_PARTIAL_REG_STALL && reload_completed
18797    && (GET_MODE (operands[0]) == HImode
18798        || (GET_MODE (operands[0]) == QImode 
18799            && (TARGET_PROMOTE_QImode || optimize_size)))"
18800   [(set (match_dup 0)
18801         (not:SI (match_dup 1)))]
18802   "operands[0] = gen_lowpart (SImode, operands[0]);
18803    operands[1] = gen_lowpart (SImode, operands[1]);")
18804
18805 (define_split 
18806   [(set (match_operand 0 "register_operand" "")
18807         (if_then_else (match_operator 1 "comparison_operator" 
18808                                 [(reg FLAGS_REG) (const_int 0)])
18809                       (match_operand 2 "register_operand" "")
18810                       (match_operand 3 "register_operand" "")))]
18811   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18812    && (GET_MODE (operands[0]) == HImode
18813        || (GET_MODE (operands[0]) == QImode 
18814            && (TARGET_PROMOTE_QImode || optimize_size)))"
18815   [(set (match_dup 0)
18816         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18817   "operands[0] = gen_lowpart (SImode, operands[0]);
18818    operands[2] = gen_lowpart (SImode, operands[2]);
18819    operands[3] = gen_lowpart (SImode, operands[3]);")
18820                         
18821 \f
18822 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18823 ;; transform a complex memory operation into two memory to register operations.
18824
18825 ;; Don't push memory operands
18826 (define_peephole2
18827   [(set (match_operand:SI 0 "push_operand" "")
18828         (match_operand:SI 1 "memory_operand" ""))
18829    (match_scratch:SI 2 "r")]
18830   "! optimize_size && ! TARGET_PUSH_MEMORY"
18831   [(set (match_dup 2) (match_dup 1))
18832    (set (match_dup 0) (match_dup 2))]
18833   "")
18834
18835 (define_peephole2
18836   [(set (match_operand:DI 0 "push_operand" "")
18837         (match_operand:DI 1 "memory_operand" ""))
18838    (match_scratch:DI 2 "r")]
18839   "! optimize_size && ! TARGET_PUSH_MEMORY"
18840   [(set (match_dup 2) (match_dup 1))
18841    (set (match_dup 0) (match_dup 2))]
18842   "")
18843
18844 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18845 ;; SImode pushes.
18846 (define_peephole2
18847   [(set (match_operand:SF 0 "push_operand" "")
18848         (match_operand:SF 1 "memory_operand" ""))
18849    (match_scratch:SF 2 "r")]
18850   "! optimize_size && ! TARGET_PUSH_MEMORY"
18851   [(set (match_dup 2) (match_dup 1))
18852    (set (match_dup 0) (match_dup 2))]
18853   "")
18854
18855 (define_peephole2
18856   [(set (match_operand:HI 0 "push_operand" "")
18857         (match_operand:HI 1 "memory_operand" ""))
18858    (match_scratch:HI 2 "r")]
18859   "! optimize_size && ! TARGET_PUSH_MEMORY"
18860   [(set (match_dup 2) (match_dup 1))
18861    (set (match_dup 0) (match_dup 2))]
18862   "")
18863
18864 (define_peephole2
18865   [(set (match_operand:QI 0 "push_operand" "")
18866         (match_operand:QI 1 "memory_operand" ""))
18867    (match_scratch:QI 2 "q")]
18868   "! optimize_size && ! TARGET_PUSH_MEMORY"
18869   [(set (match_dup 2) (match_dup 1))
18870    (set (match_dup 0) (match_dup 2))]
18871   "")
18872
18873 ;; Don't move an immediate directly to memory when the instruction
18874 ;; gets too big.
18875 (define_peephole2
18876   [(match_scratch:SI 1 "r")
18877    (set (match_operand:SI 0 "memory_operand" "")
18878         (const_int 0))]
18879   "! optimize_size
18880    && ! TARGET_USE_MOV0
18881    && TARGET_SPLIT_LONG_MOVES
18882    && get_attr_length (insn) >= ix86_cost->large_insn
18883    && peep2_regno_dead_p (0, FLAGS_REG)"
18884   [(parallel [(set (match_dup 1) (const_int 0))
18885               (clobber (reg:CC FLAGS_REG))])
18886    (set (match_dup 0) (match_dup 1))]
18887   "")
18888
18889 (define_peephole2
18890   [(match_scratch:HI 1 "r")
18891    (set (match_operand:HI 0 "memory_operand" "")
18892         (const_int 0))]
18893   "! optimize_size
18894    && ! TARGET_USE_MOV0
18895    && TARGET_SPLIT_LONG_MOVES
18896    && get_attr_length (insn) >= ix86_cost->large_insn
18897    && peep2_regno_dead_p (0, FLAGS_REG)"
18898   [(parallel [(set (match_dup 2) (const_int 0))
18899               (clobber (reg:CC FLAGS_REG))])
18900    (set (match_dup 0) (match_dup 1))]
18901   "operands[2] = gen_lowpart (SImode, operands[1]);")
18902
18903 (define_peephole2
18904   [(match_scratch:QI 1 "q")
18905    (set (match_operand:QI 0 "memory_operand" "")
18906         (const_int 0))]
18907   "! optimize_size
18908    && ! TARGET_USE_MOV0
18909    && TARGET_SPLIT_LONG_MOVES
18910    && get_attr_length (insn) >= ix86_cost->large_insn
18911    && peep2_regno_dead_p (0, FLAGS_REG)"
18912   [(parallel [(set (match_dup 2) (const_int 0))
18913               (clobber (reg:CC FLAGS_REG))])
18914    (set (match_dup 0) (match_dup 1))]
18915   "operands[2] = gen_lowpart (SImode, operands[1]);")
18916
18917 (define_peephole2
18918   [(match_scratch:SI 2 "r")
18919    (set (match_operand:SI 0 "memory_operand" "")
18920         (match_operand:SI 1 "immediate_operand" ""))]
18921   "! optimize_size
18922    && get_attr_length (insn) >= ix86_cost->large_insn
18923    && TARGET_SPLIT_LONG_MOVES"
18924   [(set (match_dup 2) (match_dup 1))
18925    (set (match_dup 0) (match_dup 2))]
18926   "")
18927
18928 (define_peephole2
18929   [(match_scratch:HI 2 "r")
18930    (set (match_operand:HI 0 "memory_operand" "")
18931         (match_operand:HI 1 "immediate_operand" ""))]
18932   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18933   && TARGET_SPLIT_LONG_MOVES"
18934   [(set (match_dup 2) (match_dup 1))
18935    (set (match_dup 0) (match_dup 2))]
18936   "")
18937
18938 (define_peephole2
18939   [(match_scratch:QI 2 "q")
18940    (set (match_operand:QI 0 "memory_operand" "")
18941         (match_operand:QI 1 "immediate_operand" ""))]
18942   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18943   && TARGET_SPLIT_LONG_MOVES"
18944   [(set (match_dup 2) (match_dup 1))
18945    (set (match_dup 0) (match_dup 2))]
18946   "")
18947
18948 ;; Don't compare memory with zero, load and use a test instead.
18949 (define_peephole2
18950   [(set (match_operand 0 "flags_reg_operand" "")
18951         (match_operator 1 "compare_operator"
18952           [(match_operand:SI 2 "memory_operand" "")
18953            (const_int 0)]))
18954    (match_scratch:SI 3 "r")]
18955   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18956   [(set (match_dup 3) (match_dup 2))
18957    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18958   "")
18959
18960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18961 ;; Don't split NOTs with a displacement operand, because resulting XOR
18962 ;; will not be pairable anyway.
18963 ;;
18964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18965 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18966 ;; so this split helps here as well.
18967 ;;
18968 ;; Note: Can't do this as a regular split because we can't get proper
18969 ;; lifetime information then.
18970
18971 (define_peephole2
18972   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18973         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18974   "!optimize_size
18975    && peep2_regno_dead_p (0, FLAGS_REG)
18976    && ((TARGET_PENTIUM 
18977         && (GET_CODE (operands[0]) != MEM
18978             || !memory_displacement_operand (operands[0], SImode)))
18979        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18980   [(parallel [(set (match_dup 0)
18981                    (xor:SI (match_dup 1) (const_int -1)))
18982               (clobber (reg:CC FLAGS_REG))])]
18983   "")
18984
18985 (define_peephole2
18986   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18987         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18988   "!optimize_size
18989    && peep2_regno_dead_p (0, FLAGS_REG)
18990    && ((TARGET_PENTIUM 
18991         && (GET_CODE (operands[0]) != MEM
18992             || !memory_displacement_operand (operands[0], HImode)))
18993        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18994   [(parallel [(set (match_dup 0)
18995                    (xor:HI (match_dup 1) (const_int -1)))
18996               (clobber (reg:CC FLAGS_REG))])]
18997   "")
18998
18999 (define_peephole2
19000   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19001         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19002   "!optimize_size
19003    && peep2_regno_dead_p (0, FLAGS_REG)
19004    && ((TARGET_PENTIUM 
19005         && (GET_CODE (operands[0]) != MEM
19006             || !memory_displacement_operand (operands[0], QImode)))
19007        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19008   [(parallel [(set (match_dup 0)
19009                    (xor:QI (match_dup 1) (const_int -1)))
19010               (clobber (reg:CC FLAGS_REG))])]
19011   "")
19012
19013 ;; Non pairable "test imm, reg" instructions can be translated to
19014 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19015 ;; byte opcode instead of two, have a short form for byte operands),
19016 ;; so do it for other CPUs as well.  Given that the value was dead,
19017 ;; this should not create any new dependencies.  Pass on the sub-word
19018 ;; versions if we're concerned about partial register stalls.
19019
19020 (define_peephole2
19021   [(set (match_operand 0 "flags_reg_operand" "")
19022         (match_operator 1 "compare_operator"
19023           [(and:SI (match_operand:SI 2 "register_operand" "")
19024                    (match_operand:SI 3 "immediate_operand" ""))
19025            (const_int 0)]))]
19026   "ix86_match_ccmode (insn, CCNOmode)
19027    && (true_regnum (operands[2]) != 0
19028        || (GET_CODE (operands[3]) == CONST_INT
19029            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19030    && peep2_reg_dead_p (1, operands[2])"
19031   [(parallel
19032      [(set (match_dup 0)
19033            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19034                             (const_int 0)]))
19035       (set (match_dup 2)
19036            (and:SI (match_dup 2) (match_dup 3)))])]
19037   "")
19038
19039 ;; We don't need to handle HImode case, because it will be promoted to SImode
19040 ;; on ! TARGET_PARTIAL_REG_STALL
19041
19042 (define_peephole2
19043   [(set (match_operand 0 "flags_reg_operand" "")
19044         (match_operator 1 "compare_operator"
19045           [(and:QI (match_operand:QI 2 "register_operand" "")
19046                    (match_operand:QI 3 "immediate_operand" ""))
19047            (const_int 0)]))]
19048   "! TARGET_PARTIAL_REG_STALL
19049    && ix86_match_ccmode (insn, CCNOmode)
19050    && true_regnum (operands[2]) != 0
19051    && peep2_reg_dead_p (1, operands[2])"
19052   [(parallel
19053      [(set (match_dup 0)
19054            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19055                             (const_int 0)]))
19056       (set (match_dup 2)
19057            (and:QI (match_dup 2) (match_dup 3)))])]
19058   "")
19059
19060 (define_peephole2
19061   [(set (match_operand 0 "flags_reg_operand" "")
19062         (match_operator 1 "compare_operator"
19063           [(and:SI
19064              (zero_extract:SI
19065                (match_operand 2 "ext_register_operand" "")
19066                (const_int 8)
19067                (const_int 8))
19068              (match_operand 3 "const_int_operand" ""))
19069            (const_int 0)]))]
19070   "! TARGET_PARTIAL_REG_STALL
19071    && ix86_match_ccmode (insn, CCNOmode)
19072    && true_regnum (operands[2]) != 0
19073    && peep2_reg_dead_p (1, operands[2])"
19074   [(parallel [(set (match_dup 0)
19075                    (match_op_dup 1
19076                      [(and:SI
19077                         (zero_extract:SI
19078                           (match_dup 2)
19079                           (const_int 8)
19080                           (const_int 8))
19081                         (match_dup 3))
19082                       (const_int 0)]))
19083               (set (zero_extract:SI (match_dup 2)
19084                                     (const_int 8)
19085                                     (const_int 8))
19086                    (and:SI 
19087                      (zero_extract:SI
19088                        (match_dup 2)
19089                        (const_int 8)
19090                        (const_int 8))
19091                      (match_dup 3)))])]
19092   "")
19093
19094 ;; Don't do logical operations with memory inputs.
19095 (define_peephole2
19096   [(match_scratch:SI 2 "r")
19097    (parallel [(set (match_operand:SI 0 "register_operand" "")
19098                    (match_operator:SI 3 "arith_or_logical_operator"
19099                      [(match_dup 0)
19100                       (match_operand:SI 1 "memory_operand" "")]))
19101               (clobber (reg:CC FLAGS_REG))])]
19102   "! optimize_size && ! TARGET_READ_MODIFY"
19103   [(set (match_dup 2) (match_dup 1))
19104    (parallel [(set (match_dup 0)
19105                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19106               (clobber (reg:CC FLAGS_REG))])]
19107   "")
19108
19109 (define_peephole2
19110   [(match_scratch:SI 2 "r")
19111    (parallel [(set (match_operand:SI 0 "register_operand" "")
19112                    (match_operator:SI 3 "arith_or_logical_operator"
19113                      [(match_operand:SI 1 "memory_operand" "")
19114                       (match_dup 0)]))
19115               (clobber (reg:CC FLAGS_REG))])]
19116   "! optimize_size && ! TARGET_READ_MODIFY"
19117   [(set (match_dup 2) (match_dup 1))
19118    (parallel [(set (match_dup 0)
19119                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "")
19122
19123 ; Don't do logical operations with memory outputs
19124 ;
19125 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19126 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19127 ; the same decoder scheduling characteristics as the original.
19128
19129 (define_peephole2
19130   [(match_scratch:SI 2 "r")
19131    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19132                    (match_operator:SI 3 "arith_or_logical_operator"
19133                      [(match_dup 0)
19134                       (match_operand:SI 1 "nonmemory_operand" "")]))
19135               (clobber (reg:CC FLAGS_REG))])]
19136   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19137   [(set (match_dup 2) (match_dup 0))
19138    (parallel [(set (match_dup 2)
19139                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19140               (clobber (reg:CC FLAGS_REG))])
19141    (set (match_dup 0) (match_dup 2))]
19142   "")
19143
19144 (define_peephole2
19145   [(match_scratch:SI 2 "r")
19146    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19147                    (match_operator:SI 3 "arith_or_logical_operator"
19148                      [(match_operand:SI 1 "nonmemory_operand" "")
19149                       (match_dup 0)]))
19150               (clobber (reg:CC FLAGS_REG))])]
19151   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19152   [(set (match_dup 2) (match_dup 0))
19153    (parallel [(set (match_dup 2)
19154                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19155               (clobber (reg:CC FLAGS_REG))])
19156    (set (match_dup 0) (match_dup 2))]
19157   "")
19158
19159 ;; Attempt to always use XOR for zeroing registers.
19160 (define_peephole2
19161   [(set (match_operand 0 "register_operand" "")
19162         (match_operand 1 "const0_operand" ""))]
19163   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19164    && (! TARGET_USE_MOV0 || optimize_size)
19165    && GENERAL_REG_P (operands[0])
19166    && peep2_regno_dead_p (0, FLAGS_REG)"
19167   [(parallel [(set (match_dup 0) (const_int 0))
19168               (clobber (reg:CC FLAGS_REG))])]
19169 {
19170   operands[0] = gen_lowpart (word_mode, operands[0]);
19171 })
19172
19173 (define_peephole2
19174   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19175         (const_int 0))]
19176   "(GET_MODE (operands[0]) == QImode
19177     || GET_MODE (operands[0]) == HImode)
19178    && (! TARGET_USE_MOV0 || optimize_size)
19179    && peep2_regno_dead_p (0, FLAGS_REG)"
19180   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19181               (clobber (reg:CC FLAGS_REG))])])
19182
19183 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19184 (define_peephole2
19185   [(set (match_operand 0 "register_operand" "")
19186         (const_int -1))]
19187   "(GET_MODE (operands[0]) == HImode
19188     || GET_MODE (operands[0]) == SImode 
19189     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19190    && (optimize_size || TARGET_PENTIUM)
19191    && peep2_regno_dead_p (0, FLAGS_REG)"
19192   [(parallel [(set (match_dup 0) (const_int -1))
19193               (clobber (reg:CC FLAGS_REG))])]
19194   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19195                               operands[0]);")
19196
19197 ;; Attempt to convert simple leas to adds. These can be created by
19198 ;; move expanders.
19199 (define_peephole2
19200   [(set (match_operand:SI 0 "register_operand" "")
19201         (plus:SI (match_dup 0)
19202                  (match_operand:SI 1 "nonmemory_operand" "")))]
19203   "peep2_regno_dead_p (0, FLAGS_REG)"
19204   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19205               (clobber (reg:CC FLAGS_REG))])]
19206   "")
19207
19208 (define_peephole2
19209   [(set (match_operand:SI 0 "register_operand" "")
19210         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19211                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19212   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19213   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19214               (clobber (reg:CC FLAGS_REG))])]
19215   "operands[2] = gen_lowpart (SImode, operands[2]);")
19216
19217 (define_peephole2
19218   [(set (match_operand:DI 0 "register_operand" "")
19219         (plus:DI (match_dup 0)
19220                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19221   "peep2_regno_dead_p (0, FLAGS_REG)"
19222   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   "")
19225
19226 (define_peephole2
19227   [(set (match_operand:SI 0 "register_operand" "")
19228         (mult:SI (match_dup 0)
19229                  (match_operand:SI 1 "const_int_operand" "")))]
19230   "exact_log2 (INTVAL (operands[1])) >= 0
19231    && peep2_regno_dead_p (0, FLAGS_REG)"
19232   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19233               (clobber (reg:CC FLAGS_REG))])]
19234   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19235
19236 (define_peephole2
19237   [(set (match_operand:DI 0 "register_operand" "")
19238         (mult:DI (match_dup 0)
19239                  (match_operand:DI 1 "const_int_operand" "")))]
19240   "exact_log2 (INTVAL (operands[1])) >= 0
19241    && peep2_regno_dead_p (0, FLAGS_REG)"
19242   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19243               (clobber (reg:CC FLAGS_REG))])]
19244   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19245
19246 (define_peephole2
19247   [(set (match_operand:SI 0 "register_operand" "")
19248         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19249                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19250   "exact_log2 (INTVAL (operands[2])) >= 0
19251    && REGNO (operands[0]) == REGNO (operands[1])
19252    && peep2_regno_dead_p (0, FLAGS_REG)"
19253   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19256
19257 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19258 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19259 ;; many CPUs it is also faster, since special hardware to avoid esp
19260 ;; dependencies is present.
19261
19262 ;; While some of these conversions may be done using splitters, we use peepholes
19263 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19264
19265 ;; Convert prologue esp subtractions to push.
19266 ;; We need register to push.  In order to keep verify_flow_info happy we have
19267 ;; two choices
19268 ;; - use scratch and clobber it in order to avoid dependencies
19269 ;; - use already live register
19270 ;; We can't use the second way right now, since there is no reliable way how to
19271 ;; verify that given register is live.  First choice will also most likely in
19272 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19273 ;; call clobbered registers are dead.  We may want to use base pointer as an
19274 ;; alternative when no register is available later.
19275
19276 (define_peephole2
19277   [(match_scratch:SI 0 "r")
19278    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19279               (clobber (reg:CC FLAGS_REG))
19280               (clobber (mem:BLK (scratch)))])]
19281   "optimize_size || !TARGET_SUB_ESP_4"
19282   [(clobber (match_dup 0))
19283    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19284               (clobber (mem:BLK (scratch)))])])
19285
19286 (define_peephole2
19287   [(match_scratch:SI 0 "r")
19288    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19289               (clobber (reg:CC FLAGS_REG))
19290               (clobber (mem:BLK (scratch)))])]
19291   "optimize_size || !TARGET_SUB_ESP_8"
19292   [(clobber (match_dup 0))
19293    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19294    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19295               (clobber (mem:BLK (scratch)))])])
19296
19297 ;; Convert esp subtractions to push.
19298 (define_peephole2
19299   [(match_scratch:SI 0 "r")
19300    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   "optimize_size || !TARGET_SUB_ESP_4"
19303   [(clobber (match_dup 0))
19304    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19305
19306 (define_peephole2
19307   [(match_scratch:SI 0 "r")
19308    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19309               (clobber (reg:CC FLAGS_REG))])]
19310   "optimize_size || !TARGET_SUB_ESP_8"
19311   [(clobber (match_dup 0))
19312    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19313    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19314
19315 ;; Convert epilogue deallocator to pop.
19316 (define_peephole2
19317   [(match_scratch:SI 0 "r")
19318    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19319               (clobber (reg:CC FLAGS_REG))
19320               (clobber (mem:BLK (scratch)))])]
19321   "optimize_size || !TARGET_ADD_ESP_4"
19322   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19323               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19324               (clobber (mem:BLK (scratch)))])]
19325   "")
19326
19327 ;; Two pops case is tricky, since pop causes dependency on destination register.
19328 ;; We use two registers if available.
19329 (define_peephole2
19330   [(match_scratch:SI 0 "r")
19331    (match_scratch:SI 1 "r")
19332    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19333               (clobber (reg:CC FLAGS_REG))
19334               (clobber (mem:BLK (scratch)))])]
19335   "optimize_size || !TARGET_ADD_ESP_8"
19336   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19337               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19338               (clobber (mem:BLK (scratch)))])
19339    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19340               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19341   "")
19342
19343 (define_peephole2
19344   [(match_scratch:SI 0 "r")
19345    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19346               (clobber (reg:CC FLAGS_REG))
19347               (clobber (mem:BLK (scratch)))])]
19348   "optimize_size"
19349   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19350               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19351               (clobber (mem:BLK (scratch)))])
19352    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19353               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19354   "")
19355
19356 ;; Convert esp additions to pop.
19357 (define_peephole2
19358   [(match_scratch:SI 0 "r")
19359    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19360               (clobber (reg:CC FLAGS_REG))])]
19361   ""
19362   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19363               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19364   "")
19365
19366 ;; Two pops case is tricky, since pop causes dependency on destination register.
19367 ;; We use two registers if available.
19368 (define_peephole2
19369   [(match_scratch:SI 0 "r")
19370    (match_scratch:SI 1 "r")
19371    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19372               (clobber (reg:CC FLAGS_REG))])]
19373   ""
19374   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19375               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19376    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19377               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19378   "")
19379
19380 (define_peephole2
19381   [(match_scratch:SI 0 "r")
19382    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19383               (clobber (reg:CC FLAGS_REG))])]
19384   "optimize_size"
19385   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19386               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19387    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19388               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19389   "")
19390 \f
19391 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19392 ;; required and register dies.  Similarly for 128 to plus -128.
19393 (define_peephole2
19394   [(set (match_operand 0 "flags_reg_operand" "")
19395         (match_operator 1 "compare_operator"
19396           [(match_operand 2 "register_operand" "")
19397            (match_operand 3 "const_int_operand" "")]))]
19398   "(INTVAL (operands[3]) == -1
19399     || INTVAL (operands[3]) == 1
19400     || INTVAL (operands[3]) == 128)
19401    && ix86_match_ccmode (insn, CCGCmode)
19402    && peep2_reg_dead_p (1, operands[2])"
19403   [(parallel [(set (match_dup 0)
19404                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19405               (clobber (match_dup 2))])]
19406   "")
19407 \f
19408 (define_peephole2
19409   [(match_scratch:DI 0 "r")
19410    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19411               (clobber (reg:CC FLAGS_REG))
19412               (clobber (mem:BLK (scratch)))])]
19413   "optimize_size || !TARGET_SUB_ESP_4"
19414   [(clobber (match_dup 0))
19415    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19416               (clobber (mem:BLK (scratch)))])])
19417
19418 (define_peephole2
19419   [(match_scratch:DI 0 "r")
19420    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19421               (clobber (reg:CC FLAGS_REG))
19422               (clobber (mem:BLK (scratch)))])]
19423   "optimize_size || !TARGET_SUB_ESP_8"
19424   [(clobber (match_dup 0))
19425    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19426    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19427               (clobber (mem:BLK (scratch)))])])
19428
19429 ;; Convert esp subtractions to push.
19430 (define_peephole2
19431   [(match_scratch:DI 0 "r")
19432    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19433               (clobber (reg:CC FLAGS_REG))])]
19434   "optimize_size || !TARGET_SUB_ESP_4"
19435   [(clobber (match_dup 0))
19436    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19437
19438 (define_peephole2
19439   [(match_scratch:DI 0 "r")
19440    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19441               (clobber (reg:CC FLAGS_REG))])]
19442   "optimize_size || !TARGET_SUB_ESP_8"
19443   [(clobber (match_dup 0))
19444    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19445    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19446
19447 ;; Convert epilogue deallocator to pop.
19448 (define_peephole2
19449   [(match_scratch:DI 0 "r")
19450    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19451               (clobber (reg:CC FLAGS_REG))
19452               (clobber (mem:BLK (scratch)))])]
19453   "optimize_size || !TARGET_ADD_ESP_4"
19454   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19455               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19456               (clobber (mem:BLK (scratch)))])]
19457   "")
19458
19459 ;; Two pops case is tricky, since pop causes dependency on destination register.
19460 ;; We use two registers if available.
19461 (define_peephole2
19462   [(match_scratch:DI 0 "r")
19463    (match_scratch:DI 1 "r")
19464    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19465               (clobber (reg:CC FLAGS_REG))
19466               (clobber (mem:BLK (scratch)))])]
19467   "optimize_size || !TARGET_ADD_ESP_8"
19468   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19469               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19470               (clobber (mem:BLK (scratch)))])
19471    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19472               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19473   "")
19474
19475 (define_peephole2
19476   [(match_scratch:DI 0 "r")
19477    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19478               (clobber (reg:CC FLAGS_REG))
19479               (clobber (mem:BLK (scratch)))])]
19480   "optimize_size"
19481   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19482               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19483               (clobber (mem:BLK (scratch)))])
19484    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19485               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19486   "")
19487
19488 ;; Convert esp additions to pop.
19489 (define_peephole2
19490   [(match_scratch:DI 0 "r")
19491    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19492               (clobber (reg:CC FLAGS_REG))])]
19493   ""
19494   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19495               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19496   "")
19497
19498 ;; Two pops case is tricky, since pop causes dependency on destination register.
19499 ;; We use two registers if available.
19500 (define_peephole2
19501   [(match_scratch:DI 0 "r")
19502    (match_scratch:DI 1 "r")
19503    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19504               (clobber (reg:CC FLAGS_REG))])]
19505   ""
19506   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19507               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19508    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19509               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19510   "")
19511
19512 (define_peephole2
19513   [(match_scratch:DI 0 "r")
19514    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19515               (clobber (reg:CC FLAGS_REG))])]
19516   "optimize_size"
19517   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19518               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19519    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19520               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19521   "")
19522 \f
19523 ;; Convert imul by three, five and nine into lea
19524 (define_peephole2
19525   [(parallel
19526     [(set (match_operand:SI 0 "register_operand" "")
19527           (mult:SI (match_operand:SI 1 "register_operand" "")
19528                    (match_operand:SI 2 "const_int_operand" "")))
19529      (clobber (reg:CC FLAGS_REG))])]
19530   "INTVAL (operands[2]) == 3
19531    || INTVAL (operands[2]) == 5
19532    || INTVAL (operands[2]) == 9"
19533   [(set (match_dup 0)
19534         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19535                  (match_dup 1)))]
19536   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19537
19538 (define_peephole2
19539   [(parallel
19540     [(set (match_operand:SI 0 "register_operand" "")
19541           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19542                    (match_operand:SI 2 "const_int_operand" "")))
19543      (clobber (reg:CC FLAGS_REG))])]
19544   "!optimize_size 
19545    && (INTVAL (operands[2]) == 3
19546        || INTVAL (operands[2]) == 5
19547        || INTVAL (operands[2]) == 9)"
19548   [(set (match_dup 0) (match_dup 1))
19549    (set (match_dup 0)
19550         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19551                  (match_dup 0)))]
19552   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19553
19554 (define_peephole2
19555   [(parallel
19556     [(set (match_operand:DI 0 "register_operand" "")
19557           (mult:DI (match_operand:DI 1 "register_operand" "")
19558                    (match_operand:DI 2 "const_int_operand" "")))
19559      (clobber (reg:CC FLAGS_REG))])]
19560   "TARGET_64BIT
19561    && (INTVAL (operands[2]) == 3
19562        || INTVAL (operands[2]) == 5
19563        || INTVAL (operands[2]) == 9)"
19564   [(set (match_dup 0)
19565         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19566                  (match_dup 1)))]
19567   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19568
19569 (define_peephole2
19570   [(parallel
19571     [(set (match_operand:DI 0 "register_operand" "")
19572           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19573                    (match_operand:DI 2 "const_int_operand" "")))
19574      (clobber (reg:CC FLAGS_REG))])]
19575   "TARGET_64BIT
19576    && !optimize_size 
19577    && (INTVAL (operands[2]) == 3
19578        || INTVAL (operands[2]) == 5
19579        || INTVAL (operands[2]) == 9)"
19580   [(set (match_dup 0) (match_dup 1))
19581    (set (match_dup 0)
19582         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19583                  (match_dup 0)))]
19584   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19585
19586 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19587 ;; imul $32bit_imm, reg, reg is direct decoded.
19588 (define_peephole2
19589   [(match_scratch:DI 3 "r")
19590    (parallel [(set (match_operand:DI 0 "register_operand" "")
19591                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19592                             (match_operand:DI 2 "immediate_operand" "")))
19593               (clobber (reg:CC FLAGS_REG))])]
19594   "TARGET_K8 && !optimize_size
19595    && (GET_CODE (operands[2]) != CONST_INT
19596        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19597   [(set (match_dup 3) (match_dup 1))
19598    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19599               (clobber (reg:CC FLAGS_REG))])]
19600 "")
19601
19602 (define_peephole2
19603   [(match_scratch:SI 3 "r")
19604    (parallel [(set (match_operand:SI 0 "register_operand" "")
19605                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19606                             (match_operand:SI 2 "immediate_operand" "")))
19607               (clobber (reg:CC FLAGS_REG))])]
19608   "TARGET_K8 && !optimize_size
19609    && (GET_CODE (operands[2]) != CONST_INT
19610        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19611   [(set (match_dup 3) (match_dup 1))
19612    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19613               (clobber (reg:CC FLAGS_REG))])]
19614 "")
19615
19616 (define_peephole2
19617   [(match_scratch:SI 3 "r")
19618    (parallel [(set (match_operand:DI 0 "register_operand" "")
19619                    (zero_extend:DI
19620                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19621                               (match_operand:SI 2 "immediate_operand" ""))))
19622               (clobber (reg:CC FLAGS_REG))])]
19623   "TARGET_K8 && !optimize_size
19624    && (GET_CODE (operands[2]) != CONST_INT
19625        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19626   [(set (match_dup 3) (match_dup 1))
19627    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19628               (clobber (reg:CC FLAGS_REG))])]
19629 "")
19630
19631 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19632 ;; Convert it into imul reg, reg
19633 ;; It would be better to force assembler to encode instruction using long
19634 ;; immediate, but there is apparently no way to do so.
19635 (define_peephole2
19636   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19637                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19638                             (match_operand:DI 2 "const_int_operand" "")))
19639               (clobber (reg:CC FLAGS_REG))])
19640    (match_scratch:DI 3 "r")]
19641   "TARGET_K8 && !optimize_size
19642    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19643   [(set (match_dup 3) (match_dup 2))
19644    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19645               (clobber (reg:CC FLAGS_REG))])]
19646 {
19647   if (!rtx_equal_p (operands[0], operands[1]))
19648     emit_move_insn (operands[0], operands[1]);
19649 })
19650
19651 (define_peephole2
19652   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19653                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19654                             (match_operand:SI 2 "const_int_operand" "")))
19655               (clobber (reg:CC FLAGS_REG))])
19656    (match_scratch:SI 3 "r")]
19657   "TARGET_K8 && !optimize_size
19658    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19659   [(set (match_dup 3) (match_dup 2))
19660    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19661               (clobber (reg:CC FLAGS_REG))])]
19662 {
19663   if (!rtx_equal_p (operands[0], operands[1]))
19664     emit_move_insn (operands[0], operands[1]);
19665 })
19666
19667 (define_peephole2
19668   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19669                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19670                             (match_operand:HI 2 "immediate_operand" "")))
19671               (clobber (reg:CC FLAGS_REG))])
19672    (match_scratch:HI 3 "r")]
19673   "TARGET_K8 && !optimize_size"
19674   [(set (match_dup 3) (match_dup 2))
19675    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19676               (clobber (reg:CC FLAGS_REG))])]
19677 {
19678   if (!rtx_equal_p (operands[0], operands[1]))
19679     emit_move_insn (operands[0], operands[1]);
19680 })
19681 \f
19682 ;; Call-value patterns last so that the wildcard operand does not
19683 ;; disrupt insn-recog's switch tables.
19684
19685 (define_insn "*call_value_pop_0"
19686   [(set (match_operand 0 "" "")
19687         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19688               (match_operand:SI 2 "" "")))
19689    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19690                             (match_operand:SI 3 "immediate_operand" "")))]
19691   "!TARGET_64BIT"
19692 {
19693   if (SIBLING_CALL_P (insn))
19694     return "jmp\t%P1";
19695   else
19696     return "call\t%P1";
19697 }
19698   [(set_attr "type" "callv")])
19699
19700 (define_insn "*call_value_pop_1"
19701   [(set (match_operand 0 "" "")
19702         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19703               (match_operand:SI 2 "" "")))
19704    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19705                             (match_operand:SI 3 "immediate_operand" "i")))]
19706   "!TARGET_64BIT"
19707 {
19708   if (constant_call_address_operand (operands[1], Pmode))
19709     {
19710       if (SIBLING_CALL_P (insn))
19711         return "jmp\t%P1";
19712       else
19713         return "call\t%P1";
19714     }
19715   if (SIBLING_CALL_P (insn))
19716     return "jmp\t%A1";
19717   else
19718     return "call\t%A1";
19719 }
19720   [(set_attr "type" "callv")])
19721
19722 (define_insn "*call_value_0"
19723   [(set (match_operand 0 "" "")
19724         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19725               (match_operand:SI 2 "" "")))]
19726   "!TARGET_64BIT"
19727 {
19728   if (SIBLING_CALL_P (insn))
19729     return "jmp\t%P1";
19730   else
19731     return "call\t%P1";
19732 }
19733   [(set_attr "type" "callv")])
19734
19735 (define_insn "*call_value_0_rex64"
19736   [(set (match_operand 0 "" "")
19737         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19738               (match_operand:DI 2 "const_int_operand" "")))]
19739   "TARGET_64BIT"
19740 {
19741   if (SIBLING_CALL_P (insn))
19742     return "jmp\t%P1";
19743   else
19744     return "call\t%P1";
19745 }
19746   [(set_attr "type" "callv")])
19747
19748 (define_insn "*call_value_1"
19749   [(set (match_operand 0 "" "")
19750         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19751               (match_operand:SI 2 "" "")))]
19752   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19753 {
19754   if (constant_call_address_operand (operands[1], Pmode))
19755     return "call\t%P1";
19756   return "call\t%A1";
19757 }
19758   [(set_attr "type" "callv")])
19759
19760 (define_insn "*sibcall_value_1"
19761   [(set (match_operand 0 "" "")
19762         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19763               (match_operand:SI 2 "" "")))]
19764   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19765 {
19766   if (constant_call_address_operand (operands[1], Pmode))
19767     return "jmp\t%P1";
19768   return "jmp\t%A1";
19769 }
19770   [(set_attr "type" "callv")])
19771
19772 (define_insn "*call_value_1_rex64"
19773   [(set (match_operand 0 "" "")
19774         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19775               (match_operand:DI 2 "" "")))]
19776   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19777 {
19778   if (constant_call_address_operand (operands[1], Pmode))
19779     return "call\t%P1";
19780   return "call\t%A1";
19781 }
19782   [(set_attr "type" "callv")])
19783
19784 (define_insn "*sibcall_value_1_rex64"
19785   [(set (match_operand 0 "" "")
19786         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19787               (match_operand:DI 2 "" "")))]
19788   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19789   "jmp\t%P1"
19790   [(set_attr "type" "callv")])
19791
19792 (define_insn "*sibcall_value_1_rex64_v"
19793   [(set (match_operand 0 "" "")
19794         (call (mem:QI (reg:DI 40))
19795               (match_operand:DI 1 "" "")))]
19796   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19797   "jmp\t*%%r11"
19798   [(set_attr "type" "callv")])
19799 \f
19800 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19801 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19802 ;; caught for use by garbage collectors and the like.  Using an insn that
19803 ;; maps to SIGILL makes it more likely the program will rightfully die.
19804 ;; Keeping with tradition, "6" is in honor of #UD.
19805 (define_insn "trap"
19806   [(trap_if (const_int 1) (const_int 6))]
19807   ""
19808   ".word\t0x0b0f"
19809   [(set_attr "length" "2")])
19810
19811 (define_expand "sse_prologue_save"
19812   [(parallel [(set (match_operand:BLK 0 "" "")
19813                    (unspec:BLK [(reg:DI 21)
19814                                 (reg:DI 22)
19815                                 (reg:DI 23)
19816                                 (reg:DI 24)
19817                                 (reg:DI 25)
19818                                 (reg:DI 26)
19819                                 (reg:DI 27)
19820                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19821               (use (match_operand:DI 1 "register_operand" ""))
19822               (use (match_operand:DI 2 "immediate_operand" ""))
19823               (use (label_ref:DI (match_operand 3 "" "")))])]
19824   "TARGET_64BIT"
19825   "")
19826
19827 (define_insn "*sse_prologue_save_insn"
19828   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19829                           (match_operand:DI 4 "const_int_operand" "n")))
19830         (unspec:BLK [(reg:DI 21)
19831                      (reg:DI 22)
19832                      (reg:DI 23)
19833                      (reg:DI 24)
19834                      (reg:DI 25)
19835                      (reg:DI 26)
19836                      (reg:DI 27)
19837                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19838    (use (match_operand:DI 1 "register_operand" "r"))
19839    (use (match_operand:DI 2 "const_int_operand" "i"))
19840    (use (label_ref:DI (match_operand 3 "" "X")))]
19841   "TARGET_64BIT
19842    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19843    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19844   "*
19845 {
19846   int i;
19847   operands[0] = gen_rtx_MEM (Pmode,
19848                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19849   output_asm_insn (\"jmp\\t%A1\", operands);
19850   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19851     {
19852       operands[4] = adjust_address (operands[0], DImode, i*16);
19853       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19854       PUT_MODE (operands[4], TImode);
19855       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19856         output_asm_insn (\"rex\", operands);
19857       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19858     }
19859   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19860                              CODE_LABEL_NUMBER (operands[3]));
19861   RET;
19862 }
19863   "
19864   [(set_attr "type" "other")
19865    (set_attr "length_immediate" "0")
19866    (set_attr "length_address" "0")
19867    (set_attr "length" "135")
19868    (set_attr "memory" "store")
19869    (set_attr "modrm" "0")
19870    (set_attr "mode" "DI")])
19871
19872 (define_expand "prefetch"
19873   [(prefetch (match_operand 0 "address_operand" "")
19874              (match_operand:SI 1 "const_int_operand" "")
19875              (match_operand:SI 2 "const_int_operand" ""))]
19876   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19877 {
19878   int rw = INTVAL (operands[1]);
19879   int locality = INTVAL (operands[2]);
19880
19881   gcc_assert (rw == 0 || rw == 1);
19882   gcc_assert (locality >= 0 && locality <= 3);
19883   gcc_assert (GET_MODE (operands[0]) == Pmode
19884               || GET_MODE (operands[0]) == VOIDmode);
19885
19886   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19887      supported by SSE counterpart or the SSE prefetch is not available
19888      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19889      of locality.  */
19890   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19891     operands[2] = GEN_INT (3);
19892   else
19893     operands[1] = const0_rtx;
19894 })
19895
19896 (define_insn "*prefetch_sse"
19897   [(prefetch (match_operand:SI 0 "address_operand" "p")
19898              (const_int 0)
19899              (match_operand:SI 1 "const_int_operand" ""))]
19900   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19901 {
19902   static const char * const patterns[4] = {
19903    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19904   };
19905
19906   int locality = INTVAL (operands[1]);
19907   gcc_assert (locality >= 0 && locality <= 3);
19908
19909   return patterns[locality];  
19910 }
19911   [(set_attr "type" "sse")
19912    (set_attr "memory" "none")])
19913
19914 (define_insn "*prefetch_sse_rex"
19915   [(prefetch (match_operand:DI 0 "address_operand" "p")
19916              (const_int 0)
19917              (match_operand:SI 1 "const_int_operand" ""))]
19918   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19919 {
19920   static const char * const patterns[4] = {
19921    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19922   };
19923
19924   int locality = INTVAL (operands[1]);
19925   gcc_assert (locality >= 0 && locality <= 3);
19926
19927   return patterns[locality];  
19928 }
19929   [(set_attr "type" "sse")
19930    (set_attr "memory" "none")])
19931
19932 (define_insn "*prefetch_3dnow"
19933   [(prefetch (match_operand:SI 0 "address_operand" "p")
19934              (match_operand:SI 1 "const_int_operand" "n")
19935              (const_int 3))]
19936   "TARGET_3DNOW && !TARGET_64BIT"
19937 {
19938   if (INTVAL (operands[1]) == 0)
19939     return "prefetch\t%a0";
19940   else
19941     return "prefetchw\t%a0";
19942 }
19943   [(set_attr "type" "mmx")
19944    (set_attr "memory" "none")])
19945
19946 (define_insn "*prefetch_3dnow_rex"
19947   [(prefetch (match_operand:DI 0 "address_operand" "p")
19948              (match_operand:SI 1 "const_int_operand" "n")
19949              (const_int 3))]
19950   "TARGET_3DNOW && TARGET_64BIT"
19951 {
19952   if (INTVAL (operands[1]) == 0)
19953     return "prefetch\t%a0";
19954   else
19955     return "prefetchw\t%a0";
19956 }
19957   [(set_attr "type" "mmx")
19958    (set_attr "memory" "none")])
19959
19960 (define_expand "stack_protect_set"
19961   [(match_operand 0 "memory_operand" "")
19962    (match_operand 1 "memory_operand" "")]
19963   ""
19964 {
19965 #ifdef TARGET_THREAD_SSP_OFFSET
19966   if (TARGET_64BIT)
19967     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19968                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19969   else
19970     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19971                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19972 #else
19973   if (TARGET_64BIT)
19974     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19975   else
19976     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19977 #endif
19978   DONE;
19979 })
19980
19981 (define_insn "stack_protect_set_si"
19982   [(set (match_operand:SI 0 "memory_operand" "=m")
19983         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19984    (set (match_scratch:SI 2 "=&r") (const_int 0))
19985    (clobber (reg:CC FLAGS_REG))]
19986   ""
19987   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19988   [(set_attr "type" "multi")])
19989
19990 (define_insn "stack_protect_set_di"
19991   [(set (match_operand:DI 0 "memory_operand" "=m")
19992         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19993    (set (match_scratch:DI 2 "=&r") (const_int 0))
19994    (clobber (reg:CC FLAGS_REG))]
19995   "TARGET_64BIT"
19996   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19997   [(set_attr "type" "multi")])
19998
19999 (define_insn "stack_tls_protect_set_si"
20000   [(set (match_operand:SI 0 "memory_operand" "=m")
20001         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20002    (set (match_scratch:SI 2 "=&r") (const_int 0))
20003    (clobber (reg:CC FLAGS_REG))]
20004   ""
20005   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20006   [(set_attr "type" "multi")])
20007
20008 (define_insn "stack_tls_protect_set_di"
20009   [(set (match_operand:DI 0 "memory_operand" "=m")
20010         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20011    (set (match_scratch:DI 2 "=&r") (const_int 0))
20012    (clobber (reg:CC FLAGS_REG))]
20013   "TARGET_64BIT"
20014   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20015   [(set_attr "type" "multi")])
20016
20017 (define_expand "stack_protect_test"
20018   [(match_operand 0 "memory_operand" "")
20019    (match_operand 1 "memory_operand" "")
20020    (match_operand 2 "" "")]
20021   ""
20022 {
20023   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20024   ix86_compare_op0 = operands[0];
20025   ix86_compare_op1 = operands[1];
20026   ix86_compare_emitted = flags;
20027
20028 #ifdef TARGET_THREAD_SSP_OFFSET
20029   if (TARGET_64BIT)
20030     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20031                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20032   else
20033     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20034                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20035 #else
20036   if (TARGET_64BIT)
20037     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20038   else
20039     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20040 #endif
20041   emit_jump_insn (gen_beq (operands[2]));
20042   DONE;
20043 })
20044
20045 (define_insn "stack_protect_test_si"
20046   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20047         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20048                      (match_operand:SI 2 "memory_operand" "m")]
20049                     UNSPEC_SP_TEST))
20050    (clobber (match_scratch:SI 3 "=&r"))]
20051   ""
20052   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20053   [(set_attr "type" "multi")])
20054
20055 (define_insn "stack_protect_test_di"
20056   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20057         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20058                      (match_operand:DI 2 "memory_operand" "m")]
20059                     UNSPEC_SP_TEST))
20060    (clobber (match_scratch:DI 3 "=&r"))]
20061   "TARGET_64BIT"
20062   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20063   [(set_attr "type" "multi")])
20064
20065 (define_insn "stack_tls_protect_test_si"
20066   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20067         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20068                      (match_operand:SI 2 "const_int_operand" "i")]
20069                     UNSPEC_SP_TLS_TEST))
20070    (clobber (match_scratch:SI 3 "=r"))]
20071   ""
20072   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20073   [(set_attr "type" "multi")])
20074
20075 (define_insn "stack_tls_protect_test_di"
20076   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20077         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20078                      (match_operand:DI 2 "const_int_operand" "i")]
20079                     UNSPEC_SP_TLS_TEST))
20080    (clobber (match_scratch:DI 3 "=r"))]
20081   "TARGET_64BIT"
20082   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20083   [(set_attr "type" "multi")])
20084
20085 (include "sse.md")
20086 (include "mmx.md")
20087 (include "sync.md")