OSDN Git Service

PR rtl-optimization/23098
[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             (match_operand:DI 1 "pic_32bit_operand" "")
1204               (const_string "lea")
1205            ]
1206            (const_string "imov")))
1207    (set (attr "mode")
1208      (cond [(eq_attr "alternative" "2,3")
1209               (const_string "DI")
1210             (eq_attr "alternative" "6,7")
1211               (if_then_else
1212                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1213                 (const_string "V4SF")
1214                 (const_string "TI"))
1215             (and (eq_attr "alternative" "8,9,10,11")
1216                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1217               (const_string "SF")
1218            ]
1219            (const_string "SI")))])
1220
1221 ;; Stores and loads of ax to arbitrary constant address.
1222 ;; We fake an second form of instruction to force reload to load address
1223 ;; into register when rax is not available
1224 (define_insn "*movabssi_1_rex64"
1225   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1226         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1227   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1228   "@
1229    movabs{l}\t{%1, %P0|%P0, %1}
1230    mov{l}\t{%1, %a0|%a0, %1}"
1231   [(set_attr "type" "imov")
1232    (set_attr "modrm" "0,*")
1233    (set_attr "length_address" "8,0")
1234    (set_attr "length_immediate" "0,*")
1235    (set_attr "memory" "store")
1236    (set_attr "mode" "SI")])
1237
1238 (define_insn "*movabssi_2_rex64"
1239   [(set (match_operand:SI 0 "register_operand" "=a,r")
1240         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1241   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1242   "@
1243    movabs{l}\t{%P1, %0|%0, %P1}
1244    mov{l}\t{%a1, %0|%0, %a1}"
1245   [(set_attr "type" "imov")
1246    (set_attr "modrm" "0,*")
1247    (set_attr "length_address" "8,0")
1248    (set_attr "length_immediate" "0")
1249    (set_attr "memory" "load")
1250    (set_attr "mode" "SI")])
1251
1252 (define_insn "*swapsi"
1253   [(set (match_operand:SI 0 "register_operand" "+r")
1254         (match_operand:SI 1 "register_operand" "+r"))
1255    (set (match_dup 1)
1256         (match_dup 0))]
1257   ""
1258   "xchg{l}\t%1, %0"
1259   [(set_attr "type" "imov")
1260    (set_attr "mode" "SI")
1261    (set_attr "pent_pair" "np")
1262    (set_attr "athlon_decode" "vector")])
1263
1264 (define_expand "movhi"
1265   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1266         (match_operand:HI 1 "general_operand" ""))]
1267   ""
1268   "ix86_expand_move (HImode, operands); DONE;")
1269
1270 (define_insn "*pushhi2"
1271   [(set (match_operand:HI 0 "push_operand" "=<,<")
1272         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1273   "!TARGET_64BIT"
1274   "@
1275    push{w}\t{|WORD PTR }%1
1276    push{w}\t%1"
1277   [(set_attr "type" "push")
1278    (set_attr "mode" "HI")])
1279
1280 ;; For 64BIT abi we always round up to 8 bytes.
1281 (define_insn "*pushhi2_rex64"
1282   [(set (match_operand:HI 0 "push_operand" "=X")
1283         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1284   "TARGET_64BIT"
1285   "push{q}\t%q1"
1286   [(set_attr "type" "push")
1287    (set_attr "mode" "QI")])
1288
1289 (define_insn "*movhi_1"
1290   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1291         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1292   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1293 {
1294   switch (get_attr_type (insn))
1295     {
1296     case TYPE_IMOVX:
1297       /* movzwl is faster than movw on p2 due to partial word stalls,
1298          though not as fast as an aligned movl.  */
1299       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1300     default:
1301       if (get_attr_mode (insn) == MODE_SI)
1302         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1303       else
1304         return "mov{w}\t{%1, %0|%0, %1}";
1305     }
1306 }
1307   [(set (attr "type")
1308      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1309               (const_string "imov")
1310             (and (eq_attr "alternative" "0")
1311                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1312                           (const_int 0))
1313                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1314                           (const_int 0))))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "1,2")
1317                  (match_operand:HI 1 "aligned_operand" ""))
1318               (const_string "imov")
1319             (and (ne (symbol_ref "TARGET_MOVX")
1320                      (const_int 0))
1321                  (eq_attr "alternative" "0,2"))
1322               (const_string "imovx")
1323            ]
1324            (const_string "imov")))
1325     (set (attr "mode")
1326       (cond [(eq_attr "type" "imovx")
1327                (const_string "SI")
1328              (and (eq_attr "alternative" "1,2")
1329                   (match_operand:HI 1 "aligned_operand" ""))
1330                (const_string "SI")
1331              (and (eq_attr "alternative" "0")
1332                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                            (const_int 0))
1334                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                            (const_int 0))))
1336                (const_string "SI")
1337             ]
1338             (const_string "HI")))])
1339
1340 ;; Stores and loads of ax to arbitrary constant address.
1341 ;; We fake an second form of instruction to force reload to load address
1342 ;; into register when rax is not available
1343 (define_insn "*movabshi_1_rex64"
1344   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1345         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1346   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1347   "@
1348    movabs{w}\t{%1, %P0|%P0, %1}
1349    mov{w}\t{%1, %a0|%a0, %1}"
1350   [(set_attr "type" "imov")
1351    (set_attr "modrm" "0,*")
1352    (set_attr "length_address" "8,0")
1353    (set_attr "length_immediate" "0,*")
1354    (set_attr "memory" "store")
1355    (set_attr "mode" "HI")])
1356
1357 (define_insn "*movabshi_2_rex64"
1358   [(set (match_operand:HI 0 "register_operand" "=a,r")
1359         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1360   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1361   "@
1362    movabs{w}\t{%P1, %0|%0, %P1}
1363    mov{w}\t{%a1, %0|%0, %a1}"
1364   [(set_attr "type" "imov")
1365    (set_attr "modrm" "0,*")
1366    (set_attr "length_address" "8,0")
1367    (set_attr "length_immediate" "0")
1368    (set_attr "memory" "load")
1369    (set_attr "mode" "HI")])
1370
1371 (define_insn "*swaphi_1"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1377   "xchg{l}\t%k1, %k0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "SI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1382
1383 (define_insn "*swaphi_2"
1384   [(set (match_operand:HI 0 "register_operand" "+r")
1385         (match_operand:HI 1 "register_operand" "+r"))
1386    (set (match_dup 1)
1387         (match_dup 0))]
1388   "TARGET_PARTIAL_REG_STALL"
1389   "xchg{w}\t%1, %0"
1390   [(set_attr "type" "imov")
1391    (set_attr "mode" "HI")
1392    (set_attr "pent_pair" "np")
1393    (set_attr "athlon_decode" "vector")])
1394
1395 (define_expand "movstricthi"
1396   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1397         (match_operand:HI 1 "general_operand" ""))]
1398   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1399 {
1400   /* Don't generate memory->memory moves, go through a register */
1401   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1402     operands[1] = force_reg (HImode, operands[1]);
1403 })
1404
1405 (define_insn "*movstricthi_1"
1406   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1407         (match_operand:HI 1 "general_operand" "rn,m"))]
1408   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1409    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1410   "mov{w}\t{%1, %0|%0, %1}"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")])
1413
1414 (define_insn "*movstricthi_xor"
1415   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1416         (match_operand:HI 1 "const0_operand" "i"))
1417    (clobber (reg:CC FLAGS_REG))]
1418   "reload_completed
1419    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1420   "xor{w}\t{%0, %0|%0, %0}"
1421   [(set_attr "type" "alu1")
1422    (set_attr "mode" "HI")
1423    (set_attr "length_immediate" "0")])
1424
1425 (define_expand "movqi"
1426   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1427         (match_operand:QI 1 "general_operand" ""))]
1428   ""
1429   "ix86_expand_move (QImode, operands); DONE;")
1430
1431 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1432 ;; "push a byte".  But actually we use pushw, which has the effect
1433 ;; of rounding the amount pushed up to a halfword.
1434
1435 (define_insn "*pushqi2"
1436   [(set (match_operand:QI 0 "push_operand" "=X,X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1438   "!TARGET_64BIT"
1439   "@
1440    push{w}\t{|word ptr }%1
1441    push{w}\t%w1"
1442   [(set_attr "type" "push")
1443    (set_attr "mode" "HI")])
1444
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushqi2_rex64"
1447   [(set (match_operand:QI 0 "push_operand" "=X")
1448         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1449   "TARGET_64BIT"
1450   "push{q}\t%q1"
1451   [(set_attr "type" "push")
1452    (set_attr "mode" "QI")])
1453
1454 ;; Situation is quite tricky about when to choose full sized (SImode) move
1455 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1456 ;; partial register dependency machines (such as AMD Athlon), where QImode
1457 ;; moves issue extra dependency and for partial register stalls machines
1458 ;; that don't use QImode patterns (and QImode move cause stall on the next
1459 ;; instruction).
1460 ;;
1461 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1462 ;; register stall machines with, where we use QImode instructions, since
1463 ;; partial register stall can be caused there.  Then we use movzx.
1464 (define_insn "*movqi_1"
1465   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1466         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1467   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1468 {
1469   switch (get_attr_type (insn))
1470     {
1471     case TYPE_IMOVX:
1472       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1473       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1474     default:
1475       if (get_attr_mode (insn) == MODE_SI)
1476         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1477       else
1478         return "mov{b}\t{%1, %0|%0, %1}";
1479     }
1480 }
1481   [(set (attr "type")
1482      (cond [(eq_attr "alternative" "5")
1483               (const_string "imovx")
1484             (ne (symbol_ref "optimize_size") (const_int 0))
1485               (const_string "imov")
1486             (and (eq_attr "alternative" "3")
1487                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1488                           (const_int 0))
1489                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1490                           (const_int 0))))
1491               (const_string "imov")
1492             (eq_attr "alternative" "3")
1493               (const_string "imovx")
1494             (and (ne (symbol_ref "TARGET_MOVX")
1495                      (const_int 0))
1496                  (eq_attr "alternative" "2"))
1497               (const_string "imovx")
1498            ]
1499            (const_string "imov")))
1500    (set (attr "mode")
1501       (cond [(eq_attr "alternative" "3,4,5")
1502                (const_string "SI")
1503              (eq_attr "alternative" "6")
1504                (const_string "QI")
1505              (eq_attr "type" "imovx")
1506                (const_string "SI")
1507              (and (eq_attr "type" "imov")
1508                   (and (eq_attr "alternative" "0,1")
1509                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1510                            (const_int 0))))
1511                (const_string "SI")
1512              ;; Avoid partial register stalls when not using QImode arithmetic
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1516                                 (const_int 0))
1517                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1518                                 (const_int 0)))))
1519                (const_string "SI")
1520            ]
1521            (const_string "QI")))])
1522
1523 (define_expand "reload_outqi"
1524   [(parallel [(match_operand:QI 0 "" "=m")
1525               (match_operand:QI 1 "register_operand" "r")
1526               (match_operand:QI 2 "register_operand" "=&q")])]
1527   ""
1528 {
1529   rtx op0, op1, op2;
1530   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1531
1532   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1533   if (! q_regs_operand (op1, QImode))
1534     {
1535       emit_insn (gen_movqi (op2, op1));
1536       op1 = op2;
1537     }
1538   emit_insn (gen_movqi (op0, op1));
1539   DONE;
1540 })
1541
1542 (define_insn "*swapqi_1"
1543   [(set (match_operand:QI 0 "register_operand" "+r")
1544         (match_operand:QI 1 "register_operand" "+r"))
1545    (set (match_dup 1)
1546         (match_dup 0))]
1547   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1548   "xchg{l}\t%k1, %k0"
1549   [(set_attr "type" "imov")
1550    (set_attr "mode" "SI")
1551    (set_attr "pent_pair" "np")
1552    (set_attr "athlon_decode" "vector")])
1553
1554 (define_insn "*swapqi_2"
1555   [(set (match_operand:QI 0 "register_operand" "+q")
1556         (match_operand:QI 1 "register_operand" "+q"))
1557    (set (match_dup 1)
1558         (match_dup 0))]
1559   "TARGET_PARTIAL_REG_STALL"
1560   "xchg{b}\t%1, %0"
1561   [(set_attr "type" "imov")
1562    (set_attr "mode" "QI")
1563    (set_attr "pent_pair" "np")
1564    (set_attr "athlon_decode" "vector")])
1565
1566 (define_expand "movstrictqi"
1567   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1568         (match_operand:QI 1 "general_operand" ""))]
1569   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1570 {
1571   /* Don't generate memory->memory moves, go through a register.  */
1572   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1573     operands[1] = force_reg (QImode, operands[1]);
1574 })
1575
1576 (define_insn "*movstrictqi_1"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1578         (match_operand:QI 1 "general_operand" "*qn,m"))]
1579   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1581   "mov{b}\t{%1, %0|%0, %1}"
1582   [(set_attr "type" "imov")
1583    (set_attr "mode" "QI")])
1584
1585 (define_insn "*movstrictqi_xor"
1586   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1587         (match_operand:QI 1 "const0_operand" "i"))
1588    (clobber (reg:CC FLAGS_REG))]
1589   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1590   "xor{b}\t{%0, %0|%0, %0}"
1591   [(set_attr "type" "alu1")
1592    (set_attr "mode" "QI")
1593    (set_attr "length_immediate" "0")])
1594
1595 (define_insn "*movsi_extv_1"
1596   [(set (match_operand:SI 0 "register_operand" "=R")
1597         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1598                          (const_int 8)
1599                          (const_int 8)))]
1600   ""
1601   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1602   [(set_attr "type" "imovx")
1603    (set_attr "mode" "SI")])
1604
1605 (define_insn "*movhi_extv_1"
1606   [(set (match_operand:HI 0 "register_operand" "=R")
1607         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1614
1615 (define_insn "*movqi_extv_1"
1616   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1617         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   "!TARGET_64BIT"
1621 {
1622   switch (get_attr_type (insn))
1623     {
1624     case TYPE_IMOVX:
1625       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1626     default:
1627       return "mov{b}\t{%h1, %0|%0, %h1}";
1628     }
1629 }
1630   [(set (attr "type")
1631      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1632                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1633                              (ne (symbol_ref "TARGET_MOVX")
1634                                  (const_int 0))))
1635         (const_string "imovx")
1636         (const_string "imov")))
1637    (set (attr "mode")
1638      (if_then_else (eq_attr "type" "imovx")
1639         (const_string "SI")
1640         (const_string "QI")))])
1641
1642 (define_insn "*movqi_extv_1_rex64"
1643   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1644         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1645                          (const_int 8)
1646                          (const_int 8)))]
1647   "TARGET_64BIT"
1648 {
1649   switch (get_attr_type (insn))
1650     {
1651     case TYPE_IMOVX:
1652       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653     default:
1654       return "mov{b}\t{%h1, %0|%0, %h1}";
1655     }
1656 }
1657   [(set (attr "type")
1658      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1659                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1660                              (ne (symbol_ref "TARGET_MOVX")
1661                                  (const_int 0))))
1662         (const_string "imovx")
1663         (const_string "imov")))
1664    (set (attr "mode")
1665      (if_then_else (eq_attr "type" "imovx")
1666         (const_string "SI")
1667         (const_string "QI")))])
1668
1669 ;; Stores and loads of ax to arbitrary constant address.
1670 ;; We fake an second form of instruction to force reload to load address
1671 ;; into register when rax is not available
1672 (define_insn "*movabsqi_1_rex64"
1673   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1674         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1675   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1676   "@
1677    movabs{b}\t{%1, %P0|%P0, %1}
1678    mov{b}\t{%1, %a0|%a0, %1}"
1679   [(set_attr "type" "imov")
1680    (set_attr "modrm" "0,*")
1681    (set_attr "length_address" "8,0")
1682    (set_attr "length_immediate" "0,*")
1683    (set_attr "memory" "store")
1684    (set_attr "mode" "QI")])
1685
1686 (define_insn "*movabsqi_2_rex64"
1687   [(set (match_operand:QI 0 "register_operand" "=a,r")
1688         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1689   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1690   "@
1691    movabs{b}\t{%P1, %0|%0, %P1}
1692    mov{b}\t{%a1, %0|%0, %a1}"
1693   [(set_attr "type" "imov")
1694    (set_attr "modrm" "0,*")
1695    (set_attr "length_address" "8,0")
1696    (set_attr "length_immediate" "0")
1697    (set_attr "memory" "load")
1698    (set_attr "mode" "QI")])
1699
1700 (define_insn "*movdi_extzv_1"
1701   [(set (match_operand:DI 0 "register_operand" "=R")
1702         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1703                          (const_int 8)
1704                          (const_int 8)))]
1705   "TARGET_64BIT"
1706   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1707   [(set_attr "type" "imovx")
1708    (set_attr "mode" "DI")])
1709
1710 (define_insn "*movsi_extzv_1"
1711   [(set (match_operand:SI 0 "register_operand" "=R")
1712         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   ""
1716   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "SI")])
1719
1720 (define_insn "*movqi_extzv_2"
1721   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1722         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1723                                     (const_int 8)
1724                                     (const_int 8)) 0))]
1725   "!TARGET_64BIT"
1726 {
1727   switch (get_attr_type (insn))
1728     {
1729     case TYPE_IMOVX:
1730       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1731     default:
1732       return "mov{b}\t{%h1, %0|%0, %h1}";
1733     }
1734 }
1735   [(set (attr "type")
1736      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1737                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1738                              (ne (symbol_ref "TARGET_MOVX")
1739                                  (const_int 0))))
1740         (const_string "imovx")
1741         (const_string "imov")))
1742    (set (attr "mode")
1743      (if_then_else (eq_attr "type" "imovx")
1744         (const_string "SI")
1745         (const_string "QI")))])
1746
1747 (define_insn "*movqi_extzv_2_rex64"
1748   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1749         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1750                                     (const_int 8)
1751                                     (const_int 8)) 0))]
1752   "TARGET_64BIT"
1753 {
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758     default:
1759       return "mov{b}\t{%h1, %0|%0, %h1}";
1760     }
1761 }
1762   [(set (attr "type")
1763      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1764                         (ne (symbol_ref "TARGET_MOVX")
1765                             (const_int 0)))
1766         (const_string "imovx")
1767         (const_string "imov")))
1768    (set (attr "mode")
1769      (if_then_else (eq_attr "type" "imovx")
1770         (const_string "SI")
1771         (const_string "QI")))])
1772
1773 (define_insn "movsi_insv_1"
1774   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1775                          (const_int 8)
1776                          (const_int 8))
1777         (match_operand:SI 1 "general_operand" "Qmn"))]
1778   "!TARGET_64BIT"
1779   "mov{b}\t{%b1, %h0|%h0, %b1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "QI")])
1782
1783 (define_insn "movdi_insv_1_rex64"
1784   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1788   "TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_insn "*movqi_insv_2"
1794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1798                      (const_int 8)))]
1799   ""
1800   "mov{b}\t{%h1, %h0|%h0, %h1}"
1801   [(set_attr "type" "imov")
1802    (set_attr "mode" "QI")])
1803
1804 (define_expand "movdi"
1805   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1806         (match_operand:DI 1 "general_operand" ""))]
1807   ""
1808   "ix86_expand_move (DImode, operands); DONE;")
1809
1810 (define_insn "*pushdi"
1811   [(set (match_operand:DI 0 "push_operand" "=<")
1812         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1813   "!TARGET_64BIT"
1814   "#")
1815
1816 (define_insn "*pushdi2_rex64"
1817   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1818         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1819   "TARGET_64BIT"
1820   "@
1821    push{q}\t%1
1822    #"
1823   [(set_attr "type" "push,multi")
1824    (set_attr "mode" "DI")])
1825
1826 ;; Convert impossible pushes of immediate to existing instructions.
1827 ;; First try to get scratch register and go through it.  In case this
1828 ;; fails, push sign extended lower part first and then overwrite
1829 ;; upper part by 32bit move.
1830 (define_peephole2
1831   [(match_scratch:DI 2 "r")
1832    (set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835    && !x86_64_immediate_operand (operands[1], DImode)"
1836   [(set (match_dup 2) (match_dup 1))
1837    (set (match_dup 0) (match_dup 2))]
1838   "")
1839
1840 ;; We need to define this as both peepholer and splitter for case
1841 ;; peephole2 pass is not run.
1842 ;; "&& 1" is needed to keep it from matching the previous pattern.
1843 (define_peephole2
1844   [(set (match_operand:DI 0 "push_operand" "")
1845         (match_operand:DI 1 "immediate_operand" ""))]
1846   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1847    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1848   [(set (match_dup 0) (match_dup 1))
1849    (set (match_dup 2) (match_dup 3))]
1850   "split_di (operands + 1, 1, operands + 2, operands + 3);
1851    operands[1] = gen_lowpart (DImode, operands[2]);
1852    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1853                                                     GEN_INT (4)));
1854   ")
1855
1856 (define_split
1857   [(set (match_operand:DI 0 "push_operand" "")
1858         (match_operand:DI 1 "immediate_operand" ""))]
1859   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1860    && !symbolic_operand (operands[1], DImode)
1861    && !x86_64_immediate_operand (operands[1], DImode)"
1862   [(set (match_dup 0) (match_dup 1))
1863    (set (match_dup 2) (match_dup 3))]
1864   "split_di (operands + 1, 1, operands + 2, operands + 3);
1865    operands[1] = gen_lowpart (DImode, operands[2]);
1866    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867                                                     GEN_INT (4)));
1868   ")
1869
1870 (define_insn "*pushdi2_prologue_rex64"
1871   [(set (match_operand:DI 0 "push_operand" "=<")
1872         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1873    (clobber (mem:BLK (scratch)))]
1874   "TARGET_64BIT"
1875   "push{q}\t%1"
1876   [(set_attr "type" "push")
1877    (set_attr "mode" "DI")])
1878
1879 (define_insn "*popdi1_epilogue_rex64"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881         (mem:DI (reg:DI SP_REG)))
1882    (set (reg:DI SP_REG)
1883         (plus:DI (reg:DI SP_REG) (const_int 8)))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "pop{q}\t%0"
1887   [(set_attr "type" "pop")
1888    (set_attr "mode" "DI")])
1889
1890 (define_insn "popdi1"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1899
1900 (define_insn "*movdi_xor_rex64"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (match_operand:DI 1 "const0_operand" "i"))
1903    (clobber (reg:CC FLAGS_REG))]
1904   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1905    && reload_completed"
1906   "xor{l}\t{%k0, %k0|%k0, %k0}"
1907   [(set_attr "type" "alu1")
1908    (set_attr "mode" "SI")
1909    (set_attr "length_immediate" "0")])
1910
1911 (define_insn "*movdi_or_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const_int_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1916    && reload_completed
1917    && operands[1] == constm1_rtx"
1918 {
1919   operands[1] = constm1_rtx;
1920   return "or{q}\t{%1, %0|%0, %1}";
1921 }
1922   [(set_attr "type" "alu1")
1923    (set_attr "mode" "DI")
1924    (set_attr "length_immediate" "1")])
1925
1926 (define_insn "*movdi_2"
1927   [(set (match_operand:DI 0 "nonimmediate_operand"
1928                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1929         (match_operand:DI 1 "general_operand"
1930                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1931   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932   "@
1933    #
1934    #
1935    pxor\t%0, %0
1936    movq\t{%1, %0|%0, %1}
1937    movq\t{%1, %0|%0, %1}
1938    pxor\t%0, %0
1939    movq\t{%1, %0|%0, %1}
1940    movdqa\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    xorps\t%0, %0
1943    movlps\t{%1, %0|%0, %1}
1944    movaps\t{%1, %0|%0, %1}
1945    movlps\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1947    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1948
1949 (define_split
1950   [(set (match_operand:DI 0 "push_operand" "")
1951         (match_operand:DI 1 "general_operand" ""))]
1952   "!TARGET_64BIT && reload_completed
1953    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1954   [(const_int 0)]
1955   "ix86_split_long_move (operands); DONE;")
1956
1957 ;; %%% This multiword shite has got to go.
1958 (define_split
1959   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1960         (match_operand:DI 1 "general_operand" ""))]
1961   "!TARGET_64BIT && reload_completed
1962    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1963    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1966
1967 (define_insn "*movdi_1_rex64"
1968   [(set (match_operand:DI 0 "nonimmediate_operand"
1969                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1970         (match_operand:DI 1 "general_operand"
1971                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1972   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1973 {
1974   switch (get_attr_type (insn))
1975     {
1976     case TYPE_SSECVT:
1977       if (which_alternative == 13)
1978         return "movq2dq\t{%1, %0|%0, %1}";
1979       else
1980         return "movdq2q\t{%1, %0|%0, %1}";
1981     case TYPE_SSEMOV:
1982       if (get_attr_mode (insn) == MODE_TI)
1983           return "movdqa\t{%1, %0|%0, %1}";
1984       /* FALLTHRU */
1985     case TYPE_MMXMOV:
1986       /* Moves from and into integer register is done using movd opcode with
1987          REX prefix.  */
1988       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1989           return "movd\t{%1, %0|%0, %1}";
1990       return "movq\t{%1, %0|%0, %1}";
1991     case TYPE_SSELOG1:
1992     case TYPE_MMXADD:
1993       return "pxor\t%0, %0";
1994     case TYPE_MULTI:
1995       return "#";
1996     case TYPE_LEA:
1997       return "lea{q}\t{%a1, %0|%0, %a1}";
1998     default:
1999       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000       if (get_attr_mode (insn) == MODE_SI)
2001         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002       else if (which_alternative == 2)
2003         return "movabs{q}\t{%1, %0|%0, %1}";
2004       else
2005         return "mov{q}\t{%1, %0|%0, %1}";
2006     }
2007 }
2008   [(set (attr "type")
2009      (cond [(eq_attr "alternative" "5")
2010               (const_string "mmx")
2011             (eq_attr "alternative" "6,7,8")
2012               (const_string "mmxmov")
2013             (eq_attr "alternative" "9")
2014               (const_string "sselog1")
2015             (eq_attr "alternative" "10,11,12")
2016               (const_string "ssemov")
2017             (eq_attr "alternative" "13,14")
2018               (const_string "ssecvt")
2019             (eq_attr "alternative" "4")
2020               (const_string "multi")
2021             (match_operand:DI 1 "pic_32bit_operand" "")
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2026    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2027    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2028
2029 ;; Stores and loads of ax to arbitrary constant address.
2030 ;; We fake an second form of instruction to force reload to load address
2031 ;; into register when rax is not available
2032 (define_insn "*movabsdi_1_rex64"
2033   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2034         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2035   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2036   "@
2037    movabs{q}\t{%1, %P0|%P0, %1}
2038    mov{q}\t{%1, %a0|%a0, %1}"
2039   [(set_attr "type" "imov")
2040    (set_attr "modrm" "0,*")
2041    (set_attr "length_address" "8,0")
2042    (set_attr "length_immediate" "0,*")
2043    (set_attr "memory" "store")
2044    (set_attr "mode" "DI")])
2045
2046 (define_insn "*movabsdi_2_rex64"
2047   [(set (match_operand:DI 0 "register_operand" "=a,r")
2048         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2049   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2050   "@
2051    movabs{q}\t{%P1, %0|%0, %P1}
2052    mov{q}\t{%a1, %0|%0, %a1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "modrm" "0,*")
2055    (set_attr "length_address" "8,0")
2056    (set_attr "length_immediate" "0")
2057    (set_attr "memory" "load")
2058    (set_attr "mode" "DI")])
2059
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it.  In case this
2062 ;; fails, move by 32bit parts.
2063 (define_peephole2
2064   [(match_scratch:DI 2 "r")
2065    (set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068    && !x86_64_immediate_operand (operands[1], DImode)"
2069   [(set (match_dup 2) (match_dup 1))
2070    (set (match_dup 0) (match_dup 2))]
2071   "")
2072
2073 ;; We need to define this as both peepholer and splitter for case
2074 ;; peephole2 pass is not run.
2075 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 (define_peephole2
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2081   [(set (match_dup 2) (match_dup 3))
2082    (set (match_dup 4) (match_dup 5))]
2083   "split_di (operands, 2, operands + 2, operands + 4);")
2084
2085 (define_split
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2089    && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode)"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2094
2095 (define_insn "*swapdi_rex64"
2096   [(set (match_operand:DI 0 "register_operand" "+r")
2097         (match_operand:DI 1 "register_operand" "+r"))
2098    (set (match_dup 1)
2099         (match_dup 0))]
2100   "TARGET_64BIT"
2101   "xchg{q}\t%1, %0"
2102   [(set_attr "type" "imov")
2103    (set_attr "mode" "DI")
2104    (set_attr "pent_pair" "np")
2105    (set_attr "athlon_decode" "vector")])
2106
2107 (define_expand "movti"
2108   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2109         (match_operand:TI 1 "nonimmediate_operand" ""))]
2110   "TARGET_SSE || TARGET_64BIT"
2111 {
2112   if (TARGET_64BIT)
2113     ix86_expand_move (TImode, operands);
2114   else
2115     ix86_expand_vector_move (TImode, operands);
2116   DONE;
2117 })
2118
2119 (define_insn "*movti_internal"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2121         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2122   "TARGET_SSE && !TARGET_64BIT
2123    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2124 {
2125   switch (which_alternative)
2126     {
2127     case 0:
2128       if (get_attr_mode (insn) == MODE_V4SF)
2129         return "xorps\t%0, %0";
2130       else
2131         return "pxor\t%0, %0";
2132     case 1:
2133     case 2:
2134       if (get_attr_mode (insn) == MODE_V4SF)
2135         return "movaps\t{%1, %0|%0, %1}";
2136       else
2137         return "movdqa\t{%1, %0|%0, %1}";
2138     default:
2139       gcc_unreachable ();
2140     }
2141 }
2142   [(set_attr "type" "ssemov,ssemov,ssemov")
2143    (set (attr "mode")
2144         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2145                  (const_string "V4SF")
2146
2147                (eq_attr "alternative" "0,1")
2148                  (if_then_else
2149                    (ne (symbol_ref "optimize_size")
2150                        (const_int 0))
2151                    (const_string "V4SF")
2152                    (const_string "TI"))
2153                (eq_attr "alternative" "2")
2154                  (if_then_else
2155                    (ne (symbol_ref "optimize_size")
2156                        (const_int 0))
2157                    (const_string "V4SF")
2158                    (const_string "TI"))]
2159                (const_string "TI")))])
2160
2161 (define_insn "*movti_rex64"
2162   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2163         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2164   "TARGET_64BIT
2165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2166 {
2167   switch (which_alternative)
2168     {
2169     case 0:
2170     case 1:
2171       return "#";
2172     case 2:
2173       if (get_attr_mode (insn) == MODE_V4SF)
2174         return "xorps\t%0, %0";
2175       else
2176         return "pxor\t%0, %0";
2177     case 3:
2178     case 4:
2179       if (get_attr_mode (insn) == MODE_V4SF)
2180         return "movaps\t{%1, %0|%0, %1}";
2181       else
2182         return "movdqa\t{%1, %0|%0, %1}";
2183     default:
2184       gcc_unreachable ();
2185     }
2186 }
2187   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2188    (set (attr "mode")
2189         (cond [(eq_attr "alternative" "2,3")
2190                  (if_then_else
2191                    (ne (symbol_ref "optimize_size")
2192                        (const_int 0))
2193                    (const_string "V4SF")
2194                    (const_string "TI"))
2195                (eq_attr "alternative" "4")
2196                  (if_then_else
2197                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2198                             (const_int 0))
2199                         (ne (symbol_ref "optimize_size")
2200                             (const_int 0)))
2201                    (const_string "V4SF")
2202                    (const_string "TI"))]
2203                (const_string "DI")))])
2204
2205 (define_split
2206   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2207         (match_operand:TI 1 "general_operand" ""))]
2208   "reload_completed && !SSE_REG_P (operands[0])
2209    && !SSE_REG_P (operands[1])"
2210   [(const_int 0)]
2211   "ix86_split_long_move (operands); DONE;")
2212
2213 (define_expand "movsf"
2214   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2215         (match_operand:SF 1 "general_operand" ""))]
2216   ""
2217   "ix86_expand_move (SFmode, operands); DONE;")
2218
2219 (define_insn "*pushsf"
2220   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2221         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2222   "!TARGET_64BIT"
2223 {
2224   /* Anything else should be already split before reg-stack.  */
2225   gcc_assert (which_alternative == 1);
2226   return "push{l}\t%1";
2227 }
2228   [(set_attr "type" "multi,push,multi")
2229    (set_attr "unit" "i387,*,*")
2230    (set_attr "mode" "SF,SI,SF")])
2231
2232 (define_insn "*pushsf_rex64"
2233   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2234         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2235   "TARGET_64BIT"
2236 {
2237   /* Anything else should be already split before reg-stack.  */
2238   gcc_assert (which_alternative == 1);
2239   return "push{q}\t%q1";
2240 }
2241   [(set_attr "type" "multi,push,multi")
2242    (set_attr "unit" "i387,*,*")
2243    (set_attr "mode" "SF,DI,SF")])
2244
2245 (define_split
2246   [(set (match_operand:SF 0 "push_operand" "")
2247         (match_operand:SF 1 "memory_operand" ""))]
2248   "reload_completed
2249    && GET_CODE (operands[1]) == MEM
2250    && constant_pool_reference_p (operands[1])"
2251   [(set (match_dup 0)
2252         (match_dup 1))]
2253   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2254
2255
2256 ;; %%% Kill this when call knows how to work this out.
2257 (define_split
2258   [(set (match_operand:SF 0 "push_operand" "")
2259         (match_operand:SF 1 "any_fp_register_operand" ""))]
2260   "!TARGET_64BIT"
2261   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2262    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2263
2264 (define_split
2265   [(set (match_operand:SF 0 "push_operand" "")
2266         (match_operand:SF 1 "any_fp_register_operand" ""))]
2267   "TARGET_64BIT"
2268   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2269    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2270
2271 (define_insn "*movsf_1"
2272   [(set (match_operand:SF 0 "nonimmediate_operand"
2273           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2274         (match_operand:SF 1 "general_operand"
2275           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2276   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2277    && (reload_in_progress || reload_completed
2278        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2279        || GET_CODE (operands[1]) != CONST_DOUBLE
2280        || memory_operand (operands[0], SFmode))" 
2281 {
2282   switch (which_alternative)
2283     {
2284     case 0:
2285       return output_387_reg_move (insn, operands);
2286
2287     case 1:
2288       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2289         return "fstp%z0\t%y0";
2290       else
2291         return "fst%z0\t%y0";
2292
2293     case 2:
2294       return standard_80387_constant_opcode (operands[1]);
2295
2296     case 3:
2297     case 4:
2298       return "mov{l}\t{%1, %0|%0, %1}";
2299     case 5:
2300       if (get_attr_mode (insn) == MODE_TI)
2301         return "pxor\t%0, %0";
2302       else
2303         return "xorps\t%0, %0";
2304     case 6:
2305       if (get_attr_mode (insn) == MODE_V4SF)
2306         return "movaps\t{%1, %0|%0, %1}";
2307       else
2308         return "movss\t{%1, %0|%0, %1}";
2309     case 7:
2310     case 8:
2311       return "movss\t{%1, %0|%0, %1}";
2312
2313     case 9:
2314     case 10:
2315       return "movd\t{%1, %0|%0, %1}";
2316
2317     case 11:
2318       return "movq\t{%1, %0|%0, %1}";
2319
2320     default:
2321       gcc_unreachable ();
2322     }
2323 }
2324   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2325    (set (attr "mode")
2326         (cond [(eq_attr "alternative" "3,4,9,10")
2327                  (const_string "SI")
2328                (eq_attr "alternative" "5")
2329                  (if_then_else
2330                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2331                                  (const_int 0))
2332                              (ne (symbol_ref "TARGET_SSE2")
2333                                  (const_int 0)))
2334                         (eq (symbol_ref "optimize_size")
2335                             (const_int 0)))
2336                    (const_string "TI")
2337                    (const_string "V4SF"))
2338                /* For architectures resolving dependencies on
2339                   whole SSE registers use APS move to break dependency
2340                   chains, otherwise use short move to avoid extra work. 
2341
2342                   Do the same for architectures resolving dependencies on
2343                   the parts.  While in DF mode it is better to always handle
2344                   just register parts, the SF mode is different due to lack
2345                   of instructions to load just part of the register.  It is
2346                   better to maintain the whole registers in single format
2347                   to avoid problems on using packed logical operations.  */
2348                (eq_attr "alternative" "6")
2349                  (if_then_else
2350                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2351                             (const_int 0))
2352                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2353                             (const_int 0)))
2354                    (const_string "V4SF")
2355                    (const_string "SF"))
2356                (eq_attr "alternative" "11")
2357                  (const_string "DI")]
2358                (const_string "SF")))])
2359
2360 (define_insn "*swapsf"
2361   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2362         (match_operand:SF 1 "fp_register_operand" "+f"))
2363    (set (match_dup 1)
2364         (match_dup 0))]
2365   "reload_completed || TARGET_80387"
2366 {
2367   if (STACK_TOP_P (operands[0]))
2368     return "fxch\t%1";
2369   else
2370     return "fxch\t%0";
2371 }
2372   [(set_attr "type" "fxch")
2373    (set_attr "mode" "SF")])
2374
2375 (define_expand "movdf"
2376   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2377         (match_operand:DF 1 "general_operand" ""))]
2378   ""
2379   "ix86_expand_move (DFmode, operands); DONE;")
2380
2381 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2382 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2383 ;; On the average, pushdf using integers can be still shorter.  Allow this
2384 ;; pattern for optimize_size too.
2385
2386 (define_insn "*pushdf_nointeger"
2387   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2388         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2389   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2390 {
2391   /* This insn should be already split before reg-stack.  */
2392   gcc_unreachable ();
2393 }
2394   [(set_attr "type" "multi")
2395    (set_attr "unit" "i387,*,*,*")
2396    (set_attr "mode" "DF,SI,SI,DF")])
2397
2398 (define_insn "*pushdf_integer"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2401   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2402 {
2403   /* This insn should be already split before reg-stack.  */
2404   gcc_unreachable ();
2405 }
2406   [(set_attr "type" "multi")
2407    (set_attr "unit" "i387,*,*")
2408    (set_attr "mode" "DF,SI,DF")])
2409
2410 ;; %%% Kill this when call knows how to work this out.
2411 (define_split
2412   [(set (match_operand:DF 0 "push_operand" "")
2413         (match_operand:DF 1 "any_fp_register_operand" ""))]
2414   "!TARGET_64BIT && reload_completed"
2415   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2416    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2417   "")
2418
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "TARGET_64BIT && reload_completed"
2423   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2425   "")
2426
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "general_operand" ""))]
2430   "reload_completed"
2431   [(const_int 0)]
2432   "ix86_split_long_move (operands); DONE;")
2433
2434 ;; Moving is usually shorter when only FP registers are used. This separate
2435 ;; movdf pattern avoids the use of integer registers for FP operations
2436 ;; when optimizing for size.
2437
2438 (define_insn "*movdf_nointeger"
2439   [(set (match_operand:DF 0 "nonimmediate_operand"
2440                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2441         (match_operand:DF 1 "general_operand"
2442                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2443   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2444    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2445    && (reload_in_progress || reload_completed
2446        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2447        || GET_CODE (operands[1]) != CONST_DOUBLE
2448        || memory_operand (operands[0], DFmode))" 
2449 {
2450   switch (which_alternative)
2451     {
2452     case 0:
2453       return output_387_reg_move (insn, operands);
2454
2455     case 1:
2456       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2457         return "fstp%z0\t%y0";
2458       else
2459         return "fst%z0\t%y0";
2460
2461     case 2:
2462       return standard_80387_constant_opcode (operands[1]);
2463
2464     case 3:
2465     case 4:
2466       return "#";
2467     case 5:
2468       switch (get_attr_mode (insn))
2469         {
2470         case MODE_V4SF:
2471           return "xorps\t%0, %0";
2472         case MODE_V2DF:
2473           return "xorpd\t%0, %0";
2474         case MODE_TI:
2475           return "pxor\t%0, %0";
2476         default:
2477           gcc_unreachable ();
2478         }
2479     case 6:
2480     case 7:
2481     case 8:
2482       switch (get_attr_mode (insn))
2483         {
2484         case MODE_V4SF:
2485           return "movaps\t{%1, %0|%0, %1}";
2486         case MODE_V2DF:
2487           return "movapd\t{%1, %0|%0, %1}";
2488         case MODE_TI:
2489           return "movdqa\t{%1, %0|%0, %1}";
2490         case MODE_DI:
2491           return "movq\t{%1, %0|%0, %1}";
2492         case MODE_DF:
2493           return "movsd\t{%1, %0|%0, %1}";
2494         case MODE_V1DF:
2495           return "movlpd\t{%1, %0|%0, %1}";
2496         case MODE_V2SF:
2497           return "movlps\t{%1, %0|%0, %1}";
2498         default:
2499           gcc_unreachable ();
2500         }
2501
2502     default:
2503       gcc_unreachable ();
2504     }
2505 }
2506   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2507    (set (attr "mode")
2508         (cond [(eq_attr "alternative" "0,1,2")
2509                  (const_string "DF")
2510                (eq_attr "alternative" "3,4")
2511                  (const_string "SI")
2512
2513                /* For SSE1, we have many fewer alternatives.  */
2514                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2515                  (cond [(eq_attr "alternative" "5,6")
2516                           (const_string "V4SF")
2517                        ]
2518                    (const_string "V2SF"))
2519
2520                /* xorps is one byte shorter.  */
2521                (eq_attr "alternative" "5")
2522                  (cond [(ne (symbol_ref "optimize_size")
2523                             (const_int 0))
2524                           (const_string "V4SF")
2525                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2526                             (const_int 0))
2527                           (const_string "TI")
2528                        ]
2529                        (const_string "V2DF"))
2530
2531                /* For architectures resolving dependencies on
2532                   whole SSE registers use APD move to break dependency
2533                   chains, otherwise use short move to avoid extra work.
2534
2535                   movaps encodes one byte shorter.  */
2536                (eq_attr "alternative" "6")
2537                  (cond
2538                    [(ne (symbol_ref "optimize_size")
2539                         (const_int 0))
2540                       (const_string "V4SF")
2541                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2542                         (const_int 0))
2543                       (const_string "V2DF")
2544                    ]
2545                    (const_string "DF"))
2546                /* For architectures resolving dependencies on register
2547                   parts we may avoid extra work to zero out upper part
2548                   of register.  */
2549                (eq_attr "alternative" "7")
2550                  (if_then_else
2551                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2552                        (const_int 0))
2553                    (const_string "V1DF")
2554                    (const_string "DF"))
2555               ]
2556               (const_string "DF")))])
2557
2558 (define_insn "*movdf_integer"
2559   [(set (match_operand:DF 0 "nonimmediate_operand"
2560                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2561         (match_operand:DF 1 "general_operand"
2562                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2563   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2564    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2565    && (reload_in_progress || reload_completed
2566        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2567        || GET_CODE (operands[1]) != CONST_DOUBLE
2568        || memory_operand (operands[0], DFmode))" 
2569 {
2570   switch (which_alternative)
2571     {
2572     case 0:
2573       return output_387_reg_move (insn, operands);
2574
2575     case 1:
2576       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2577         return "fstp%z0\t%y0";
2578       else
2579         return "fst%z0\t%y0";
2580
2581     case 2:
2582       return standard_80387_constant_opcode (operands[1]);
2583
2584     case 3:
2585     case 4:
2586       return "#";
2587
2588     case 5:
2589       switch (get_attr_mode (insn))
2590         {
2591         case MODE_V4SF:
2592           return "xorps\t%0, %0";
2593         case MODE_V2DF:
2594           return "xorpd\t%0, %0";
2595         case MODE_TI:
2596           return "pxor\t%0, %0";
2597         default:
2598           gcc_unreachable ();
2599         }
2600     case 6:
2601     case 7:
2602     case 8:
2603       switch (get_attr_mode (insn))
2604         {
2605         case MODE_V4SF:
2606           return "movaps\t{%1, %0|%0, %1}";
2607         case MODE_V2DF:
2608           return "movapd\t{%1, %0|%0, %1}";
2609         case MODE_TI:
2610           return "movdqa\t{%1, %0|%0, %1}";
2611         case MODE_DI:
2612           return "movq\t{%1, %0|%0, %1}";
2613         case MODE_DF:
2614           return "movsd\t{%1, %0|%0, %1}";
2615         case MODE_V1DF:
2616           return "movlpd\t{%1, %0|%0, %1}";
2617         case MODE_V2SF:
2618           return "movlps\t{%1, %0|%0, %1}";
2619         default:
2620           gcc_unreachable ();
2621         }
2622
2623     default:
2624       gcc_unreachable();
2625     }
2626 }
2627   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628    (set (attr "mode")
2629         (cond [(eq_attr "alternative" "0,1,2")
2630                  (const_string "DF")
2631                (eq_attr "alternative" "3,4")
2632                  (const_string "SI")
2633
2634                /* For SSE1, we have many fewer alternatives.  */
2635                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636                  (cond [(eq_attr "alternative" "5,6")
2637                           (const_string "V4SF")
2638                        ]
2639                    (const_string "V2SF"))
2640
2641                /* xorps is one byte shorter.  */
2642                (eq_attr "alternative" "5")
2643                  (cond [(ne (symbol_ref "optimize_size")
2644                             (const_int 0))
2645                           (const_string "V4SF")
2646                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647                             (const_int 0))
2648                           (const_string "TI")
2649                        ]
2650                        (const_string "V2DF"))
2651
2652                /* For architectures resolving dependencies on
2653                   whole SSE registers use APD move to break dependency
2654                   chains, otherwise use short move to avoid extra work.
2655
2656                   movaps encodes one byte shorter.  */
2657                (eq_attr "alternative" "6")
2658                  (cond
2659                    [(ne (symbol_ref "optimize_size")
2660                         (const_int 0))
2661                       (const_string "V4SF")
2662                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663                         (const_int 0))
2664                       (const_string "V2DF")
2665                    ]
2666                    (const_string "DF"))
2667                /* For architectures resolving dependencies on register
2668                   parts we may avoid extra work to zero out upper part
2669                   of register.  */
2670                (eq_attr "alternative" "7")
2671                  (if_then_else
2672                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                        (const_int 0))
2674                    (const_string "V1DF")
2675                    (const_string "DF"))
2676               ]
2677               (const_string "DF")))])
2678
2679 (define_split
2680   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2681         (match_operand:DF 1 "general_operand" ""))]
2682   "reload_completed
2683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2684    && ! (ANY_FP_REG_P (operands[0]) || 
2685          (GET_CODE (operands[0]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2687    && ! (ANY_FP_REG_P (operands[1]) || 
2688          (GET_CODE (operands[1]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2692
2693 (define_insn "*swapdf"
2694   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2695         (match_operand:DF 1 "fp_register_operand" "+f"))
2696    (set (match_dup 1)
2697         (match_dup 0))]
2698   "reload_completed || TARGET_80387"
2699 {
2700   if (STACK_TOP_P (operands[0]))
2701     return "fxch\t%1";
2702   else
2703     return "fxch\t%0";
2704 }
2705   [(set_attr "type" "fxch")
2706    (set_attr "mode" "DF")])
2707
2708 (define_expand "movxf"
2709   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2710         (match_operand:XF 1 "general_operand" ""))]
2711   ""
2712   "ix86_expand_move (XFmode, operands); DONE;")
2713
2714 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2715 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2716 ;; Pushing using integer instructions is longer except for constants
2717 ;; and direct memory references.
2718 ;; (assuming that any given constant is pushed only once, but this ought to be
2719 ;;  handled elsewhere).
2720
2721 (define_insn "*pushxf_nointeger"
2722   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2723         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2724   "optimize_size"
2725 {
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2728 }
2729   [(set_attr "type" "multi")
2730    (set_attr "unit" "i387,*,*")
2731    (set_attr "mode" "XF,SI,SI")])
2732
2733 (define_insn "*pushxf_integer"
2734   [(set (match_operand:XF 0 "push_operand" "=<,<")
2735         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2736   "!optimize_size"
2737 {
2738   /* This insn should be already split before reg-stack.  */
2739   gcc_unreachable ();
2740 }
2741   [(set_attr "type" "multi")
2742    (set_attr "unit" "i387,*")
2743    (set_attr "mode" "XF,SI")])
2744
2745 (define_split
2746   [(set (match_operand 0 "push_operand" "")
2747         (match_operand 1 "general_operand" ""))]
2748   "reload_completed
2749    && (GET_MODE (operands[0]) == XFmode
2750        || GET_MODE (operands[0]) == DFmode)
2751    && !ANY_FP_REG_P (operands[1])"
2752   [(const_int 0)]
2753   "ix86_split_long_move (operands); DONE;")
2754
2755 (define_split
2756   [(set (match_operand:XF 0 "push_operand" "")
2757         (match_operand:XF 1 "any_fp_register_operand" ""))]
2758   "!TARGET_64BIT"
2759   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2760    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2762
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "TARGET_64BIT"
2767   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2768    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770
2771 ;; Do not use integer registers when optimizing for size
2772 (define_insn "*movxf_nointeger"
2773   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2774         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775   "optimize_size
2776    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777    && (reload_in_progress || reload_completed
2778        || GET_CODE (operands[1]) != CONST_DOUBLE
2779        || memory_operand (operands[0], XFmode))" 
2780 {
2781   switch (which_alternative)
2782     {
2783     case 0:
2784       return output_387_reg_move (insn, operands);
2785
2786     case 1:
2787       /* There is no non-popping store to memory for XFmode.  So if
2788          we need one, follow the store with a load.  */
2789       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790         return "fstp%z0\t%y0\;fld%z0\t%y0";
2791       else
2792         return "fstp%z0\t%y0";
2793
2794     case 2:
2795       return standard_80387_constant_opcode (operands[1]);
2796
2797     case 3: case 4:
2798       return "#";
2799     default:
2800       gcc_unreachable ();
2801     }
2802 }
2803   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2804    (set_attr "mode" "XF,XF,XF,SI,SI")])
2805
2806 (define_insn "*movxf_integer"
2807   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2808         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2809   "!optimize_size
2810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2811    && (reload_in_progress || reload_completed
2812        || GET_CODE (operands[1]) != CONST_DOUBLE
2813        || memory_operand (operands[0], XFmode))" 
2814 {
2815   switch (which_alternative)
2816     {
2817     case 0:
2818       return output_387_reg_move (insn, operands);
2819
2820     case 1:
2821       /* There is no non-popping store to memory for XFmode.  So if
2822          we need one, follow the store with a load.  */
2823       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2824         return "fstp%z0\t%y0\;fld%z0\t%y0";
2825       else
2826         return "fstp%z0\t%y0";
2827
2828     case 2:
2829       return standard_80387_constant_opcode (operands[1]);
2830
2831     case 3: case 4:
2832       return "#";
2833
2834     default:
2835       gcc_unreachable ();
2836     }
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && constant_pool_reference_p (operands[1])"
2864   [(set (match_dup 0) (match_dup 1))]
2865 {
2866   rtx c = avoid_constant_pool_reference (operands[1]);
2867   rtx r = operands[0];
2868
2869   if (GET_CODE (r) == SUBREG)
2870     r = SUBREG_REG (r);
2871
2872   if (SSE_REG_P (r))
2873     {
2874       if (!standard_sse_constant_p (c))
2875         FAIL;
2876     }
2877   else if (FP_REG_P (r))
2878     {
2879       if (!standard_80387_constant_p (c))
2880         FAIL;
2881     }
2882   else if (MMX_REG_P (r))
2883     FAIL;
2884
2885   operands[1] = c;
2886 })
2887
2888 (define_insn "swapxf"
2889   [(set (match_operand:XF 0 "register_operand" "+f")
2890         (match_operand:XF 1 "register_operand" "+f"))
2891    (set (match_dup 1)
2892         (match_dup 0))]
2893   "TARGET_80387"
2894 {
2895   if (STACK_TOP_P (operands[0]))
2896     return "fxch\t%1";
2897   else
2898     return "fxch\t%0";
2899 }
2900   [(set_attr "type" "fxch")
2901    (set_attr "mode" "XF")])
2902
2903 (define_expand "movtf"
2904   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2905         (match_operand:TF 1 "nonimmediate_operand" ""))]
2906   "TARGET_64BIT"
2907 {
2908   ix86_expand_move (TFmode, operands);
2909   DONE;
2910 })
2911
2912 (define_insn "*movtf_internal"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2914         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2915   "TARGET_64BIT
2916    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2917 {
2918   switch (which_alternative)
2919     {
2920     case 0:
2921     case 1:
2922       return "#";
2923     case 2:
2924       if (get_attr_mode (insn) == MODE_V4SF)
2925         return "xorps\t%0, %0";
2926       else
2927         return "pxor\t%0, %0";
2928     case 3:
2929     case 4:
2930       if (get_attr_mode (insn) == MODE_V4SF)
2931         return "movaps\t{%1, %0|%0, %1}";
2932       else
2933         return "movdqa\t{%1, %0|%0, %1}";
2934     default:
2935       gcc_unreachable ();
2936     }
2937 }
2938   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2939    (set (attr "mode")
2940         (cond [(eq_attr "alternative" "2,3")
2941                  (if_then_else
2942                    (ne (symbol_ref "optimize_size")
2943                        (const_int 0))
2944                    (const_string "V4SF")
2945                    (const_string "TI"))
2946                (eq_attr "alternative" "4")
2947                  (if_then_else
2948                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2949                             (const_int 0))
2950                         (ne (symbol_ref "optimize_size")
2951                             (const_int 0)))
2952                    (const_string "V4SF")
2953                    (const_string "TI"))]
2954                (const_string "DI")))])
2955
2956 (define_split
2957   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2958         (match_operand:TF 1 "general_operand" ""))]
2959   "reload_completed && !SSE_REG_P (operands[0])
2960    && !SSE_REG_P (operands[1])"
2961   [(const_int 0)]
2962   "ix86_split_long_move (operands); DONE;")
2963 \f
2964 ;; Zero extension instructions
2965
2966 (define_expand "zero_extendhisi2"
2967   [(set (match_operand:SI 0 "register_operand" "")
2968      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2969   ""
2970 {
2971   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2972     {
2973       operands[1] = force_reg (HImode, operands[1]);
2974       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2975       DONE;
2976     }
2977 })
2978
2979 (define_insn "zero_extendhisi2_and"
2980   [(set (match_operand:SI 0 "register_operand" "=r")
2981      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984   "#"
2985   [(set_attr "type" "alu1")
2986    (set_attr "mode" "SI")])
2987
2988 (define_split
2989   [(set (match_operand:SI 0 "register_operand" "")
2990         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2994               (clobber (reg:CC FLAGS_REG))])]
2995   "")
2996
2997 (define_insn "*zero_extendhisi2_movzwl"
2998   [(set (match_operand:SI 0 "register_operand" "=r")
2999      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3000   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3001   "movz{wl|x}\t{%1, %0|%0, %1}"
3002   [(set_attr "type" "imovx")
3003    (set_attr "mode" "SI")])
3004
3005 (define_expand "zero_extendqihi2"
3006   [(parallel
3007     [(set (match_operand:HI 0 "register_operand" "")
3008        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3009      (clobber (reg:CC FLAGS_REG))])]
3010   ""
3011   "")
3012
3013 (define_insn "*zero_extendqihi2_and"
3014   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3015      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018   "#"
3019   [(set_attr "type" "alu1")
3020    (set_attr "mode" "HI")])
3021
3022 (define_insn "*zero_extendqihi2_movzbw_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,r")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3027   "#"
3028   [(set_attr "type" "imovx,alu1")
3029    (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw"
3032   [(set (match_operand:HI 0 "register_operand" "=r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3035   "movz{bw|x}\t{%1, %0|%0, %1}"
3036   [(set_attr "type" "imovx")
3037    (set_attr "mode" "HI")])
3038
3039 ;; For the movzbw case strip only the clobber
3040 (define_split
3041   [(set (match_operand:HI 0 "register_operand" "")
3042         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "reload_completed 
3045    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3046    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3049
3050 ;; When source and destination does not overlap, clear destination
3051 ;; first and then do the movb
3052 (define_split
3053   [(set (match_operand:HI 0 "register_operand" "")
3054         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3055    (clobber (reg:CC FLAGS_REG))]
3056   "reload_completed
3057    && ANY_QI_REG_P (operands[0])
3058    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3059    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3060   [(set (match_dup 0) (const_int 0))
3061    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3062   "operands[2] = gen_lowpart (QImode, operands[0]);")
3063
3064 ;; Rest is handled by single and.
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && true_regnum (operands[0]) == true_regnum (operands[1])"
3071   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3072               (clobber (reg:CC FLAGS_REG))])]
3073   "")
3074
3075 (define_expand "zero_extendqisi2"
3076   [(parallel
3077     [(set (match_operand:SI 0 "register_operand" "")
3078        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3079      (clobber (reg:CC FLAGS_REG))])]
3080   ""
3081   "")
3082
3083 (define_insn "*zero_extendqisi2_and"
3084   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3088   "#"
3089   [(set_attr "type" "alu1")
3090    (set_attr "mode" "SI")])
3091
3092 (define_insn "*zero_extendqisi2_movzbw_and"
3093   [(set (match_operand:SI 0 "register_operand" "=r,r")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3097   "#"
3098   [(set_attr "type" "imovx,alu1")
3099    (set_attr "mode" "SI")])
3100
3101 (define_insn "*zero_extendqisi2_movzbw"
3102   [(set (match_operand:SI 0 "register_operand" "=r")
3103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3104   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3105   "movz{bl|x}\t{%1, %0|%0, %1}"
3106   [(set_attr "type" "imovx")
3107    (set_attr "mode" "SI")])
3108
3109 ;; For the movzbl case strip only the clobber
3110 (define_split
3111   [(set (match_operand:SI 0 "register_operand" "")
3112         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113    (clobber (reg:CC FLAGS_REG))]
3114   "reload_completed 
3115    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3116    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3117   [(set (match_dup 0)
3118         (zero_extend:SI (match_dup 1)))])
3119
3120 ;; When source and destination does not overlap, clear destination
3121 ;; first and then do the movb
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && ANY_QI_REG_P (operands[0])
3128    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3129    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3130    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3131   [(set (match_dup 0) (const_int 0))
3132    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3133   "operands[2] = gen_lowpart (QImode, operands[0]);")
3134
3135 ;; Rest is handled by single and.
3136 (define_split
3137   [(set (match_operand:SI 0 "register_operand" "")
3138         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3139    (clobber (reg:CC FLAGS_REG))]
3140   "reload_completed
3141    && true_regnum (operands[0]) == true_regnum (operands[1])"
3142   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3143               (clobber (reg:CC FLAGS_REG))])]
3144   "")
3145
3146 ;; %%% Kill me once multi-word ops are sane.
3147 (define_expand "zero_extendsidi2"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3150   ""
3151   "if (!TARGET_64BIT)
3152      {
3153        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3154        DONE;
3155      }
3156   ")
3157
3158 (define_insn "zero_extendsidi2_32"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3160         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3161    (clobber (reg:CC FLAGS_REG))]
3162   "!TARGET_64BIT"
3163   "@
3164    #
3165    #
3166    #
3167    movd\t{%1, %0|%0, %1}
3168    movd\t{%1, %0|%0, %1}"
3169   [(set_attr "mode" "SI,SI,SI,DI,TI")
3170    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3171
3172 (define_insn "zero_extendsidi2_rex64"
3173   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3174      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3175   "TARGET_64BIT"
3176   "@
3177    mov\t{%k1, %k0|%k0, %k1}
3178    #
3179    movd\t{%1, %0|%0, %1}
3180    movd\t{%1, %0|%0, %1}"
3181   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3182    (set_attr "mode" "SI,DI,SI,SI")])
3183
3184 (define_split
3185   [(set (match_operand:DI 0 "memory_operand" "")
3186      (zero_extend:DI (match_dup 0)))]
3187   "TARGET_64BIT"
3188   [(set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_split 
3192   [(set (match_operand:DI 0 "register_operand" "")
3193         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3194    (clobber (reg:CC FLAGS_REG))]
3195   "!TARGET_64BIT && reload_completed
3196    && true_regnum (operands[0]) == true_regnum (operands[1])"
3197   [(set (match_dup 4) (const_int 0))]
3198   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3199
3200 (define_split 
3201   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3202         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT && reload_completed
3205    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3206   [(set (match_dup 3) (match_dup 1))
3207    (set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_insn "zero_extendhidi2"
3211   [(set (match_operand:DI 0 "register_operand" "=r")
3212      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3213   "TARGET_64BIT"
3214   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "DI")])
3217
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3221   "TARGET_64BIT"
3222   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "DI")])
3225 \f
3226 ;; Sign extension instructions
3227
3228 (define_expand "extendsidi2"
3229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231               (clobber (reg:CC FLAGS_REG))
3232               (clobber (match_scratch:SI 2 ""))])]
3233   ""
3234 {
3235   if (TARGET_64BIT)
3236     {
3237       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3238       DONE;
3239     }
3240 })
3241
3242 (define_insn "*extendsidi2_1"
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245    (clobber (reg:CC FLAGS_REG))
3246    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3247   "!TARGET_64BIT"
3248   "#")
3249
3250 (define_insn "extendsidi2_rex64"
3251   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3253   "TARGET_64BIT"
3254   "@
3255    {cltq|cdqe}
3256    movs{lq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")
3259    (set_attr "prefix_0f" "0")
3260    (set_attr "modrm" "0,1")])
3261
3262 (define_insn "extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "TARGET_64BIT"
3266   "movs{wq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")])
3269
3270 (define_insn "extendqidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3273   "TARGET_64BIT"
3274   "movs{bq|x}\t{%1,%0|%0, %1}"
3275    [(set_attr "type" "imovx")
3276     (set_attr "mode" "DI")])
3277
3278 ;; Extend to memory case when source register does die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "(reload_completed
3285     && dead_or_set_p (insn, operands[1])
3286     && !reg_mentioned_p (operands[1], operands[0]))"
3287   [(set (match_dup 3) (match_dup 1))
3288    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289               (clobber (reg:CC FLAGS_REG))])
3290    (set (match_dup 4) (match_dup 1))]
3291   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292
3293 ;; Extend to memory case when source register does not die.
3294 (define_split 
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_operand:SI 2 "register_operand" ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   emit_move_insn (operands[3], operands[1]);
3305
3306   /* Generate a cltd if possible and doing so it profitable.  */
3307   if (true_regnum (operands[1]) == 0
3308       && true_regnum (operands[2]) == 1
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3312     }
3313   else
3314     {
3315       emit_move_insn (operands[2], operands[1]);
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3317     }
3318   emit_move_insn (operands[4], operands[2]);
3319   DONE;
3320 })
3321
3322 ;; Extend to register case.  Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3324 (define_split 
3325   [(set (match_operand:DI 0 "register_operand" "")
3326         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327    (clobber (reg:CC FLAGS_REG))
3328    (clobber (match_scratch:SI 2 ""))]
3329   "reload_completed"
3330   [(const_int 0)]
3331 {
3332   split_di (&operands[0], 1, &operands[3], &operands[4]);
3333
3334   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[3], operands[1]);
3336
3337   /* Generate a cltd if possible and doing so it profitable.  */
3338   if (true_regnum (operands[3]) == 0
3339       && (optimize_size || TARGET_USE_CLTD))
3340     {
3341       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3342       DONE;
3343     }
3344
3345   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[4], operands[1]);
3347
3348   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3349   DONE;
3350 })
3351
3352 (define_insn "extendhisi2"
3353   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355   ""
3356 {
3357   switch (get_attr_prefix_0f (insn))
3358     {
3359     case 0:
3360       return "{cwtl|cwde}";
3361     default:
3362       return "movs{wl|x}\t{%1,%0|%0, %1}";
3363     }
3364 }
3365   [(set_attr "type" "imovx")
3366    (set_attr "mode" "SI")
3367    (set (attr "prefix_0f")
3368      ;; movsx is short decodable while cwtl is vector decoded.
3369      (if_then_else (and (eq_attr "cpu" "!k6")
3370                         (eq_attr "alternative" "0"))
3371         (const_string "0")
3372         (const_string "1")))
3373    (set (attr "modrm")
3374      (if_then_else (eq_attr "prefix_0f" "0")
3375         (const_string "0")
3376         (const_string "1")))])
3377
3378 (define_insn "*extendhisi2_zext"
3379   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3380         (zero_extend:DI
3381           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382   "TARGET_64BIT"
3383 {
3384   switch (get_attr_prefix_0f (insn))
3385     {
3386     case 0:
3387       return "{cwtl|cwde}";
3388     default:
3389       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390     }
3391 }
3392   [(set_attr "type" "imovx")
3393    (set_attr "mode" "SI")
3394    (set (attr "prefix_0f")
3395      ;; movsx is short decodable while cwtl is vector decoded.
3396      (if_then_else (and (eq_attr "cpu" "!k6")
3397                         (eq_attr "alternative" "0"))
3398         (const_string "0")
3399         (const_string "1")))
3400    (set (attr "modrm")
3401      (if_then_else (eq_attr "prefix_0f" "0")
3402         (const_string "0")
3403         (const_string "1")))])
3404
3405 (define_insn "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408   ""
3409 {
3410   switch (get_attr_prefix_0f (insn))
3411     {
3412     case 0:
3413       return "{cbtw|cbw}";
3414     default:
3415       return "movs{bw|x}\t{%1,%0|%0, %1}";
3416     }
3417 }
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "HI")
3420    (set (attr "prefix_0f")
3421      ;; movsx is short decodable while cwtl is vector decoded.
3422      (if_then_else (and (eq_attr "cpu" "!k6")
3423                         (eq_attr "alternative" "0"))
3424         (const_string "0")
3425         (const_string "1")))
3426    (set (attr "modrm")
3427      (if_then_else (eq_attr "prefix_0f" "0")
3428         (const_string "0")
3429         (const_string "1")))])
3430
3431 (define_insn "extendqisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=r")
3433         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3434   ""
3435   "movs{bl|x}\t{%1,%0|%0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3438
3439 (define_insn "*extendqisi2_zext"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (zero_extend:DI
3442           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3443   "TARGET_64BIT"
3444   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3447 \f
3448 ;; Conversions between float and double.
3449
3450 ;; These are all no-ops in the model used for the 80387.  So just
3451 ;; emit moves.
3452
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3454 (define_insn "*dummy_extendsfdf2"
3455   [(set (match_operand:DF 0 "push_operand" "=<")
3456         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3457   "0"
3458   "#")
3459
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "!TARGET_64BIT"
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_split
3468   [(set (match_operand:DF 0 "push_operand" "")
3469         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3473
3474 (define_insn "*dummy_extendsfxf2"
3475   [(set (match_operand:XF 0 "push_operand" "=<")
3476         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3477   "0"
3478   "#")
3479
3480 (define_split
3481   [(set (match_operand:XF 0 "push_operand" "")
3482         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3483   ""
3484   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   "TARGET_64BIT"
3492   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3499   ""
3500   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   "TARGET_64BIT"
3508   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511
3512 (define_expand "extendsfdf2"
3513   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3516 {
3517   /* ??? Needed for compress_float_constant since all fp constants
3518      are LEGITIMATE_CONSTANT_P.  */
3519   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522     operands[1] = force_reg (SFmode, operands[1]);
3523 })
3524
3525 (define_insn "*extendsfdf2_mixed"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3530 {
3531   switch (which_alternative)
3532     {
3533     case 0:
3534       return output_387_reg_move (insn, operands);
3535
3536     case 1:
3537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538         return "fstp%z0\t%y0";
3539       else
3540         return "fst%z0\t%y0";
3541
3542     case 2:
3543       return "cvtss2sd\t{%1, %0|%0, %1}";
3544
3545     default:
3546       gcc_unreachable ();
3547     }
3548 }
3549   [(set_attr "type" "fmov,fmov,ssecvt")
3550    (set_attr "mode" "SF,XF,DF")])
3551
3552 (define_insn "*extendsfdf2_sse"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555   "TARGET_SSE2 && TARGET_SSE_MATH
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   "cvtss2sd\t{%1, %0|%0, %1}"
3558   [(set_attr "type" "ssecvt")
3559    (set_attr "mode" "DF")])
3560
3561 (define_insn "*extendsfdf2_i387"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3564   "TARGET_80387
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566 {
3567   switch (which_alternative)
3568     {
3569     case 0:
3570       return output_387_reg_move (insn, operands);
3571
3572     case 1:
3573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574         return "fstp%z0\t%y0";
3575       else
3576         return "fst%z0\t%y0";
3577
3578     default:
3579       gcc_unreachable ();
3580     }
3581 }
3582   [(set_attr "type" "fmov")
3583    (set_attr "mode" "SF,XF")])
3584
3585 (define_expand "extendsfxf2"
3586   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588   "TARGET_80387"
3589 {
3590   /* ??? Needed for compress_float_constant since all fp constants
3591      are LEGITIMATE_CONSTANT_P.  */
3592   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595     operands[1] = force_reg (SFmode, operands[1]);
3596 })
3597
3598 (define_insn "*extendsfxf2_i387"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3601   "TARGET_80387
3602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3603 {
3604   switch (which_alternative)
3605     {
3606     case 0:
3607       return output_387_reg_move (insn, operands);
3608
3609     case 1:
3610       /* There is no non-popping store to memory for XFmode.  So if
3611          we need one, follow the store with a load.  */
3612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613         return "fstp%z0\t%y0";
3614       else
3615         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3616
3617     default:
3618       gcc_unreachable ();
3619     }
3620 }
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF,XF")])
3623
3624 (define_expand "extenddfxf2"
3625   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627   "TARGET_80387"
3628 {
3629   /* ??? Needed for compress_float_constant since all fp constants
3630      are LEGITIMATE_CONSTANT_P.  */
3631   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_reg (DFmode, operands[1]);
3635 })
3636
3637 (define_insn "*extenddfxf2_i387"
3638   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3640   "TARGET_80387
3641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       return output_387_reg_move (insn, operands);
3647
3648     case 1:
3649       /* There is no non-popping store to memory for XFmode.  So if
3650          we need one, follow the store with a load.  */
3651       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653       else
3654         return "fstp%z0\t%y0";
3655
3656     default:
3657       gcc_unreachable ();
3658     }
3659 }
3660   [(set_attr "type" "fmov")
3661    (set_attr "mode" "DF,XF")])
3662
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case.  Otherwise this is just like a simple move
3666 ;; insn.  So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3668
3669 ;; Conversion from DFmode to SFmode.
3670
3671 (define_expand "truncdfsf2"
3672   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3673         (float_truncate:SF
3674           (match_operand:DF 1 "nonimmediate_operand" "")))]
3675   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3676 {
3677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678     operands[1] = force_reg (DFmode, operands[1]);
3679
3680   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3681     ;
3682   else if (flag_unsafe_math_optimizations)
3683     ;
3684   else
3685     {
3686       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3687       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3688       DONE;
3689     }
3690 })
3691
3692 (define_expand "truncdfsf2_with_temp"
3693   [(parallel [(set (match_operand:SF 0 "" "")
3694                    (float_truncate:SF (match_operand:DF 1 "" "")))
3695               (clobber (match_operand:SF 2 "" ""))])]
3696   "")
3697
3698 (define_insn "*truncdfsf_fast_mixed"
3699   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3700         (float_truncate:SF
3701           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3703 {
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708         return "fstp%z0\t%y0";
3709       else
3710         return "fst%z0\t%y0";
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713     case 2:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     default:
3716       gcc_unreachable ();
3717     }
3718 }
3719   [(set_attr "type" "fmov,fmov,ssecvt")
3720    (set_attr "mode" "SF")])
3721
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728   "TARGET_SSE2 && TARGET_SSE_MATH"
3729   "cvtsd2ss\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "ssecvt")
3731    (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_fast_i387"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737   "TARGET_80387 && flag_unsafe_math_optimizations"
3738   "* return output_387_reg_move (insn, operands);"
3739   [(set_attr "type" "fmov")
3740    (set_attr "mode" "SF")])
3741
3742 (define_insn "*truncdfsf_mixed"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3746    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3747   "TARGET_MIX_SSE_I387"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     case 1:
3757       return "#";
3758     case 2:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     default:
3761       gcc_unreachable ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,multi,ssecvt")
3765    (set_attr "unit" "*,i387,*")
3766    (set_attr "mode" "SF")])
3767
3768 (define_insn "*truncdfsf_i387"
3769   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3770         (float_truncate:SF
3771           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3772    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3773   "TARGET_80387"
3774 {
3775   switch (which_alternative)
3776     {
3777     case 0:
3778       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779         return "fstp%z0\t%y0";
3780       else
3781         return "fst%z0\t%y0";
3782     case 1:
3783       return "#";
3784     default:
3785       gcc_unreachable ();
3786     }
3787 }
3788   [(set_attr "type" "fmov,multi")
3789    (set_attr "unit" "*,i387")
3790    (set_attr "mode" "SF")])
3791
3792 (define_insn "*truncdfsf2_i387_1"
3793   [(set (match_operand:SF 0 "memory_operand" "=m")
3794         (float_truncate:SF
3795           (match_operand:DF 1 "register_operand" "f")))]
3796   "TARGET_80387
3797    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3798    && !TARGET_MIX_SSE_I387"
3799 {
3800   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801     return "fstp%z0\t%y0";
3802   else
3803     return "fst%z0\t%y0";
3804 }
3805   [(set_attr "type" "fmov")
3806    (set_attr "mode" "SF")])
3807
3808 (define_split
3809   [(set (match_operand:SF 0 "register_operand" "")
3810         (float_truncate:SF
3811          (match_operand:DF 1 "fp_register_operand" "")))
3812    (clobber (match_operand 2 "" ""))]
3813   "reload_completed"
3814   [(set (match_dup 2) (match_dup 1))
3815    (set (match_dup 0) (match_dup 2))]
3816 {
3817   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3818 })
3819
3820 ;; Conversion from XFmode to SFmode.
3821
3822 (define_expand "truncxfsf2"
3823   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3824                    (float_truncate:SF
3825                     (match_operand:XF 1 "register_operand" "")))
3826               (clobber (match_dup 2))])]
3827   "TARGET_80387"
3828 {
3829   if (flag_unsafe_math_optimizations)
3830     {
3831       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3832       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3833       if (reg != operands[0])
3834         emit_move_insn (operands[0], reg);
3835       DONE;
3836     }
3837   else
3838     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3839 })
3840
3841 (define_insn "*truncxfsf2_mixed"
3842   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3843         (float_truncate:SF
3844          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3845    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3846   "TARGET_MIX_SSE_I387"
3847 {
3848   gcc_assert (!which_alternative);
3849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850     return "fstp%z0\t%y0";
3851   else
3852     return "fst%z0\t%y0";
3853 }
3854   [(set_attr "type" "fmov,multi,multi,multi")
3855    (set_attr "unit" "*,i387,i387,i387")
3856    (set_attr "mode" "SF")])
3857
3858 (define_insn "truncxfsf2_i387_noop"
3859   [(set (match_operand:SF 0 "register_operand" "=f")
3860         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3861   "TARGET_80387 && flag_unsafe_math_optimizations"
3862 {
3863   return output_387_reg_move (insn, operands);
3864 }
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3867
3868 (define_insn "*truncxfsf2_i387"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3873   "TARGET_80387"
3874 {
3875   gcc_assert (!which_alternative);
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878    else
3879      return "fst%z0\t%y0";
3880 }
3881   [(set_attr "type" "fmov,multi,multi")
3882    (set_attr "unit" "*,i387,i387")
3883    (set_attr "mode" "SF")])
3884
3885 (define_insn "*truncxfsf2_i387_1"
3886   [(set (match_operand:SF 0 "memory_operand" "=m")
3887         (float_truncate:SF
3888          (match_operand:XF 1 "register_operand" "f")))]
3889   "TARGET_80387"
3890 {
3891   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3892     return "fstp%z0\t%y0";
3893   else
3894     return "fst%z0\t%y0";
3895 }
3896   [(set_attr "type" "fmov")
3897    (set_attr "mode" "SF")])
3898
3899 (define_split
3900   [(set (match_operand:SF 0 "register_operand" "")
3901         (float_truncate:SF
3902          (match_operand:XF 1 "register_operand" "")))
3903    (clobber (match_operand:SF 2 "memory_operand" ""))]
3904   "TARGET_80387 && reload_completed"
3905   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3906    (set (match_dup 0) (match_dup 2))]
3907   "")
3908
3909 (define_split
3910   [(set (match_operand:SF 0 "memory_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387"
3915   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3916   "")
3917
3918 ;; Conversion from XFmode to DFmode.
3919
3920 (define_expand "truncxfdf2"
3921   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3922                    (float_truncate:DF
3923                     (match_operand:XF 1 "register_operand" "")))
3924               (clobber (match_dup 2))])]
3925   "TARGET_80387"
3926 {
3927   if (flag_unsafe_math_optimizations)
3928     {
3929       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3930       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3931       if (reg != operands[0])
3932         emit_move_insn (operands[0], reg);
3933       DONE;
3934     }
3935   else
3936     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3937 })
3938
3939 (define_insn "*truncxfdf2_mixed"
3940   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3941         (float_truncate:DF
3942          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3943    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3944   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 {
3946   gcc_assert (!which_alternative);
3947   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948     return "fstp%z0\t%y0";
3949   else
3950     return "fst%z0\t%y0";
3951 }
3952   [(set_attr "type" "fmov,multi,multi,multi")
3953    (set_attr "unit" "*,i387,i387,i387")
3954    (set_attr "mode" "DF")])
3955
3956 (define_insn "truncxfdf2_i387_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3960 {
3961   return output_387_reg_move (insn, operands);
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "*truncxfdf2_i387"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3971   "TARGET_80387"
3972 {
3973   gcc_assert (!which_alternative);
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3978 }
3979   [(set_attr "type" "fmov,multi,multi")
3980    (set_attr "unit" "*,i387,i387")
3981    (set_attr "mode" "DF")])
3982
3983 (define_insn "*truncxfdf2_i387_1"
3984   [(set (match_operand:DF 0 "memory_operand" "=m")
3985         (float_truncate:DF
3986           (match_operand:XF 1 "register_operand" "f")))]
3987   "TARGET_80387"
3988 {
3989   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3990     return "fstp%z0\t%y0";
3991   else
3992     return "fst%z0\t%y0";
3993 }
3994   [(set_attr "type" "fmov")
3995    (set_attr "mode" "DF")])
3996
3997 (define_split
3998   [(set (match_operand:DF 0 "register_operand" "")
3999         (float_truncate:DF
4000          (match_operand:XF 1 "register_operand" "")))
4001    (clobber (match_operand:DF 2 "memory_operand" ""))]
4002   "TARGET_80387 && reload_completed"
4003   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4004    (set (match_dup 0) (match_dup 2))]
4005   "")
4006
4007 (define_split
4008   [(set (match_operand:DF 0 "memory_operand" "")
4009         (float_truncate:DF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:DF 2 "memory_operand" ""))]
4012   "TARGET_80387"
4013   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4014   "")
4015 \f
4016 ;; Signed conversion to DImode.
4017
4018 (define_expand "fix_truncxfdi2"
4019   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4021               (clobber (reg:CC FLAGS_REG))])]
4022   "TARGET_80387"
4023 {
4024   if (TARGET_FISTTP)
4025    {
4026      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4027      DONE;
4028    }
4029 })
4030
4031 (define_expand "fix_trunc<mode>di2"
4032   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4034               (clobber (reg:CC FLAGS_REG))])]
4035   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4036 {
4037   if (TARGET_FISTTP
4038       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4039    {
4040      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4041      DONE;
4042    }
4043   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4044    {
4045      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4046      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4047      if (out != operands[0])
4048         emit_move_insn (operands[0], out);
4049      DONE;
4050    }
4051 })
4052
4053 ;; Signed conversion to SImode.
4054
4055 (define_expand "fix_truncxfsi2"
4056   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4057                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4058               (clobber (reg:CC FLAGS_REG))])]
4059   "TARGET_80387"
4060 {
4061   if (TARGET_FISTTP)
4062    {
4063      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4064      DONE;
4065    }
4066 })
4067
4068 (define_expand "fix_trunc<mode>si2"
4069   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))])]
4072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4073 {
4074   if (TARGET_FISTTP
4075       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4076    {
4077      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4078      DONE;
4079    }
4080   if (SSE_FLOAT_MODE_P (<MODE>mode))
4081    {
4082      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4083      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4084      if (out != operands[0])
4085         emit_move_insn (operands[0], out);
4086      DONE;
4087    }
4088 })
4089
4090 ;; Signed conversion to HImode.
4091
4092 (define_expand "fix_trunc<mode>hi2"
4093   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4094                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4095               (clobber (reg:CC FLAGS_REG))])]
4096   "TARGET_80387
4097    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4098 {
4099   if (TARGET_FISTTP)
4100    {
4101      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4102      DONE;
4103    }
4104 })
4105
4106 ;; When SSE is available, it is always faster to use it!
4107 (define_insn "fix_truncsfdi_sse"
4108   [(set (match_operand:DI 0 "register_operand" "=r,r")
4109         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4110   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111   "cvttss2si{q}\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "sseicvt")
4113    (set_attr "mode" "SF")
4114    (set_attr "athlon_decode" "double,vector")])
4115
4116 (define_insn "fix_truncdfdi_sse"
4117   [(set (match_operand:DI 0 "register_operand" "=r,r")
4118         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4119   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "DF")
4123    (set_attr "athlon_decode" "double,vector")])
4124
4125 (define_insn "fix_truncsfsi_sse"
4126   [(set (match_operand:SI 0 "register_operand" "=r,r")
4127         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4128   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttss2si\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4133
4134 (define_insn "fix_truncdfsi_sse"
4135   [(set (match_operand:SI 0 "register_operand" "=r,r")
4136         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4137   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttsd2si\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "DF")
4141    (set_attr "athlon_decode" "double,vector")])
4142
4143 ;; Avoid vector decoded forms of the instruction.
4144 (define_peephole2
4145   [(match_scratch:DF 2 "Y")
4146    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4148   "TARGET_K8 && !optimize_size"
4149   [(set (match_dup 2) (match_dup 1))
4150    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151   "")
4152
4153 (define_peephole2
4154   [(match_scratch:SF 2 "x")
4155    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160   "")
4161
4162 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4163   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4164         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4165   "TARGET_80387 && TARGET_FISTTP
4166    && FLOAT_MODE_P (GET_MODE (operands[1]))
4167    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4168          && (TARGET_64BIT || <MODE>mode != DImode))
4169         && TARGET_SSE_MATH)
4170    && !(reload_completed || reload_in_progress)"
4171   "#"
4172   "&& 1"
4173   [(const_int 0)]
4174 {
4175   if (memory_operand (operands[0], VOIDmode))
4176     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4177   else
4178     {
4179       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4180       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4181                                                             operands[1],
4182                                                             operands[2]));
4183     }
4184   DONE;
4185 }
4186   [(set_attr "type" "fisttp")
4187    (set_attr "mode" "<MODE>")])
4188
4189 (define_insn "fix_trunc<mode>_i387_fisttp"
4190   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4191         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4192    (clobber (match_scratch:XF 2 "=&1f"))]
4193   "TARGET_80387 && TARGET_FISTTP
4194    && FLOAT_MODE_P (GET_MODE (operands[1]))
4195    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4196          && (TARGET_64BIT || <MODE>mode != DImode))
4197         && TARGET_SSE_MATH)"
4198   "* return output_fix_trunc (insn, operands, 1);"
4199   [(set_attr "type" "fisttp")
4200    (set_attr "mode" "<MODE>")])
4201
4202 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4205    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4206    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4207   "TARGET_80387 && TARGET_FISTTP
4208    && FLOAT_MODE_P (GET_MODE (operands[1]))
4209    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4210         && (TARGET_64BIT || <MODE>mode != DImode))
4211         && TARGET_SSE_MATH)"
4212   "#"
4213   [(set_attr "type" "fisttp")
4214    (set_attr "mode" "<MODE>")])
4215
4216 (define_split
4217   [(set (match_operand:X87MODEI 0 "register_operand" "")
4218         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4219    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4220    (clobber (match_scratch 3 ""))]
4221   "reload_completed"
4222   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4223               (clobber (match_dup 3))])
4224    (set (match_dup 0) (match_dup 2))]
4225   "")
4226
4227 (define_split
4228   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4230    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4231    (clobber (match_scratch 3 ""))]
4232   "reload_completed"
4233   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4234               (clobber (match_dup 3))])]
4235   "")
4236
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (reg:CC FLAGS_REG))]
4246   "TARGET_80387 && !TARGET_FISTTP
4247    && FLOAT_MODE_P (GET_MODE (operands[1]))
4248    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249          && (TARGET_64BIT || <MODE>mode != DImode))
4250    && !(reload_completed || reload_in_progress)"
4251   "#"
4252   "&& 1"
4253   [(const_int 0)]
4254 {
4255   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4256
4257   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259   if (memory_operand (operands[0], VOIDmode))
4260     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261                                          operands[2], operands[3]));
4262   else
4263     {
4264       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266                                                      operands[2], operands[3],
4267                                                      operands[4]));
4268     }
4269   DONE;
4270 }
4271   [(set_attr "type" "fistp")
4272    (set_attr "i387_cw" "trunc")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_truncdi_i387"
4276   [(set (match_operand:DI 0 "memory_operand" "=m")
4277         (fix:DI (match_operand 1 "register_operand" "f")))
4278    (use (match_operand:HI 2 "memory_operand" "m"))
4279    (use (match_operand:HI 3 "memory_operand" "m"))
4280    (clobber (match_scratch:XF 4 "=&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "* return output_fix_trunc (insn, operands, 0);"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4288
4289 (define_insn "fix_truncdi_i387_with_temp"
4290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:DI (match_operand 1 "register_operand" "f,f")))
4292    (use (match_operand:HI 2 "memory_operand" "m,m"))
4293    (use (match_operand:HI 3 "memory_operand" "m,m"))
4294    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296   "TARGET_80387 && !TARGET_FISTTP
4297    && FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299   "#"
4300   [(set_attr "type" "fistp")
4301    (set_attr "i387_cw" "trunc")
4302    (set_attr "mode" "DI")])
4303
4304 (define_split 
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])
4316    (set (match_dup 0) (match_dup 4))]
4317   "")
4318
4319 (define_split 
4320   [(set (match_operand:DI 0 "memory_operand" "")
4321         (fix:DI (match_operand 1 "register_operand" "")))
4322    (use (match_operand:HI 2 "memory_operand" ""))
4323    (use (match_operand:HI 3 "memory_operand" ""))
4324    (clobber (match_operand:DI 4 "memory_operand" ""))
4325    (clobber (match_scratch 5 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328               (use (match_dup 2))
4329               (use (match_dup 3))
4330               (clobber (match_dup 5))])]
4331   "")
4332
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "TARGET_80387 && !TARGET_FISTTP
4339    && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, 0);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4345
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4359
4360 (define_split 
4361   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363    (use (match_operand:HI 2 "memory_operand" ""))
4364    (use (match_operand:HI 3 "memory_operand" ""))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))]
4371   "")
4372
4373 (define_split 
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376    (use (match_operand:HI 2 "memory_operand" ""))
4377    (use (match_operand:HI 3 "memory_operand" ""))
4378    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4379   "reload_completed"
4380   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4381               (use (match_dup 2))
4382               (use (match_dup 3))])]
4383   "")
4384
4385 (define_insn "x86_fnstcw_1"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388   "TARGET_80387"
4389   "fnstcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")])
4393
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPSR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")
4402    (set_attr "athlon_decode" "vector")])
4403 \f
4404 ;; Conversion between fixed point and floating point.
4405
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4408
4409 (define_expand "floathisf2"
4410   [(set (match_operand:SF 0 "register_operand" "")
4411         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412   "TARGET_80387 || TARGET_SSE_MATH"
4413 {
4414   if (TARGET_SSE_MATH)
4415     {
4416       emit_insn (gen_floatsisf2 (operands[0],
4417                                  convert_to_mode (SImode, operands[1], 0)));
4418       DONE;
4419     }
4420 })
4421
4422 (define_insn "*floathisf2_i387"
4423   [(set (match_operand:SF 0 "register_operand" "=f,f")
4424         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4426   "@
4427    fild%z1\t%1
4428    #"
4429   [(set_attr "type" "fmov,multi")
4430    (set_attr "mode" "SF")
4431    (set_attr "unit" "*,i387")
4432    (set_attr "fp_int_src" "true")])
4433
4434 (define_expand "floatsisf2"
4435   [(set (match_operand:SF 0 "register_operand" "")
4436         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4437   "TARGET_80387 || TARGET_SSE_MATH"
4438   "")
4439
4440 (define_insn "*floatsisf2_mixed"
4441   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4443   "TARGET_MIX_SSE_I387"
4444   "@
4445    fild%z1\t%1
4446    #
4447    cvtsi2ss\t{%1, %0|%0, %1}
4448    cvtsi2ss\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4450    (set_attr "mode" "SF")
4451    (set_attr "unit" "*,i387,*,*")
4452    (set_attr "athlon_decode" "*,*,vector,double")
4453    (set_attr "fp_int_src" "true")])
4454
4455 (define_insn "*floatsisf2_sse"
4456   [(set (match_operand:SF 0 "register_operand" "=x,x")
4457         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4458   "TARGET_SSE_MATH"
4459   "cvtsi2ss\t{%1, %0|%0, %1}"
4460   [(set_attr "type" "sseicvt")
4461    (set_attr "mode" "SF")
4462    (set_attr "athlon_decode" "vector,double")
4463    (set_attr "fp_int_src" "true")])
4464
4465 (define_insn "*floatsisf2_i387"
4466   [(set (match_operand:SF 0 "register_operand" "=f,f")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4468   "TARGET_80387"
4469   "@
4470    fild%z1\t%1
4471    #"
4472   [(set_attr "type" "fmov,multi")
4473    (set_attr "mode" "SF")
4474    (set_attr "unit" "*,i387")
4475    (set_attr "fp_int_src" "true")])
4476
4477 (define_expand "floatdisf2"
4478   [(set (match_operand:SF 0 "register_operand" "")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4480   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4481   "")
4482
4483 (define_insn "*floatdisf2_mixed"
4484   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4487   "@
4488    fild%z1\t%1
4489    #
4490    cvtsi2ss{q}\t{%1, %0|%0, %1}
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "unit" "*,i387,*,*")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatdisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_64BIT && TARGET_SSE_MATH"
4502   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "unit" "*,i387")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_expand "floathidf2"
4521   [(set (match_operand:DF 0 "register_operand" "")
4522         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4523   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524 {
4525   if (TARGET_SSE2 && TARGET_SSE_MATH)
4526     {
4527       emit_insn (gen_floatsidf2 (operands[0],
4528                                  convert_to_mode (SImode, operands[1], 0)));
4529       DONE;
4530     }
4531 })
4532
4533 (define_insn "*floathidf2_i387"
4534   [(set (match_operand:DF 0 "register_operand" "=f,f")
4535         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4536   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4537   "@
4538    fild%z1\t%1
4539    #"
4540   [(set_attr "type" "fmov,multi")
4541    (set_attr "mode" "DF")
4542    (set_attr "unit" "*,i387")
4543    (set_attr "fp_int_src" "true")])
4544
4545 (define_expand "floatsidf2"
4546   [(set (match_operand:DF 0 "register_operand" "")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549   "")
4550
4551 (define_insn "*floatsidf2_mixed"
4552   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4555   "@
4556    fild%z1\t%1
4557    #
4558    cvtsi2sd\t{%1, %0|%0, %1}
4559    cvtsi2sd\t{%1, %0|%0, %1}"
4560   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561    (set_attr "mode" "DF")
4562    (set_attr "unit" "*,i387,*,*")
4563    (set_attr "athlon_decode" "*,*,double,direct")
4564    (set_attr "fp_int_src" "true")])
4565
4566 (define_insn "*floatsidf2_sse"
4567   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4568         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_SSE2 && TARGET_SSE_MATH"
4570   "cvtsi2sd\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "DF")
4573    (set_attr "athlon_decode" "double,direct")
4574    (set_attr "fp_int_src" "true")])
4575
4576 (define_insn "*floatsidf2_i387"
4577   [(set (match_operand:DF 0 "register_operand" "=f,f")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4579   "TARGET_80387"
4580   "@
4581    fild%z1\t%1
4582    #"
4583   [(set_attr "type" "fmov,multi")
4584    (set_attr "mode" "DF")
4585    (set_attr "unit" "*,i387")
4586    (set_attr "fp_int_src" "true")])
4587
4588 (define_expand "floatdidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4593
4594 (define_insn "*floatdidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd{q}\t{%1, %0|%0, %1}
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "unit" "*,i387,*,*")
4606    (set_attr "athlon_decode" "*,*,double,direct")
4607    (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatdidf2_sse"
4610   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4611         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4612   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4613   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4614   [(set_attr "type" "sseicvt")
4615    (set_attr "mode" "DF")
4616    (set_attr "athlon_decode" "double,direct")
4617    (set_attr "fp_int_src" "true")])
4618
4619 (define_insn "*floatdidf2_i387"
4620   [(set (match_operand:DF 0 "register_operand" "=f,f")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4622   "TARGET_80387"
4623   "@
4624    fild%z1\t%1
4625    #"
4626   [(set_attr "type" "fmov,multi")
4627    (set_attr "mode" "DF")
4628    (set_attr "unit" "*,i387")
4629    (set_attr "fp_int_src" "true")])
4630
4631 (define_insn "floathixf2"
4632   [(set (match_operand:XF 0 "register_operand" "=f,f")
4633         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4634   "TARGET_80387"
4635   "@
4636    fild%z1\t%1
4637    #"
4638   [(set_attr "type" "fmov,multi")
4639    (set_attr "mode" "XF")
4640    (set_attr "unit" "*,i387")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "floatsixf2"
4644   [(set (match_operand:XF 0 "register_operand" "=f,f")
4645         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "XF")
4652    (set_attr "unit" "*,i387")
4653    (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "floatdixf2"
4656   [(set (match_operand:XF 0 "register_operand" "=f,f")
4657         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658   "TARGET_80387"
4659   "@
4660    fild%z1\t%1
4661    #"
4662   [(set_attr "type" "fmov,multi")
4663    (set_attr "mode" "XF")
4664    (set_attr "unit" "*,i387")
4665    (set_attr "fp_int_src" "true")])
4666
4667 ;; %%% Kill these when reload knows how to do it.
4668 (define_split
4669   [(set (match_operand 0 "fp_register_operand" "")
4670         (float (match_operand 1 "register_operand" "")))]
4671   "reload_completed
4672    && TARGET_80387
4673    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4674   [(const_int 0)]
4675 {
4676   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4677   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4678   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4679   ix86_free_from_memory (GET_MODE (operands[1]));
4680   DONE;
4681 })
4682
4683 (define_expand "floatunssisf2"
4684   [(use (match_operand:SF 0 "register_operand" ""))
4685    (use (match_operand:SI 1 "register_operand" ""))]
4686   "!TARGET_64BIT && TARGET_SSE_MATH"
4687   "x86_emit_floatuns (operands); DONE;")
4688
4689 (define_expand "floatunsdisf2"
4690   [(use (match_operand:SF 0 "register_operand" ""))
4691    (use (match_operand:DI 1 "register_operand" ""))]
4692   "TARGET_64BIT && TARGET_SSE_MATH"
4693   "x86_emit_floatuns (operands); DONE;")
4694
4695 (define_expand "floatunsdidf2"
4696   [(use (match_operand:DF 0 "register_operand" ""))
4697    (use (match_operand:DI 1 "register_operand" ""))]
4698   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699   "x86_emit_floatuns (operands); DONE;")
4700 \f
4701 ;; SSE extract/set expanders
4702
4703 \f
4704 ;; Add instructions
4705
4706 ;; %%% splits for addditi3
4707
4708 (define_expand "addti3"
4709   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4711                  (match_operand:TI 2 "x86_64_general_operand" "")))
4712    (clobber (reg:CC FLAGS_REG))]
4713   "TARGET_64BIT"
4714   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4715
4716 (define_insn "*addti3_1"
4717   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4719                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4720    (clobber (reg:CC FLAGS_REG))]
4721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4722   "#")
4723
4724 (define_split
4725   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4727                  (match_operand:TI 2 "general_operand" "")))
4728    (clobber (reg:CC FLAGS_REG))]
4729   "TARGET_64BIT && reload_completed"
4730   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4731                                           UNSPEC_ADD_CARRY))
4732               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4733    (parallel [(set (match_dup 3)
4734                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4735                                      (match_dup 4))
4736                             (match_dup 5)))
4737               (clobber (reg:CC FLAGS_REG))])]
4738   "split_ti (operands+0, 1, operands+0, operands+3);
4739    split_ti (operands+1, 1, operands+1, operands+4);
4740    split_ti (operands+2, 1, operands+2, operands+5);")
4741
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4746
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4754
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4762
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4780
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4792
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4804
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4816
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4828
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4840
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4853
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4877
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4885
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4893
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4910
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4918
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4921
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4937 {
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4949 }
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4952
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4966 {
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4970 }
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4973
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4988 {
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
4999 }
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5002
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5016 {
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5019 }
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5037 {
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5072 {
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076 }
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5079
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5086 {
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5092
5093     case TYPE_INCDEC:
5094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5095       if (operands[2] == const1_rtx)
5096         return "inc{q}\t%0";
5097       else
5098         {
5099           gcc_assert (operands[2] == constm1_rtx);
5100           return "dec{q}\t%0";
5101         }
5102
5103     default:
5104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5105
5106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5108       if (GET_CODE (operands[2]) == CONST_INT
5109           /* Avoid overflows.  */
5110           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5111           && (INTVAL (operands[2]) == 128
5112               || (INTVAL (operands[2]) < 0
5113                   && INTVAL (operands[2]) != -128)))
5114         {
5115           operands[2] = GEN_INT (-INTVAL (operands[2]));
5116           return "sub{q}\t{%2, %0|%0, %2}";
5117         }
5118       return "add{q}\t{%2, %0|%0, %2}";
5119     }
5120 }
5121   [(set (attr "type")
5122      (cond [(eq_attr "alternative" "2")
5123               (const_string "lea")
5124             ; Current assemblers are broken and do not allow @GOTOFF in
5125             ; ought but a memory context.
5126             (match_operand:DI 2 "pic_symbolic_operand" "")
5127               (const_string "lea")
5128             (match_operand:DI 2 "incdec_operand" "")
5129               (const_string "incdec")
5130            ]
5131            (const_string "alu")))
5132    (set_attr "mode" "DI")])
5133
5134 ;; Convert lea to the lea pattern to avoid flags dependency.
5135 (define_split
5136   [(set (match_operand:DI 0 "register_operand" "")
5137         (plus:DI (match_operand:DI 1 "register_operand" "")
5138                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5139    (clobber (reg:CC FLAGS_REG))]
5140   "TARGET_64BIT && reload_completed
5141    && true_regnum (operands[0]) != true_regnum (operands[1])"
5142   [(set (match_dup 0)
5143         (plus:DI (match_dup 1)
5144                  (match_dup 2)))]
5145   "")
5146
5147 (define_insn "*adddi_2_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare
5150           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5151                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5152           (const_int 0)))                       
5153    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5154         (plus:DI (match_dup 1) (match_dup 2)))]
5155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5156    && ix86_binary_operator_ok (PLUS, DImode, operands)
5157    /* Current assemblers are broken and do not allow @GOTOFF in
5158       ought but a memory context.  */
5159    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5160 {
5161   switch (get_attr_type (insn))
5162     {
5163     case TYPE_INCDEC:
5164       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else
5168         {
5169           gcc_assert (operands[2] == constm1_rtx);
5170           return "dec{q}\t%0";
5171         }
5172
5173     default:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175       /* ???? We ought to handle there the 32bit case too
5176          - do we need new constraint?  */
5177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5179       if (GET_CODE (operands[2]) == CONST_INT
5180           /* Avoid overflows.  */
5181           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182           && (INTVAL (operands[2]) == 128
5183               || (INTVAL (operands[2]) < 0
5184                   && INTVAL (operands[2]) != -128)))
5185         {
5186           operands[2] = GEN_INT (-INTVAL (operands[2]));
5187           return "sub{q}\t{%2, %0|%0, %2}";
5188         }
5189       return "add{q}\t{%2, %0|%0, %2}";
5190     }
5191 }
5192   [(set (attr "type")
5193      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194         (const_string "incdec")
5195         (const_string "alu")))
5196    (set_attr "mode" "DI")])
5197
5198 (define_insn "*adddi_3_rex64"
5199   [(set (reg FLAGS_REG)
5200         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5201                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5202    (clobber (match_scratch:DI 0 "=r"))]
5203   "TARGET_64BIT
5204    && ix86_match_ccmode (insn, CCZmode)
5205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5206    /* Current assemblers are broken and do not allow @GOTOFF in
5207       ought but a memory context.  */
5208    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5209 {
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_INCDEC:
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       if (operands[2] == const1_rtx)
5215         return "inc{q}\t%0";
5216       else
5217         {
5218           gcc_assert (operands[2] == constm1_rtx);
5219           return "dec{q}\t%0";
5220         }
5221
5222     default:
5223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224       /* ???? We ought to handle there the 32bit case too
5225          - do we need new constraint?  */
5226       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5227          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5228       if (GET_CODE (operands[2]) == CONST_INT
5229           /* Avoid overflows.  */
5230           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5231           && (INTVAL (operands[2]) == 128
5232               || (INTVAL (operands[2]) < 0
5233                   && INTVAL (operands[2]) != -128)))
5234         {
5235           operands[2] = GEN_INT (-INTVAL (operands[2]));
5236           return "sub{q}\t{%2, %0|%0, %2}";
5237         }
5238       return "add{q}\t{%2, %0|%0, %2}";
5239     }
5240 }
5241   [(set (attr "type")
5242      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5243         (const_string "incdec")
5244         (const_string "alu")))
5245    (set_attr "mode" "DI")])
5246
5247 ; For comparisons against 1, -1 and 128, we may generate better code
5248 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5249 ; is matched then.  We can't accept general immediate, because for
5250 ; case of overflows,  the result is messed up.
5251 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5252 ; when negated.
5253 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5254 ; only for comparisons not depending on it.
5255 (define_insn "*adddi_4_rex64"
5256   [(set (reg FLAGS_REG)
5257         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5258                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5259    (clobber (match_scratch:DI 0 "=rm"))]
5260   "TARGET_64BIT
5261    &&  ix86_match_ccmode (insn, CCGCmode)"
5262 {
5263   switch (get_attr_type (insn))
5264     {
5265     case TYPE_INCDEC:
5266       if (operands[2] == constm1_rtx)
5267         return "inc{q}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == const1_rtx);
5271           return "dec{q}\t%0";
5272         }
5273
5274     default:
5275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5278       if ((INTVAL (operands[2]) == -128
5279            || (INTVAL (operands[2]) > 0
5280                && INTVAL (operands[2]) != 128))
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5283         return "sub{q}\t{%2, %0|%0, %2}";
5284       operands[2] = GEN_INT (-INTVAL (operands[2]));
5285       return "add{q}\t{%2, %0|%0, %2}";
5286     }
5287 }
5288   [(set (attr "type")
5289      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290         (const_string "incdec")
5291         (const_string "alu")))
5292    (set_attr "mode" "DI")])
5293
5294 (define_insn "*adddi_5_rex64"
5295   [(set (reg FLAGS_REG)
5296         (compare
5297           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5298                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5299           (const_int 0)))                       
5300    (clobber (match_scratch:DI 0 "=r"))]
5301   "TARGET_64BIT
5302    && ix86_match_ccmode (insn, CCGOCmode)
5303    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5304    /* Current assemblers are broken and do not allow @GOTOFF in
5305       ought but a memory context.  */
5306    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5307 {
5308   switch (get_attr_type (insn))
5309     {
5310     case TYPE_INCDEC:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else
5315         {
5316           gcc_assert (operands[2] == constm1_rtx);
5317           return "dec{q}\t%0";
5318         }
5319
5320     default:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5324       if (GET_CODE (operands[2]) == CONST_INT
5325           /* Avoid overflows.  */
5326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327           && (INTVAL (operands[2]) == 128
5328               || (INTVAL (operands[2]) < 0
5329                   && INTVAL (operands[2]) != -128)))
5330         {
5331           operands[2] = GEN_INT (-INTVAL (operands[2]));
5332           return "sub{q}\t{%2, %0|%0, %2}";
5333         }
5334       return "add{q}\t{%2, %0|%0, %2}";
5335     }
5336 }
5337   [(set (attr "type")
5338      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339         (const_string "incdec")
5340         (const_string "alu")))
5341    (set_attr "mode" "DI")])
5342
5343
5344 (define_insn "*addsi_1"
5345   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %0|%0, %a2}";
5356
5357     case TYPE_INCDEC:
5358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359       if (operands[2] == const1_rtx)
5360         return "inc{l}\t%0";
5361       else
5362         {
5363           gcc_assert (operands[2] == constm1_rtx);
5364           return "dec{l}\t%0";
5365         }
5366
5367     default:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           && (INTVAL (operands[2]) == 128
5374               || (INTVAL (operands[2]) < 0
5375                   && INTVAL (operands[2]) != -128)))
5376         {
5377           operands[2] = GEN_INT (-INTVAL (operands[2]));
5378           return "sub{l}\t{%2, %0|%0, %2}";
5379         }
5380       return "add{l}\t{%2, %0|%0, %2}";
5381     }
5382 }
5383   [(set (attr "type")
5384      (cond [(eq_attr "alternative" "2")
5385               (const_string "lea")
5386             ; Current assemblers are broken and do not allow @GOTOFF in
5387             ; ought but a memory context.
5388             (match_operand:SI 2 "pic_symbolic_operand" "")
5389               (const_string "lea")
5390             (match_operand:SI 2 "incdec_operand" "")
5391               (const_string "incdec")
5392            ]
5393            (const_string "alu")))
5394    (set_attr "mode" "SI")])
5395
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5397 (define_split
5398   [(set (match_operand 0 "register_operand" "")
5399         (plus (match_operand 1 "register_operand" "")
5400               (match_operand 2 "nonmemory_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "reload_completed
5403    && true_regnum (operands[0]) != true_regnum (operands[1])"
5404   [(const_int 0)]
5405 {
5406   rtx pat;
5407   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5408      may confuse gen_lowpart.  */
5409   if (GET_MODE (operands[0]) != Pmode)
5410     {
5411       operands[1] = gen_lowpart (Pmode, operands[1]);
5412       operands[2] = gen_lowpart (Pmode, operands[2]);
5413     }
5414   operands[0] = gen_lowpart (SImode, operands[0]);
5415   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5416   if (Pmode != SImode)
5417     pat = gen_rtx_SUBREG (SImode, pat, 0);
5418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5419   DONE;
5420 })
5421
5422 ;; It may seem that nonimmediate operand is proper one for operand 1.
5423 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5424 ;; we take care in ix86_binary_operator_ok to not allow two memory
5425 ;; operands so proper swapping will be done in reload.  This allow
5426 ;; patterns constructed from addsi_1 to match.
5427 (define_insn "addsi_1_zext"
5428   [(set (match_operand:DI 0 "register_operand" "=r,r")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5431                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5434 {
5435   switch (get_attr_type (insn))
5436     {
5437     case TYPE_LEA:
5438       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5439       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5440
5441     case TYPE_INCDEC:
5442       if (operands[2] == const1_rtx)
5443         return "inc{l}\t%k0";
5444       else
5445         {
5446           gcc_assert (operands[2] == constm1_rtx);
5447           return "dec{l}\t%k0";
5448         }
5449
5450     default:
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if (GET_CODE (operands[2]) == CONST_INT
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{l}\t{%2, %k0|%k0, %2}";
5460         }
5461       return "add{l}\t{%2, %k0|%k0, %2}";
5462     }
5463 }
5464   [(set (attr "type")
5465      (cond [(eq_attr "alternative" "1")
5466               (const_string "lea")
5467             ; Current assemblers are broken and do not allow @GOTOFF in
5468             ; ought but a memory context.
5469             (match_operand:SI 2 "pic_symbolic_operand" "")
5470               (const_string "lea")
5471             (match_operand:SI 2 "incdec_operand" "")
5472               (const_string "incdec")
5473            ]
5474            (const_string "alu")))
5475    (set_attr "mode" "SI")])
5476
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479   [(set (match_operand:DI 0 "register_operand" "")
5480         (zero_extend:DI
5481           (plus:SI (match_operand:SI 1 "register_operand" "")
5482                    (match_operand:SI 2 "nonmemory_operand" ""))))
5483    (clobber (reg:CC FLAGS_REG))]
5484   "TARGET_64BIT && reload_completed
5485    && true_regnum (operands[0]) != true_regnum (operands[1])"
5486   [(set (match_dup 0)
5487         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5488 {
5489   operands[1] = gen_lowpart (Pmode, operands[1]);
5490   operands[2] = gen_lowpart (Pmode, operands[2]);
5491 })
5492
5493 (define_insn "*addsi_2"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5498           (const_int 0)))                       
5499    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:SI (match_dup 1) (match_dup 2)))]
5501   "ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, SImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{l}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{l}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5523       if (GET_CODE (operands[2]) == CONST_INT
5524           && (INTVAL (operands[2]) == 128
5525               || (INTVAL (operands[2]) < 0
5526                   && INTVAL (operands[2]) != -128)))
5527         {
5528           operands[2] = GEN_INT (-INTVAL (operands[2]));
5529           return "sub{l}\t{%2, %0|%0, %2}";
5530         }
5531       return "add{l}\t{%2, %0|%0, %2}";
5532     }
5533 }
5534   [(set (attr "type")
5535      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5536         (const_string "incdec")
5537         (const_string "alu")))
5538    (set_attr "mode" "SI")])
5539
5540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5541 (define_insn "*addsi_2_zext"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:SI 2 "general_operand" "rmni"))
5546           (const_int 0)))                       
5547    (set (match_operand:DI 0 "register_operand" "=r")
5548         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (operands[2] == const1_rtx)
5559         return "inc{l}\t%k0";
5560       else
5561         {
5562           gcc_assert (operands[2] == constm1_rtx);
5563           return "dec{l}\t%k0";
5564         }
5565
5566     default:
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %k0|%k0, %2}";
5576         }
5577       return "add{l}\t{%2, %k0|%k0, %2}";
5578     }
5579 }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5585
5586 (define_insn "*addsi_3"
5587   [(set (reg FLAGS_REG)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (clobber (match_scratch:SI 0 "=r"))]
5591   "ix86_match_ccmode (insn, CCZmode)
5592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593    /* Current assemblers are broken and do not allow @GOTOFF in
5594       ought but a memory context.  */
5595    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 {
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_INCDEC:
5600       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5601       if (operands[2] == const1_rtx)
5602         return "inc{l}\t%0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{l}\t%0";
5607         }
5608
5609     default:
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %0|%0, %2}";
5620         }
5621       return "add{l}\t{%2, %0|%0, %2}";
5622     }
5623 }
5624   [(set (attr "type")
5625      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5626         (const_string "incdec")
5627         (const_string "alu")))
5628    (set_attr "mode" "SI")])
5629
5630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5631 (define_insn "*addsi_3_zext"
5632   [(set (reg FLAGS_REG)
5633         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 {
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5653
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5676 ; is matched then.  We can't accept general immediate, because for
5677 ; case of overflows,  the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683   [(set (reg FLAGS_REG)
5684         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685                  (match_operand:SI 2 "const_int_operand" "n")))
5686    (clobber (match_scratch:SI 0 "=rm"))]
5687   "ix86_match_ccmode (insn, CCGCmode)
5688    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5689 {
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == constm1_rtx)
5694         return "inc{l}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == const1_rtx);
5698           return "dec{l}\t%0";
5699         }
5700
5701     default:
5702       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if ((INTVAL (operands[2]) == -128
5706            || (INTVAL (operands[2]) > 0
5707                && INTVAL (operands[2]) != 128)))
5708         return "sub{l}\t{%2, %0|%0, %2}";
5709       operands[2] = GEN_INT (-INTVAL (operands[2]));
5710       return "add{l}\t{%2, %0|%0, %2}";
5711     }
5712 }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715         (const_string "incdec")
5716         (const_string "alu")))
5717    (set_attr "mode" "SI")])
5718
5719 (define_insn "*addsi_5"
5720   [(set (reg FLAGS_REG)
5721         (compare
5722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723                    (match_operand:SI 2 "general_operand" "rmni"))
5724           (const_int 0)))                       
5725    (clobber (match_scratch:SI 0 "=r"))]
5726   "ix86_match_ccmode (insn, CCGOCmode)
5727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else
5739         {
5740           gcc_assert (operands[2] == constm1_rtx);
5741           return "dec{l}\t%0";
5742         }
5743
5744     default:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5758 }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5764
5765 (define_expand "addhi3"
5766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5767                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5768                             (match_operand:HI 2 "general_operand" "")))
5769               (clobber (reg:CC FLAGS_REG))])]
5770   "TARGET_HIMODE_MATH"
5771   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5772
5773 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5774 ;; type optimizations enabled by define-splits.  This is not important
5775 ;; for PII, and in fact harmful because of partial register stalls.
5776
5777 (define_insn "*addhi_1_lea"
5778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5779         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5780                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "!TARGET_PARTIAL_REG_STALL
5783    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5784 {
5785   switch (get_attr_type (insn))
5786     {
5787     case TYPE_LEA:
5788       return "#";
5789     case TYPE_INCDEC:
5790       if (operands[2] == const1_rtx)
5791         return "inc{w}\t%0";
5792       else
5793         {
5794           gcc_assert (operands[2] == constm1_rtx);
5795           return "dec{w}\t%0";
5796         }
5797
5798     default:
5799       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5800          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5801       if (GET_CODE (operands[2]) == CONST_INT
5802           && (INTVAL (operands[2]) == 128
5803               || (INTVAL (operands[2]) < 0
5804                   && INTVAL (operands[2]) != -128)))
5805         {
5806           operands[2] = GEN_INT (-INTVAL (operands[2]));
5807           return "sub{w}\t{%2, %0|%0, %2}";
5808         }
5809       return "add{w}\t{%2, %0|%0, %2}";
5810     }
5811 }
5812   [(set (attr "type")
5813      (if_then_else (eq_attr "alternative" "2")
5814         (const_string "lea")
5815         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5816            (const_string "incdec")
5817            (const_string "alu"))))
5818    (set_attr "mode" "HI,HI,SI")])
5819
5820 (define_insn "*addhi_1"
5821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5822         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5823                  (match_operand:HI 2 "general_operand" "ri,rm")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "TARGET_PARTIAL_REG_STALL
5826    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5827 {
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_INCDEC:
5831       if (operands[2] == const1_rtx)
5832         return "inc{w}\t%0";
5833       else
5834         {
5835           gcc_assert (operands[2] == constm1_rtx);
5836           return "dec{w}\t%0";
5837         }
5838
5839     default:
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (GET_CODE (operands[2]) == CONST_INT
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{w}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{w}\t{%2, %0|%0, %2}";
5851     }
5852 }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "HI")])
5858
5859 (define_insn "*addhi_2"
5860   [(set (reg FLAGS_REG)
5861         (compare
5862           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5864           (const_int 0)))                       
5865    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5866         (plus:HI (match_dup 1) (match_dup 2)))]
5867   "ix86_match_ccmode (insn, CCGOCmode)
5868    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5869 {
5870   switch (get_attr_type (insn))
5871     {
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{w}\t%0";
5875       else
5876         {
5877           gcc_assert (operands[2] == constm1_rtx);
5878           return "dec{w}\t%0";
5879         }
5880
5881     default:
5882       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5883          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5884       if (GET_CODE (operands[2]) == CONST_INT
5885           && (INTVAL (operands[2]) == 128
5886               || (INTVAL (operands[2]) < 0
5887                   && INTVAL (operands[2]) != -128)))
5888         {
5889           operands[2] = GEN_INT (-INTVAL (operands[2]));
5890           return "sub{w}\t{%2, %0|%0, %2}";
5891         }
5892       return "add{w}\t{%2, %0|%0, %2}";
5893     }
5894 }
5895   [(set (attr "type")
5896      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5897         (const_string "incdec")
5898         (const_string "alu")))
5899    (set_attr "mode" "HI")])
5900
5901 (define_insn "*addhi_3"
5902   [(set (reg FLAGS_REG)
5903         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5904                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5905    (clobber (match_scratch:HI 0 "=r"))]
5906   "ix86_match_ccmode (insn, CCZmode)
5907    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5908 {
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{w}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{w}\t%0";
5918         }
5919
5920     default:
5921       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923       if (GET_CODE (operands[2]) == CONST_INT
5924           && (INTVAL (operands[2]) == 128
5925               || (INTVAL (operands[2]) < 0
5926                   && INTVAL (operands[2]) != -128)))
5927         {
5928           operands[2] = GEN_INT (-INTVAL (operands[2]));
5929           return "sub{w}\t{%2, %0|%0, %2}";
5930         }
5931       return "add{w}\t{%2, %0|%0, %2}";
5932     }
5933 }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936         (const_string "incdec")
5937         (const_string "alu")))
5938    (set_attr "mode" "HI")])
5939
5940 ; See comments above addsi_4 for details.
5941 (define_insn "*addhi_4"
5942   [(set (reg FLAGS_REG)
5943         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5944                  (match_operand:HI 2 "const_int_operand" "n")))
5945    (clobber (match_scratch:HI 0 "=rm"))]
5946   "ix86_match_ccmode (insn, CCGCmode)
5947    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5948 {
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == constm1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == const1_rtx);
5957           return "dec{w}\t%0";
5958         }
5959
5960     default:
5961       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5963          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5964       if ((INTVAL (operands[2]) == -128
5965            || (INTVAL (operands[2]) > 0
5966                && INTVAL (operands[2]) != 128)))
5967         return "sub{w}\t{%2, %0|%0, %2}";
5968       operands[2] = GEN_INT (-INTVAL (operands[2]));
5969       return "add{w}\t{%2, %0|%0, %2}";
5970     }
5971 }
5972   [(set (attr "type")
5973      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974         (const_string "incdec")
5975         (const_string "alu")))
5976    (set_attr "mode" "SI")])
5977
5978
5979 (define_insn "*addhi_5"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5983                    (match_operand:HI 2 "general_operand" "rmni"))
5984           (const_int 0)))                       
5985    (clobber (match_scratch:HI 0 "=r"))]
5986   "ix86_match_ccmode (insn, CCGOCmode)
5987    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{w}\t%0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{w}\t{%2, %0|%0, %2}";
6010         }
6011       return "add{w}\t{%2, %0|%0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "HI")])
6019
6020 (define_expand "addqi3"
6021   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6022                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6023                             (match_operand:QI 2 "general_operand" "")))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "TARGET_QIMODE_MATH"
6026   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6027
6028 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6029 (define_insn "*addqi_1_lea"
6030   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033    (clobber (reg:CC FLAGS_REG))]
6034   "!TARGET_PARTIAL_REG_STALL
6035    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6036 {
6037   int widen = (which_alternative == 2);
6038   switch (get_attr_type (insn))
6039     {
6040     case TYPE_LEA:
6041       return "#";
6042     case TYPE_INCDEC:
6043       if (operands[2] == const1_rtx)
6044         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045       else
6046         {
6047           gcc_assert (operands[2] == constm1_rtx);
6048           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6049         }
6050
6051     default:
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if (GET_CODE (operands[2]) == CONST_INT
6055           && (INTVAL (operands[2]) == 128
6056               || (INTVAL (operands[2]) < 0
6057                   && INTVAL (operands[2]) != -128)))
6058         {
6059           operands[2] = GEN_INT (-INTVAL (operands[2]));
6060           if (widen)
6061             return "sub{l}\t{%2, %k0|%k0, %2}";
6062           else
6063             return "sub{b}\t{%2, %0|%0, %2}";
6064         }
6065       if (widen)
6066         return "add{l}\t{%k2, %k0|%k0, %k2}";
6067       else
6068         return "add{b}\t{%2, %0|%0, %2}";
6069     }
6070 }
6071   [(set (attr "type")
6072      (if_then_else (eq_attr "alternative" "3")
6073         (const_string "lea")
6074         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6075            (const_string "incdec")
6076            (const_string "alu"))))
6077    (set_attr "mode" "QI,QI,SI,SI")])
6078
6079 (define_insn "*addqi_1"
6080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6083    (clobber (reg:CC FLAGS_REG))]
6084   "TARGET_PARTIAL_REG_STALL
6085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6086 {
6087   int widen = (which_alternative == 2);
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6118 }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "QI,QI,SI")])
6124
6125 (define_insn "*addqi_1_slp"
6126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127         (plus:QI (match_dup 0)
6128                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6129    (clobber (reg:CC FLAGS_REG))]
6130   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6132 {
6133   switch (get_attr_type (insn))
6134     {
6135     case TYPE_INCDEC:
6136       if (operands[1] == const1_rtx)
6137         return "inc{b}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[1] == constm1_rtx);
6141           return "dec{b}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6146       if (GET_CODE (operands[1]) == CONST_INT
6147           && INTVAL (operands[1]) < 0)
6148         {
6149           operands[1] = GEN_INT (-INTVAL (operands[1]));
6150           return "sub{b}\t{%1, %0|%0, %1}";
6151         }
6152       return "add{b}\t{%1, %0|%0, %1}";
6153     }
6154 }
6155   [(set (attr "type")
6156      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6157         (const_string "incdec")
6158         (const_string "alu1")))
6159    (set (attr "memory")
6160      (if_then_else (match_operand 1 "memory_operand" "")
6161         (const_string "load")
6162         (const_string "none")))
6163    (set_attr "mode" "QI")])
6164
6165 (define_insn "*addqi_2"
6166   [(set (reg FLAGS_REG)
6167         (compare
6168           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6169                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6170           (const_int 0)))
6171    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6172         (plus:QI (match_dup 1) (match_dup 2)))]
6173   "ix86_match_ccmode (insn, CCGOCmode)
6174    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175 {
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx
6184                       || (GET_CODE (operands[2]) == CONST_INT
6185                           && INTVAL (operands[2]) == 255));
6186           return "dec{b}\t%0";
6187         }
6188
6189     default:
6190       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6191       if (GET_CODE (operands[2]) == CONST_INT
6192           && INTVAL (operands[2]) < 0)
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{b}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{b}\t{%2, %0|%0, %2}";
6198     }
6199 }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "QI")])
6205
6206 (define_insn "*addqi_3"
6207   [(set (reg FLAGS_REG)
6208         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6209                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6210    (clobber (match_scratch:QI 0 "=q"))]
6211   "ix86_match_ccmode (insn, CCZmode)
6212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6213 {
6214   switch (get_attr_type (insn))
6215     {
6216     case TYPE_INCDEC:
6217       if (operands[2] == const1_rtx)
6218         return "inc{b}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx
6222                       || (GET_CODE (operands[2]) == CONST_INT
6223                           && INTVAL (operands[2]) == 255));
6224           return "dec{b}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && INTVAL (operands[2]) < 0)
6231         {
6232           operands[2] = GEN_INT (-INTVAL (operands[2]));
6233           return "sub{b}\t{%2, %0|%0, %2}";
6234         }
6235       return "add{b}\t{%2, %0|%0, %2}";
6236     }
6237 }
6238   [(set (attr "type")
6239      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240         (const_string "incdec")
6241         (const_string "alu")))
6242    (set_attr "mode" "QI")])
6243
6244 ; See comments above addsi_4 for details.
6245 (define_insn "*addqi_4"
6246   [(set (reg FLAGS_REG)
6247         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6248                  (match_operand:QI 2 "const_int_operand" "n")))
6249    (clobber (match_scratch:QI 0 "=qm"))]
6250   "ix86_match_ccmode (insn, CCGCmode)
6251    && (INTVAL (operands[2]) & 0xff) != 0x80"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx
6257           || (GET_CODE (operands[2]) == CONST_INT
6258               && INTVAL (operands[2]) == 255))
6259         return "inc{b}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == const1_rtx);
6263           return "dec{b}\t%0";
6264         }
6265
6266     default:
6267       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6268       if (INTVAL (operands[2]) < 0)
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "add{b}\t{%2, %0|%0, %2}";
6272         }
6273       return "sub{b}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "QI")])
6281
6282
6283 (define_insn "*addqi_5"
6284   [(set (reg FLAGS_REG)
6285         (compare
6286           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6287                    (match_operand:QI 2 "general_operand" "qmni"))
6288           (const_int 0)))
6289    (clobber (match_scratch:QI 0 "=q"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{b}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx
6301                       || (GET_CODE (operands[2]) == CONST_INT
6302                           && INTVAL (operands[2]) == 255));
6303           return "dec{b}\t%0";
6304         }
6305
6306     default:
6307       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6308       if (GET_CODE (operands[2]) == CONST_INT
6309           && INTVAL (operands[2]) < 0)
6310         {
6311           operands[2] = GEN_INT (-INTVAL (operands[2]));
6312           return "sub{b}\t{%2, %0|%0, %2}";
6313         }
6314       return "add{b}\t{%2, %0|%0, %2}";
6315     }
6316 }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set_attr "mode" "QI")])
6322
6323
6324 (define_insn "addqi_ext_1"
6325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6326                          (const_int 8)
6327                          (const_int 8))
6328         (plus:SI
6329           (zero_extract:SI
6330             (match_operand 1 "ext_register_operand" "0")
6331             (const_int 8)
6332             (const_int 8))
6333           (match_operand:QI 2 "general_operand" "Qmn")))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "!TARGET_64BIT"
6336 {
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       if (operands[2] == const1_rtx)
6341         return "inc{b}\t%h0";
6342       else
6343         {
6344           gcc_assert (operands[2] == constm1_rtx
6345                       || (GET_CODE (operands[2]) == CONST_INT
6346                           && INTVAL (operands[2]) == 255));
6347           return "dec{b}\t%h0";
6348         }
6349
6350     default:
6351       return "add{b}\t{%2, %h0|%h0, %2}";
6352     }
6353 }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI")])
6359
6360 (define_insn "*addqi_ext_1_rex64"
6361   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6362                          (const_int 8)
6363                          (const_int 8))
6364         (plus:SI
6365           (zero_extract:SI
6366             (match_operand 1 "ext_register_operand" "0")
6367             (const_int 8)
6368             (const_int 8))
6369           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "TARGET_64BIT"
6372 {
6373   switch (get_attr_type (insn))
6374     {
6375     case TYPE_INCDEC:
6376       if (operands[2] == const1_rtx)
6377         return "inc{b}\t%h0";
6378       else
6379         {
6380           gcc_assert (operands[2] == constm1_rtx
6381                       || (GET_CODE (operands[2]) == CONST_INT
6382                           && INTVAL (operands[2]) == 255));
6383           return "dec{b}\t%h0";
6384         }
6385
6386     default:
6387       return "add{b}\t{%2, %h0|%h0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396 (define_insn "*addqi_ext_2"
6397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398                          (const_int 8)
6399                          (const_int 8))
6400         (plus:SI
6401           (zero_extract:SI
6402             (match_operand 1 "ext_register_operand" "%0")
6403             (const_int 8)
6404             (const_int 8))
6405           (zero_extract:SI
6406             (match_operand 2 "ext_register_operand" "Q")
6407             (const_int 8)
6408             (const_int 8))))
6409    (clobber (reg:CC FLAGS_REG))]
6410   ""
6411   "add{b}\t{%h2, %h0|%h0, %h2}"
6412   [(set_attr "type" "alu")
6413    (set_attr "mode" "QI")])
6414
6415 ;; The patterns that match these are at the end of this file.
6416
6417 (define_expand "addxf3"
6418   [(set (match_operand:XF 0 "register_operand" "")
6419         (plus:XF (match_operand:XF 1 "register_operand" "")
6420                  (match_operand:XF 2 "register_operand" "")))]
6421   "TARGET_80387"
6422   "")
6423
6424 (define_expand "adddf3"
6425   [(set (match_operand:DF 0 "register_operand" "")
6426         (plus:DF (match_operand:DF 1 "register_operand" "")
6427                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6428   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6429   "")
6430
6431 (define_expand "addsf3"
6432   [(set (match_operand:SF 0 "register_operand" "")
6433         (plus:SF (match_operand:SF 1 "register_operand" "")
6434                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6435   "TARGET_80387 || TARGET_SSE_MATH"
6436   "")
6437 \f
6438 ;; Subtract instructions
6439
6440 ;; %%% splits for subditi3
6441
6442 (define_expand "subti3"
6443   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6444                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6445                              (match_operand:TI 2 "x86_64_general_operand" "")))
6446               (clobber (reg:CC FLAGS_REG))])]
6447   "TARGET_64BIT"
6448   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6449
6450 (define_insn "*subti3_1"
6451   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6452         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6453                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6454    (clobber (reg:CC FLAGS_REG))]
6455   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6456   "#")
6457
6458 (define_split
6459   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6460         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6461                   (match_operand:TI 2 "general_operand" "")))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && reload_completed"
6464   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6465               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6466    (parallel [(set (match_dup 3)
6467                    (minus:DI (match_dup 4)
6468                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6469                                       (match_dup 5))))
6470               (clobber (reg:CC FLAGS_REG))])]
6471   "split_ti (operands+0, 1, operands+0, operands+3);
6472    split_ti (operands+1, 1, operands+1, operands+4);
6473    split_ti (operands+2, 1, operands+2, operands+5);")
6474
6475 ;; %%% splits for subsidi3
6476
6477 (define_expand "subdi3"
6478   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6479                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6480                              (match_operand:DI 2 "x86_64_general_operand" "")))
6481               (clobber (reg:CC FLAGS_REG))])]
6482   ""
6483   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6484
6485 (define_insn "*subdi3_1"
6486   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6487         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6488                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6491   "#")
6492
6493 (define_split
6494   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6495         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6496                   (match_operand:DI 2 "general_operand" "")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!TARGET_64BIT && reload_completed"
6499   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6500               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6501    (parallel [(set (match_dup 3)
6502                    (minus:SI (match_dup 4)
6503                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6504                                       (match_dup 5))))
6505               (clobber (reg:CC FLAGS_REG))])]
6506   "split_di (operands+0, 1, operands+0, operands+3);
6507    split_di (operands+1, 1, operands+1, operands+4);
6508    split_di (operands+2, 1, operands+2, operands+5);")
6509
6510 (define_insn "subdi3_carry_rex64"
6511   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6512           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6513             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6514                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6517   "sbb{q}\t{%2, %0|%0, %2}"
6518   [(set_attr "type" "alu")
6519    (set_attr "pent_pair" "pu")
6520    (set_attr "mode" "DI")])
6521
6522 (define_insn "*subdi_1_rex64"
6523   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6524         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6525                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6526    (clobber (reg:CC FLAGS_REG))]
6527   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6528   "sub{q}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "mode" "DI")])
6531
6532 (define_insn "*subdi_2_rex64"
6533   [(set (reg FLAGS_REG)
6534         (compare
6535           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6537           (const_int 0)))
6538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6539         (minus:DI (match_dup 1) (match_dup 2)))]
6540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6541    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542   "sub{q}\t{%2, %0|%0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "DI")])
6545
6546 (define_insn "*subdi_3_rex63"
6547   [(set (reg FLAGS_REG)
6548         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6549                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6550    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551         (minus:DI (match_dup 1) (match_dup 2)))]
6552   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{q}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "DI")])
6557
6558 (define_insn "subqi3_carry"
6559   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6560           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6561             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:QI 2 "general_operand" "qi,qm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6565   "sbb{b}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "QI")])
6569
6570 (define_insn "subhi3_carry"
6571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6573             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6574                (match_operand:HI 2 "general_operand" "ri,rm"))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6577   "sbb{w}\t{%2, %0|%0, %2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "pent_pair" "pu")
6580    (set_attr "mode" "HI")])
6581
6582 (define_insn "subsi3_carry"
6583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6585             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6586                (match_operand:SI 2 "general_operand" "ri,rm"))))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6589   "sbb{l}\t{%2, %0|%0, %2}"
6590   [(set_attr "type" "alu")
6591    (set_attr "pent_pair" "pu")
6592    (set_attr "mode" "SI")])
6593
6594 (define_insn "subsi3_carry_zext"
6595   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6596           (zero_extend:DI
6597             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6598               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6599                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sbb{l}\t{%2, %k0|%k0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "SI")])
6606
6607 (define_expand "subsi3"
6608   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6609                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6610                              (match_operand:SI 2 "general_operand" "")))
6611               (clobber (reg:CC FLAGS_REG))])]
6612   ""
6613   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6614
6615 (define_insn "*subsi_1"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618                   (match_operand:SI 2 "general_operand" "ri,rm")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sub{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "SI")])
6624
6625 (define_insn "*subsi_1_zext"
6626   [(set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_operand:SI 1 "register_operand" "0")
6629                     (match_operand:SI 2 "general_operand" "rim"))))
6630    (clobber (reg:CC FLAGS_REG))]
6631   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{l}\t{%2, %k0|%k0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "SI")])
6635
6636 (define_insn "*subsi_2"
6637   [(set (reg FLAGS_REG)
6638         (compare
6639           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6640                     (match_operand:SI 2 "general_operand" "ri,rm"))
6641           (const_int 0)))
6642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:SI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCGOCmode)
6645    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6646   "sub{l}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "SI")])
6649
6650 (define_insn "*subsi_2_zext"
6651   [(set (reg FLAGS_REG)
6652         (compare
6653           (minus:SI (match_operand:SI 1 "register_operand" "0")
6654                     (match_operand:SI 2 "general_operand" "rim"))
6655           (const_int 0)))
6656    (set (match_operand:DI 0 "register_operand" "=r")
6657         (zero_extend:DI
6658           (minus:SI (match_dup 1)
6659                     (match_dup 2))))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sub{l}\t{%2, %k0|%k0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "SI")])
6665
6666 (define_insn "*subsi_3"
6667   [(set (reg FLAGS_REG)
6668         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6669                  (match_operand:SI 2 "general_operand" "ri,rm")))
6670    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671         (minus:SI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCmode)
6673    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sub{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "SI")])
6677
6678 (define_insn "*subsi_3_zext"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:SI 1 "register_operand" "0")
6681                  (match_operand:SI 2 "general_operand" "rim")))
6682    (set (match_operand:DI 0 "register_operand" "=r")
6683         (zero_extend:DI
6684           (minus:SI (match_dup 1)
6685                     (match_dup 2))))]
6686   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6687    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6691
6692 (define_expand "subhi3"
6693   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6694                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6695                              (match_operand:HI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_HIMODE_MATH"
6698   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6699
6700 (define_insn "*subhi_1"
6701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:HI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6706   "sub{w}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "HI")])
6709
6710 (define_insn "*subhi_2"
6711   [(set (reg FLAGS_REG)
6712         (compare
6713           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6714                     (match_operand:HI 2 "general_operand" "ri,rm"))
6715           (const_int 0)))
6716    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6717         (minus:HI (match_dup 1) (match_dup 2)))]
6718   "ix86_match_ccmode (insn, CCGOCmode)
6719    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6720   "sub{w}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "HI")])
6723
6724 (define_insn "*subhi_3"
6725   [(set (reg FLAGS_REG)
6726         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6727                  (match_operand:HI 2 "general_operand" "ri,rm")))
6728    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6729         (minus:HI (match_dup 1) (match_dup 2)))]
6730   "ix86_match_ccmode (insn, CCmode)
6731    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6732   "sub{w}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "HI")])
6735
6736 (define_expand "subqi3"
6737   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6738                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6739                              (match_operand:QI 2 "general_operand" "")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_QIMODE_MATH"
6742   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6743
6744 (define_insn "*subqi_1"
6745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6746         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6747                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6750   "sub{b}\t{%2, %0|%0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "QI")])
6753
6754 (define_insn "*subqi_1_slp"
6755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6756         (minus:QI (match_dup 0)
6757                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6761   "sub{b}\t{%1, %0|%0, %1}"
6762   [(set_attr "type" "alu1")
6763    (set_attr "mode" "QI")])
6764
6765 (define_insn "*subqi_2"
6766   [(set (reg FLAGS_REG)
6767         (compare
6768           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6769                     (match_operand:QI 2 "general_operand" "qi,qm"))
6770           (const_int 0)))
6771    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6772         (minus:HI (match_dup 1) (match_dup 2)))]
6773   "ix86_match_ccmode (insn, CCGOCmode)
6774    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6775   "sub{b}\t{%2, %0|%0, %2}"
6776   [(set_attr "type" "alu")
6777    (set_attr "mode" "QI")])
6778
6779 (define_insn "*subqi_3"
6780   [(set (reg FLAGS_REG)
6781         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6782                  (match_operand:QI 2 "general_operand" "qi,qm")))
6783    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6784         (minus:HI (match_dup 1) (match_dup 2)))]
6785   "ix86_match_ccmode (insn, CCmode)
6786    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6787   "sub{b}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "QI")])
6790
6791 ;; The patterns that match these are at the end of this file.
6792
6793 (define_expand "subxf3"
6794   [(set (match_operand:XF 0 "register_operand" "")
6795         (minus:XF (match_operand:XF 1 "register_operand" "")
6796                   (match_operand:XF 2 "register_operand" "")))]
6797   "TARGET_80387"
6798   "")
6799
6800 (define_expand "subdf3"
6801   [(set (match_operand:DF 0 "register_operand" "")
6802         (minus:DF (match_operand:DF 1 "register_operand" "")
6803                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6804   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6805   "")
6806
6807 (define_expand "subsf3"
6808   [(set (match_operand:SF 0 "register_operand" "")
6809         (minus:SF (match_operand:SF 1 "register_operand" "")
6810                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6811   "TARGET_80387 || TARGET_SSE_MATH"
6812   "")
6813 \f
6814 ;; Multiply instructions
6815
6816 (define_expand "muldi3"
6817   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6818                    (mult:DI (match_operand:DI 1 "register_operand" "")
6819                             (match_operand:DI 2 "x86_64_general_operand" "")))
6820               (clobber (reg:CC FLAGS_REG))])]
6821   "TARGET_64BIT"
6822   "")
6823
6824 (define_insn "*muldi3_1_rex64"
6825   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6826         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6827                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{q}\t{%2, %1, %0|%0, %1, %2}
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "DI")])
6847
6848 (define_expand "mulsi3"
6849   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6850                    (mult:SI (match_operand:SI 1 "register_operand" "")
6851                             (match_operand:SI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   ""
6854   "")
6855
6856 (define_insn "*mulsi3_1"
6857   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6858         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{l}\t{%2, %1, %0|%0, %1, %2}
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1")
6872                   (const_string "vector")
6873                (and (eq_attr "alternative" "2")
6874                     (match_operand 1 "memory_operand" ""))
6875                   (const_string "vector")]
6876               (const_string "direct")))
6877    (set_attr "mode" "SI")])
6878
6879 (define_insn "*mulsi3_1_zext"
6880   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881         (zero_extend:DI
6882           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6883                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_64BIT
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "@
6888    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %k0|%k0, %2}"
6891   [(set_attr "type" "imul")
6892    (set_attr "prefix_0f" "0,0,1")
6893    (set (attr "athlon_decode")
6894         (cond [(eq_attr "cpu" "athlon")
6895                   (const_string "vector")
6896                (eq_attr "alternative" "1")
6897                   (const_string "vector")
6898                (and (eq_attr "alternative" "2")
6899                     (match_operand 1 "memory_operand" ""))
6900                   (const_string "vector")]
6901               (const_string "direct")))
6902    (set_attr "mode" "SI")])
6903
6904 (define_expand "mulhi3"
6905   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6906                    (mult:HI (match_operand:HI 1 "register_operand" "")
6907                             (match_operand:HI 2 "general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_HIMODE_MATH"
6910   "")
6911
6912 (define_insn "*mulhi3_1"
6913   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6914         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6918   "@
6919    imul{w}\t{%2, %1, %0|%0, %1, %2}
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %0|%0, %2}"
6922   [(set_attr "type" "imul")
6923    (set_attr "prefix_0f" "0,0,1")
6924    (set (attr "athlon_decode")
6925         (cond [(eq_attr "cpu" "athlon")
6926                   (const_string "vector")
6927                (eq_attr "alternative" "1,2")
6928                   (const_string "vector")]
6929               (const_string "direct")))
6930    (set_attr "mode" "HI")])
6931
6932 (define_expand "mulqi3"
6933   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6934                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6935                             (match_operand:QI 2 "register_operand" "")))
6936               (clobber (reg:CC FLAGS_REG))])]
6937   "TARGET_QIMODE_MATH"
6938   "")
6939
6940 (define_insn "*mulqi3_1"
6941   [(set (match_operand:QI 0 "register_operand" "=a")
6942         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6943                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6944    (clobber (reg:CC FLAGS_REG))]
6945   "TARGET_QIMODE_MATH
6946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6947   "mul{b}\t%2"
6948   [(set_attr "type" "imul")
6949    (set_attr "length_immediate" "0")
6950    (set (attr "athlon_decode")
6951      (if_then_else (eq_attr "cpu" "athlon")
6952         (const_string "vector")
6953         (const_string "direct")))
6954    (set_attr "mode" "QI")])
6955
6956 (define_expand "umulqihi3"
6957   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6958                    (mult:HI (zero_extend:HI
6959                               (match_operand:QI 1 "nonimmediate_operand" ""))
6960                             (zero_extend:HI
6961                               (match_operand:QI 2 "register_operand" ""))))
6962               (clobber (reg:CC FLAGS_REG))])]
6963   "TARGET_QIMODE_MATH"
6964   "")
6965
6966 (define_insn "*umulqihi3_1"
6967   [(set (match_operand:HI 0 "register_operand" "=a")
6968         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970    (clobber (reg:CC FLAGS_REG))]
6971   "TARGET_QIMODE_MATH
6972    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6973   "mul{b}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "direct")))
6980    (set_attr "mode" "QI")])
6981
6982 (define_expand "mulqihi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6985                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "TARGET_QIMODE_MATH"
6988   "")
6989
6990 (define_insn "*mulqihi3_insn"
6991   [(set (match_operand:HI 0 "register_operand" "=a")
6992         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6993                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_QIMODE_MATH
6996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997   "imul{b}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "direct")))
7004    (set_attr "mode" "QI")])
7005
7006 (define_expand "umulditi3"
7007   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7008                    (mult:TI (zero_extend:TI
7009                               (match_operand:DI 1 "nonimmediate_operand" ""))
7010                             (zero_extend:TI
7011                               (match_operand:DI 2 "register_operand" ""))))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_64BIT"
7014   "")
7015
7016 (define_insn "*umulditi3_insn"
7017   [(set (match_operand:TI 0 "register_operand" "=A")
7018         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7019                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "TARGET_64BIT
7022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7023   "mul{q}\t%2"
7024   [(set_attr "type" "imul")
7025    (set_attr "length_immediate" "0")
7026    (set (attr "athlon_decode")
7027      (if_then_else (eq_attr "cpu" "athlon")
7028         (const_string "vector")
7029         (const_string "double")))
7030    (set_attr "mode" "DI")])
7031
7032 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7033 (define_expand "umulsidi3"
7034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035                    (mult:DI (zero_extend:DI
7036                               (match_operand:SI 1 "nonimmediate_operand" ""))
7037                             (zero_extend:DI
7038                               (match_operand:SI 2 "register_operand" ""))))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "!TARGET_64BIT"
7041   "")
7042
7043 (define_insn "*umulsidi3_insn"
7044   [(set (match_operand:DI 0 "register_operand" "=A")
7045         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7046                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "!TARGET_64BIT
7049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7050   "mul{l}\t%2"
7051   [(set_attr "type" "imul")
7052    (set_attr "length_immediate" "0")
7053    (set (attr "athlon_decode")
7054      (if_then_else (eq_attr "cpu" "athlon")
7055         (const_string "vector")
7056         (const_string "double")))
7057    (set_attr "mode" "SI")])
7058
7059 (define_expand "mulditi3"
7060   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7061                    (mult:TI (sign_extend:TI
7062                               (match_operand:DI 1 "nonimmediate_operand" ""))
7063                             (sign_extend:TI
7064                               (match_operand:DI 2 "register_operand" ""))))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7068
7069 (define_insn "*mulditi3_insn"
7070   [(set (match_operand:TI 0 "register_operand" "=A")
7071         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7072                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "TARGET_64BIT
7075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7076   "imul{q}\t%2"
7077   [(set_attr "type" "imul")
7078    (set_attr "length_immediate" "0")
7079    (set (attr "athlon_decode")
7080      (if_then_else (eq_attr "cpu" "athlon")
7081         (const_string "vector")
7082         (const_string "double")))
7083    (set_attr "mode" "DI")])
7084
7085 (define_expand "mulsidi3"
7086   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7087                    (mult:DI (sign_extend:DI
7088                               (match_operand:SI 1 "nonimmediate_operand" ""))
7089                             (sign_extend:DI
7090                               (match_operand:SI 2 "register_operand" ""))))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "!TARGET_64BIT"
7093   "")
7094
7095 (define_insn "*mulsidi3_insn"
7096   [(set (match_operand:DI 0 "register_operand" "=A")
7097         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7098                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "!TARGET_64BIT
7101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7102   "imul{l}\t%2"
7103   [(set_attr "type" "imul")
7104    (set_attr "length_immediate" "0")
7105    (set (attr "athlon_decode")
7106      (if_then_else (eq_attr "cpu" "athlon")
7107         (const_string "vector")
7108         (const_string "double")))
7109    (set_attr "mode" "SI")])
7110
7111 (define_expand "umuldi3_highpart"
7112   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7113                    (truncate:DI
7114                      (lshiftrt:TI
7115                        (mult:TI (zero_extend:TI
7116                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7117                                 (zero_extend:TI
7118                                   (match_operand:DI 2 "register_operand" "")))
7119                        (const_int 64))))
7120               (clobber (match_scratch:DI 3 ""))
7121               (clobber (reg:CC FLAGS_REG))])]
7122   "TARGET_64BIT"
7123   "")
7124
7125 (define_insn "*umuldi3_highpart_rex64"
7126   [(set (match_operand:DI 0 "register_operand" "=d")
7127         (truncate:DI
7128           (lshiftrt:TI
7129             (mult:TI (zero_extend:TI
7130                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7131                      (zero_extend:TI
7132                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7133             (const_int 64))))
7134    (clobber (match_scratch:DI 3 "=1"))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "TARGET_64BIT
7137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138   "mul{q}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "DI")])
7146
7147 (define_expand "umulsi3_highpart"
7148   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149                    (truncate:SI
7150                      (lshiftrt:DI
7151                        (mult:DI (zero_extend:DI
7152                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7153                                 (zero_extend:DI
7154                                   (match_operand:SI 2 "register_operand" "")))
7155                        (const_int 32))))
7156               (clobber (match_scratch:SI 3 ""))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "")
7160
7161 (define_insn "*umulsi3_highpart_insn"
7162   [(set (match_operand:SI 0 "register_operand" "=d")
7163         (truncate:SI
7164           (lshiftrt:DI
7165             (mult:DI (zero_extend:DI
7166                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7167                      (zero_extend:DI
7168                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7169             (const_int 32))))
7170    (clobber (match_scratch:SI 3 "=1"))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "mode" "SI")])
7181
7182 (define_insn "*umulsi3_highpart_zext"
7183   [(set (match_operand:DI 0 "register_operand" "=d")
7184         (zero_extend:DI (truncate:SI
7185           (lshiftrt:DI
7186             (mult:DI (zero_extend:DI
7187                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188                      (zero_extend:DI
7189                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190             (const_int 32)))))
7191    (clobber (match_scratch:SI 3 "=1"))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "mul{l}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "mode" "SI")])
7203
7204 (define_expand "smuldi3_highpart"
7205   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7206                    (truncate:DI
7207                      (lshiftrt:TI
7208                        (mult:TI (sign_extend:TI
7209                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7210                                 (sign_extend:TI
7211                                   (match_operand:DI 2 "register_operand" "")))
7212                        (const_int 64))))
7213               (clobber (match_scratch:DI 3 ""))
7214               (clobber (reg:CC FLAGS_REG))])]
7215   "TARGET_64BIT"
7216   "")
7217
7218 (define_insn "*smuldi3_highpart_rex64"
7219   [(set (match_operand:DI 0 "register_operand" "=d")
7220         (truncate:DI
7221           (lshiftrt:TI
7222             (mult:TI (sign_extend:TI
7223                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7224                      (sign_extend:TI
7225                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7226             (const_int 64))))
7227    (clobber (match_scratch:DI 3 "=1"))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_64BIT
7230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7231   "imul{q}\t%2"
7232   [(set_attr "type" "imul")
7233    (set (attr "athlon_decode")
7234      (if_then_else (eq_attr "cpu" "athlon")
7235         (const_string "vector")
7236         (const_string "double")))
7237    (set_attr "mode" "DI")])
7238
7239 (define_expand "smulsi3_highpart"
7240   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7241                    (truncate:SI
7242                      (lshiftrt:DI
7243                        (mult:DI (sign_extend:DI
7244                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7245                                 (sign_extend:DI
7246                                   (match_operand:SI 2 "register_operand" "")))
7247                        (const_int 32))))
7248               (clobber (match_scratch:SI 3 ""))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   ""
7251   "")
7252
7253 (define_insn "*smulsi3_highpart_insn"
7254   [(set (match_operand:SI 0 "register_operand" "=d")
7255         (truncate:SI
7256           (lshiftrt:DI
7257             (mult:DI (sign_extend:DI
7258                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7259                      (sign_extend:DI
7260                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7261             (const_int 32))))
7262    (clobber (match_scratch:SI 3 "=1"))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7265   "imul{l}\t%2"
7266   [(set_attr "type" "imul")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "mode" "SI")])
7272
7273 (define_insn "*smulsi3_highpart_zext"
7274   [(set (match_operand:DI 0 "register_operand" "=d")
7275         (zero_extend:DI (truncate:SI
7276           (lshiftrt:DI
7277             (mult:DI (sign_extend:DI
7278                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7279                      (sign_extend:DI
7280                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7281             (const_int 32)))))
7282    (clobber (match_scratch:SI 3 "=1"))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set (attr "athlon_decode")
7289      (if_then_else (eq_attr "cpu" "athlon")
7290         (const_string "vector")
7291         (const_string "double")))
7292    (set_attr "mode" "SI")])
7293
7294 ;; The patterns that match these are at the end of this file.
7295
7296 (define_expand "mulxf3"
7297   [(set (match_operand:XF 0 "register_operand" "")
7298         (mult:XF (match_operand:XF 1 "register_operand" "")
7299                  (match_operand:XF 2 "register_operand" "")))]
7300   "TARGET_80387"
7301   "")
7302
7303 (define_expand "muldf3"
7304   [(set (match_operand:DF 0 "register_operand" "")
7305         (mult:DF (match_operand:DF 1 "register_operand" "")
7306                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7307   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7308   "")
7309
7310 (define_expand "mulsf3"
7311   [(set (match_operand:SF 0 "register_operand" "")
7312         (mult:SF (match_operand:SF 1 "register_operand" "")
7313                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7314   "TARGET_80387 || TARGET_SSE_MATH"
7315   "")
7316 \f
7317 ;; Divide instructions
7318
7319 (define_insn "divqi3"
7320   [(set (match_operand:QI 0 "register_operand" "=a")
7321         (div:QI (match_operand:HI 1 "register_operand" "0")
7322                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_QIMODE_MATH"
7325   "idiv{b}\t%2"
7326   [(set_attr "type" "idiv")
7327    (set_attr "mode" "QI")])
7328
7329 (define_insn "udivqi3"
7330   [(set (match_operand:QI 0 "register_operand" "=a")
7331         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7332                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_QIMODE_MATH"
7335   "div{b}\t%2"
7336   [(set_attr "type" "idiv")
7337    (set_attr "mode" "QI")])
7338
7339 ;; The patterns that match these are at the end of this file.
7340
7341 (define_expand "divxf3"
7342   [(set (match_operand:XF 0 "register_operand" "")
7343         (div:XF (match_operand:XF 1 "register_operand" "")
7344                 (match_operand:XF 2 "register_operand" "")))]
7345   "TARGET_80387"
7346   "")
7347
7348 (define_expand "divdf3"
7349   [(set (match_operand:DF 0 "register_operand" "")
7350         (div:DF (match_operand:DF 1 "register_operand" "")
7351                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353    "")
7354  
7355 (define_expand "divsf3"
7356   [(set (match_operand:SF 0 "register_operand" "")
7357         (div:SF (match_operand:SF 1 "register_operand" "")
7358                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359   "TARGET_80387 || TARGET_SSE_MATH"
7360   "")
7361 \f
7362 ;; Remainder instructions.
7363
7364 (define_expand "divmoddi4"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7366                    (div:DI (match_operand:DI 1 "register_operand" "")
7367                            (match_operand:DI 2 "nonimmediate_operand" "")))
7368               (set (match_operand:DI 3 "register_operand" "")
7369                    (mod:DI (match_dup 1) (match_dup 2)))
7370               (clobber (reg:CC FLAGS_REG))])]
7371   "TARGET_64BIT"
7372   "")
7373
7374 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7375 ;; Penalize eax case slightly because it results in worse scheduling
7376 ;; of code.
7377 (define_insn "*divmoddi4_nocltd_rex64"
7378   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7379         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7380                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7381    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7382         (mod:DI (match_dup 2) (match_dup 3)))
7383    (clobber (reg:CC FLAGS_REG))]
7384   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7385   "#"
7386   [(set_attr "type" "multi")])
7387
7388 (define_insn "*divmoddi4_cltd_rex64"
7389   [(set (match_operand:DI 0 "register_operand" "=a")
7390         (div:DI (match_operand:DI 2 "register_operand" "a")
7391                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7392    (set (match_operand:DI 1 "register_operand" "=&d")
7393         (mod:DI (match_dup 2) (match_dup 3)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7396   "#"
7397   [(set_attr "type" "multi")])
7398
7399 (define_insn "*divmoddi_noext_rex64"
7400   [(set (match_operand:DI 0 "register_operand" "=a")
7401         (div:DI (match_operand:DI 1 "register_operand" "0")
7402                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403    (set (match_operand:DI 3 "register_operand" "=d")
7404         (mod:DI (match_dup 1) (match_dup 2)))
7405    (use (match_operand:DI 4 "register_operand" "3"))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_64BIT"
7408   "idiv{q}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "DI")])
7411
7412 (define_split
7413   [(set (match_operand:DI 0 "register_operand" "")
7414         (div:DI (match_operand:DI 1 "register_operand" "")
7415                 (match_operand:DI 2 "nonimmediate_operand" "")))
7416    (set (match_operand:DI 3 "register_operand" "")
7417         (mod:DI (match_dup 1) (match_dup 2)))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_64BIT && reload_completed"
7420   [(parallel [(set (match_dup 3)
7421                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7422               (clobber (reg:CC FLAGS_REG))])
7423    (parallel [(set (match_dup 0)
7424                    (div:DI (reg:DI 0) (match_dup 2)))
7425               (set (match_dup 3)
7426                    (mod:DI (reg:DI 0) (match_dup 2)))
7427               (use (match_dup 3))
7428               (clobber (reg:CC FLAGS_REG))])]
7429 {
7430   /* Avoid use of cltd in favor of a mov+shift.  */
7431   if (!TARGET_USE_CLTD && !optimize_size)
7432     {
7433       if (true_regnum (operands[1]))
7434         emit_move_insn (operands[0], operands[1]);
7435       else
7436         emit_move_insn (operands[3], operands[1]);
7437       operands[4] = operands[3];
7438     }
7439   else
7440     {
7441       gcc_assert (!true_regnum (operands[1]));
7442       operands[4] = operands[1];
7443     }
7444 })
7445
7446
7447 (define_expand "divmodsi4"
7448   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7449                    (div:SI (match_operand:SI 1 "register_operand" "")
7450                            (match_operand:SI 2 "nonimmediate_operand" "")))
7451               (set (match_operand:SI 3 "register_operand" "")
7452                    (mod:SI (match_dup 1) (match_dup 2)))
7453               (clobber (reg:CC FLAGS_REG))])]
7454   ""
7455   "")
7456
7457 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7458 ;; Penalize eax case slightly because it results in worse scheduling
7459 ;; of code.
7460 (define_insn "*divmodsi4_nocltd"
7461   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7462         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7463                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7464    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7465         (mod:SI (match_dup 2) (match_dup 3)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "!optimize_size && !TARGET_USE_CLTD"
7468   "#"
7469   [(set_attr "type" "multi")])
7470
7471 (define_insn "*divmodsi4_cltd"
7472   [(set (match_operand:SI 0 "register_operand" "=a")
7473         (div:SI (match_operand:SI 2 "register_operand" "a")
7474                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7475    (set (match_operand:SI 1 "register_operand" "=&d")
7476         (mod:SI (match_dup 2) (match_dup 3)))
7477    (clobber (reg:CC FLAGS_REG))]
7478   "optimize_size || TARGET_USE_CLTD"
7479   "#"
7480   [(set_attr "type" "multi")])
7481
7482 (define_insn "*divmodsi_noext"
7483   [(set (match_operand:SI 0 "register_operand" "=a")
7484         (div:SI (match_operand:SI 1 "register_operand" "0")
7485                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486    (set (match_operand:SI 3 "register_operand" "=d")
7487         (mod:SI (match_dup 1) (match_dup 2)))
7488    (use (match_operand:SI 4 "register_operand" "3"))
7489    (clobber (reg:CC FLAGS_REG))]
7490   ""
7491   "idiv{l}\t%2"
7492   [(set_attr "type" "idiv")
7493    (set_attr "mode" "SI")])
7494
7495 (define_split
7496   [(set (match_operand:SI 0 "register_operand" "")
7497         (div:SI (match_operand:SI 1 "register_operand" "")
7498                 (match_operand:SI 2 "nonimmediate_operand" "")))
7499    (set (match_operand:SI 3 "register_operand" "")
7500         (mod:SI (match_dup 1) (match_dup 2)))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "reload_completed"
7503   [(parallel [(set (match_dup 3)
7504                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7505               (clobber (reg:CC FLAGS_REG))])
7506    (parallel [(set (match_dup 0)
7507                    (div:SI (reg:SI 0) (match_dup 2)))
7508               (set (match_dup 3)
7509                    (mod:SI (reg:SI 0) (match_dup 2)))
7510               (use (match_dup 3))
7511               (clobber (reg:CC FLAGS_REG))])]
7512 {
7513   /* Avoid use of cltd in favor of a mov+shift.  */
7514   if (!TARGET_USE_CLTD && !optimize_size)
7515     {
7516       if (true_regnum (operands[1]))
7517         emit_move_insn (operands[0], operands[1]);
7518       else
7519         emit_move_insn (operands[3], operands[1]);
7520       operands[4] = operands[3];
7521     }
7522   else
7523     {
7524       gcc_assert (!true_regnum (operands[1]));
7525       operands[4] = operands[1];
7526     }
7527 })
7528 ;; %%% Split me.
7529 (define_insn "divmodhi4"
7530   [(set (match_operand:HI 0 "register_operand" "=a")
7531         (div:HI (match_operand:HI 1 "register_operand" "0")
7532                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7533    (set (match_operand:HI 3 "register_operand" "=&d")
7534         (mod:HI (match_dup 1) (match_dup 2)))
7535    (clobber (reg:CC FLAGS_REG))]
7536   "TARGET_HIMODE_MATH"
7537   "cwtd\;idiv{w}\t%2"
7538   [(set_attr "type" "multi")
7539    (set_attr "length_immediate" "0")
7540    (set_attr "mode" "SI")])
7541
7542 (define_insn "udivmoddi4"
7543   [(set (match_operand:DI 0 "register_operand" "=a")
7544         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7545                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546    (set (match_operand:DI 3 "register_operand" "=&d")
7547         (umod:DI (match_dup 1) (match_dup 2)))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT"
7550   "xor{q}\t%3, %3\;div{q}\t%2"
7551   [(set_attr "type" "multi")
7552    (set_attr "length_immediate" "0")
7553    (set_attr "mode" "DI")])
7554
7555 (define_insn "*udivmoddi4_noext"
7556   [(set (match_operand:DI 0 "register_operand" "=a")
7557         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7558                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559    (set (match_operand:DI 3 "register_operand" "=d")
7560         (umod:DI (match_dup 1) (match_dup 2)))
7561    (use (match_dup 3))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "TARGET_64BIT"
7564   "div{q}\t%2"
7565   [(set_attr "type" "idiv")
7566    (set_attr "mode" "DI")])
7567
7568 (define_split
7569   [(set (match_operand:DI 0 "register_operand" "")
7570         (udiv:DI (match_operand:DI 1 "register_operand" "")
7571                  (match_operand:DI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:DI 3 "register_operand" "")
7573         (umod:DI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_64BIT && reload_completed"
7576   [(set (match_dup 3) (const_int 0))
7577    (parallel [(set (match_dup 0)
7578                    (udiv:DI (match_dup 1) (match_dup 2)))
7579               (set (match_dup 3)
7580                    (umod:DI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 3))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "")
7584
7585 (define_insn "udivmodsi4"
7586   [(set (match_operand:SI 0 "register_operand" "=a")
7587         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7588                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7589    (set (match_operand:SI 3 "register_operand" "=&d")
7590         (umod:SI (match_dup 1) (match_dup 2)))
7591    (clobber (reg:CC FLAGS_REG))]
7592   ""
7593   "xor{l}\t%3, %3\;div{l}\t%2"
7594   [(set_attr "type" "multi")
7595    (set_attr "length_immediate" "0")
7596    (set_attr "mode" "SI")])
7597
7598 (define_insn "*udivmodsi4_noext"
7599   [(set (match_operand:SI 0 "register_operand" "=a")
7600         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7601                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602    (set (match_operand:SI 3 "register_operand" "=d")
7603         (umod:SI (match_dup 1) (match_dup 2)))
7604    (use (match_dup 3))
7605    (clobber (reg:CC FLAGS_REG))]
7606   ""
7607   "div{l}\t%2"
7608   [(set_attr "type" "idiv")
7609    (set_attr "mode" "SI")])
7610
7611 (define_split
7612   [(set (match_operand:SI 0 "register_operand" "")
7613         (udiv:SI (match_operand:SI 1 "register_operand" "")
7614                  (match_operand:SI 2 "nonimmediate_operand" "")))
7615    (set (match_operand:SI 3 "register_operand" "")
7616         (umod:SI (match_dup 1) (match_dup 2)))
7617    (clobber (reg:CC FLAGS_REG))]
7618   "reload_completed"
7619   [(set (match_dup 3) (const_int 0))
7620    (parallel [(set (match_dup 0)
7621                    (udiv:SI (match_dup 1) (match_dup 2)))
7622               (set (match_dup 3)
7623                    (umod:SI (match_dup 1) (match_dup 2)))
7624               (use (match_dup 3))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   "")
7627
7628 (define_expand "udivmodhi4"
7629   [(set (match_dup 4) (const_int 0))
7630    (parallel [(set (match_operand:HI 0 "register_operand" "")
7631                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7632                             (match_operand:HI 2 "nonimmediate_operand" "")))
7633               (set (match_operand:HI 3 "register_operand" "")
7634                    (umod:HI (match_dup 1) (match_dup 2)))
7635               (use (match_dup 4))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_HIMODE_MATH"
7638   "operands[4] = gen_reg_rtx (HImode);")
7639
7640 (define_insn "*udivmodhi_noext"
7641   [(set (match_operand:HI 0 "register_operand" "=a")
7642         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7643                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:HI 3 "register_operand" "=d")
7645         (umod:HI (match_dup 1) (match_dup 2)))
7646    (use (match_operand:HI 4 "register_operand" "3"))
7647    (clobber (reg:CC FLAGS_REG))]
7648   ""
7649   "div{w}\t%2"
7650   [(set_attr "type" "idiv")
7651    (set_attr "mode" "HI")])
7652
7653 ;; We cannot use div/idiv for double division, because it causes
7654 ;; "division by zero" on the overflow and that's not what we expect
7655 ;; from truncate.  Because true (non truncating) double division is
7656 ;; never generated, we can't create this insn anyway.
7657 ;
7658 ;(define_insn ""
7659 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7660 ;       (truncate:SI
7661 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7662 ;                  (zero_extend:DI
7663 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7664 ;   (set (match_operand:SI 3 "register_operand" "=d")
7665 ;       (truncate:SI
7666 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7667 ;   (clobber (reg:CC FLAGS_REG))]
7668 ;  ""
7669 ;  "div{l}\t{%2, %0|%0, %2}"
7670 ;  [(set_attr "type" "idiv")])
7671 \f
7672 ;;- Logical AND instructions
7673
7674 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7675 ;; Note that this excludes ah.
7676
7677 (define_insn "*testdi_1_rex64"
7678   [(set (reg FLAGS_REG)
7679         (compare
7680           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7681                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7682           (const_int 0)))]
7683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685   "@
7686    test{l}\t{%k1, %k0|%k0, %k1}
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{q}\t{%1, %0|%0, %1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}"
7691   [(set_attr "type" "test")
7692    (set_attr "modrm" "0,1,0,1,1")
7693    (set_attr "mode" "SI,SI,DI,DI,DI")
7694    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7695
7696 (define_insn "testsi_1"
7697   [(set (reg FLAGS_REG)
7698         (compare
7699           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7700                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7701           (const_int 0)))]
7702   "ix86_match_ccmode (insn, CCNOmode)
7703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704   "test{l}\t{%1, %0|%0, %1}"
7705   [(set_attr "type" "test")
7706    (set_attr "modrm" "0,1,1")
7707    (set_attr "mode" "SI")
7708    (set_attr "pent_pair" "uv,np,uv")])
7709
7710 (define_expand "testsi_ccno_1"
7711   [(set (reg:CCNO FLAGS_REG)
7712         (compare:CCNO
7713           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7714                   (match_operand:SI 1 "nonmemory_operand" ""))
7715           (const_int 0)))]
7716   ""
7717   "")
7718
7719 (define_insn "*testhi_1"
7720   [(set (reg FLAGS_REG)
7721         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7722                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7723                  (const_int 0)))]
7724   "ix86_match_ccmode (insn, CCNOmode)
7725    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7726   "test{w}\t{%1, %0|%0, %1}"
7727   [(set_attr "type" "test")
7728    (set_attr "modrm" "0,1,1")
7729    (set_attr "mode" "HI")
7730    (set_attr "pent_pair" "uv,np,uv")])
7731
7732 (define_expand "testqi_ccz_1"
7733   [(set (reg:CCZ FLAGS_REG)
7734         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7735                              (match_operand:QI 1 "nonmemory_operand" ""))
7736                  (const_int 0)))]
7737   ""
7738   "")
7739
7740 (define_insn "*testqi_1_maybe_si"
7741   [(set (reg FLAGS_REG)
7742         (compare
7743           (and:QI
7744             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7745             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7746           (const_int 0)))]
7747    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7748     && ix86_match_ccmode (insn,
7749                          GET_CODE (operands[1]) == CONST_INT
7750                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7751 {
7752   if (which_alternative == 3)
7753     {
7754       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7755         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7756       return "test{l}\t{%1, %k0|%k0, %1}";
7757     }
7758   return "test{b}\t{%1, %0|%0, %1}";
7759 }
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1,1")
7762    (set_attr "mode" "QI,QI,QI,SI")
7763    (set_attr "pent_pair" "uv,np,uv,np")])
7764
7765 (define_insn "*testqi_1"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:QI
7769             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7770             (match_operand:QI 1 "general_operand" "n,n,qn"))
7771           (const_int 0)))]
7772   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7773    && ix86_match_ccmode (insn, CCNOmode)"
7774   "test{b}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "QI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testqi_ext_ccno_0"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI
7784             (zero_extract:SI
7785               (match_operand 0 "ext_register_operand" "")
7786               (const_int 8)
7787               (const_int 8))
7788             (match_operand 1 "const_int_operand" ""))
7789           (const_int 0)))]
7790   ""
7791   "")
7792
7793 (define_insn "*testqi_ext_0"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI
7797             (zero_extract:SI
7798               (match_operand 0 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8))
7801             (match_operand 1 "const_int_operand" "n"))
7802           (const_int 0)))]
7803   "ix86_match_ccmode (insn, CCNOmode)"
7804   "test{b}\t{%1, %h0|%h0, %1}"
7805   [(set_attr "type" "test")
7806    (set_attr "mode" "QI")
7807    (set_attr "length_immediate" "1")
7808    (set_attr "pent_pair" "np")])
7809
7810 (define_insn "*testqi_ext_1"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:SI
7814             (zero_extract:SI
7815               (match_operand 0 "ext_register_operand" "Q")
7816               (const_int 8)
7817               (const_int 8))
7818             (zero_extend:SI
7819               (match_operand:QI 1 "general_operand" "Qm")))
7820           (const_int 0)))]
7821   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")])
7826
7827 (define_insn "*testqi_ext_1_rex64"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:SI
7831             (zero_extract:SI
7832               (match_operand 0 "ext_register_operand" "Q")
7833               (const_int 8)
7834               (const_int 8))
7835             (zero_extend:SI
7836               (match_operand:QI 1 "register_operand" "Q")))
7837           (const_int 0)))]
7838   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7839   "test{b}\t{%1, %h0|%h0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "mode" "QI")])
7842
7843 (define_insn "*testqi_ext_2"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extract:SI
7852               (match_operand 1 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8)))
7855           (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)"
7857   "test{b}\t{%h1, %h0|%h0, %h1}"
7858   [(set_attr "type" "test")
7859    (set_attr "mode" "QI")])
7860
7861 ;; Combine likes to form bit extractions for some tests.  Humor it.
7862 (define_insn "*testqi_ext_3"
7863   [(set (reg FLAGS_REG)
7864         (compare (zero_extract:SI
7865                    (match_operand 0 "nonimmediate_operand" "rm")
7866                    (match_operand:SI 1 "const_int_operand" "")
7867                    (match_operand:SI 2 "const_int_operand" ""))
7868                  (const_int 0)))]
7869   "ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_MODE (operands[0]) == SImode
7871        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7872        || GET_MODE (operands[0]) == HImode
7873        || GET_MODE (operands[0]) == QImode)"
7874   "#")
7875
7876 (define_insn "*testqi_ext_3_rex64"
7877   [(set (reg FLAGS_REG)
7878         (compare (zero_extract:DI
7879                    (match_operand 0 "nonimmediate_operand" "rm")
7880                    (match_operand:DI 1 "const_int_operand" "")
7881                    (match_operand:DI 2 "const_int_operand" ""))
7882                  (const_int 0)))]
7883   "TARGET_64BIT
7884    && ix86_match_ccmode (insn, CCNOmode)
7885    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7886    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7887    /* Ensure that resulting mask is zero or sign extended operand.  */
7888    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7889        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7890            && INTVAL (operands[1]) > 32))
7891    && (GET_MODE (operands[0]) == SImode
7892        || GET_MODE (operands[0]) == DImode
7893        || GET_MODE (operands[0]) == HImode
7894        || GET_MODE (operands[0]) == QImode)"
7895   "#")
7896
7897 (define_split
7898   [(set (match_operand 0 "flags_reg_operand" "")
7899         (match_operator 1 "compare_operator"
7900           [(zero_extract
7901              (match_operand 2 "nonimmediate_operand" "")
7902              (match_operand 3 "const_int_operand" "")
7903              (match_operand 4 "const_int_operand" ""))
7904            (const_int 0)]))]
7905   "ix86_match_ccmode (insn, CCNOmode)"
7906   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7907 {
7908   rtx val = operands[2];
7909   HOST_WIDE_INT len = INTVAL (operands[3]);
7910   HOST_WIDE_INT pos = INTVAL (operands[4]);
7911   HOST_WIDE_INT mask;
7912   enum machine_mode mode, submode;
7913
7914   mode = GET_MODE (val);
7915   if (GET_CODE (val) == MEM)
7916     {
7917       /* ??? Combine likes to put non-volatile mem extractions in QImode
7918          no matter the size of the test.  So find a mode that works.  */
7919       if (! MEM_VOLATILE_P (val))
7920         {
7921           mode = smallest_mode_for_size (pos + len, MODE_INT);
7922           val = adjust_address (val, mode, 0);
7923         }
7924     }
7925   else if (GET_CODE (val) == SUBREG
7926            && (submode = GET_MODE (SUBREG_REG (val)),
7927                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7928            && pos + len <= GET_MODE_BITSIZE (submode))
7929     {
7930       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7931       mode = submode;
7932       val = SUBREG_REG (val);
7933     }
7934   else if (mode == HImode && pos + len <= 8)
7935     {
7936       /* Small HImode tests can be converted to QImode.  */
7937       mode = QImode;
7938       val = gen_lowpart (QImode, val);
7939     }
7940
7941   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7942   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7943
7944   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7945 })
7946
7947 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7948 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7949 ;; this is relatively important trick.
7950 ;; Do the conversion only post-reload to avoid limiting of the register class
7951 ;; to QI regs.
7952 (define_split
7953   [(set (match_operand 0 "flags_reg_operand" "")
7954         (match_operator 1 "compare_operator"
7955           [(and (match_operand 2 "register_operand" "")
7956                 (match_operand 3 "const_int_operand" ""))
7957            (const_int 0)]))]
7958    "reload_completed
7959     && QI_REG_P (operands[2])
7960     && GET_MODE (operands[2]) != QImode
7961     && ((ix86_match_ccmode (insn, CCZmode)
7962          && !(INTVAL (operands[3]) & ~(255 << 8)))
7963         || (ix86_match_ccmode (insn, CCNOmode)
7964             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7965   [(set (match_dup 0)
7966         (match_op_dup 1
7967           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7968                    (match_dup 3))
7969            (const_int 0)]))]
7970   "operands[2] = gen_lowpart (SImode, operands[2]);
7971    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7972
7973 (define_split
7974   [(set (match_operand 0 "flags_reg_operand" "")
7975         (match_operator 1 "compare_operator"
7976           [(and (match_operand 2 "nonimmediate_operand" "")
7977                 (match_operand 3 "const_int_operand" ""))
7978            (const_int 0)]))]
7979    "reload_completed
7980     && GET_MODE (operands[2]) != QImode
7981     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7982     && ((ix86_match_ccmode (insn, CCZmode)
7983          && !(INTVAL (operands[3]) & ~255))
7984         || (ix86_match_ccmode (insn, CCNOmode)
7985             && !(INTVAL (operands[3]) & ~127)))"
7986   [(set (match_dup 0)
7987         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7988                          (const_int 0)]))]
7989   "operands[2] = gen_lowpart (QImode, operands[2]);
7990    operands[3] = gen_lowpart (QImode, operands[3]);")
7991
7992
7993 ;; %%% This used to optimize known byte-wide and operations to memory,
7994 ;; and sometimes to QImode registers.  If this is considered useful,
7995 ;; it should be done with splitters.
7996
7997 (define_expand "anddi3"
7998   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "TARGET_64BIT"
8003   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8004
8005 (define_insn "*anddi_1_rex64"
8006   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8007         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8008                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8011 {
8012   switch (get_attr_type (insn))
8013     {
8014     case TYPE_IMOVX:
8015       {
8016         enum machine_mode mode;
8017
8018         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8019         if (INTVAL (operands[2]) == 0xff)
8020           mode = QImode;
8021         else
8022           {
8023             gcc_assert (INTVAL (operands[2]) == 0xffff);
8024             mode = HImode;
8025           }
8026         
8027         operands[1] = gen_lowpart (mode, operands[1]);
8028         if (mode == QImode)
8029           return "movz{bq|x}\t{%1,%0|%0, %1}";
8030         else
8031           return "movz{wq|x}\t{%1,%0|%0, %1}";
8032       }
8033
8034     default:
8035       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8036       if (get_attr_mode (insn) == MODE_SI)
8037         return "and{l}\t{%k2, %k0|%k0, %k2}";
8038       else
8039         return "and{q}\t{%2, %0|%0, %2}";
8040     }
8041 }
8042   [(set_attr "type" "alu,alu,alu,imovx")
8043    (set_attr "length_immediate" "*,*,*,0")
8044    (set_attr "mode" "SI,DI,DI,DI")])
8045
8046 (define_insn "*anddi_2"
8047   [(set (reg FLAGS_REG)
8048         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8049                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8050                  (const_int 0)))
8051    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8052         (and:DI (match_dup 1) (match_dup 2)))]
8053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8054    && ix86_binary_operator_ok (AND, DImode, operands)"
8055   "@
8056    and{l}\t{%k2, %k0|%k0, %k2}
8057    and{q}\t{%2, %0|%0, %2}
8058    and{q}\t{%2, %0|%0, %2}"
8059   [(set_attr "type" "alu")
8060    (set_attr "mode" "SI,DI,DI")])
8061
8062 (define_expand "andsi3"
8063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8064         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8065                 (match_operand:SI 2 "general_operand" "")))
8066    (clobber (reg:CC FLAGS_REG))]
8067   ""
8068   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8069
8070 (define_insn "*andsi_1"
8071   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8072         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8073                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8074    (clobber (reg:CC FLAGS_REG))]
8075   "ix86_binary_operator_ok (AND, SImode, operands)"
8076 {
8077   switch (get_attr_type (insn))
8078     {
8079     case TYPE_IMOVX:
8080       {
8081         enum machine_mode mode;
8082
8083         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8084         if (INTVAL (operands[2]) == 0xff)
8085           mode = QImode;
8086         else
8087           {
8088             gcc_assert (INTVAL (operands[2]) == 0xffff);
8089             mode = HImode;
8090           }
8091         
8092         operands[1] = gen_lowpart (mode, operands[1]);
8093         if (mode == QImode)
8094           return "movz{bl|x}\t{%1,%0|%0, %1}";
8095         else
8096           return "movz{wl|x}\t{%1,%0|%0, %1}";
8097       }
8098
8099     default:
8100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8101       return "and{l}\t{%2, %0|%0, %2}";
8102     }
8103 }
8104   [(set_attr "type" "alu,alu,imovx")
8105    (set_attr "length_immediate" "*,*,0")
8106    (set_attr "mode" "SI")])
8107
8108 (define_split
8109   [(set (match_operand 0 "register_operand" "")
8110         (and (match_dup 0)
8111              (const_int -65536)))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8114   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8115   "operands[1] = gen_lowpart (HImode, operands[0]);")
8116
8117 (define_split
8118   [(set (match_operand 0 "ext_register_operand" "")
8119         (and (match_dup 0)
8120              (const_int -256)))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8123   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8124   "operands[1] = gen_lowpart (QImode, operands[0]);")
8125
8126 (define_split
8127   [(set (match_operand 0 "ext_register_operand" "")
8128         (and (match_dup 0)
8129              (const_int -65281)))
8130    (clobber (reg:CC FLAGS_REG))]
8131   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8132   [(parallel [(set (zero_extract:SI (match_dup 0)
8133                                     (const_int 8)
8134                                     (const_int 8))
8135                    (xor:SI 
8136                      (zero_extract:SI (match_dup 0)
8137                                       (const_int 8)
8138                                       (const_int 8))
8139                      (zero_extract:SI (match_dup 0)
8140                                       (const_int 8)
8141                                       (const_int 8))))
8142               (clobber (reg:CC FLAGS_REG))])]
8143   "operands[0] = gen_lowpart (SImode, operands[0]);")
8144
8145 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8146 (define_insn "*andsi_1_zext"
8147   [(set (match_operand:DI 0 "register_operand" "=r")
8148         (zero_extend:DI
8149           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8150                   (match_operand:SI 2 "general_operand" "rim"))))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8153   "and{l}\t{%2, %k0|%k0, %2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "SI")])
8156
8157 (define_insn "*andsi_2"
8158   [(set (reg FLAGS_REG)
8159         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8160                          (match_operand:SI 2 "general_operand" "rim,ri"))
8161                  (const_int 0)))
8162    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8163         (and:SI (match_dup 1) (match_dup 2)))]
8164   "ix86_match_ccmode (insn, CCNOmode)
8165    && ix86_binary_operator_ok (AND, SImode, operands)"
8166   "and{l}\t{%2, %0|%0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8169
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_2_zext"
8172   [(set (reg FLAGS_REG)
8173         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8174                          (match_operand:SI 2 "general_operand" "rim"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, SImode, operands)"
8180   "and{l}\t{%2, %k0|%k0, %2}"
8181   [(set_attr "type" "alu")
8182    (set_attr "mode" "SI")])
8183
8184 (define_expand "andhi3"
8185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8186         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8187                 (match_operand:HI 2 "general_operand" "")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "TARGET_HIMODE_MATH"
8190   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8191
8192 (define_insn "*andhi_1"
8193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8194         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8195                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "ix86_binary_operator_ok (AND, HImode, operands)"
8198 {
8199   switch (get_attr_type (insn))
8200     {
8201     case TYPE_IMOVX:
8202       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8203       gcc_assert (INTVAL (operands[2]) == 0xff);
8204       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8205
8206     default:
8207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8208
8209       return "and{w}\t{%2, %0|%0, %2}";
8210     }
8211 }
8212   [(set_attr "type" "alu,alu,imovx")
8213    (set_attr "length_immediate" "*,*,0")
8214    (set_attr "mode" "HI,HI,SI")])
8215
8216 (define_insn "*andhi_2"
8217   [(set (reg FLAGS_REG)
8218         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8219                          (match_operand:HI 2 "general_operand" "rim,ri"))
8220                  (const_int 0)))
8221    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8222         (and:HI (match_dup 1) (match_dup 2)))]
8223   "ix86_match_ccmode (insn, CCNOmode)
8224    && ix86_binary_operator_ok (AND, HImode, operands)"
8225   "and{w}\t{%2, %0|%0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "HI")])
8228
8229 (define_expand "andqi3"
8230   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8231         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8232                 (match_operand:QI 2 "general_operand" "")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_QIMODE_MATH"
8235   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8236
8237 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8238 (define_insn "*andqi_1"
8239   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8240         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8241                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "ix86_binary_operator_ok (AND, QImode, operands)"
8244   "@
8245    and{b}\t{%2, %0|%0, %2}
8246    and{b}\t{%2, %0|%0, %2}
8247    and{l}\t{%k2, %k0|%k0, %k2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "QI,QI,SI")])
8250
8251 (define_insn "*andqi_1_slp"
8252   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8253         (and:QI (match_dup 0)
8254                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8257    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8258   "and{b}\t{%1, %0|%0, %1}"
8259   [(set_attr "type" "alu1")
8260    (set_attr "mode" "QI")])
8261
8262 (define_insn "*andqi_2_maybe_si"
8263   [(set (reg FLAGS_REG)
8264         (compare (and:QI
8265                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8267                  (const_int 0)))
8268    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8269         (and:QI (match_dup 1) (match_dup 2)))]
8270   "ix86_binary_operator_ok (AND, QImode, operands)
8271    && ix86_match_ccmode (insn,
8272                          GET_CODE (operands[2]) == CONST_INT
8273                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8274 {
8275   if (which_alternative == 2)
8276     {
8277       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8278         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8279       return "and{l}\t{%2, %k0|%k0, %2}";
8280     }
8281   return "and{b}\t{%2, %0|%0, %2}";
8282 }
8283   [(set_attr "type" "alu")
8284    (set_attr "mode" "QI,QI,SI")])
8285
8286 (define_insn "*andqi_2"
8287   [(set (reg FLAGS_REG)
8288         (compare (and:QI
8289                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8290                    (match_operand:QI 2 "general_operand" "qim,qi"))
8291                  (const_int 0)))
8292    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8293         (and:QI (match_dup 1) (match_dup 2)))]
8294   "ix86_match_ccmode (insn, CCNOmode)
8295    && ix86_binary_operator_ok (AND, QImode, operands)"
8296   "and{b}\t{%2, %0|%0, %2}"
8297   [(set_attr "type" "alu")
8298    (set_attr "mode" "QI")])
8299
8300 (define_insn "*andqi_2_slp"
8301   [(set (reg FLAGS_REG)
8302         (compare (and:QI
8303                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8304                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8305                  (const_int 0)))
8306    (set (strict_low_part (match_dup 0))
8307         (and:QI (match_dup 0) (match_dup 1)))]
8308   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8309    && ix86_match_ccmode (insn, CCNOmode)
8310    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8311   "and{b}\t{%1, %0|%0, %1}"
8312   [(set_attr "type" "alu1")
8313    (set_attr "mode" "QI")])
8314
8315 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8316 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8317 ;; for a QImode operand, which of course failed.
8318
8319 (define_insn "andqi_ext_0"
8320   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8321                          (const_int 8)
8322                          (const_int 8))
8323         (and:SI 
8324           (zero_extract:SI
8325             (match_operand 1 "ext_register_operand" "0")
8326             (const_int 8)
8327             (const_int 8))
8328           (match_operand 2 "const_int_operand" "n")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   ""
8331   "and{b}\t{%2, %h0|%h0, %2}"
8332   [(set_attr "type" "alu")
8333    (set_attr "length_immediate" "1")
8334    (set_attr "mode" "QI")])
8335
8336 ;; Generated by peephole translating test to and.  This shows up
8337 ;; often in fp comparisons.
8338
8339 (define_insn "*andqi_ext_0_cc"
8340   [(set (reg FLAGS_REG)
8341         (compare
8342           (and:SI
8343             (zero_extract:SI
8344               (match_operand 1 "ext_register_operand" "0")
8345               (const_int 8)
8346               (const_int 8))
8347             (match_operand 2 "const_int_operand" "n"))
8348           (const_int 0)))
8349    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8350                          (const_int 8)
8351                          (const_int 8))
8352         (and:SI 
8353           (zero_extract:SI
8354             (match_dup 1)
8355             (const_int 8)
8356             (const_int 8))
8357           (match_dup 2)))]
8358   "ix86_match_ccmode (insn, CCNOmode)"
8359   "and{b}\t{%2, %h0|%h0, %2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "length_immediate" "1")
8362    (set_attr "mode" "QI")])
8363
8364 (define_insn "*andqi_ext_1"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (and:SI 
8369           (zero_extract:SI
8370             (match_operand 1 "ext_register_operand" "0")
8371             (const_int 8)
8372             (const_int 8))
8373           (zero_extend:SI
8374             (match_operand:QI 2 "general_operand" "Qm"))))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!TARGET_64BIT"
8377   "and{b}\t{%2, %h0|%h0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "0")
8380    (set_attr "mode" "QI")])
8381
8382 (define_insn "*andqi_ext_1_rex64"
8383   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8384                          (const_int 8)
8385                          (const_int 8))
8386         (and:SI 
8387           (zero_extract:SI
8388             (match_operand 1 "ext_register_operand" "0")
8389             (const_int 8)
8390             (const_int 8))
8391           (zero_extend:SI
8392             (match_operand 2 "ext_register_operand" "Q"))))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_64BIT"
8395   "and{b}\t{%2, %h0|%h0, %2}"
8396   [(set_attr "type" "alu")
8397    (set_attr "length_immediate" "0")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_ext_2"
8401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402                          (const_int 8)
8403                          (const_int 8))
8404         (and:SI
8405           (zero_extract:SI
8406             (match_operand 1 "ext_register_operand" "%0")
8407             (const_int 8)
8408             (const_int 8))
8409           (zero_extract:SI
8410             (match_operand 2 "ext_register_operand" "Q")
8411             (const_int 8)
8412             (const_int 8))))
8413    (clobber (reg:CC FLAGS_REG))]
8414   ""
8415   "and{b}\t{%h2, %h0|%h0, %h2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8419
8420 ;; Convert wide AND instructions with immediate operand to shorter QImode
8421 ;; equivalents when possible.
8422 ;; Don't do the splitting with memory operands, since it introduces risk
8423 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8424 ;; for size, but that can (should?) be handled by generic code instead.
8425 (define_split
8426   [(set (match_operand 0 "register_operand" "")
8427         (and (match_operand 1 "register_operand" "")
8428              (match_operand 2 "const_int_operand" "")))
8429    (clobber (reg:CC FLAGS_REG))]
8430    "reload_completed
8431     && QI_REG_P (operands[0])
8432     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8433     && !(~INTVAL (operands[2]) & ~(255 << 8))
8434     && GET_MODE (operands[0]) != QImode"
8435   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8436                    (and:SI (zero_extract:SI (match_dup 1)
8437                                             (const_int 8) (const_int 8))
8438                            (match_dup 2)))
8439               (clobber (reg:CC FLAGS_REG))])]
8440   "operands[0] = gen_lowpart (SImode, operands[0]);
8441    operands[1] = gen_lowpart (SImode, operands[1]);
8442    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8443
8444 ;; Since AND can be encoded with sign extended immediate, this is only
8445 ;; profitable when 7th bit is not set.
8446 (define_split
8447   [(set (match_operand 0 "register_operand" "")
8448         (and (match_operand 1 "general_operand" "")
8449              (match_operand 2 "const_int_operand" "")))
8450    (clobber (reg:CC FLAGS_REG))]
8451    "reload_completed
8452     && ANY_QI_REG_P (operands[0])
8453     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8454     && !(~INTVAL (operands[2]) & ~255)
8455     && !(INTVAL (operands[2]) & 128)
8456     && GET_MODE (operands[0]) != QImode"
8457   [(parallel [(set (strict_low_part (match_dup 0))
8458                    (and:QI (match_dup 1)
8459                            (match_dup 2)))
8460               (clobber (reg:CC FLAGS_REG))])]
8461   "operands[0] = gen_lowpart (QImode, operands[0]);
8462    operands[1] = gen_lowpart (QImode, operands[1]);
8463    operands[2] = gen_lowpart (QImode, operands[2]);")
8464 \f
8465 ;; Logical inclusive OR instructions
8466
8467 ;; %%% This used to optimize known byte-wide and operations to memory.
8468 ;; If this is considered useful, it should be done with splitters.
8469
8470 (define_expand "iordi3"
8471   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8472         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8473                 (match_operand:DI 2 "x86_64_general_operand" "")))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "TARGET_64BIT"
8476   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8477
8478 (define_insn "*iordi_1_rex64"
8479   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8480         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8481                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT
8484    && ix86_binary_operator_ok (IOR, DImode, operands)"
8485   "or{q}\t{%2, %0|%0, %2}"
8486   [(set_attr "type" "alu")
8487    (set_attr "mode" "DI")])
8488
8489 (define_insn "*iordi_2_rex64"
8490   [(set (reg FLAGS_REG)
8491         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8492                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8493                  (const_int 0)))
8494    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8495         (ior:DI (match_dup 1) (match_dup 2)))]
8496   "TARGET_64BIT
8497    && ix86_match_ccmode (insn, CCNOmode)
8498    && ix86_binary_operator_ok (IOR, DImode, operands)"
8499   "or{q}\t{%2, %0|%0, %2}"
8500   [(set_attr "type" "alu")
8501    (set_attr "mode" "DI")])
8502
8503 (define_insn "*iordi_3_rex64"
8504   [(set (reg FLAGS_REG)
8505         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8506                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8507                  (const_int 0)))
8508    (clobber (match_scratch:DI 0 "=r"))]
8509   "TARGET_64BIT
8510    && ix86_match_ccmode (insn, CCNOmode)
8511    && ix86_binary_operator_ok (IOR, DImode, operands)"
8512   "or{q}\t{%2, %0|%0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "DI")])
8515
8516
8517 (define_expand "iorsi3"
8518   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8519         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8520                 (match_operand:SI 2 "general_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   ""
8523   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8524
8525 (define_insn "*iorsi_1"
8526   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8527         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8528                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8529    (clobber (reg:CC FLAGS_REG))]
8530   "ix86_binary_operator_ok (IOR, SImode, operands)"
8531   "or{l}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "SI")])
8534
8535 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8536 (define_insn "*iorsi_1_zext"
8537   [(set (match_operand:DI 0 "register_operand" "=rm")
8538         (zero_extend:DI
8539           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8540                   (match_operand:SI 2 "general_operand" "rim"))))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8543   "or{l}\t{%2, %k0|%k0, %2}"
8544   [(set_attr "type" "alu")
8545    (set_attr "mode" "SI")])
8546
8547 (define_insn "*iorsi_1_zext_imm"
8548   [(set (match_operand:DI 0 "register_operand" "=rm")
8549         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8550                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT"
8553   "or{l}\t{%2, %k0|%k0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "SI")])
8556
8557 (define_insn "*iorsi_2"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8560                          (match_operand:SI 2 "general_operand" "rim,ri"))
8561                  (const_int 0)))
8562    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8563         (ior:SI (match_dup 1) (match_dup 2)))]
8564   "ix86_match_ccmode (insn, CCNOmode)
8565    && ix86_binary_operator_ok (IOR, SImode, operands)"
8566   "or{l}\t{%2, %0|%0, %2}"
8567   [(set_attr "type" "alu")
8568    (set_attr "mode" "SI")])
8569
8570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8571 ;; ??? Special case for immediate operand is missing - it is tricky.
8572 (define_insn "*iorsi_2_zext"
8573   [(set (reg FLAGS_REG)
8574         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:SI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (set (match_operand:DI 0 "register_operand" "=r")
8578         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8579   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8580    && ix86_binary_operator_ok (IOR, SImode, operands)"
8581   "or{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8584
8585 (define_insn "*iorsi_2_zext_imm"
8586   [(set (reg FLAGS_REG)
8587         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8588                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8589                  (const_int 0)))
8590    (set (match_operand:DI 0 "register_operand" "=r")
8591         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8592   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8593    && ix86_binary_operator_ok (IOR, SImode, operands)"
8594   "or{l}\t{%2, %k0|%k0, %2}"
8595   [(set_attr "type" "alu")
8596    (set_attr "mode" "SI")])
8597
8598 (define_insn "*iorsi_3"
8599   [(set (reg FLAGS_REG)
8600         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8601                          (match_operand:SI 2 "general_operand" "rim"))
8602                  (const_int 0)))
8603    (clobber (match_scratch:SI 0 "=r"))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8606   "or{l}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "SI")])
8609
8610 (define_expand "iorhi3"
8611   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8612         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8613                 (match_operand:HI 2 "general_operand" "")))
8614    (clobber (reg:CC FLAGS_REG))]
8615   "TARGET_HIMODE_MATH"
8616   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8617
8618 (define_insn "*iorhi_1"
8619   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8620         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8621                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "ix86_binary_operator_ok (IOR, HImode, operands)"
8624   "or{w}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "HI")])
8627
8628 (define_insn "*iorhi_2"
8629   [(set (reg FLAGS_REG)
8630         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631                          (match_operand:HI 2 "general_operand" "rim,ri"))
8632                  (const_int 0)))
8633    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8634         (ior:HI (match_dup 1) (match_dup 2)))]
8635   "ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, HImode, operands)"
8637   "or{w}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "HI")])
8640
8641 (define_insn "*iorhi_3"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:HI 2 "general_operand" "rim"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:HI 0 "=r"))]
8647   "ix86_match_ccmode (insn, CCNOmode)
8648    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8649   "or{w}\t{%2, %0|%0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "mode" "HI")])
8652
8653 (define_expand "iorqi3"
8654   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8655         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8656                 (match_operand:QI 2 "general_operand" "")))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_QIMODE_MATH"
8659   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8660
8661 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8662 (define_insn "*iorqi_1"
8663   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8664         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8665                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "ix86_binary_operator_ok (IOR, QImode, operands)"
8668   "@
8669    or{b}\t{%2, %0|%0, %2}
8670    or{b}\t{%2, %0|%0, %2}
8671    or{l}\t{%k2, %k0|%k0, %k2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "QI,QI,SI")])
8674
8675 (define_insn "*iorqi_1_slp"
8676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8677         (ior:QI (match_dup 0)
8678                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8681    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8682   "or{b}\t{%1, %0|%0, %1}"
8683   [(set_attr "type" "alu1")
8684    (set_attr "mode" "QI")])
8685
8686 (define_insn "*iorqi_2"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8689                          (match_operand:QI 2 "general_operand" "qim,qi"))
8690                  (const_int 0)))
8691    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8692         (ior:QI (match_dup 1) (match_dup 2)))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (IOR, QImode, operands)"
8695   "or{b}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "QI")])
8698
8699 (define_insn "*iorqi_2_slp"
8700   [(set (reg FLAGS_REG)
8701         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8702                          (match_operand:QI 1 "general_operand" "qim,qi"))
8703                  (const_int 0)))
8704    (set (strict_low_part (match_dup 0))
8705         (ior:QI (match_dup 0) (match_dup 1)))]
8706   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8707    && ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8709   "or{b}\t{%1, %0|%0, %1}"
8710   [(set_attr "type" "alu1")
8711    (set_attr "mode" "QI")])
8712
8713 (define_insn "*iorqi_3"
8714   [(set (reg FLAGS_REG)
8715         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8716                          (match_operand:QI 2 "general_operand" "qim"))
8717                  (const_int 0)))
8718    (clobber (match_scratch:QI 0 "=q"))]
8719   "ix86_match_ccmode (insn, CCNOmode)
8720    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8721   "or{b}\t{%2, %0|%0, %2}"
8722   [(set_attr "type" "alu")
8723    (set_attr "mode" "QI")])
8724
8725 (define_insn "iorqi_ext_0"
8726   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8727                          (const_int 8)
8728                          (const_int 8))
8729         (ior:SI 
8730           (zero_extract:SI
8731             (match_operand 1 "ext_register_operand" "0")
8732             (const_int 8)
8733             (const_int 8))
8734           (match_operand 2 "const_int_operand" "n")))
8735    (clobber (reg:CC FLAGS_REG))]
8736   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8737   "or{b}\t{%2, %h0|%h0, %2}"
8738   [(set_attr "type" "alu")
8739    (set_attr "length_immediate" "1")
8740    (set_attr "mode" "QI")])
8741
8742 (define_insn "*iorqi_ext_1"
8743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8744                          (const_int 8)
8745                          (const_int 8))
8746         (ior:SI 
8747           (zero_extract:SI
8748             (match_operand 1 "ext_register_operand" "0")
8749             (const_int 8)
8750             (const_int 8))
8751           (zero_extend:SI
8752             (match_operand:QI 2 "general_operand" "Qm"))))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "!TARGET_64BIT
8755    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8756   "or{b}\t{%2, %h0|%h0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "length_immediate" "0")
8759    (set_attr "mode" "QI")])
8760
8761 (define_insn "*iorqi_ext_1_rex64"
8762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763                          (const_int 8)
8764                          (const_int 8))
8765         (ior:SI 
8766           (zero_extract:SI
8767             (match_operand 1 "ext_register_operand" "0")
8768             (const_int 8)
8769             (const_int 8))
8770           (zero_extend:SI
8771             (match_operand 2 "ext_register_operand" "Q"))))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_64BIT
8774    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775   "or{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "0")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_ext_2"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (ior:SI 
8785           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8786                            (const_int 8)
8787                            (const_int 8))
8788           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8789                            (const_int 8)
8790                            (const_int 8))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8793   "ior{b}\t{%h2, %h0|%h0, %h2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "length_immediate" "0")
8796    (set_attr "mode" "QI")])
8797
8798 (define_split
8799   [(set (match_operand 0 "register_operand" "")
8800         (ior (match_operand 1 "register_operand" "")
8801              (match_operand 2 "const_int_operand" "")))
8802    (clobber (reg:CC FLAGS_REG))]
8803    "reload_completed
8804     && QI_REG_P (operands[0])
8805     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8806     && !(INTVAL (operands[2]) & ~(255 << 8))
8807     && GET_MODE (operands[0]) != QImode"
8808   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8809                    (ior:SI (zero_extract:SI (match_dup 1)
8810                                             (const_int 8) (const_int 8))
8811                            (match_dup 2)))
8812               (clobber (reg:CC FLAGS_REG))])]
8813   "operands[0] = gen_lowpart (SImode, operands[0]);
8814    operands[1] = gen_lowpart (SImode, operands[1]);
8815    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8816
8817 ;; Since OR can be encoded with sign extended immediate, this is only
8818 ;; profitable when 7th bit is set.
8819 (define_split
8820   [(set (match_operand 0 "register_operand" "")
8821         (ior (match_operand 1 "general_operand" "")
8822              (match_operand 2 "const_int_operand" "")))
8823    (clobber (reg:CC FLAGS_REG))]
8824    "reload_completed
8825     && ANY_QI_REG_P (operands[0])
8826     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8827     && !(INTVAL (operands[2]) & ~255)
8828     && (INTVAL (operands[2]) & 128)
8829     && GET_MODE (operands[0]) != QImode"
8830   [(parallel [(set (strict_low_part (match_dup 0))
8831                    (ior:QI (match_dup 1)
8832                            (match_dup 2)))
8833               (clobber (reg:CC FLAGS_REG))])]
8834   "operands[0] = gen_lowpart (QImode, operands[0]);
8835    operands[1] = gen_lowpart (QImode, operands[1]);
8836    operands[2] = gen_lowpart (QImode, operands[2]);")
8837 \f
8838 ;; Logical XOR instructions
8839
8840 ;; %%% This used to optimize known byte-wide and operations to memory.
8841 ;; If this is considered useful, it should be done with splitters.
8842
8843 (define_expand "xordi3"
8844   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8845         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8846                 (match_operand:DI 2 "x86_64_general_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "TARGET_64BIT"
8849   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8850
8851 (define_insn "*xordi_1_rex64"
8852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8853         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8854                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_64BIT
8857    && ix86_binary_operator_ok (XOR, DImode, operands)"
8858   "@
8859    xor{q}\t{%2, %0|%0, %2}
8860    xor{q}\t{%2, %0|%0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "DI,DI")])
8863
8864 (define_insn "*xordi_2_rex64"
8865   [(set (reg FLAGS_REG)
8866         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8867                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8868                  (const_int 0)))
8869    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8870         (xor:DI (match_dup 1) (match_dup 2)))]
8871   "TARGET_64BIT
8872    && ix86_match_ccmode (insn, CCNOmode)
8873    && ix86_binary_operator_ok (XOR, DImode, operands)"
8874   "@
8875    xor{q}\t{%2, %0|%0, %2}
8876    xor{q}\t{%2, %0|%0, %2}"
8877   [(set_attr "type" "alu")
8878    (set_attr "mode" "DI,DI")])
8879
8880 (define_insn "*xordi_3_rex64"
8881   [(set (reg FLAGS_REG)
8882         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8883                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8884                  (const_int 0)))
8885    (clobber (match_scratch:DI 0 "=r"))]
8886   "TARGET_64BIT
8887    && ix86_match_ccmode (insn, CCNOmode)
8888    && ix86_binary_operator_ok (XOR, DImode, operands)"
8889   "xor{q}\t{%2, %0|%0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "DI")])
8892
8893 (define_expand "xorsi3"
8894   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8895         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8896                 (match_operand:SI 2 "general_operand" "")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   ""
8899   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8900
8901 (define_insn "*xorsi_1"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8903         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8904                 (match_operand:SI 2 "general_operand" "ri,rm")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "ix86_binary_operator_ok (XOR, SImode, operands)"
8907   "xor{l}\t{%2, %0|%0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "mode" "SI")])
8910
8911 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8912 ;; Add speccase for immediates
8913 (define_insn "*xorsi_1_zext"
8914   [(set (match_operand:DI 0 "register_operand" "=r")
8915         (zero_extend:DI
8916           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8917                   (match_operand:SI 2 "general_operand" "rim"))))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8920   "xor{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8923
8924 (define_insn "*xorsi_1_zext_imm"
8925   [(set (match_operand:DI 0 "register_operand" "=r")
8926         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8927                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930   "xor{l}\t{%2, %k0|%k0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "SI")])
8933
8934 (define_insn "*xorsi_2"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8937                          (match_operand:SI 2 "general_operand" "rim,ri"))
8938                  (const_int 0)))
8939    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8940         (xor:SI (match_dup 1) (match_dup 2)))]
8941   "ix86_match_ccmode (insn, CCNOmode)
8942    && ix86_binary_operator_ok (XOR, SImode, operands)"
8943   "xor{l}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "SI")])
8946
8947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8948 ;; ??? Special case for immediate operand is missing - it is tricky.
8949 (define_insn "*xorsi_2_zext"
8950   [(set (reg FLAGS_REG)
8951         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8952                          (match_operand:SI 2 "general_operand" "rim"))
8953                  (const_int 0)))
8954    (set (match_operand:DI 0 "register_operand" "=r")
8955         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8956   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8957    && ix86_binary_operator_ok (XOR, SImode, operands)"
8958   "xor{l}\t{%2, %k0|%k0, %2}"
8959   [(set_attr "type" "alu")
8960    (set_attr "mode" "SI")])
8961
8962 (define_insn "*xorsi_2_zext_imm"
8963   [(set (reg FLAGS_REG)
8964         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8965                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8966                  (const_int 0)))
8967    (set (match_operand:DI 0 "register_operand" "=r")
8968         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8969   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8970    && ix86_binary_operator_ok (XOR, SImode, operands)"
8971   "xor{l}\t{%2, %k0|%k0, %2}"
8972   [(set_attr "type" "alu")
8973    (set_attr "mode" "SI")])
8974
8975 (define_insn "*xorsi_3"
8976   [(set (reg FLAGS_REG)
8977         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8978                          (match_operand:SI 2 "general_operand" "rim"))
8979                  (const_int 0)))
8980    (clobber (match_scratch:SI 0 "=r"))]
8981   "ix86_match_ccmode (insn, CCNOmode)
8982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8983   "xor{l}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8986
8987 (define_expand "xorhi3"
8988   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8989         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8990                 (match_operand:HI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "TARGET_HIMODE_MATH"
8993   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8994
8995 (define_insn "*xorhi_1"
8996   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8997         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, HImode, operands)"
9001   "xor{w}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "HI")])
9004
9005 (define_insn "*xorhi_2"
9006   [(set (reg FLAGS_REG)
9007         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008                          (match_operand:HI 2 "general_operand" "rim,ri"))
9009                  (const_int 0)))
9010    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9011         (xor:HI (match_dup 1) (match_dup 2)))]
9012   "ix86_match_ccmode (insn, CCNOmode)
9013    && ix86_binary_operator_ok (XOR, HImode, operands)"
9014   "xor{w}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "HI")])
9017
9018 (define_insn "*xorhi_3"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:HI 2 "general_operand" "rim"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:HI 0 "=r"))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9026   "xor{w}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "HI")])
9029
9030 (define_expand "xorqi3"
9031   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9032         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9033                 (match_operand:QI 2 "general_operand" "")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "TARGET_QIMODE_MATH"
9036   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9037
9038 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9039 (define_insn "*xorqi_1"
9040   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9041         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9042                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, QImode, operands)"
9045   "@
9046    xor{b}\t{%2, %0|%0, %2}
9047    xor{b}\t{%2, %0|%0, %2}
9048    xor{l}\t{%k2, %k0|%k0, %k2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "QI,QI,SI")])
9051
9052 (define_insn "*xorqi_1_slp"
9053   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9054         (xor:QI (match_dup 0)
9055                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9058    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9059   "xor{b}\t{%1, %0|%0, %1}"
9060   [(set_attr "type" "alu1")
9061    (set_attr "mode" "QI")])
9062
9063 (define_insn "xorqi_ext_0"
9064   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065                          (const_int 8)
9066                          (const_int 8))
9067         (xor:SI 
9068           (zero_extract:SI
9069             (match_operand 1 "ext_register_operand" "0")
9070             (const_int 8)
9071             (const_int 8))
9072           (match_operand 2 "const_int_operand" "n")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9075   "xor{b}\t{%2, %h0|%h0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "length_immediate" "1")
9078    (set_attr "mode" "QI")])
9079
9080 (define_insn "*xorqi_ext_1"
9081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9082                          (const_int 8)
9083                          (const_int 8))
9084         (xor:SI 
9085           (zero_extract:SI
9086             (match_operand 1 "ext_register_operand" "0")
9087             (const_int 8)
9088             (const_int 8))
9089           (zero_extend:SI
9090             (match_operand:QI 2 "general_operand" "Qm"))))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "!TARGET_64BIT
9093    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9094   "xor{b}\t{%2, %h0|%h0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "length_immediate" "0")
9097    (set_attr "mode" "QI")])
9098
9099 (define_insn "*xorqi_ext_1_rex64"
9100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9101                          (const_int 8)
9102                          (const_int 8))
9103         (xor:SI 
9104           (zero_extract:SI
9105             (match_operand 1 "ext_register_operand" "0")
9106             (const_int 8)
9107             (const_int 8))
9108           (zero_extend:SI
9109             (match_operand 2 "ext_register_operand" "Q"))))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "TARGET_64BIT
9112    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113   "xor{b}\t{%2, %h0|%h0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "length_immediate" "0")
9116    (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_ext_2"
9119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120                          (const_int 8)
9121                          (const_int 8))
9122         (xor:SI 
9123           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9124                            (const_int 8)
9125                            (const_int 8))
9126           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9127                            (const_int 8)
9128                            (const_int 8))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9131   "xor{b}\t{%h2, %h0|%h0, %h2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "length_immediate" "0")
9134    (set_attr "mode" "QI")])
9135
9136 (define_insn "*xorqi_cc_1"
9137   [(set (reg FLAGS_REG)
9138         (compare
9139           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9140                   (match_operand:QI 2 "general_operand" "qim,qi"))
9141           (const_int 0)))
9142    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9143         (xor:QI (match_dup 1) (match_dup 2)))]
9144   "ix86_match_ccmode (insn, CCNOmode)
9145    && ix86_binary_operator_ok (XOR, QImode, operands)"
9146   "xor{b}\t{%2, %0|%0, %2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "mode" "QI")])
9149
9150 (define_insn "*xorqi_2_slp"
9151   [(set (reg FLAGS_REG)
9152         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9153                          (match_operand:QI 1 "general_operand" "qim,qi"))
9154                  (const_int 0)))
9155    (set (strict_low_part (match_dup 0))
9156         (xor:QI (match_dup 0) (match_dup 1)))]
9157   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9158    && ix86_match_ccmode (insn, CCNOmode)
9159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9160   "xor{b}\t{%1, %0|%0, %1}"
9161   [(set_attr "type" "alu1")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*xorqi_cc_2"
9165   [(set (reg FLAGS_REG)
9166         (compare
9167           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9168                   (match_operand:QI 2 "general_operand" "qim"))
9169           (const_int 0)))
9170    (clobber (match_scratch:QI 0 "=q"))]
9171   "ix86_match_ccmode (insn, CCNOmode)
9172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9173   "xor{b}\t{%2, %0|%0, %2}"
9174   [(set_attr "type" "alu")
9175    (set_attr "mode" "QI")])
9176
9177 (define_insn "*xorqi_cc_ext_1"
9178   [(set (reg FLAGS_REG)
9179         (compare
9180           (xor:SI
9181             (zero_extract:SI
9182               (match_operand 1 "ext_register_operand" "0")
9183               (const_int 8)
9184               (const_int 8))
9185             (match_operand:QI 2 "general_operand" "qmn"))
9186           (const_int 0)))
9187    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9188                          (const_int 8)
9189                          (const_int 8))
9190         (xor:SI 
9191           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9192           (match_dup 2)))]
9193   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9194   "xor{b}\t{%2, %h0|%h0, %2}"
9195   [(set_attr "type" "alu")
9196    (set_attr "mode" "QI")])
9197
9198 (define_insn "*xorqi_cc_ext_1_rex64"
9199   [(set (reg FLAGS_REG)
9200         (compare
9201           (xor:SI
9202             (zero_extract:SI
9203               (match_operand 1 "ext_register_operand" "0")
9204               (const_int 8)
9205               (const_int 8))
9206             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9207           (const_int 0)))
9208    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9209                          (const_int 8)
9210                          (const_int 8))
9211         (xor:SI 
9212           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9213           (match_dup 2)))]
9214   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9215   "xor{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "mode" "QI")])
9218
9219 (define_expand "xorqi_cc_ext_1"
9220   [(parallel [
9221      (set (reg:CCNO FLAGS_REG)
9222           (compare:CCNO
9223             (xor:SI
9224               (zero_extract:SI
9225                 (match_operand 1 "ext_register_operand" "")
9226                 (const_int 8)
9227                 (const_int 8))
9228               (match_operand:QI 2 "general_operand" ""))
9229             (const_int 0)))
9230      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9231                            (const_int 8)
9232                            (const_int 8))
9233           (xor:SI 
9234             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9235             (match_dup 2)))])]
9236   ""
9237   "")
9238
9239 (define_split
9240   [(set (match_operand 0 "register_operand" "")
9241         (xor (match_operand 1 "register_operand" "")
9242              (match_operand 2 "const_int_operand" "")))
9243    (clobber (reg:CC FLAGS_REG))]
9244    "reload_completed
9245     && QI_REG_P (operands[0])
9246     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9247     && !(INTVAL (operands[2]) & ~(255 << 8))
9248     && GET_MODE (operands[0]) != QImode"
9249   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9250                    (xor:SI (zero_extract:SI (match_dup 1)
9251                                             (const_int 8) (const_int 8))
9252                            (match_dup 2)))
9253               (clobber (reg:CC FLAGS_REG))])]
9254   "operands[0] = gen_lowpart (SImode, operands[0]);
9255    operands[1] = gen_lowpart (SImode, operands[1]);
9256    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9257
9258 ;; Since XOR can be encoded with sign extended immediate, this is only
9259 ;; profitable when 7th bit is set.
9260 (define_split
9261   [(set (match_operand 0 "register_operand" "")
9262         (xor (match_operand 1 "general_operand" "")
9263              (match_operand 2 "const_int_operand" "")))
9264    (clobber (reg:CC FLAGS_REG))]
9265    "reload_completed
9266     && ANY_QI_REG_P (operands[0])
9267     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9268     && !(INTVAL (operands[2]) & ~255)
9269     && (INTVAL (operands[2]) & 128)
9270     && GET_MODE (operands[0]) != QImode"
9271   [(parallel [(set (strict_low_part (match_dup 0))
9272                    (xor:QI (match_dup 1)
9273                            (match_dup 2)))
9274               (clobber (reg:CC FLAGS_REG))])]
9275   "operands[0] = gen_lowpart (QImode, operands[0]);
9276    operands[1] = gen_lowpart (QImode, operands[1]);
9277    operands[2] = gen_lowpart (QImode, operands[2]);")
9278 \f
9279 ;; Negation instructions
9280
9281 (define_expand "negti2"
9282   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9283                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9284               (clobber (reg:CC FLAGS_REG))])]
9285   "TARGET_64BIT"
9286   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9287
9288 (define_insn "*negti2_1"
9289   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9290         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "TARGET_64BIT
9293    && ix86_unary_operator_ok (NEG, TImode, operands)"
9294   "#")
9295
9296 (define_split
9297   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9298         (neg:TI (match_operand:TI 1 "general_operand" "")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "TARGET_64BIT && reload_completed"
9301   [(parallel
9302     [(set (reg:CCZ FLAGS_REG)
9303           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9304      (set (match_dup 0) (neg:DI (match_dup 2)))])
9305    (parallel
9306     [(set (match_dup 1)
9307           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9308                             (match_dup 3))
9309                    (const_int 0)))
9310      (clobber (reg:CC FLAGS_REG))])
9311    (parallel
9312     [(set (match_dup 1)
9313           (neg:DI (match_dup 1)))
9314      (clobber (reg:CC FLAGS_REG))])]
9315   "split_ti (operands+1, 1, operands+2, operands+3);
9316    split_ti (operands+0, 1, operands+0, operands+1);")
9317
9318 (define_expand "negdi2"
9319   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9320                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9321               (clobber (reg:CC FLAGS_REG))])]
9322   ""
9323   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9324
9325 (define_insn "*negdi2_1"
9326   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9327         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "!TARGET_64BIT
9330    && ix86_unary_operator_ok (NEG, DImode, operands)"
9331   "#")
9332
9333 (define_split
9334   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9335         (neg:DI (match_operand:DI 1 "general_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "!TARGET_64BIT && reload_completed"
9338   [(parallel
9339     [(set (reg:CCZ FLAGS_REG)
9340           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9341      (set (match_dup 0) (neg:SI (match_dup 2)))])
9342    (parallel
9343     [(set (match_dup 1)
9344           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9345                             (match_dup 3))
9346                    (const_int 0)))
9347      (clobber (reg:CC FLAGS_REG))])
9348    (parallel
9349     [(set (match_dup 1)
9350           (neg:SI (match_dup 1)))
9351      (clobber (reg:CC FLAGS_REG))])]
9352   "split_di (operands+1, 1, operands+2, operands+3);
9353    split_di (operands+0, 1, operands+0, operands+1);")
9354
9355 (define_insn "*negdi2_1_rex64"
9356   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9357         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9360   "neg{q}\t%0"
9361   [(set_attr "type" "negnot")
9362    (set_attr "mode" "DI")])
9363
9364 ;; The problem with neg is that it does not perform (compare x 0),
9365 ;; it really performs (compare 0 x), which leaves us with the zero
9366 ;; flag being the only useful item.
9367
9368 (define_insn "*negdi2_cmpz_rex64"
9369   [(set (reg:CCZ FLAGS_REG)
9370         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9371                      (const_int 0)))
9372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9373         (neg:DI (match_dup 1)))]
9374   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9375   "neg{q}\t%0"
9376   [(set_attr "type" "negnot")
9377    (set_attr "mode" "DI")])
9378
9379
9380 (define_expand "negsi2"
9381   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9382                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9383               (clobber (reg:CC FLAGS_REG))])]
9384   ""
9385   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9386
9387 (define_insn "*negsi2_1"
9388   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9389         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "ix86_unary_operator_ok (NEG, SImode, operands)"
9392   "neg{l}\t%0"
9393   [(set_attr "type" "negnot")
9394    (set_attr "mode" "SI")])
9395
9396 ;; Combine is quite creative about this pattern.
9397 (define_insn "*negsi2_1_zext"
9398   [(set (match_operand:DI 0 "register_operand" "=r")
9399         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9400                                         (const_int 32)))
9401                      (const_int 32)))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9404   "neg{l}\t%k0"
9405   [(set_attr "type" "negnot")
9406    (set_attr "mode" "SI")])
9407
9408 ;; The problem with neg is that it does not perform (compare x 0),
9409 ;; it really performs (compare 0 x), which leaves us with the zero
9410 ;; flag being the only useful item.
9411
9412 (define_insn "*negsi2_cmpz"
9413   [(set (reg:CCZ FLAGS_REG)
9414         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9415                      (const_int 0)))
9416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9417         (neg:SI (match_dup 1)))]
9418   "ix86_unary_operator_ok (NEG, SImode, operands)"
9419   "neg{l}\t%0"
9420   [(set_attr "type" "negnot")
9421    (set_attr "mode" "SI")])
9422
9423 (define_insn "*negsi2_cmpz_zext"
9424   [(set (reg:CCZ FLAGS_REG)
9425         (compare:CCZ (lshiftrt:DI
9426                        (neg:DI (ashift:DI
9427                                  (match_operand:DI 1 "register_operand" "0")
9428                                  (const_int 32)))
9429                        (const_int 32))
9430                      (const_int 0)))
9431    (set (match_operand:DI 0 "register_operand" "=r")
9432         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9433                                         (const_int 32)))
9434                      (const_int 32)))]
9435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9436   "neg{l}\t%k0"
9437   [(set_attr "type" "negnot")
9438    (set_attr "mode" "SI")])
9439
9440 (define_expand "neghi2"
9441   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9442                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9443               (clobber (reg:CC FLAGS_REG))])]
9444   "TARGET_HIMODE_MATH"
9445   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9446
9447 (define_insn "*neghi2_1"
9448   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9449         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "ix86_unary_operator_ok (NEG, HImode, operands)"
9452   "neg{w}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "HI")])
9455
9456 (define_insn "*neghi2_cmpz"
9457   [(set (reg:CCZ FLAGS_REG)
9458         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9459                      (const_int 0)))
9460    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9461         (neg:HI (match_dup 1)))]
9462   "ix86_unary_operator_ok (NEG, HImode, operands)"
9463   "neg{w}\t%0"
9464   [(set_attr "type" "negnot")
9465    (set_attr "mode" "HI")])
9466
9467 (define_expand "negqi2"
9468   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9469                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9470               (clobber (reg:CC FLAGS_REG))])]
9471   "TARGET_QIMODE_MATH"
9472   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9473
9474 (define_insn "*negqi2_1"
9475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9476         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9477    (clobber (reg:CC FLAGS_REG))]
9478   "ix86_unary_operator_ok (NEG, QImode, operands)"
9479   "neg{b}\t%0"
9480   [(set_attr "type" "negnot")
9481    (set_attr "mode" "QI")])
9482
9483 (define_insn "*negqi2_cmpz"
9484   [(set (reg:CCZ FLAGS_REG)
9485         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9486                      (const_int 0)))
9487    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9488         (neg:QI (match_dup 1)))]
9489   "ix86_unary_operator_ok (NEG, QImode, operands)"
9490   "neg{b}\t%0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "QI")])
9493
9494 ;; Changing of sign for FP values is doable using integer unit too.
9495
9496 (define_expand "negsf2"
9497   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9498         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9499   "TARGET_80387 || TARGET_SSE_MATH"
9500   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9501
9502 (define_expand "abssf2"
9503   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9504         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9505   "TARGET_80387 || TARGET_SSE_MATH"
9506   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9507
9508 (define_insn "*absnegsf2_mixed"
9509   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9510         (match_operator:SF 3 "absneg_operator"
9511           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9512    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9515    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9516   "#")
9517
9518 (define_insn "*absnegsf2_sse"
9519   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9520         (match_operator:SF 3 "absneg_operator"
9521           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9522    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_SSE_MATH
9525    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526   "#")
9527
9528 (define_insn "*absnegsf2_i387"
9529   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9530         (match_operator:SF 3 "absneg_operator"
9531           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9532    (use (match_operand 2 "" ""))
9533    (clobber (reg:CC FLAGS_REG))]
9534   "TARGET_80387 && !TARGET_SSE_MATH
9535    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536   "#")
9537
9538 (define_expand "copysignsf3"
9539   [(match_operand:SF 0 "register_operand" "")
9540    (match_operand:SF 1 "nonmemory_operand" "")
9541    (match_operand:SF 2 "register_operand" "")]
9542   "TARGET_SSE_MATH"
9543 {
9544   ix86_expand_copysign (operands);
9545   DONE;
9546 })
9547
9548 (define_insn_and_split "copysignsf3_const"
9549   [(set (match_operand:SF 0 "register_operand"          "=x")
9550         (unspec:SF
9551           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9552            (match_operand:SF 2 "register_operand"       "0")
9553            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9554           UNSPEC_COPYSIGN))]
9555   "TARGET_SSE_MATH"
9556   "#"
9557   "&& reload_completed"
9558   [(const_int 0)]
9559 {
9560   ix86_split_copysign_const (operands);
9561   DONE;
9562 })
9563
9564 (define_insn "copysignsf3_var"
9565   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9566         (unspec:SF
9567           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9568            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9569            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9570            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9571           UNSPEC_COPYSIGN))
9572    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9573   "TARGET_SSE_MATH"
9574   "#")
9575
9576 (define_split
9577   [(set (match_operand:SF 0 "register_operand" "")
9578         (unspec:SF
9579           [(match_operand:SF 2 "register_operand" "")
9580            (match_operand:SF 3 "register_operand" "")
9581            (match_operand:V4SF 4 "" "")
9582            (match_operand:V4SF 5 "" "")]
9583           UNSPEC_COPYSIGN))
9584    (clobber (match_scratch:V4SF 1 ""))]
9585   "TARGET_SSE_MATH && reload_completed"
9586   [(const_int 0)]
9587 {
9588   ix86_split_copysign_var (operands);
9589   DONE;
9590 })
9591
9592 (define_expand "negdf2"
9593   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9594         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9595   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9596   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9597
9598 (define_expand "absdf2"
9599   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9600         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9601   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9602   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9603
9604 (define_insn "*absnegdf2_mixed"
9605   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9606         (match_operator:DF 3 "absneg_operator"
9607           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9608    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9611    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9612   "#")
9613
9614 (define_insn "*absnegdf2_sse"
9615   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9616         (match_operator:DF 3 "absneg_operator"
9617           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9618    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "TARGET_SSE2 && TARGET_SSE_MATH
9621    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622   "#")
9623
9624 (define_insn "*absnegdf2_i387"
9625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9626         (match_operator:DF 3 "absneg_operator"
9627           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9628    (use (match_operand 2 "" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9631    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632   "#")
9633
9634 (define_expand "copysigndf3"
9635   [(match_operand:DF 0 "register_operand" "")
9636    (match_operand:DF 1 "nonmemory_operand" "")
9637    (match_operand:DF 2 "register_operand" "")]
9638   "TARGET_SSE2 && TARGET_SSE_MATH"
9639 {
9640   ix86_expand_copysign (operands);
9641   DONE;
9642 })
9643
9644 (define_insn_and_split "copysigndf3_const"
9645   [(set (match_operand:DF 0 "register_operand"          "=x")
9646         (unspec:DF
9647           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9648            (match_operand:DF 2 "register_operand"       "0")
9649            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9650           UNSPEC_COPYSIGN))]
9651   "TARGET_SSE2 && TARGET_SSE_MATH"
9652   "#"
9653   "&& reload_completed"
9654   [(const_int 0)]
9655 {
9656   ix86_split_copysign_const (operands);
9657   DONE;
9658 })
9659
9660 (define_insn "copysigndf3_var"
9661   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9662         (unspec:DF
9663           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9664            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9665            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9666            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9667           UNSPEC_COPYSIGN))
9668    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9669   "TARGET_SSE2 && TARGET_SSE_MATH"
9670   "#")
9671
9672 (define_split
9673   [(set (match_operand:DF 0 "register_operand" "")
9674         (unspec:DF
9675           [(match_operand:DF 2 "register_operand" "")
9676            (match_operand:DF 3 "register_operand" "")
9677            (match_operand:V2DF 4 "" "")
9678            (match_operand:V2DF 5 "" "")]
9679           UNSPEC_COPYSIGN))
9680    (clobber (match_scratch:V2DF 1 ""))]
9681   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9682   [(const_int 0)]
9683 {
9684   ix86_split_copysign_var (operands);
9685   DONE;
9686 })
9687
9688 (define_expand "negxf2"
9689   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9690         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9691   "TARGET_80387"
9692   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9693
9694 (define_expand "absxf2"
9695   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9696         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9697   "TARGET_80387"
9698   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9699
9700 (define_insn "*absnegxf2_i387"
9701   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9702         (match_operator:XF 3 "absneg_operator"
9703           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9704    (use (match_operand 2 "" ""))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_80387
9707    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9708   "#")
9709
9710 ;; Splitters for fp abs and neg.
9711
9712 (define_split
9713   [(set (match_operand 0 "fp_register_operand" "")
9714         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9715    (use (match_operand 2 "" ""))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "reload_completed"
9718   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9719
9720 (define_split
9721   [(set (match_operand 0 "register_operand" "")
9722         (match_operator 3 "absneg_operator"
9723           [(match_operand 1 "register_operand" "")]))
9724    (use (match_operand 2 "nonimmediate_operand" ""))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "reload_completed && SSE_REG_P (operands[0])"
9727   [(set (match_dup 0) (match_dup 3))]
9728 {
9729   enum machine_mode mode = GET_MODE (operands[0]);
9730   enum machine_mode vmode = GET_MODE (operands[2]);
9731   rtx tmp;
9732   
9733   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9734   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9735   if (operands_match_p (operands[0], operands[2]))
9736     {
9737       tmp = operands[1];
9738       operands[1] = operands[2];
9739       operands[2] = tmp;
9740     }
9741   if (GET_CODE (operands[3]) == ABS)
9742     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9743   else
9744     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9745   operands[3] = tmp;
9746 })
9747
9748 (define_split
9749   [(set (match_operand:SF 0 "register_operand" "")
9750         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9751    (use (match_operand:V4SF 2 "" ""))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "reload_completed"
9754   [(parallel [(set (match_dup 0) (match_dup 1))
9755               (clobber (reg:CC FLAGS_REG))])]
9756
9757   rtx tmp;
9758   operands[0] = gen_lowpart (SImode, operands[0]);
9759   if (GET_CODE (operands[1]) == ABS)
9760     {
9761       tmp = gen_int_mode (0x7fffffff, SImode);
9762       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9763     }
9764   else
9765     {
9766       tmp = gen_int_mode (0x80000000, SImode);
9767       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9768     }
9769   operands[1] = tmp;
9770 })
9771
9772 (define_split
9773   [(set (match_operand:DF 0 "register_operand" "")
9774         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9775    (use (match_operand 2 "" ""))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "reload_completed"
9778   [(parallel [(set (match_dup 0) (match_dup 1))
9779               (clobber (reg:CC FLAGS_REG))])]
9780 {
9781   rtx tmp;
9782   if (TARGET_64BIT)
9783     {
9784       tmp = gen_lowpart (DImode, operands[0]);
9785       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9786       operands[0] = tmp;
9787
9788       if (GET_CODE (operands[1]) == ABS)
9789         tmp = const0_rtx;
9790       else
9791         tmp = gen_rtx_NOT (DImode, tmp);
9792     }
9793   else
9794     {
9795       operands[0] = gen_highpart (SImode, operands[0]);
9796       if (GET_CODE (operands[1]) == ABS)
9797         {
9798           tmp = gen_int_mode (0x7fffffff, SImode);
9799           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9800         }
9801       else
9802         {
9803           tmp = gen_int_mode (0x80000000, SImode);
9804           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9805         }
9806     }
9807   operands[1] = tmp;
9808 })
9809
9810 (define_split
9811   [(set (match_operand:XF 0 "register_operand" "")
9812         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9813    (use (match_operand 2 "" ""))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "reload_completed"
9816   [(parallel [(set (match_dup 0) (match_dup 1))
9817               (clobber (reg:CC FLAGS_REG))])]
9818 {
9819   rtx tmp;
9820   operands[0] = gen_rtx_REG (SImode,
9821                              true_regnum (operands[0])
9822                              + (TARGET_64BIT ? 1 : 2));
9823   if (GET_CODE (operands[1]) == ABS)
9824     {
9825       tmp = GEN_INT (0x7fff);
9826       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9827     }
9828   else
9829     {
9830       tmp = GEN_INT (0x8000);
9831       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9832     }
9833   operands[1] = tmp;
9834 })
9835
9836 (define_split
9837   [(set (match_operand 0 "memory_operand" "")
9838         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9839    (use (match_operand 2 "" ""))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "reload_completed"
9842   [(parallel [(set (match_dup 0) (match_dup 1))
9843               (clobber (reg:CC FLAGS_REG))])]
9844 {
9845   enum machine_mode mode = GET_MODE (operands[0]);
9846   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9847   rtx tmp;
9848
9849   operands[0] = adjust_address (operands[0], QImode, size - 1);
9850   if (GET_CODE (operands[1]) == ABS)
9851     {
9852       tmp = gen_int_mode (0x7f, QImode);
9853       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9854     }
9855   else
9856     {
9857       tmp = gen_int_mode (0x80, QImode);
9858       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9859     }
9860   operands[1] = tmp;
9861 })
9862
9863 ;; Conditionalize these after reload. If they match before reload, we 
9864 ;; lose the clobber and ability to use integer instructions.
9865
9866 (define_insn "*negsf2_1"
9867   [(set (match_operand:SF 0 "register_operand" "=f")
9868         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9869   "TARGET_80387 && reload_completed"
9870   "fchs"
9871   [(set_attr "type" "fsgn")
9872    (set_attr "mode" "SF")])
9873
9874 (define_insn "*negdf2_1"
9875   [(set (match_operand:DF 0 "register_operand" "=f")
9876         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fchs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "DF")])
9881
9882 (define_insn "*negxf2_1"
9883   [(set (match_operand:XF 0 "register_operand" "=f")
9884         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "XF")])
9889
9890 (define_insn "*abssf2_1"
9891   [(set (match_operand:SF 0 "register_operand" "=f")
9892         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fabs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "SF")])
9897
9898 (define_insn "*absdf2_1"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9901   "TARGET_80387 && reload_completed"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "DF")])
9905
9906 (define_insn "*absxf2_1"
9907   [(set (match_operand:XF 0 "register_operand" "=f")
9908         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9909   "TARGET_80387 && reload_completed"
9910   "fabs"
9911   [(set_attr "type" "fsgn")
9912    (set_attr "mode" "DF")])
9913
9914 (define_insn "*negextendsfdf2"
9915   [(set (match_operand:DF 0 "register_operand" "=f")
9916         (neg:DF (float_extend:DF
9917                   (match_operand:SF 1 "register_operand" "0"))))]
9918   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9919   "fchs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "DF")])
9922
9923 (define_insn "*negextenddfxf2"
9924   [(set (match_operand:XF 0 "register_operand" "=f")
9925         (neg:XF (float_extend:XF
9926                   (match_operand:DF 1 "register_operand" "0"))))]
9927   "TARGET_80387"
9928   "fchs"
9929   [(set_attr "type" "fsgn")
9930    (set_attr "mode" "XF")])
9931
9932 (define_insn "*negextendsfxf2"
9933   [(set (match_operand:XF 0 "register_operand" "=f")
9934         (neg:XF (float_extend:XF
9935                   (match_operand:SF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9940
9941 (define_insn "*absextendsfdf2"
9942   [(set (match_operand:DF 0 "register_operand" "=f")
9943         (abs:DF (float_extend:DF
9944                   (match_operand:SF 1 "register_operand" "0"))))]
9945   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9946   "fabs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "DF")])
9949
9950 (define_insn "*absextenddfxf2"
9951   [(set (match_operand:XF 0 "register_operand" "=f")
9952         (abs:XF (float_extend:XF
9953           (match_operand:DF 1 "register_operand" "0"))))]
9954   "TARGET_80387"
9955   "fabs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "XF")])
9958
9959 (define_insn "*absextendsfxf2"
9960   [(set (match_operand:XF 0 "register_operand" "=f")
9961         (abs:XF (float_extend:XF
9962           (match_operand:SF 1 "register_operand" "0"))))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "XF")])
9967 \f
9968 ;; One complement instructions
9969
9970 (define_expand "one_cmpldi2"
9971   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9972         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9973   "TARGET_64BIT"
9974   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9975
9976 (define_insn "*one_cmpldi2_1_rex64"
9977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9978         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9979   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9980   "not{q}\t%0"
9981   [(set_attr "type" "negnot")
9982    (set_attr "mode" "DI")])
9983
9984 (define_insn "*one_cmpldi2_2_rex64"
9985   [(set (reg FLAGS_REG)
9986         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9987                  (const_int 0)))
9988    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9989         (not:DI (match_dup 1)))]
9990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9991    && ix86_unary_operator_ok (NOT, DImode, operands)"
9992   "#"
9993   [(set_attr "type" "alu1")
9994    (set_attr "mode" "DI")])
9995
9996 (define_split
9997   [(set (match_operand 0 "flags_reg_operand" "")
9998         (match_operator 2 "compare_operator"
9999           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10000            (const_int 0)]))
10001    (set (match_operand:DI 1 "nonimmediate_operand" "")
10002         (not:DI (match_dup 3)))]
10003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10004   [(parallel [(set (match_dup 0)
10005                    (match_op_dup 2
10006                      [(xor:DI (match_dup 3) (const_int -1))
10007                       (const_int 0)]))
10008               (set (match_dup 1)
10009                    (xor:DI (match_dup 3) (const_int -1)))])]
10010   "")
10011
10012 (define_expand "one_cmplsi2"
10013   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10014         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10015   ""
10016   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10017
10018 (define_insn "*one_cmplsi2_1"
10019   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10020         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10021   "ix86_unary_operator_ok (NOT, SImode, operands)"
10022   "not{l}\t%0"
10023   [(set_attr "type" "negnot")
10024    (set_attr "mode" "SI")])
10025
10026 ;; ??? Currently never generated - xor is used instead.
10027 (define_insn "*one_cmplsi2_1_zext"
10028   [(set (match_operand:DI 0 "register_operand" "=r")
10029         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10030   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10031   "not{l}\t%k0"
10032   [(set_attr "type" "negnot")
10033    (set_attr "mode" "SI")])
10034
10035 (define_insn "*one_cmplsi2_2"
10036   [(set (reg FLAGS_REG)
10037         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10038                  (const_int 0)))
10039    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10040         (not:SI (match_dup 1)))]
10041   "ix86_match_ccmode (insn, CCNOmode)
10042    && ix86_unary_operator_ok (NOT, SImode, operands)"
10043   "#"
10044   [(set_attr "type" "alu1")
10045    (set_attr "mode" "SI")])
10046
10047 (define_split
10048   [(set (match_operand 0 "flags_reg_operand" "")
10049         (match_operator 2 "compare_operator"
10050           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10051            (const_int 0)]))
10052    (set (match_operand:SI 1 "nonimmediate_operand" "")
10053         (not:SI (match_dup 3)))]
10054   "ix86_match_ccmode (insn, CCNOmode)"
10055   [(parallel [(set (match_dup 0)
10056                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057                                     (const_int 0)]))
10058               (set (match_dup 1)
10059                    (xor:SI (match_dup 3) (const_int -1)))])]
10060   "")
10061
10062 ;; ??? Currently never generated - xor is used instead.
10063 (define_insn "*one_cmplsi2_2_zext"
10064   [(set (reg FLAGS_REG)
10065         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10066                  (const_int 0)))
10067    (set (match_operand:DI 0 "register_operand" "=r")
10068         (zero_extend:DI (not:SI (match_dup 1))))]
10069   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10070    && ix86_unary_operator_ok (NOT, SImode, operands)"
10071   "#"
10072   [(set_attr "type" "alu1")
10073    (set_attr "mode" "SI")])
10074
10075 (define_split
10076   [(set (match_operand 0 "flags_reg_operand" "")
10077         (match_operator 2 "compare_operator"
10078           [(not:SI (match_operand:SI 3 "register_operand" ""))
10079            (const_int 0)]))
10080    (set (match_operand:DI 1 "register_operand" "")
10081         (zero_extend:DI (not:SI (match_dup 3))))]
10082   "ix86_match_ccmode (insn, CCNOmode)"
10083   [(parallel [(set (match_dup 0)
10084                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10085                                     (const_int 0)]))
10086               (set (match_dup 1)
10087                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10088   "")
10089
10090 (define_expand "one_cmplhi2"
10091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10092         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10093   "TARGET_HIMODE_MATH"
10094   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10095
10096 (define_insn "*one_cmplhi2_1"
10097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10098         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10099   "ix86_unary_operator_ok (NOT, HImode, operands)"
10100   "not{w}\t%0"
10101   [(set_attr "type" "negnot")
10102    (set_attr "mode" "HI")])
10103
10104 (define_insn "*one_cmplhi2_2"
10105   [(set (reg FLAGS_REG)
10106         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10107                  (const_int 0)))
10108    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10109         (not:HI (match_dup 1)))]
10110   "ix86_match_ccmode (insn, CCNOmode)
10111    && ix86_unary_operator_ok (NEG, HImode, operands)"
10112   "#"
10113   [(set_attr "type" "alu1")
10114    (set_attr "mode" "HI")])
10115
10116 (define_split
10117   [(set (match_operand 0 "flags_reg_operand" "")
10118         (match_operator 2 "compare_operator"
10119           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10120            (const_int 0)]))
10121    (set (match_operand:HI 1 "nonimmediate_operand" "")
10122         (not:HI (match_dup 3)))]
10123   "ix86_match_ccmode (insn, CCNOmode)"
10124   [(parallel [(set (match_dup 0)
10125                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10126                                     (const_int 0)]))
10127               (set (match_dup 1)
10128                    (xor:HI (match_dup 3) (const_int -1)))])]
10129   "")
10130
10131 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10132 (define_expand "one_cmplqi2"
10133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10134         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10135   "TARGET_QIMODE_MATH"
10136   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10137
10138 (define_insn "*one_cmplqi2_1"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10141   "ix86_unary_operator_ok (NOT, QImode, operands)"
10142   "@
10143    not{b}\t%0
10144    not{l}\t%k0"
10145   [(set_attr "type" "negnot")
10146    (set_attr "mode" "QI,SI")])
10147
10148 (define_insn "*one_cmplqi2_2"
10149   [(set (reg FLAGS_REG)
10150         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10151                  (const_int 0)))
10152    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10153         (not:QI (match_dup 1)))]
10154   "ix86_match_ccmode (insn, CCNOmode)
10155    && ix86_unary_operator_ok (NOT, QImode, operands)"
10156   "#"
10157   [(set_attr "type" "alu1")
10158    (set_attr "mode" "QI")])
10159
10160 (define_split
10161   [(set (match_operand 0 "flags_reg_operand" "")
10162         (match_operator 2 "compare_operator"
10163           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10164            (const_int 0)]))
10165    (set (match_operand:QI 1 "nonimmediate_operand" "")
10166         (not:QI (match_dup 3)))]
10167   "ix86_match_ccmode (insn, CCNOmode)"
10168   [(parallel [(set (match_dup 0)
10169                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10170                                     (const_int 0)]))
10171               (set (match_dup 1)
10172                    (xor:QI (match_dup 3) (const_int -1)))])]
10173   "")
10174 \f
10175 ;; Arithmetic shift instructions
10176
10177 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10178 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10179 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10180 ;; from the assembler input.
10181 ;;
10182 ;; This instruction shifts the target reg/mem as usual, but instead of
10183 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10184 ;; is a left shift double, bits are taken from the high order bits of
10185 ;; reg, else if the insn is a shift right double, bits are taken from the
10186 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10187 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10188 ;;
10189 ;; Since sh[lr]d does not change the `reg' operand, that is done
10190 ;; separately, making all shifts emit pairs of shift double and normal
10191 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10192 ;; support a 63 bit shift, each shift where the count is in a reg expands
10193 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10194 ;;
10195 ;; If the shift count is a constant, we need never emit more than one
10196 ;; shift pair, instead using moves and sign extension for counts greater
10197 ;; than 31.
10198
10199 (define_expand "ashlti3"
10200   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10201                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10202                               (match_operand:QI 2 "nonmemory_operand" "")))
10203               (clobber (reg:CC FLAGS_REG))])]
10204   "TARGET_64BIT"
10205 {
10206   if (! immediate_operand (operands[2], QImode))
10207     {
10208       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10209       DONE;
10210     }
10211   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10212   DONE;
10213 })
10214
10215 (define_insn "ashlti3_1"
10216   [(set (match_operand:TI 0 "register_operand" "=r")
10217         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10218                    (match_operand:QI 2 "register_operand" "c")))
10219    (clobber (match_scratch:DI 3 "=&r"))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "TARGET_64BIT"
10222   "#"
10223   [(set_attr "type" "multi")])
10224
10225 (define_insn "*ashlti3_2"
10226   [(set (match_operand:TI 0 "register_operand" "=r")
10227         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228                    (match_operand:QI 2 "immediate_operand" "O")))
10229    (clobber (reg:CC FLAGS_REG))]
10230   "TARGET_64BIT"
10231   "#"
10232   [(set_attr "type" "multi")])
10233
10234 (define_split
10235   [(set (match_operand:TI 0 "register_operand" "")
10236         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10237                    (match_operand:QI 2 "register_operand" "")))
10238    (clobber (match_scratch:DI 3 ""))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "TARGET_64BIT && reload_completed"
10241   [(const_int 0)]
10242   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10243
10244 (define_split
10245   [(set (match_operand:TI 0 "register_operand" "")
10246         (ashift:TI (match_operand:TI 1 "register_operand" "")
10247                    (match_operand:QI 2 "immediate_operand" "")))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && reload_completed"
10250   [(const_int 0)]
10251   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10252
10253 (define_insn "x86_64_shld"
10254   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10255         (ior:DI (ashift:DI (match_dup 0)
10256                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10257                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10258                   (minus:QI (const_int 64) (match_dup 2)))))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_64BIT"
10261   "@
10262    shld{q}\t{%2, %1, %0|%0, %1, %2}
10263    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10264   [(set_attr "type" "ishift")
10265    (set_attr "prefix_0f" "1")
10266    (set_attr "mode" "DI")
10267    (set_attr "athlon_decode" "vector")])
10268
10269 (define_expand "x86_64_shift_adj"
10270   [(set (reg:CCZ FLAGS_REG)
10271         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10272                              (const_int 64))
10273                      (const_int 0)))
10274    (set (match_operand:DI 0 "register_operand" "")
10275         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10276                          (match_operand:DI 1 "register_operand" "")
10277                          (match_dup 0)))
10278    (set (match_dup 1)
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 3 "register_operand" "r")
10281                          (match_dup 1)))]
10282   "TARGET_64BIT"
10283   "")
10284
10285 (define_expand "ashldi3"
10286   [(set (match_operand:DI 0 "shiftdi_operand" "")
10287         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10288                    (match_operand:QI 2 "nonmemory_operand" "")))]
10289   ""
10290   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10291
10292 (define_insn "*ashldi3_1_rex64"
10293   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10294         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10295                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10298 {
10299   switch (get_attr_type (insn))
10300     {
10301     case TYPE_ALU:
10302       gcc_assert (operands[2] == const1_rtx);
10303       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10304       return "add{q}\t{%0, %0|%0, %0}";
10305
10306     case TYPE_LEA:
10307       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10308       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10309       operands[1] = gen_rtx_MULT (DImode, operands[1],
10310                                   GEN_INT (1 << INTVAL (operands[2])));
10311       return "lea{q}\t{%a1, %0|%0, %a1}";
10312
10313     default:
10314       if (REG_P (operands[2]))
10315         return "sal{q}\t{%b2, %0|%0, %b2}";
10316       else if (operands[2] == const1_rtx
10317                && (TARGET_SHIFT1 || optimize_size))
10318         return "sal{q}\t%0";
10319       else
10320         return "sal{q}\t{%2, %0|%0, %2}";
10321     }
10322 }
10323   [(set (attr "type")
10324      (cond [(eq_attr "alternative" "1")
10325               (const_string "lea")
10326             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10327                           (const_int 0))
10328                       (match_operand 0 "register_operand" ""))
10329                  (match_operand 2 "const1_operand" ""))
10330               (const_string "alu")
10331            ]
10332            (const_string "ishift")))
10333    (set_attr "mode" "DI")])
10334
10335 ;; Convert lea to the lea pattern to avoid flags dependency.
10336 (define_split
10337   [(set (match_operand:DI 0 "register_operand" "")
10338         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10339                    (match_operand:QI 2 "immediate_operand" "")))
10340    (clobber (reg:CC FLAGS_REG))]
10341   "TARGET_64BIT && reload_completed
10342    && true_regnum (operands[0]) != true_regnum (operands[1])"
10343   [(set (match_dup 0)
10344         (mult:DI (match_dup 1)
10345                  (match_dup 2)))]
10346   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10347
10348 ;; This pattern can't accept a variable shift count, since shifts by
10349 ;; zero don't affect the flags.  We assume that shifts by constant
10350 ;; zero are optimized away.
10351 (define_insn "*ashldi3_cmp_rex64"
10352   [(set (reg FLAGS_REG)
10353         (compare
10354           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10355                      (match_operand:QI 2 "immediate_operand" "e"))
10356           (const_int 0)))
10357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10358         (ashift:DI (match_dup 1) (match_dup 2)))]
10359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10360    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10361 {
10362   switch (get_attr_type (insn))
10363     {
10364     case TYPE_ALU:
10365       gcc_assert (operands[2] == const1_rtx);
10366       return "add{q}\t{%0, %0|%0, %0}";
10367
10368     default:
10369       if (REG_P (operands[2]))
10370         return "sal{q}\t{%b2, %0|%0, %b2}";
10371       else if (operands[2] == const1_rtx
10372                && (TARGET_SHIFT1 || optimize_size))
10373         return "sal{q}\t%0";
10374       else
10375         return "sal{q}\t{%2, %0|%0, %2}";
10376     }
10377 }
10378   [(set (attr "type")
10379      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10380                           (const_int 0))
10381                       (match_operand 0 "register_operand" ""))
10382                  (match_operand 2 "const1_operand" ""))
10383               (const_string "alu")
10384            ]
10385            (const_string "ishift")))
10386    (set_attr "mode" "DI")])
10387
10388 (define_insn "*ashldi3_1"
10389   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10390         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10391                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "!TARGET_64BIT"
10394   "#"
10395   [(set_attr "type" "multi")])
10396
10397 ;; By default we don't ask for a scratch register, because when DImode
10398 ;; values are manipulated, registers are already at a premium.  But if
10399 ;; we have one handy, we won't turn it away.
10400 (define_peephole2
10401   [(match_scratch:SI 3 "r")
10402    (parallel [(set (match_operand:DI 0 "register_operand" "")
10403                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10404                               (match_operand:QI 2 "nonmemory_operand" "")))
10405               (clobber (reg:CC FLAGS_REG))])
10406    (match_dup 3)]
10407   "!TARGET_64BIT && TARGET_CMOVE"
10408   [(const_int 0)]
10409   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10410
10411 (define_split
10412   [(set (match_operand:DI 0 "register_operand" "")
10413         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414                    (match_operand:QI 2 "nonmemory_operand" "")))
10415    (clobber (reg:CC FLAGS_REG))]
10416   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10417   [(const_int 0)]
10418   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10419
10420 (define_insn "x86_shld_1"
10421   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10422         (ior:SI (ashift:SI (match_dup 0)
10423                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10424                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10425                   (minus:QI (const_int 32) (match_dup 2)))))
10426    (clobber (reg:CC FLAGS_REG))]
10427   ""
10428   "@
10429    shld{l}\t{%2, %1, %0|%0, %1, %2}
10430    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10431   [(set_attr "type" "ishift")
10432    (set_attr "prefix_0f" "1")
10433    (set_attr "mode" "SI")
10434    (set_attr "pent_pair" "np")
10435    (set_attr "athlon_decode" "vector")])
10436
10437 (define_expand "x86_shift_adj_1"
10438   [(set (reg:CCZ FLAGS_REG)
10439         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10440                              (const_int 32))
10441                      (const_int 0)))
10442    (set (match_operand:SI 0 "register_operand" "")
10443         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10444                          (match_operand:SI 1 "register_operand" "")
10445                          (match_dup 0)))
10446    (set (match_dup 1)
10447         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10448                          (match_operand:SI 3 "register_operand" "r")
10449                          (match_dup 1)))]
10450   "TARGET_CMOVE"
10451   "")
10452
10453 (define_expand "x86_shift_adj_2"
10454   [(use (match_operand:SI 0 "register_operand" ""))
10455    (use (match_operand:SI 1 "register_operand" ""))
10456    (use (match_operand:QI 2 "register_operand" ""))]
10457   ""
10458 {
10459   rtx label = gen_label_rtx ();
10460   rtx tmp;
10461
10462   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10463
10464   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10465   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10466   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10467                               gen_rtx_LABEL_REF (VOIDmode, label),
10468                               pc_rtx);
10469   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10470   JUMP_LABEL (tmp) = label;
10471
10472   emit_move_insn (operands[0], operands[1]);
10473   ix86_expand_clear (operands[1]);
10474
10475   emit_label (label);
10476   LABEL_NUSES (label) = 1;
10477
10478   DONE;
10479 })
10480
10481 (define_expand "ashlsi3"
10482   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10483         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10484                    (match_operand:QI 2 "nonmemory_operand" "")))
10485    (clobber (reg:CC FLAGS_REG))]
10486   ""
10487   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10488
10489 (define_insn "*ashlsi3_1"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10491         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10492                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10495 {
10496   switch (get_attr_type (insn))
10497     {
10498     case TYPE_ALU:
10499       gcc_assert (operands[2] == const1_rtx);
10500       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10501       return "add{l}\t{%0, %0|%0, %0}";
10502
10503     case TYPE_LEA:
10504       return "#";
10505
10506     default:
10507       if (REG_P (operands[2]))
10508         return "sal{l}\t{%b2, %0|%0, %b2}";
10509       else if (operands[2] == const1_rtx
10510                && (TARGET_SHIFT1 || optimize_size))
10511         return "sal{l}\t%0";
10512       else
10513         return "sal{l}\t{%2, %0|%0, %2}";
10514     }
10515 }
10516   [(set (attr "type")
10517      (cond [(eq_attr "alternative" "1")
10518               (const_string "lea")
10519             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "SI")])
10527
10528 ;; Convert lea to the lea pattern to avoid flags dependency.
10529 (define_split
10530   [(set (match_operand 0 "register_operand" "")
10531         (ashift (match_operand 1 "index_register_operand" "")
10532                 (match_operand:QI 2 "const_int_operand" "")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "reload_completed
10535    && true_regnum (operands[0]) != true_regnum (operands[1])
10536    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10537   [(const_int 0)]
10538 {
10539   rtx pat;
10540   enum machine_mode mode = GET_MODE (operands[0]);
10541
10542   if (GET_MODE_SIZE (mode) < 4)
10543     operands[0] = gen_lowpart (SImode, operands[0]);
10544   if (mode != Pmode)
10545     operands[1] = gen_lowpart (Pmode, operands[1]);
10546   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10547
10548   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10549   if (Pmode != SImode)
10550     pat = gen_rtx_SUBREG (SImode, pat, 0);
10551   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10552   DONE;
10553 })
10554
10555 ;; Rare case of shifting RSP is handled by generating move and shift
10556 (define_split
10557   [(set (match_operand 0 "register_operand" "")
10558         (ashift (match_operand 1 "register_operand" "")
10559                 (match_operand:QI 2 "const_int_operand" "")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "reload_completed
10562    && true_regnum (operands[0]) != true_regnum (operands[1])"
10563   [(const_int 0)]
10564 {
10565   rtx pat, clob;
10566   emit_move_insn (operands[1], operands[0]);
10567   pat = gen_rtx_SET (VOIDmode, operands[0],
10568                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10569                                      operands[0], operands[2]));
10570   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10571   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10572   DONE;
10573 })
10574
10575 (define_insn "*ashlsi3_1_zext"
10576   [(set (match_operand:DI 0 "register_operand" "=r,r")
10577         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10578                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10581 {
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       return "add{l}\t{%k0, %k0|%k0, %k0}";
10587
10588     case TYPE_LEA:
10589       return "#";
10590
10591     default:
10592       if (REG_P (operands[2]))
10593         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10594       else if (operands[2] == const1_rtx
10595                && (TARGET_SHIFT1 || optimize_size))
10596         return "sal{l}\t%k0";
10597       else
10598         return "sal{l}\t{%2, %k0|%k0, %2}";
10599     }
10600 }
10601   [(set (attr "type")
10602      (cond [(eq_attr "alternative" "1")
10603               (const_string "lea")
10604             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10605                      (const_int 0))
10606                  (match_operand 2 "const1_operand" ""))
10607               (const_string "alu")
10608            ]
10609            (const_string "ishift")))
10610    (set_attr "mode" "SI")])
10611
10612 ;; Convert lea to the lea pattern to avoid flags dependency.
10613 (define_split
10614   [(set (match_operand:DI 0 "register_operand" "")
10615         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10616                                 (match_operand:QI 2 "const_int_operand" ""))))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_64BIT && reload_completed
10619    && true_regnum (operands[0]) != true_regnum (operands[1])"
10620   [(set (match_dup 0) (zero_extend:DI
10621                         (subreg:SI (mult:SI (match_dup 1)
10622                                             (match_dup 2)) 0)))]
10623 {
10624   operands[1] = gen_lowpart (Pmode, operands[1]);
10625   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10626 })
10627
10628 ;; This pattern can't accept a variable shift count, since shifts by
10629 ;; zero don't affect the flags.  We assume that shifts by constant
10630 ;; zero are optimized away.
10631 (define_insn "*ashlsi3_cmp"
10632   [(set (reg FLAGS_REG)
10633         (compare
10634           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10635                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10636           (const_int 0)))
10637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10638         (ashift:SI (match_dup 1) (match_dup 2)))]
10639   "ix86_match_ccmode (insn, CCGOCmode)
10640    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10641 {
10642   switch (get_attr_type (insn))
10643     {
10644     case TYPE_ALU:
10645       gcc_assert (operands[2] == const1_rtx);
10646       return "add{l}\t{%0, %0|%0, %0}";
10647
10648     default:
10649       if (REG_P (operands[2]))
10650         return "sal{l}\t{%b2, %0|%0, %b2}";
10651       else if (operands[2] == const1_rtx
10652                && (TARGET_SHIFT1 || optimize_size))
10653         return "sal{l}\t%0";
10654       else
10655         return "sal{l}\t{%2, %0|%0, %2}";
10656     }
10657 }
10658   [(set (attr "type")
10659      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660                           (const_int 0))
10661                       (match_operand 0 "register_operand" ""))
10662                  (match_operand 2 "const1_operand" ""))
10663               (const_string "alu")
10664            ]
10665            (const_string "ishift")))
10666    (set_attr "mode" "SI")])
10667
10668 (define_insn "*ashlsi3_cmp_zext"
10669   [(set (reg FLAGS_REG)
10670         (compare
10671           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10672                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10673           (const_int 0)))
10674    (set (match_operand:DI 0 "register_operand" "=r")
10675         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10677    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10678 {
10679   switch (get_attr_type (insn))
10680     {
10681     case TYPE_ALU:
10682       gcc_assert (operands[2] == const1_rtx);
10683       return "add{l}\t{%k0, %k0|%k0, %k0}";
10684
10685     default:
10686       if (REG_P (operands[2]))
10687         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10688       else if (operands[2] == const1_rtx
10689                && (TARGET_SHIFT1 || optimize_size))
10690         return "sal{l}\t%k0";
10691       else
10692         return "sal{l}\t{%2, %k0|%k0, %2}";
10693     }
10694 }
10695   [(set (attr "type")
10696      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697                      (const_int 0))
10698                  (match_operand 2 "const1_operand" ""))
10699               (const_string "alu")
10700            ]
10701            (const_string "ishift")))
10702    (set_attr "mode" "SI")])
10703
10704 (define_expand "ashlhi3"
10705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10706         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10707                    (match_operand:QI 2 "nonmemory_operand" "")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_HIMODE_MATH"
10710   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10711
10712 (define_insn "*ashlhi3_1_lea"
10713   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10714         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10715                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10716    (clobber (reg:CC FLAGS_REG))]
10717   "!TARGET_PARTIAL_REG_STALL
10718    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10719 {
10720   switch (get_attr_type (insn))
10721     {
10722     case TYPE_LEA:
10723       return "#";
10724     case TYPE_ALU:
10725       gcc_assert (operands[2] == const1_rtx);
10726       return "add{w}\t{%0, %0|%0, %0}";
10727
10728     default:
10729       if (REG_P (operands[2]))
10730         return "sal{w}\t{%b2, %0|%0, %b2}";
10731       else if (operands[2] == const1_rtx
10732                && (TARGET_SHIFT1 || optimize_size))
10733         return "sal{w}\t%0";
10734       else
10735         return "sal{w}\t{%2, %0|%0, %2}";
10736     }
10737 }
10738   [(set (attr "type")
10739      (cond [(eq_attr "alternative" "1")
10740               (const_string "lea")
10741             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742                           (const_int 0))
10743                       (match_operand 0 "register_operand" ""))
10744                  (match_operand 2 "const1_operand" ""))
10745               (const_string "alu")
10746            ]
10747            (const_string "ishift")))
10748    (set_attr "mode" "HI,SI")])
10749
10750 (define_insn "*ashlhi3_1"
10751   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10752         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10753                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10754    (clobber (reg:CC FLAGS_REG))]
10755   "TARGET_PARTIAL_REG_STALL
10756    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10757 {
10758   switch (get_attr_type (insn))
10759     {
10760     case TYPE_ALU:
10761       gcc_assert (operands[2] == const1_rtx);
10762       return "add{w}\t{%0, %0|%0, %0}";
10763
10764     default:
10765       if (REG_P (operands[2]))
10766         return "sal{w}\t{%b2, %0|%0, %b2}";
10767       else if (operands[2] == const1_rtx
10768                && (TARGET_SHIFT1 || optimize_size))
10769         return "sal{w}\t%0";
10770       else
10771         return "sal{w}\t{%2, %0|%0, %2}";
10772     }
10773 }
10774   [(set (attr "type")
10775      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776                           (const_int 0))
10777                       (match_operand 0 "register_operand" ""))
10778                  (match_operand 2 "const1_operand" ""))
10779               (const_string "alu")
10780            ]
10781            (const_string "ishift")))
10782    (set_attr "mode" "HI")])
10783
10784 ;; This pattern can't accept a variable shift count, since shifts by
10785 ;; zero don't affect the flags.  We assume that shifts by constant
10786 ;; zero are optimized away.
10787 (define_insn "*ashlhi3_cmp"
10788   [(set (reg FLAGS_REG)
10789         (compare
10790           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10791                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10792           (const_int 0)))
10793    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10794         (ashift:HI (match_dup 1) (match_dup 2)))]
10795   "ix86_match_ccmode (insn, CCGOCmode)
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 {
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10803
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10813 }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10823
10824 (define_expand "ashlqi3"
10825   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10826         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10827                    (match_operand:QI 2 "nonmemory_operand" "")))
10828    (clobber (reg:CC FLAGS_REG))]
10829   "TARGET_QIMODE_MATH"
10830   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10831
10832 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10833
10834 (define_insn "*ashlqi3_1_lea"
10835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10836         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10837                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "!TARGET_PARTIAL_REG_STALL
10840    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 {
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_LEA:
10845       return "#";
10846     case TYPE_ALU:
10847       gcc_assert (operands[2] == const1_rtx);
10848       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10849         return "add{l}\t{%k0, %k0|%k0, %k0}";
10850       else
10851         return "add{b}\t{%0, %0|%0, %0}";
10852
10853     default:
10854       if (REG_P (operands[2]))
10855         {
10856           if (get_attr_mode (insn) == MODE_SI)
10857             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10858           else
10859             return "sal{b}\t{%b2, %0|%0, %b2}";
10860         }
10861       else if (operands[2] == const1_rtx
10862                && (TARGET_SHIFT1 || optimize_size))
10863         {
10864           if (get_attr_mode (insn) == MODE_SI)
10865             return "sal{l}\t%0";
10866           else
10867             return "sal{b}\t%0";
10868         }
10869       else
10870         {
10871           if (get_attr_mode (insn) == MODE_SI)
10872             return "sal{l}\t{%2, %k0|%k0, %2}";
10873           else
10874             return "sal{b}\t{%2, %0|%0, %2}";
10875         }
10876     }
10877 }
10878   [(set (attr "type")
10879      (cond [(eq_attr "alternative" "2")
10880               (const_string "lea")
10881             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10882                           (const_int 0))
10883                       (match_operand 0 "register_operand" ""))
10884                  (match_operand 2 "const1_operand" ""))
10885               (const_string "alu")
10886            ]
10887            (const_string "ishift")))
10888    (set_attr "mode" "QI,SI,SI")])
10889
10890 (define_insn "*ashlqi3_1"
10891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10892         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10893                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_PARTIAL_REG_STALL
10896    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10897 {
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       gcc_assert (operands[2] == const1_rtx);
10902       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10903         return "add{l}\t{%k0, %k0|%k0, %k0}";
10904       else
10905         return "add{b}\t{%0, %0|%0, %0}";
10906
10907     default:
10908       if (REG_P (operands[2]))
10909         {
10910           if (get_attr_mode (insn) == MODE_SI)
10911             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10912           else
10913             return "sal{b}\t{%b2, %0|%0, %b2}";
10914         }
10915       else if (operands[2] == const1_rtx
10916                && (TARGET_SHIFT1 || optimize_size))
10917         {
10918           if (get_attr_mode (insn) == MODE_SI)
10919             return "sal{l}\t%0";
10920           else
10921             return "sal{b}\t%0";
10922         }
10923       else
10924         {
10925           if (get_attr_mode (insn) == MODE_SI)
10926             return "sal{l}\t{%2, %k0|%k0, %2}";
10927           else
10928             return "sal{b}\t{%2, %0|%0, %2}";
10929         }
10930     }
10931 }
10932   [(set (attr "type")
10933      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "QI,SI")])
10941
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags.  We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashlqi3_cmp"
10946   [(set (reg FLAGS_REG)
10947         (compare
10948           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10949                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10950           (const_int 0)))
10951    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10952         (ashift:QI (match_dup 1) (match_dup 2)))]
10953   "ix86_match_ccmode (insn, CCGOCmode)
10954    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       return "add{b}\t{%0, %0|%0, %0}";
10961
10962     default:
10963       if (REG_P (operands[2]))
10964         return "sal{b}\t{%b2, %0|%0, %b2}";
10965       else if (operands[2] == const1_rtx
10966                && (TARGET_SHIFT1 || optimize_size))
10967         return "sal{b}\t%0";
10968       else
10969         return "sal{b}\t{%2, %0|%0, %2}";
10970     }
10971 }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI")])
10981
10982 ;; See comment above `ashldi3' about how this works.
10983
10984 (define_expand "ashrti3"
10985   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10986                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10987                                 (match_operand:QI 2 "nonmemory_operand" "")))
10988               (clobber (reg:CC FLAGS_REG))])]
10989   "TARGET_64BIT"
10990 {
10991   if (! immediate_operand (operands[2], QImode))
10992     {
10993       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10994       DONE;
10995     }
10996   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
10997   DONE;
10998 })
10999
11000 (define_insn "ashrti3_1"
11001   [(set (match_operand:TI 0 "register_operand" "=r")
11002         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11003                      (match_operand:QI 2 "register_operand" "c")))
11004    (clobber (match_scratch:DI 3 "=&r"))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_64BIT"
11007   "#"
11008   [(set_attr "type" "multi")])
11009
11010 (define_insn "*ashrti3_2"
11011   [(set (match_operand:TI 0 "register_operand" "=r")
11012         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11013                      (match_operand:QI 2 "immediate_operand" "O")))
11014    (clobber (reg:CC FLAGS_REG))]
11015   "TARGET_64BIT"
11016   "#"
11017   [(set_attr "type" "multi")])
11018
11019 (define_split
11020   [(set (match_operand:TI 0 "register_operand" "")
11021         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11022                      (match_operand:QI 2 "register_operand" "")))
11023    (clobber (match_scratch:DI 3 ""))
11024    (clobber (reg:CC FLAGS_REG))]
11025   "TARGET_64BIT && reload_completed"
11026   [(const_int 0)]
11027   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11028
11029 (define_split
11030   [(set (match_operand:TI 0 "register_operand" "")
11031         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11032                      (match_operand:QI 2 "immediate_operand" "")))
11033    (clobber (reg:CC FLAGS_REG))]
11034   "TARGET_64BIT && reload_completed"
11035   [(const_int 0)]
11036   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11037
11038 (define_insn "x86_64_shrd"
11039   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11040         (ior:DI (ashiftrt:DI (match_dup 0)
11041                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11042                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11043                   (minus:QI (const_int 64) (match_dup 2)))))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT"
11046   "@
11047    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11048    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11049   [(set_attr "type" "ishift")
11050    (set_attr "prefix_0f" "1")
11051    (set_attr "mode" "DI")
11052    (set_attr "athlon_decode" "vector")])
11053
11054 (define_expand "ashrdi3"
11055   [(set (match_operand:DI 0 "shiftdi_operand" "")
11056         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11057                      (match_operand:QI 2 "nonmemory_operand" "")))]
11058   ""
11059   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11060
11061 (define_insn "*ashrdi3_63_rex64"
11062   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11063         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11064                      (match_operand:DI 2 "const_int_operand" "i,i")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "TARGET_64BIT && INTVAL (operands[2]) == 63
11067    && (TARGET_USE_CLTD || optimize_size)
11068    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11069   "@
11070    {cqto|cqo}
11071    sar{q}\t{%2, %0|%0, %2}"
11072   [(set_attr "type" "imovx,ishift")
11073    (set_attr "prefix_0f" "0,*")
11074    (set_attr "length_immediate" "0,*")
11075    (set_attr "modrm" "0,1")
11076    (set_attr "mode" "DI")])
11077
11078 (define_insn "*ashrdi3_1_one_bit_rex64"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11080         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11081                      (match_operand:QI 2 "const1_operand" "")))
11082    (clobber (reg:CC FLAGS_REG))]
11083   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11084    && (TARGET_SHIFT1 || optimize_size)"
11085   "sar{q}\t%0"
11086   [(set_attr "type" "ishift")
11087    (set (attr "length") 
11088      (if_then_else (match_operand:DI 0 "register_operand" "") 
11089         (const_string "2")
11090         (const_string "*")))])
11091
11092 (define_insn "*ashrdi3_1_rex64"
11093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11094         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11095                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11098   "@
11099    sar{q}\t{%2, %0|%0, %2}
11100    sar{q}\t{%b2, %0|%0, %b2}"
11101   [(set_attr "type" "ishift")
11102    (set_attr "mode" "DI")])
11103
11104 ;; This pattern can't accept a variable shift count, since shifts by
11105 ;; zero don't affect the flags.  We assume that shifts by constant
11106 ;; zero are optimized away.
11107 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11108   [(set (reg FLAGS_REG)
11109         (compare
11110           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11111                        (match_operand:QI 2 "const1_operand" ""))
11112           (const_int 0)))
11113    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11114         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11115   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11116    && (TARGET_SHIFT1 || optimize_size)
11117    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11118   "sar{q}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand:DI 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrdi3_cmp_rex64"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11132                        (match_operand:QI 2 "const_int_operand" "n"))
11133           (const_int 0)))
11134    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11135         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11136   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11137    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "sar{q}\t{%2, %0|%0, %2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "mode" "DI")])
11141
11142 (define_insn "*ashrdi3_1"
11143   [(set (match_operand:DI 0 "register_operand" "=r")
11144         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11145                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "!TARGET_64BIT"
11148   "#"
11149   [(set_attr "type" "multi")])
11150
11151 ;; By default we don't ask for a scratch register, because when DImode
11152 ;; values are manipulated, registers are already at a premium.  But if
11153 ;; we have one handy, we won't turn it away.
11154 (define_peephole2
11155   [(match_scratch:SI 3 "r")
11156    (parallel [(set (match_operand:DI 0 "register_operand" "")
11157                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11158                                 (match_operand:QI 2 "nonmemory_operand" "")))
11159               (clobber (reg:CC FLAGS_REG))])
11160    (match_dup 3)]
11161   "!TARGET_64BIT && TARGET_CMOVE"
11162   [(const_int 0)]
11163   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11164
11165 (define_split
11166   [(set (match_operand:DI 0 "register_operand" "")
11167         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11168                      (match_operand:QI 2 "nonmemory_operand" "")))
11169    (clobber (reg:CC FLAGS_REG))]
11170   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11171   [(const_int 0)]
11172   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11173
11174 (define_insn "x86_shrd_1"
11175   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176         (ior:SI (ashiftrt:SI (match_dup 0)
11177                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11179                   (minus:QI (const_int 32) (match_dup 2)))))
11180    (clobber (reg:CC FLAGS_REG))]
11181   ""
11182   "@
11183    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11184    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "pent_pair" "np")
11188    (set_attr "mode" "SI")])
11189
11190 (define_expand "x86_shift_adj_3"
11191   [(use (match_operand:SI 0 "register_operand" ""))
11192    (use (match_operand:SI 1 "register_operand" ""))
11193    (use (match_operand:QI 2 "register_operand" ""))]
11194   ""
11195 {
11196   rtx label = gen_label_rtx ();
11197   rtx tmp;
11198
11199   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11200
11201   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11202   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11203   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11204                               gen_rtx_LABEL_REF (VOIDmode, label),
11205                               pc_rtx);
11206   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11207   JUMP_LABEL (tmp) = label;
11208
11209   emit_move_insn (operands[0], operands[1]);
11210   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11211
11212   emit_label (label);
11213   LABEL_NUSES (label) = 1;
11214
11215   DONE;
11216 })
11217
11218 (define_insn "ashrsi3_31"
11219   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11220         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11221                      (match_operand:SI 2 "const_int_operand" "i,i")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11224    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11225   "@
11226    {cltd|cdq}
11227    sar{l}\t{%2, %0|%0, %2}"
11228   [(set_attr "type" "imovx,ishift")
11229    (set_attr "prefix_0f" "0,*")
11230    (set_attr "length_immediate" "0,*")
11231    (set_attr "modrm" "0,1")
11232    (set_attr "mode" "SI")])
11233
11234 (define_insn "*ashrsi3_31_zext"
11235   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11236         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11237                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11240    && INTVAL (operands[2]) == 31
11241    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11242   "@
11243    {cltd|cdq}
11244    sar{l}\t{%2, %k0|%k0, %2}"
11245   [(set_attr "type" "imovx,ishift")
11246    (set_attr "prefix_0f" "0,*")
11247    (set_attr "length_immediate" "0,*")
11248    (set_attr "modrm" "0,1")
11249    (set_attr "mode" "SI")])
11250
11251 (define_expand "ashrsi3"
11252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11253         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11254                      (match_operand:QI 2 "nonmemory_operand" "")))
11255    (clobber (reg:CC FLAGS_REG))]
11256   ""
11257   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11258
11259 (define_insn "*ashrsi3_1_one_bit"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11262                      (match_operand:QI 2 "const1_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11265    && (TARGET_SHIFT1 || optimize_size)"
11266   "sar{l}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand:SI 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11272
11273 (define_insn "*ashrsi3_1_one_bit_zext"
11274   [(set (match_operand:DI 0 "register_operand" "=r")
11275         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11276                                      (match_operand:QI 2 "const1_operand" ""))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11279    && (TARGET_SHIFT1 || optimize_size)"
11280   "sar{l}\t%k0"
11281   [(set_attr "type" "ishift")
11282    (set_attr "length" "2")])
11283
11284 (define_insn "*ashrsi3_1"
11285   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11286         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11290   "@
11291    sar{l}\t{%2, %0|%0, %2}
11292    sar{l}\t{%b2, %0|%0, %b2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "mode" "SI")])
11295
11296 (define_insn "*ashrsi3_1_zext"
11297   [(set (match_operand:DI 0 "register_operand" "=r,r")
11298         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11299                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302   "@
11303    sar{l}\t{%2, %k0|%k0, %2}
11304    sar{l}\t{%b2, %k0|%k0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "SI")])
11307
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags.  We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*ashrsi3_one_bit_cmp"
11312   [(set (reg FLAGS_REG)
11313         (compare
11314           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11315                        (match_operand:QI 2 "const1_operand" ""))
11316           (const_int 0)))
11317    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11318         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11319   "ix86_match_ccmode (insn, CCGOCmode)
11320    && (TARGET_SHIFT1 || optimize_size)
11321    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11322   "sar{l}\t%0"
11323   [(set_attr "type" "ishift")
11324    (set (attr "length") 
11325      (if_then_else (match_operand:SI 0 "register_operand" "") 
11326         (const_string "2")
11327         (const_string "*")))])
11328
11329 (define_insn "*ashrsi3_one_bit_cmp_zext"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" ""))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "register_operand" "=r")
11336         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11340   "sar{l}\t%k0"
11341   [(set_attr "type" "ishift")
11342    (set_attr "length" "2")])
11343
11344 ;; This pattern can't accept a variable shift count, since shifts by
11345 ;; zero don't affect the flags.  We assume that shifts by constant
11346 ;; zero are optimized away.
11347 (define_insn "*ashrsi3_cmp"
11348   [(set (reg FLAGS_REG)
11349         (compare
11350           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11351                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11352           (const_int 0)))
11353    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11354         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11355   "ix86_match_ccmode (insn, CCGOCmode)
11356    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357   "sar{l}\t{%2, %0|%0, %2}"
11358   [(set_attr "type" "ishift")
11359    (set_attr "mode" "SI")])
11360
11361 (define_insn "*ashrsi3_cmp_zext"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11365                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11366           (const_int 0)))
11367    (set (match_operand:DI 0 "register_operand" "=r")
11368         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11369   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11370    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371   "sar{l}\t{%2, %k0|%k0, %2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "SI")])
11374
11375 (define_expand "ashrhi3"
11376   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11377         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_HIMODE_MATH"
11381   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11382
11383 (define_insn "*ashrhi3_1_one_bit"
11384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "sar{w}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11396
11397 (define_insn "*ashrhi3_1"
11398   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11399         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11400                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11403   "@
11404    sar{w}\t{%2, %0|%0, %2}
11405    sar{w}\t{%b2, %0|%0, %b2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "HI")])
11408
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags.  We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrhi3_one_bit_cmp"
11413   [(set (reg FLAGS_REG)
11414         (compare
11415           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11416                        (match_operand:QI 2 "const1_operand" ""))
11417           (const_int 0)))
11418    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11419         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11420   "ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11423   "sar{w}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set (attr "length") 
11426      (if_then_else (match_operand 0 "register_operand" "") 
11427         (const_string "2")
11428         (const_string "*")))])
11429
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags.  We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrhi3_cmp"
11434   [(set (reg FLAGS_REG)
11435         (compare
11436           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11437                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11438           (const_int 0)))
11439    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11440         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11441   "ix86_match_ccmode (insn, CCGOCmode)
11442    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "sar{w}\t{%2, %0|%0, %2}"
11444   [(set_attr "type" "ishift")
11445    (set_attr "mode" "HI")])
11446
11447 (define_expand "ashrqi3"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11449         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11450                      (match_operand:QI 2 "nonmemory_operand" "")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_QIMODE_MATH"
11453   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11454
11455 (define_insn "*ashrqi3_1_one_bit"
11456   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11457         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11458                      (match_operand:QI 2 "const1_operand" "")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11461    && (TARGET_SHIFT1 || optimize_size)"
11462   "sar{b}\t%0"
11463   [(set_attr "type" "ishift")
11464    (set (attr "length") 
11465      (if_then_else (match_operand 0 "register_operand" "") 
11466         (const_string "2")
11467         (const_string "*")))])
11468
11469 (define_insn "*ashrqi3_1_one_bit_slp"
11470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11471         (ashiftrt:QI (match_dup 0)
11472                      (match_operand:QI 1 "const1_operand" "")))
11473    (clobber (reg:CC FLAGS_REG))]
11474   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11475    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11476    && (TARGET_SHIFT1 || optimize_size)"
11477   "sar{b}\t%0"
11478   [(set_attr "type" "ishift1")
11479    (set (attr "length") 
11480      (if_then_else (match_operand 0 "register_operand" "") 
11481         (const_string "2")
11482         (const_string "*")))])
11483
11484 (define_insn "*ashrqi3_1"
11485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11486         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11487                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11490   "@
11491    sar{b}\t{%2, %0|%0, %2}
11492    sar{b}\t{%b2, %0|%0, %b2}"
11493   [(set_attr "type" "ishift")
11494    (set_attr "mode" "QI")])
11495
11496 (define_insn "*ashrqi3_1_slp"
11497   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11498         (ashiftrt:QI (match_dup 0)
11499                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11502    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11503   "@
11504    sar{b}\t{%1, %0|%0, %1}
11505    sar{b}\t{%b1, %0|%0, %b1}"
11506   [(set_attr "type" "ishift1")
11507    (set_attr "mode" "QI")])
11508
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags.  We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*ashrqi3_one_bit_cmp"
11513   [(set (reg FLAGS_REG)
11514         (compare
11515           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11516                        (match_operand:QI 2 "const1_operand" "I"))
11517           (const_int 0)))
11518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11519         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11520   "ix86_match_ccmode (insn, CCGOCmode)
11521    && (TARGET_SHIFT1 || optimize_size)
11522    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11523   "sar{b}\t%0"
11524   [(set_attr "type" "ishift")
11525    (set (attr "length") 
11526      (if_then_else (match_operand 0 "register_operand" "") 
11527         (const_string "2")
11528         (const_string "*")))])
11529
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags.  We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*ashrqi3_cmp"
11534   [(set (reg FLAGS_REG)
11535         (compare
11536           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11537                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11538           (const_int 0)))
11539    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11540         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11541   "ix86_match_ccmode (insn, CCGOCmode)
11542    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11543   "sar{b}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "ishift")
11545    (set_attr "mode" "QI")])
11546 \f
11547 ;; Logical shift instructions
11548
11549 ;; See comment above `ashldi3' about how this works.
11550
11551 (define_expand "lshrti3"
11552   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11553                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11554                                 (match_operand:QI 2 "nonmemory_operand" "")))
11555               (clobber (reg:CC FLAGS_REG))])]
11556   "TARGET_64BIT"
11557 {
11558   if (! immediate_operand (operands[2], QImode))
11559     {
11560       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11561       DONE;
11562     }
11563   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11564   DONE;
11565 })
11566
11567 (define_insn "lshrti3_1"
11568   [(set (match_operand:TI 0 "register_operand" "=r")
11569         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11570                      (match_operand:QI 2 "register_operand" "c")))
11571    (clobber (match_scratch:DI 3 "=&r"))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "TARGET_64BIT"
11574   "#"
11575   [(set_attr "type" "multi")])
11576
11577 (define_insn "*lshrti3_2"
11578   [(set (match_operand:TI 0 "register_operand" "=r")
11579         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580                      (match_operand:QI 2 "immediate_operand" "O")))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_split 
11587   [(set (match_operand:TI 0 "register_operand" "")
11588         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11589                      (match_operand:QI 2 "register_operand" "")))
11590    (clobber (match_scratch:DI 3 ""))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && reload_completed"
11593   [(const_int 0)]
11594   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11595
11596 (define_split 
11597   [(set (match_operand:TI 0 "register_operand" "")
11598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599                      (match_operand:QI 2 "immediate_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11604
11605 (define_expand "lshrdi3"
11606   [(set (match_operand:DI 0 "shiftdi_operand" "")
11607         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11608                      (match_operand:QI 2 "nonmemory_operand" "")))]
11609   ""
11610   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11611
11612 (define_insn "*lshrdi3_1_one_bit_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11614         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11615                      (match_operand:QI 2 "const1_operand" "")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11618    && (TARGET_SHIFT1 || optimize_size)"
11619   "shr{q}\t%0"
11620   [(set_attr "type" "ishift")
11621    (set (attr "length") 
11622      (if_then_else (match_operand:DI 0 "register_operand" "") 
11623         (const_string "2")
11624         (const_string "*")))])
11625
11626 (define_insn "*lshrdi3_1_rex64"
11627   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11628         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632   "@
11633    shr{q}\t{%2, %0|%0, %2}
11634    shr{q}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "DI")])
11637
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags.  We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11648         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11652   "shr{q}\t%0"
11653   [(set_attr "type" "ishift")
11654    (set (attr "length") 
11655      (if_then_else (match_operand:DI 0 "register_operand" "") 
11656         (const_string "2")
11657         (const_string "*")))])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*lshrdi3_cmp_rex64"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_operand" "e"))
11667           (const_int 0)))
11668    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "shr{q}\t{%2, %0|%0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "DI")])
11675
11676 (define_insn "*lshrdi3_1"
11677   [(set (match_operand:DI 0 "register_operand" "=r")
11678         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11679                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "!TARGET_64BIT"
11682   "#"
11683   [(set_attr "type" "multi")])
11684
11685 ;; By default we don't ask for a scratch register, because when DImode
11686 ;; values are manipulated, registers are already at a premium.  But if
11687 ;; we have one handy, we won't turn it away.
11688 (define_peephole2
11689   [(match_scratch:SI 3 "r")
11690    (parallel [(set (match_operand:DI 0 "register_operand" "")
11691                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11692                                 (match_operand:QI 2 "nonmemory_operand" "")))
11693               (clobber (reg:CC FLAGS_REG))])
11694    (match_dup 3)]
11695   "!TARGET_64BIT && TARGET_CMOVE"
11696   [(const_int 0)]
11697   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11698
11699 (define_split 
11700   [(set (match_operand:DI 0 "register_operand" "")
11701         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702                      (match_operand:QI 2 "nonmemory_operand" "")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11705   [(const_int 0)]
11706   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11707
11708 (define_expand "lshrsi3"
11709   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11710         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11711                      (match_operand:QI 2 "nonmemory_operand" "")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   ""
11714   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11715
11716 (define_insn "*lshrsi3_1_one_bit"
11717   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11718         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11719                      (match_operand:QI 2 "const1_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11722    && (TARGET_SHIFT1 || optimize_size)"
11723   "shr{l}\t%0"
11724   [(set_attr "type" "ishift")
11725    (set (attr "length") 
11726      (if_then_else (match_operand:SI 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11729
11730 (define_insn "*lshrsi3_1_one_bit_zext"
11731   [(set (match_operand:DI 0 "register_operand" "=r")
11732         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11733                      (match_operand:QI 2 "const1_operand" "")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "shr{l}\t%k0"
11738   [(set_attr "type" "ishift")
11739    (set_attr "length" "2")])
11740
11741 (define_insn "*lshrsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11747   "@
11748    shr{l}\t{%2, %0|%0, %2}
11749    shr{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "ishift")
11751    (set_attr "mode" "SI")])
11752
11753 (define_insn "*lshrsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11760   "@
11761    shr{l}\t{%2, %k0|%k0, %2}
11762    shr{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "ishift")
11764    (set_attr "mode" "SI")])
11765
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags.  We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*lshrsi3_one_bit_cmp"
11770   [(set (reg FLAGS_REG)
11771         (compare
11772           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11773                        (match_operand:QI 2 "const1_operand" ""))
11774           (const_int 0)))
11775    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11776         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11777   "ix86_match_ccmode (insn, CCGOCmode)
11778    && (TARGET_SHIFT1 || optimize_size)
11779    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11780   "shr{l}\t%0"
11781   [(set_attr "type" "ishift")
11782    (set (attr "length") 
11783      (if_then_else (match_operand:SI 0 "register_operand" "") 
11784         (const_string "2")
11785         (const_string "*")))])
11786
11787 (define_insn "*lshrsi3_cmp_one_bit_zext"
11788   [(set (reg FLAGS_REG)
11789         (compare
11790           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11791                        (match_operand:QI 2 "const1_operand" ""))
11792           (const_int 0)))
11793    (set (match_operand:DI 0 "register_operand" "=r")
11794         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11795   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11796    && (TARGET_SHIFT1 || optimize_size)
11797    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11798   "shr{l}\t%k0"
11799   [(set_attr "type" "ishift")
11800    (set_attr "length" "2")])
11801
11802 ;; This pattern can't accept a variable shift count, since shifts by
11803 ;; zero don't affect the flags.  We assume that shifts by constant
11804 ;; zero are optimized away.
11805 (define_insn "*lshrsi3_cmp"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810           (const_int 0)))
11811    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11812         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11813   "ix86_match_ccmode (insn, CCGOCmode)
11814    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11815   "shr{l}\t{%2, %0|%0, %2}"
11816   [(set_attr "type" "ishift")
11817    (set_attr "mode" "SI")])
11818
11819 (define_insn "*lshrsi3_cmp_zext"
11820   [(set (reg FLAGS_REG)
11821         (compare
11822           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11823                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11824           (const_int 0)))
11825    (set (match_operand:DI 0 "register_operand" "=r")
11826         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11827   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11828    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11829   "shr{l}\t{%2, %k0|%k0, %2}"
11830   [(set_attr "type" "ishift")
11831    (set_attr "mode" "SI")])
11832
11833 (define_expand "lshrhi3"
11834   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11835         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11836                      (match_operand:QI 2 "nonmemory_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "TARGET_HIMODE_MATH"
11839   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11840
11841 (define_insn "*lshrhi3_1_one_bit"
11842   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11843         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11844                      (match_operand:QI 2 "const1_operand" "")))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11847    && (TARGET_SHIFT1 || optimize_size)"
11848   "shr{w}\t%0"
11849   [(set_attr "type" "ishift")
11850    (set (attr "length") 
11851      (if_then_else (match_operand 0 "register_operand" "") 
11852         (const_string "2")
11853         (const_string "*")))])
11854
11855 (define_insn "*lshrhi3_1"
11856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11857         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11858                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11861   "@
11862    shr{w}\t{%2, %0|%0, %2}
11863    shr{w}\t{%b2, %0|%0, %b2}"
11864   [(set_attr "type" "ishift")
11865    (set_attr "mode" "HI")])
11866
11867 ;; This pattern can't accept a variable shift count, since shifts by
11868 ;; zero don't affect the flags.  We assume that shifts by constant
11869 ;; zero are optimized away.
11870 (define_insn "*lshrhi3_one_bit_cmp"
11871   [(set (reg FLAGS_REG)
11872         (compare
11873           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const1_operand" ""))
11875           (const_int 0)))
11876    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11877         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11878   "ix86_match_ccmode (insn, CCGOCmode)
11879    && (TARGET_SHIFT1 || optimize_size)
11880    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11881   "shr{w}\t%0"
11882   [(set_attr "type" "ishift")
11883    (set (attr "length") 
11884      (if_then_else (match_operand:SI 0 "register_operand" "") 
11885         (const_string "2")
11886         (const_string "*")))])
11887
11888 ;; This pattern can't accept a variable shift count, since shifts by
11889 ;; zero don't affect the flags.  We assume that shifts by constant
11890 ;; zero are optimized away.
11891 (define_insn "*lshrhi3_cmp"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11895                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11896           (const_int 0)))
11897    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11899   "ix86_match_ccmode (insn, CCGOCmode)
11900    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11901   "shr{w}\t{%2, %0|%0, %2}"
11902   [(set_attr "type" "ishift")
11903    (set_attr "mode" "HI")])
11904
11905 (define_expand "lshrqi3"
11906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11907         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11908                      (match_operand:QI 2 "nonmemory_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_QIMODE_MATH"
11911   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11912
11913 (define_insn "*lshrqi3_1_one_bit"
11914   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11915         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11916                      (match_operand:QI 2 "const1_operand" "")))
11917    (clobber (reg:CC FLAGS_REG))]
11918   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11919    && (TARGET_SHIFT1 || optimize_size)"
11920   "shr{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set (attr "length") 
11923      (if_then_else (match_operand 0 "register_operand" "") 
11924         (const_string "2")
11925         (const_string "*")))])
11926
11927 (define_insn "*lshrqi3_1_one_bit_slp"
11928   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11929         (lshiftrt:QI (match_dup 0)
11930                      (match_operand:QI 1 "const1_operand" "")))
11931    (clobber (reg:CC FLAGS_REG))]
11932   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11933    && (TARGET_SHIFT1 || optimize_size)"
11934   "shr{b}\t%0"
11935   [(set_attr "type" "ishift1")
11936    (set (attr "length") 
11937      (if_then_else (match_operand 0 "register_operand" "") 
11938         (const_string "2")
11939         (const_string "*")))])
11940
11941 (define_insn "*lshrqi3_1"
11942   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11943         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11944                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11947   "@
11948    shr{b}\t{%2, %0|%0, %2}
11949    shr{b}\t{%b2, %0|%0, %b2}"
11950   [(set_attr "type" "ishift")
11951    (set_attr "mode" "QI")])
11952
11953 (define_insn "*lshrqi3_1_slp"
11954   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11955         (lshiftrt:QI (match_dup 0)
11956                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11959    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11960   "@
11961    shr{b}\t{%1, %0|%0, %1}
11962    shr{b}\t{%b1, %0|%0, %b1}"
11963   [(set_attr "type" "ishift1")
11964    (set_attr "mode" "QI")])
11965
11966 ;; This pattern can't accept a variable shift count, since shifts by
11967 ;; zero don't affect the flags.  We assume that shifts by constant
11968 ;; zero are optimized away.
11969 (define_insn "*lshrqi2_one_bit_cmp"
11970   [(set (reg FLAGS_REG)
11971         (compare
11972           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11973                        (match_operand:QI 2 "const1_operand" ""))
11974           (const_int 0)))
11975    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11976         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11977   "ix86_match_ccmode (insn, CCGOCmode)
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11980   "shr{b}\t%0"
11981   [(set_attr "type" "ishift")
11982    (set (attr "length") 
11983      (if_then_else (match_operand:SI 0 "register_operand" "") 
11984         (const_string "2")
11985         (const_string "*")))])
11986
11987 ;; This pattern can't accept a variable shift count, since shifts by
11988 ;; zero don't affect the flags.  We assume that shifts by constant
11989 ;; zero are optimized away.
11990 (define_insn "*lshrqi2_cmp"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995           (const_int 0)))
11996    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11997         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11998   "ix86_match_ccmode (insn, CCGOCmode)
11999    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12000   "shr{b}\t{%2, %0|%0, %2}"
12001   [(set_attr "type" "ishift")
12002    (set_attr "mode" "QI")])
12003 \f
12004 ;; Rotate instructions
12005
12006 (define_expand "rotldi3"
12007   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12008         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12009                    (match_operand:QI 2 "nonmemory_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT"
12012   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12013
12014 (define_insn "*rotlsi3_1_one_bit_rex64"
12015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12016         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017                    (match_operand:QI 2 "const1_operand" "")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12020    && (TARGET_SHIFT1 || optimize_size)"
12021   "rol{q}\t%0"
12022   [(set_attr "type" "rotate")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:DI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 (define_insn "*rotldi3_1_rex64"
12029   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12030         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12031                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12034   "@
12035    rol{q}\t{%2, %0|%0, %2}
12036    rol{q}\t{%b2, %0|%0, %b2}"
12037   [(set_attr "type" "rotate")
12038    (set_attr "mode" "DI")])
12039
12040 (define_expand "rotlsi3"
12041   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12042         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12043                    (match_operand:QI 2 "nonmemory_operand" "")))
12044    (clobber (reg:CC FLAGS_REG))]
12045   ""
12046   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12047
12048 (define_insn "*rotlsi3_1_one_bit"
12049   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12050         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12051                    (match_operand:QI 2 "const1_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12054    && (TARGET_SHIFT1 || optimize_size)"
12055   "rol{l}\t%0"
12056   [(set_attr "type" "rotate")
12057    (set (attr "length") 
12058      (if_then_else (match_operand:SI 0 "register_operand" "") 
12059         (const_string "2")
12060         (const_string "*")))])
12061
12062 (define_insn "*rotlsi3_1_one_bit_zext"
12063   [(set (match_operand:DI 0 "register_operand" "=r")
12064         (zero_extend:DI
12065           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12066                      (match_operand:QI 2 "const1_operand" ""))))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12069    && (TARGET_SHIFT1 || optimize_size)"
12070   "rol{l}\t%k0"
12071   [(set_attr "type" "rotate")
12072    (set_attr "length" "2")])
12073
12074 (define_insn "*rotlsi3_1"
12075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12076         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12077                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12080   "@
12081    rol{l}\t{%2, %0|%0, %2}
12082    rol{l}\t{%b2, %0|%0, %b2}"
12083   [(set_attr "type" "rotate")
12084    (set_attr "mode" "SI")])
12085
12086 (define_insn "*rotlsi3_1_zext"
12087   [(set (match_operand:DI 0 "register_operand" "=r,r")
12088         (zero_extend:DI
12089           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12090                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12093   "@
12094    rol{l}\t{%2, %k0|%k0, %2}
12095    rol{l}\t{%b2, %k0|%k0, %b2}"
12096   [(set_attr "type" "rotate")
12097    (set_attr "mode" "SI")])
12098
12099 (define_expand "rotlhi3"
12100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12101         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12102                    (match_operand:QI 2 "nonmemory_operand" "")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_HIMODE_MATH"
12105   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12106
12107 (define_insn "*rotlhi3_1_one_bit"
12108   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12109         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12110                    (match_operand:QI 2 "const1_operand" "")))
12111    (clobber (reg:CC FLAGS_REG))]
12112   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12113    && (TARGET_SHIFT1 || optimize_size)"
12114   "rol{w}\t%0"
12115   [(set_attr "type" "rotate")
12116    (set (attr "length") 
12117      (if_then_else (match_operand 0 "register_operand" "") 
12118         (const_string "2")
12119         (const_string "*")))])
12120
12121 (define_insn "*rotlhi3_1"
12122   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12123         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12124                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12127   "@
12128    rol{w}\t{%2, %0|%0, %2}
12129    rol{w}\t{%b2, %0|%0, %b2}"
12130   [(set_attr "type" "rotate")
12131    (set_attr "mode" "HI")])
12132
12133 (define_expand "rotlqi3"
12134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12135         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12136                    (match_operand:QI 2 "nonmemory_operand" "")))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_QIMODE_MATH"
12139   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12140
12141 (define_insn "*rotlqi3_1_one_bit_slp"
12142   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12143         (rotate:QI (match_dup 0)
12144                    (match_operand:QI 1 "const1_operand" "")))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "rol{b}\t%0"
12149   [(set_attr "type" "rotate1")
12150    (set (attr "length") 
12151      (if_then_else (match_operand 0 "register_operand" "") 
12152         (const_string "2")
12153         (const_string "*")))])
12154
12155 (define_insn "*rotlqi3_1_one_bit"
12156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158                    (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "rol{b}\t%0"
12163   [(set_attr "type" "rotate")
12164    (set (attr "length") 
12165      (if_then_else (match_operand 0 "register_operand" "") 
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 (define_insn "*rotlqi3_1_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171         (rotate:QI (match_dup 0)
12172                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12176   "@
12177    rol{b}\t{%1, %0|%0, %1}
12178    rol{b}\t{%b1, %0|%0, %b1}"
12179   [(set_attr "type" "rotate1")
12180    (set_attr "mode" "QI")])
12181
12182 (define_insn "*rotlqi3_1"
12183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12184         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12185                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12188   "@
12189    rol{b}\t{%2, %0|%0, %2}
12190    rol{b}\t{%b2, %0|%0, %b2}"
12191   [(set_attr "type" "rotate")
12192    (set_attr "mode" "QI")])
12193
12194 (define_expand "rotrdi3"
12195   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12196         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12197                      (match_operand:QI 2 "nonmemory_operand" "")))
12198    (clobber (reg:CC FLAGS_REG))]
12199   "TARGET_64BIT"
12200   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12201
12202 (define_insn "*rotrdi3_1_one_bit_rex64"
12203   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12204         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12205                      (match_operand:QI 2 "const1_operand" "")))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12208    && (TARGET_SHIFT1 || optimize_size)"
12209   "ror{q}\t%0"
12210   [(set_attr "type" "rotate")
12211    (set (attr "length") 
12212      (if_then_else (match_operand:DI 0 "register_operand" "") 
12213         (const_string "2")
12214         (const_string "*")))])
12215
12216 (define_insn "*rotrdi3_1_rex64"
12217   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12218         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12219                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12222   "@
12223    ror{q}\t{%2, %0|%0, %2}
12224    ror{q}\t{%b2, %0|%0, %b2}"
12225   [(set_attr "type" "rotate")
12226    (set_attr "mode" "DI")])
12227
12228 (define_expand "rotrsi3"
12229   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12230         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12231                      (match_operand:QI 2 "nonmemory_operand" "")))
12232    (clobber (reg:CC FLAGS_REG))]
12233   ""
12234   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12235
12236 (define_insn "*rotrsi3_1_one_bit"
12237   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12238         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12239                      (match_operand:QI 2 "const1_operand" "")))
12240    (clobber (reg:CC FLAGS_REG))]
12241   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12242    && (TARGET_SHIFT1 || optimize_size)"
12243   "ror{l}\t%0"
12244   [(set_attr "type" "rotate")
12245    (set (attr "length") 
12246      (if_then_else (match_operand:SI 0 "register_operand" "") 
12247         (const_string "2")
12248         (const_string "*")))])
12249
12250 (define_insn "*rotrsi3_1_one_bit_zext"
12251   [(set (match_operand:DI 0 "register_operand" "=r")
12252         (zero_extend:DI
12253           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12254                        (match_operand:QI 2 "const1_operand" ""))))
12255    (clobber (reg:CC FLAGS_REG))]
12256   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12257    && (TARGET_SHIFT1 || optimize_size)"
12258   "ror{l}\t%k0"
12259   [(set_attr "type" "rotate")
12260    (set (attr "length") 
12261      (if_then_else (match_operand:SI 0 "register_operand" "") 
12262         (const_string "2")
12263         (const_string "*")))])
12264
12265 (define_insn "*rotrsi3_1"
12266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12267         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12268                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12271   "@
12272    ror{l}\t{%2, %0|%0, %2}
12273    ror{l}\t{%b2, %0|%0, %b2}"
12274   [(set_attr "type" "rotate")
12275    (set_attr "mode" "SI")])
12276
12277 (define_insn "*rotrsi3_1_zext"
12278   [(set (match_operand:DI 0 "register_operand" "=r,r")
12279         (zero_extend:DI
12280           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12281                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12284   "@
12285    ror{l}\t{%2, %k0|%k0, %2}
12286    ror{l}\t{%b2, %k0|%k0, %b2}"
12287   [(set_attr "type" "rotate")
12288    (set_attr "mode" "SI")])
12289
12290 (define_expand "rotrhi3"
12291   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12292         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12293                      (match_operand:QI 2 "nonmemory_operand" "")))
12294    (clobber (reg:CC FLAGS_REG))]
12295   "TARGET_HIMODE_MATH"
12296   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12297
12298 (define_insn "*rotrhi3_one_bit"
12299   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12300         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12301                      (match_operand:QI 2 "const1_operand" "")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12304    && (TARGET_SHIFT1 || optimize_size)"
12305   "ror{w}\t%0"
12306   [(set_attr "type" "rotate")
12307    (set (attr "length") 
12308      (if_then_else (match_operand 0 "register_operand" "") 
12309         (const_string "2")
12310         (const_string "*")))])
12311
12312 (define_insn "*rotrhi3"
12313   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12314         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12315                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12318   "@
12319    ror{w}\t{%2, %0|%0, %2}
12320    ror{w}\t{%b2, %0|%0, %b2}"
12321   [(set_attr "type" "rotate")
12322    (set_attr "mode" "HI")])
12323
12324 (define_expand "rotrqi3"
12325   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12326         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12327                      (match_operand:QI 2 "nonmemory_operand" "")))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_QIMODE_MATH"
12330   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12331
12332 (define_insn "*rotrqi3_1_one_bit"
12333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12334         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12335                      (match_operand:QI 2 "const1_operand" "")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12338    && (TARGET_SHIFT1 || optimize_size)"
12339   "ror{b}\t%0"
12340   [(set_attr "type" "rotate")
12341    (set (attr "length") 
12342      (if_then_else (match_operand 0 "register_operand" "") 
12343         (const_string "2")
12344         (const_string "*")))])
12345
12346 (define_insn "*rotrqi3_1_one_bit_slp"
12347   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12348         (rotatert:QI (match_dup 0)
12349                      (match_operand:QI 1 "const1_operand" "")))
12350    (clobber (reg:CC FLAGS_REG))]
12351   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12352    && (TARGET_SHIFT1 || optimize_size)"
12353   "ror{b}\t%0"
12354   [(set_attr "type" "rotate1")
12355    (set (attr "length") 
12356      (if_then_else (match_operand 0 "register_operand" "") 
12357         (const_string "2")
12358         (const_string "*")))])
12359
12360 (define_insn "*rotrqi3_1"
12361   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12362         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12363                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12366   "@
12367    ror{b}\t{%2, %0|%0, %2}
12368    ror{b}\t{%b2, %0|%0, %b2}"
12369   [(set_attr "type" "rotate")
12370    (set_attr "mode" "QI")])
12371
12372 (define_insn "*rotrqi3_1_slp"
12373   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12374         (rotatert:QI (match_dup 0)
12375                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12378    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12379   "@
12380    ror{b}\t{%1, %0|%0, %1}
12381    ror{b}\t{%b1, %0|%0, %b1}"
12382   [(set_attr "type" "rotate1")
12383    (set_attr "mode" "QI")])
12384 \f
12385 ;; Bit set / bit test instructions
12386
12387 (define_expand "extv"
12388   [(set (match_operand:SI 0 "register_operand" "")
12389         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12390                          (match_operand:SI 2 "immediate_operand" "")
12391                          (match_operand:SI 3 "immediate_operand" "")))]
12392   ""
12393 {
12394   /* Handle extractions from %ah et al.  */
12395   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12396     FAIL;
12397
12398   /* From mips.md: extract_bit_field doesn't verify that our source
12399      matches the predicate, so check it again here.  */
12400   if (! ext_register_operand (operands[1], VOIDmode))
12401     FAIL;
12402 })
12403
12404 (define_expand "extzv"
12405   [(set (match_operand:SI 0 "register_operand" "")
12406         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12407                          (match_operand:SI 2 "immediate_operand" "")
12408                          (match_operand:SI 3 "immediate_operand" "")))]
12409   ""
12410 {
12411   /* Handle extractions from %ah et al.  */
12412   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12413     FAIL;
12414
12415   /* From mips.md: extract_bit_field doesn't verify that our source
12416      matches the predicate, so check it again here.  */
12417   if (! ext_register_operand (operands[1], VOIDmode))
12418     FAIL;
12419 })
12420
12421 (define_expand "insv"
12422   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12423                       (match_operand 1 "immediate_operand" "")
12424                       (match_operand 2 "immediate_operand" ""))
12425         (match_operand 3 "register_operand" ""))]
12426   ""
12427 {
12428   /* Handle extractions from %ah et al.  */
12429   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12430     FAIL;
12431
12432   /* From mips.md: insert_bit_field doesn't verify that our source
12433      matches the predicate, so check it again here.  */
12434   if (! ext_register_operand (operands[0], VOIDmode))
12435     FAIL;
12436
12437   if (TARGET_64BIT)
12438     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12439   else
12440     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12441
12442   DONE;
12443 })
12444
12445 ;; %%% bts, btr, btc, bt.
12446 ;; In general these instructions are *slow* when applied to memory,
12447 ;; since they enforce atomic operation.  When applied to registers,
12448 ;; it depends on the cpu implementation.  They're never faster than
12449 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12450 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12451 ;; within the instruction itself, so operating on bits in the high
12452 ;; 32-bits of a register becomes easier.
12453 ;;
12454 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12455 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12456 ;; negdf respectively, so they can never be disabled entirely.
12457
12458 (define_insn "*btsq"
12459   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12460                          (const_int 1)
12461                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12462         (const_int 1))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12465   "bts{q} %1,%0"
12466   [(set_attr "type" "alu1")])
12467
12468 (define_insn "*btrq"
12469   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12470                          (const_int 1)
12471                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12472         (const_int 0))
12473    (clobber (reg:CC FLAGS_REG))]
12474   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12475   "btr{q} %1,%0"
12476   [(set_attr "type" "alu1")])
12477
12478 (define_insn "*btcq"
12479   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12480                          (const_int 1)
12481                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12482         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12485   "btc{q} %1,%0"
12486   [(set_attr "type" "alu1")])
12487
12488 ;; Allow Nocona to avoid these instructions if a register is available.
12489
12490 (define_peephole2
12491   [(match_scratch:DI 2 "r")
12492    (parallel [(set (zero_extract:DI
12493                      (match_operand:DI 0 "register_operand" "")
12494                      (const_int 1)
12495                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12496                    (const_int 1))
12497               (clobber (reg:CC FLAGS_REG))])]
12498   "TARGET_64BIT && !TARGET_USE_BT"
12499   [(const_int 0)]
12500 {
12501   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12502   rtx op1;
12503
12504   if (HOST_BITS_PER_WIDE_INT >= 64)
12505     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12506   else if (i < HOST_BITS_PER_WIDE_INT)
12507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12508   else
12509     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12510
12511   op1 = immed_double_const (lo, hi, DImode);
12512   if (i >= 31)
12513     {
12514       emit_move_insn (operands[2], op1);
12515       op1 = operands[2];
12516     }
12517
12518   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12519   DONE;
12520 })
12521
12522 (define_peephole2
12523   [(match_scratch:DI 2 "r")
12524    (parallel [(set (zero_extract:DI
12525                      (match_operand:DI 0 "register_operand" "")
12526                      (const_int 1)
12527                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12528                    (const_int 0))
12529               (clobber (reg:CC FLAGS_REG))])]
12530   "TARGET_64BIT && !TARGET_USE_BT"
12531   [(const_int 0)]
12532 {
12533   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12534   rtx op1;
12535
12536   if (HOST_BITS_PER_WIDE_INT >= 64)
12537     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12538   else if (i < HOST_BITS_PER_WIDE_INT)
12539     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12540   else
12541     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12542
12543   op1 = immed_double_const (~lo, ~hi, DImode);
12544   if (i >= 32)
12545     {
12546       emit_move_insn (operands[2], op1);
12547       op1 = operands[2];
12548     }
12549
12550   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12551   DONE;
12552 })
12553
12554 (define_peephole2
12555   [(match_scratch:DI 2 "r")
12556    (parallel [(set (zero_extract:DI
12557                      (match_operand:DI 0 "register_operand" "")
12558                      (const_int 1)
12559                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12560               (not:DI (zero_extract:DI
12561                         (match_dup 0) (const_int 1) (match_dup 1))))
12562               (clobber (reg:CC FLAGS_REG))])]
12563   "TARGET_64BIT && !TARGET_USE_BT"
12564   [(const_int 0)]
12565 {
12566   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12567   rtx op1;
12568
12569   if (HOST_BITS_PER_WIDE_INT >= 64)
12570     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12571   else if (i < HOST_BITS_PER_WIDE_INT)
12572     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12573   else
12574     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12575
12576   op1 = immed_double_const (lo, hi, DImode);
12577   if (i >= 31)
12578     {
12579       emit_move_insn (operands[2], op1);
12580       op1 = operands[2];
12581     }
12582
12583   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12584   DONE;
12585 })
12586 \f
12587 ;; Store-flag instructions.
12588
12589 ;; For all sCOND expanders, also expand the compare or test insn that
12590 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12591
12592 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12593 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12594 ;; way, which can later delete the movzx if only QImode is needed.
12595
12596 (define_expand "seq"
12597   [(set (match_operand:QI 0 "register_operand" "")
12598         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12599   ""
12600   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12601
12602 (define_expand "sne"
12603   [(set (match_operand:QI 0 "register_operand" "")
12604         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12605   ""
12606   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12607
12608 (define_expand "sgt"
12609   [(set (match_operand:QI 0 "register_operand" "")
12610         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12611   ""
12612   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12613
12614 (define_expand "sgtu"
12615   [(set (match_operand:QI 0 "register_operand" "")
12616         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12617   ""
12618   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12619
12620 (define_expand "slt"
12621   [(set (match_operand:QI 0 "register_operand" "")
12622         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12623   ""
12624   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12625
12626 (define_expand "sltu"
12627   [(set (match_operand:QI 0 "register_operand" "")
12628         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12629   ""
12630   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12631
12632 (define_expand "sge"
12633   [(set (match_operand:QI 0 "register_operand" "")
12634         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12635   ""
12636   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12637
12638 (define_expand "sgeu"
12639   [(set (match_operand:QI 0 "register_operand" "")
12640         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12641   ""
12642   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12643
12644 (define_expand "sle"
12645   [(set (match_operand:QI 0 "register_operand" "")
12646         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12647   ""
12648   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12649
12650 (define_expand "sleu"
12651   [(set (match_operand:QI 0 "register_operand" "")
12652         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12653   ""
12654   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12655
12656 (define_expand "sunordered"
12657   [(set (match_operand:QI 0 "register_operand" "")
12658         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12659   "TARGET_80387 || TARGET_SSE"
12660   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12661
12662 (define_expand "sordered"
12663   [(set (match_operand:QI 0 "register_operand" "")
12664         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12665   "TARGET_80387"
12666   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12667
12668 (define_expand "suneq"
12669   [(set (match_operand:QI 0 "register_operand" "")
12670         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12671   "TARGET_80387 || TARGET_SSE"
12672   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sunge"
12675   [(set (match_operand:QI 0 "register_operand" "")
12676         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12677   "TARGET_80387 || TARGET_SSE"
12678   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sungt"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   "TARGET_80387 || TARGET_SSE"
12684   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sunle"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   "TARGET_80387 || TARGET_SSE"
12690   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sunlt"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   "TARGET_80387 || TARGET_SSE"
12696   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sltgt"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   "TARGET_80387 || TARGET_SSE"
12702   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12703
12704 (define_insn "*setcc_1"
12705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12706         (match_operator:QI 1 "ix86_comparison_operator"
12707           [(reg FLAGS_REG) (const_int 0)]))]
12708   ""
12709   "set%C1\t%0"
12710   [(set_attr "type" "setcc")
12711    (set_attr "mode" "QI")])
12712
12713 (define_insn "*setcc_2"
12714   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12715         (match_operator:QI 1 "ix86_comparison_operator"
12716           [(reg FLAGS_REG) (const_int 0)]))]
12717   ""
12718   "set%C1\t%0"
12719   [(set_attr "type" "setcc")
12720    (set_attr "mode" "QI")])
12721
12722 ;; In general it is not safe to assume too much about CCmode registers,
12723 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12724 ;; conditions this is safe on x86, so help combine not create
12725 ;;
12726 ;;      seta    %al
12727 ;;      testb   %al, %al
12728 ;;      sete    %al
12729
12730 (define_split 
12731   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12732         (ne:QI (match_operator 1 "ix86_comparison_operator"
12733                  [(reg FLAGS_REG) (const_int 0)])
12734             (const_int 0)))]
12735   ""
12736   [(set (match_dup 0) (match_dup 1))]
12737 {
12738   PUT_MODE (operands[1], QImode);
12739 })
12740
12741 (define_split 
12742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12743         (ne:QI (match_operator 1 "ix86_comparison_operator"
12744                  [(reg FLAGS_REG) (const_int 0)])
12745             (const_int 0)))]
12746   ""
12747   [(set (match_dup 0) (match_dup 1))]
12748 {
12749   PUT_MODE (operands[1], QImode);
12750 })
12751
12752 (define_split 
12753   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12754         (eq:QI (match_operator 1 "ix86_comparison_operator"
12755                  [(reg FLAGS_REG) (const_int 0)])
12756             (const_int 0)))]
12757   ""
12758   [(set (match_dup 0) (match_dup 1))]
12759 {
12760   rtx new_op1 = copy_rtx (operands[1]);
12761   operands[1] = new_op1;
12762   PUT_MODE (new_op1, QImode);
12763   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12764                                              GET_MODE (XEXP (new_op1, 0))));
12765
12766   /* Make sure that (a) the CCmode we have for the flags is strong
12767      enough for the reversed compare or (b) we have a valid FP compare.  */
12768   if (! ix86_comparison_operator (new_op1, VOIDmode))
12769     FAIL;
12770 })
12771
12772 (define_split 
12773   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12774         (eq:QI (match_operator 1 "ix86_comparison_operator"
12775                  [(reg FLAGS_REG) (const_int 0)])
12776             (const_int 0)))]
12777   ""
12778   [(set (match_dup 0) (match_dup 1))]
12779 {
12780   rtx new_op1 = copy_rtx (operands[1]);
12781   operands[1] = new_op1;
12782   PUT_MODE (new_op1, QImode);
12783   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12784                                              GET_MODE (XEXP (new_op1, 0))));
12785
12786   /* Make sure that (a) the CCmode we have for the flags is strong
12787      enough for the reversed compare or (b) we have a valid FP compare.  */
12788   if (! ix86_comparison_operator (new_op1, VOIDmode))
12789     FAIL;
12790 })
12791
12792 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12793 ;; subsequent logical operations are used to imitate conditional moves.
12794 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12795 ;; it directly.
12796
12797 (define_insn "*sse_setccsf"
12798   [(set (match_operand:SF 0 "register_operand" "=x")
12799         (match_operator:SF 1 "sse_comparison_operator"
12800           [(match_operand:SF 2 "register_operand" "0")
12801            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12802   "TARGET_SSE"
12803   "cmp%D1ss\t{%3, %0|%0, %3}"
12804   [(set_attr "type" "ssecmp")
12805    (set_attr "mode" "SF")])
12806
12807 (define_insn "*sse_setccdf"
12808   [(set (match_operand:DF 0 "register_operand" "=Y")
12809         (match_operator:DF 1 "sse_comparison_operator"
12810           [(match_operand:DF 2 "register_operand" "0")
12811            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12812   "TARGET_SSE2"
12813   "cmp%D1sd\t{%3, %0|%0, %3}"
12814   [(set_attr "type" "ssecmp")
12815    (set_attr "mode" "DF")])
12816 \f
12817 ;; Basic conditional jump instructions.
12818 ;; We ignore the overflow flag for signed branch instructions.
12819
12820 ;; For all bCOND expanders, also expand the compare or test insn that
12821 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12822
12823 (define_expand "beq"
12824   [(set (pc)
12825         (if_then_else (match_dup 1)
12826                       (label_ref (match_operand 0 "" ""))
12827                       (pc)))]
12828   ""
12829   "ix86_expand_branch (EQ, operands[0]); DONE;")
12830
12831 (define_expand "bne"
12832   [(set (pc)
12833         (if_then_else (match_dup 1)
12834                       (label_ref (match_operand 0 "" ""))
12835                       (pc)))]
12836   ""
12837   "ix86_expand_branch (NE, operands[0]); DONE;")
12838
12839 (define_expand "bgt"
12840   [(set (pc)
12841         (if_then_else (match_dup 1)
12842                       (label_ref (match_operand 0 "" ""))
12843                       (pc)))]
12844   ""
12845   "ix86_expand_branch (GT, operands[0]); DONE;")
12846
12847 (define_expand "bgtu"
12848   [(set (pc)
12849         (if_then_else (match_dup 1)
12850                       (label_ref (match_operand 0 "" ""))
12851                       (pc)))]
12852   ""
12853   "ix86_expand_branch (GTU, operands[0]); DONE;")
12854
12855 (define_expand "blt"
12856   [(set (pc)
12857         (if_then_else (match_dup 1)
12858                       (label_ref (match_operand 0 "" ""))
12859                       (pc)))]
12860   ""
12861   "ix86_expand_branch (LT, operands[0]); DONE;")
12862
12863 (define_expand "bltu"
12864   [(set (pc)
12865         (if_then_else (match_dup 1)
12866                       (label_ref (match_operand 0 "" ""))
12867                       (pc)))]
12868   ""
12869   "ix86_expand_branch (LTU, operands[0]); DONE;")
12870
12871 (define_expand "bge"
12872   [(set (pc)
12873         (if_then_else (match_dup 1)
12874                       (label_ref (match_operand 0 "" ""))
12875                       (pc)))]
12876   ""
12877   "ix86_expand_branch (GE, operands[0]); DONE;")
12878
12879 (define_expand "bgeu"
12880   [(set (pc)
12881         (if_then_else (match_dup 1)
12882                       (label_ref (match_operand 0 "" ""))
12883                       (pc)))]
12884   ""
12885   "ix86_expand_branch (GEU, operands[0]); DONE;")
12886
12887 (define_expand "ble"
12888   [(set (pc)
12889         (if_then_else (match_dup 1)
12890                       (label_ref (match_operand 0 "" ""))
12891                       (pc)))]
12892   ""
12893   "ix86_expand_branch (LE, operands[0]); DONE;")
12894
12895 (define_expand "bleu"
12896   [(set (pc)
12897         (if_then_else (match_dup 1)
12898                       (label_ref (match_operand 0 "" ""))
12899                       (pc)))]
12900   ""
12901   "ix86_expand_branch (LEU, operands[0]); DONE;")
12902
12903 (define_expand "bunordered"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   "TARGET_80387 || TARGET_SSE_MATH"
12909   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12910
12911 (define_expand "bordered"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   "TARGET_80387 || TARGET_SSE_MATH"
12917   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12918
12919 (define_expand "buneq"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   "TARGET_80387 || TARGET_SSE_MATH"
12925   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12926
12927 (define_expand "bunge"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   "TARGET_80387 || TARGET_SSE_MATH"
12933   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12934
12935 (define_expand "bungt"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   "TARGET_80387 || TARGET_SSE_MATH"
12941   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12942
12943 (define_expand "bunle"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   "TARGET_80387 || TARGET_SSE_MATH"
12949   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12950
12951 (define_expand "bunlt"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   "TARGET_80387 || TARGET_SSE_MATH"
12957   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12958
12959 (define_expand "bltgt"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   "TARGET_80387 || TARGET_SSE_MATH"
12965   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12966
12967 (define_insn "*jcc_1"
12968   [(set (pc)
12969         (if_then_else (match_operator 1 "ix86_comparison_operator"
12970                                       [(reg FLAGS_REG) (const_int 0)])
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "%+j%C1\t%l0"
12975   [(set_attr "type" "ibr")
12976    (set_attr "modrm" "0")
12977    (set (attr "length")
12978            (if_then_else (and (ge (minus (match_dup 0) (pc))
12979                                   (const_int -126))
12980                               (lt (minus (match_dup 0) (pc))
12981                                   (const_int 128)))
12982              (const_int 2)
12983              (const_int 6)))])
12984
12985 (define_insn "*jcc_2"
12986   [(set (pc)
12987         (if_then_else (match_operator 1 "ix86_comparison_operator"
12988                                       [(reg FLAGS_REG) (const_int 0)])
12989                       (pc)
12990                       (label_ref (match_operand 0 "" ""))))]
12991   ""
12992   "%+j%c1\t%l0"
12993   [(set_attr "type" "ibr")
12994    (set_attr "modrm" "0")
12995    (set (attr "length")
12996            (if_then_else (and (ge (minus (match_dup 0) (pc))
12997                                   (const_int -126))
12998                               (lt (minus (match_dup 0) (pc))
12999                                   (const_int 128)))
13000              (const_int 2)
13001              (const_int 6)))])
13002
13003 ;; In general it is not safe to assume too much about CCmode registers,
13004 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13005 ;; conditions this is safe on x86, so help combine not create
13006 ;;
13007 ;;      seta    %al
13008 ;;      testb   %al, %al
13009 ;;      je      Lfoo
13010
13011 (define_split 
13012   [(set (pc)
13013         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13014                                       [(reg FLAGS_REG) (const_int 0)])
13015                           (const_int 0))
13016                       (label_ref (match_operand 1 "" ""))
13017                       (pc)))]
13018   ""
13019   [(set (pc)
13020         (if_then_else (match_dup 0)
13021                       (label_ref (match_dup 1))
13022                       (pc)))]
13023 {
13024   PUT_MODE (operands[0], VOIDmode);
13025 })
13026   
13027 (define_split 
13028   [(set (pc)
13029         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13030                                       [(reg FLAGS_REG) (const_int 0)])
13031                           (const_int 0))
13032                       (label_ref (match_operand 1 "" ""))
13033                       (pc)))]
13034   ""
13035   [(set (pc)
13036         (if_then_else (match_dup 0)
13037                       (label_ref (match_dup 1))
13038                       (pc)))]
13039 {
13040   rtx new_op0 = copy_rtx (operands[0]);
13041   operands[0] = new_op0;
13042   PUT_MODE (new_op0, VOIDmode);
13043   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13044                                              GET_MODE (XEXP (new_op0, 0))));
13045
13046   /* Make sure that (a) the CCmode we have for the flags is strong
13047      enough for the reversed compare or (b) we have a valid FP compare.  */
13048   if (! ix86_comparison_operator (new_op0, VOIDmode))
13049     FAIL;
13050 })
13051
13052 ;; Define combination compare-and-branch fp compare instructions to use
13053 ;; during early optimization.  Splitting the operation apart early makes
13054 ;; for bad code when we want to reverse the operation.
13055
13056 (define_insn "*fp_jcc_1_mixed"
13057   [(set (pc)
13058         (if_then_else (match_operator 0 "comparison_operator"
13059                         [(match_operand 1 "register_operand" "f#x,x#f")
13060                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13061           (label_ref (match_operand 3 "" ""))
13062           (pc)))
13063    (clobber (reg:CCFP FPSR_REG))
13064    (clobber (reg:CCFP FLAGS_REG))]
13065   "TARGET_MIX_SSE_I387
13066    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13067    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13068    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13069   "#")
13070
13071 (define_insn "*fp_jcc_1_sse"
13072   [(set (pc)
13073         (if_then_else (match_operator 0 "comparison_operator"
13074                         [(match_operand 1 "register_operand" "x")
13075                          (match_operand 2 "nonimmediate_operand" "xm")])
13076           (label_ref (match_operand 3 "" ""))
13077           (pc)))
13078    (clobber (reg:CCFP FPSR_REG))
13079    (clobber (reg:CCFP FLAGS_REG))]
13080   "TARGET_SSE_MATH
13081    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13082    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13083    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13084   "#")
13085
13086 (define_insn "*fp_jcc_1_387"
13087   [(set (pc)
13088         (if_then_else (match_operator 0 "comparison_operator"
13089                         [(match_operand 1 "register_operand" "f")
13090                          (match_operand 2 "register_operand" "f")])
13091           (label_ref (match_operand 3 "" ""))
13092           (pc)))
13093    (clobber (reg:CCFP FPSR_REG))
13094    (clobber (reg:CCFP FLAGS_REG))]
13095   "TARGET_CMOVE && TARGET_80387
13096    && FLOAT_MODE_P (GET_MODE (operands[1]))
13097    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13098    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13099   "#")
13100
13101 (define_insn "*fp_jcc_2_mixed"
13102   [(set (pc)
13103         (if_then_else (match_operator 0 "comparison_operator"
13104                         [(match_operand 1 "register_operand" "f#x,x#f")
13105                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13106           (pc)
13107           (label_ref (match_operand 3 "" ""))))
13108    (clobber (reg:CCFP FPSR_REG))
13109    (clobber (reg:CCFP FLAGS_REG))]
13110   "TARGET_MIX_SSE_I387
13111    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13112    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13113    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13114   "#")
13115
13116 (define_insn "*fp_jcc_2_sse"
13117   [(set (pc)
13118         (if_then_else (match_operator 0 "comparison_operator"
13119                         [(match_operand 1 "register_operand" "x")
13120                          (match_operand 2 "nonimmediate_operand" "xm")])
13121           (pc)
13122           (label_ref (match_operand 3 "" ""))))
13123    (clobber (reg:CCFP FPSR_REG))
13124    (clobber (reg:CCFP FLAGS_REG))]
13125   "TARGET_SSE_MATH
13126    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13127    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13128    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13129   "#")
13130
13131 (define_insn "*fp_jcc_2_387"
13132   [(set (pc)
13133         (if_then_else (match_operator 0 "comparison_operator"
13134                         [(match_operand 1 "register_operand" "f")
13135                          (match_operand 2 "register_operand" "f")])
13136           (pc)
13137           (label_ref (match_operand 3 "" ""))))
13138    (clobber (reg:CCFP FPSR_REG))
13139    (clobber (reg:CCFP FLAGS_REG))]
13140   "TARGET_CMOVE && TARGET_80387
13141    && FLOAT_MODE_P (GET_MODE (operands[1]))
13142    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13143    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13144   "#")
13145
13146 (define_insn "*fp_jcc_3_387"
13147   [(set (pc)
13148         (if_then_else (match_operator 0 "comparison_operator"
13149                         [(match_operand 1 "register_operand" "f")
13150                          (match_operand 2 "nonimmediate_operand" "fm")])
13151           (label_ref (match_operand 3 "" ""))
13152           (pc)))
13153    (clobber (reg:CCFP FPSR_REG))
13154    (clobber (reg:CCFP FLAGS_REG))
13155    (clobber (match_scratch:HI 4 "=a"))]
13156   "TARGET_80387
13157    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13158    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13159    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13160    && SELECT_CC_MODE (GET_CODE (operands[0]),
13161                       operands[1], operands[2]) == CCFPmode
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13164
13165 (define_insn "*fp_jcc_4_387"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "nonimmediate_operand" "fm")])
13170           (pc)
13171           (label_ref (match_operand 3 "" ""))))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))
13174    (clobber (match_scratch:HI 4 "=a"))]
13175   "TARGET_80387
13176    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13179    && SELECT_CC_MODE (GET_CODE (operands[0]),
13180                       operands[1], operands[2]) == CCFPmode
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13183
13184 (define_insn "*fp_jcc_5_387"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "f")
13188                          (match_operand 2 "register_operand" "f")])
13189           (label_ref (match_operand 3 "" ""))
13190           (pc)))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))
13193    (clobber (match_scratch:HI 4 "=a"))]
13194   "TARGET_80387
13195    && FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13199
13200 (define_insn "*fp_jcc_6_387"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "f")
13204                          (match_operand 2 "register_operand" "f")])
13205           (pc)
13206           (label_ref (match_operand 3 "" ""))))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))
13209    (clobber (match_scratch:HI 4 "=a"))]
13210   "TARGET_80387
13211    && FLOAT_MODE_P (GET_MODE (operands[1]))
13212    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214   "#")
13215
13216 (define_insn "*fp_jcc_7_387"
13217   [(set (pc)
13218         (if_then_else (match_operator 0 "comparison_operator"
13219                         [(match_operand 1 "register_operand" "f")
13220                          (match_operand 2 "const0_operand" "X")])
13221           (label_ref (match_operand 3 "" ""))
13222           (pc)))
13223    (clobber (reg:CCFP FPSR_REG))
13224    (clobber (reg:CCFP FLAGS_REG))
13225    (clobber (match_scratch:HI 4 "=a"))]
13226   "TARGET_80387
13227    && FLOAT_MODE_P (GET_MODE (operands[1]))
13228    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13229    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13230    && SELECT_CC_MODE (GET_CODE (operands[0]),
13231                       operands[1], operands[2]) == CCFPmode
13232    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13233   "#")
13234
13235 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13236 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13237 ;; with a precedence over other operators and is always put in the first
13238 ;; place. Swap condition and operands to match ficom instruction.
13239
13240 (define_insn "*fp_jcc_8<mode>_387"
13241   [(set (pc)
13242         (if_then_else (match_operator 0 "comparison_operator"
13243                         [(match_operator 1 "float_operator"
13244                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13245                            (match_operand 3 "register_operand" "f,f")])
13246           (label_ref (match_operand 4 "" ""))
13247           (pc)))
13248    (clobber (reg:CCFP FPSR_REG))
13249    (clobber (reg:CCFP FLAGS_REG))
13250    (clobber (match_scratch:HI 5 "=a,a"))]
13251   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13252    && FLOAT_MODE_P (GET_MODE (operands[3]))
13253    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13254    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13255    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13256    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13257   "#")
13258
13259 (define_split
13260   [(set (pc)
13261         (if_then_else (match_operator 0 "comparison_operator"
13262                         [(match_operand 1 "register_operand" "")
13263                          (match_operand 2 "nonimmediate_operand" "")])
13264           (match_operand 3 "" "")
13265           (match_operand 4 "" "")))
13266    (clobber (reg:CCFP FPSR_REG))
13267    (clobber (reg:CCFP FLAGS_REG))]
13268   "reload_completed"
13269   [(const_int 0)]
13270 {
13271   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13272                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13273   DONE;
13274 })
13275
13276 (define_split
13277   [(set (pc)
13278         (if_then_else (match_operator 0 "comparison_operator"
13279                         [(match_operand 1 "register_operand" "")
13280                          (match_operand 2 "general_operand" "")])
13281           (match_operand 3 "" "")
13282           (match_operand 4 "" "")))
13283    (clobber (reg:CCFP FPSR_REG))
13284    (clobber (reg:CCFP FLAGS_REG))
13285    (clobber (match_scratch:HI 5 "=a"))]
13286   "reload_completed"
13287   [(const_int 0)]
13288 {
13289   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13290                         operands[3], operands[4], operands[5], NULL_RTX);
13291   DONE;
13292 })
13293
13294 (define_split
13295   [(set (pc)
13296         (if_then_else (match_operator 0 "comparison_operator"
13297                         [(match_operator 1 "float_operator"
13298                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13299                            (match_operand 3 "register_operand" "")])
13300           (match_operand 4 "" "")
13301           (match_operand 5 "" "")))
13302    (clobber (reg:CCFP FPSR_REG))
13303    (clobber (reg:CCFP FLAGS_REG))
13304    (clobber (match_scratch:HI 6 "=a"))]
13305   "reload_completed"
13306   [(const_int 0)]
13307 {
13308   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13309   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13310                         operands[3], operands[7],
13311                         operands[4], operands[5], operands[6], NULL_RTX);
13312   DONE;
13313 })
13314
13315 ;; %%% Kill this when reload knows how to do it.
13316 (define_split
13317   [(set (pc)
13318         (if_then_else (match_operator 0 "comparison_operator"
13319                         [(match_operator 1 "float_operator"
13320                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13321                            (match_operand 3 "register_operand" "")])
13322           (match_operand 4 "" "")
13323           (match_operand 5 "" "")))
13324    (clobber (reg:CCFP FPSR_REG))
13325    (clobber (reg:CCFP FLAGS_REG))
13326    (clobber (match_scratch:HI 6 "=a"))]
13327   "reload_completed"
13328   [(const_int 0)]
13329 {
13330   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13331   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13332   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13333                         operands[3], operands[7],
13334                         operands[4], operands[5], operands[6], operands[2]);
13335   DONE;
13336 })
13337 \f
13338 ;; Unconditional and other jump instructions
13339
13340 (define_insn "jump"
13341   [(set (pc)
13342         (label_ref (match_operand 0 "" "")))]
13343   ""
13344   "jmp\t%l0"
13345   [(set_attr "type" "ibr")
13346    (set (attr "length")
13347            (if_then_else (and (ge (minus (match_dup 0) (pc))
13348                                   (const_int -126))
13349                               (lt (minus (match_dup 0) (pc))
13350                                   (const_int 128)))
13351              (const_int 2)
13352              (const_int 5)))
13353    (set_attr "modrm" "0")])
13354
13355 (define_expand "indirect_jump"
13356   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13357   ""
13358   "")
13359
13360 (define_insn "*indirect_jump"
13361   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13362   "!TARGET_64BIT"
13363   "jmp\t%A0"
13364   [(set_attr "type" "ibr")
13365    (set_attr "length_immediate" "0")])
13366
13367 (define_insn "*indirect_jump_rtx64"
13368   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13369   "TARGET_64BIT"
13370   "jmp\t%A0"
13371   [(set_attr "type" "ibr")
13372    (set_attr "length_immediate" "0")])
13373
13374 (define_expand "tablejump"
13375   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13376               (use (label_ref (match_operand 1 "" "")))])]
13377   ""
13378 {
13379   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13380      relative.  Convert the relative address to an absolute address.  */
13381   if (flag_pic)
13382     {
13383       rtx op0, op1;
13384       enum rtx_code code;
13385
13386       if (TARGET_64BIT)
13387         {
13388           code = PLUS;
13389           op0 = operands[0];
13390           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13391         }
13392       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13393         {
13394           code = PLUS;
13395           op0 = operands[0];
13396           op1 = pic_offset_table_rtx;
13397         }
13398       else
13399         {
13400           code = MINUS;
13401           op0 = pic_offset_table_rtx;
13402           op1 = operands[0];
13403         }
13404
13405       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13406                                          OPTAB_DIRECT);
13407     }
13408 })
13409
13410 (define_insn "*tablejump_1"
13411   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13412    (use (label_ref (match_operand 1 "" "")))]
13413   "!TARGET_64BIT"
13414   "jmp\t%A0"
13415   [(set_attr "type" "ibr")
13416    (set_attr "length_immediate" "0")])
13417
13418 (define_insn "*tablejump_1_rtx64"
13419   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13420    (use (label_ref (match_operand 1 "" "")))]
13421   "TARGET_64BIT"
13422   "jmp\t%A0"
13423   [(set_attr "type" "ibr")
13424    (set_attr "length_immediate" "0")])
13425 \f
13426 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13427
13428 (define_peephole2
13429   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13430    (set (match_operand:QI 1 "register_operand" "")
13431         (match_operator:QI 2 "ix86_comparison_operator"
13432           [(reg FLAGS_REG) (const_int 0)]))
13433    (set (match_operand 3 "q_regs_operand" "")
13434         (zero_extend (match_dup 1)))]
13435   "(peep2_reg_dead_p (3, operands[1])
13436     || operands_match_p (operands[1], operands[3]))
13437    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13438   [(set (match_dup 4) (match_dup 0))
13439    (set (strict_low_part (match_dup 5))
13440         (match_dup 2))]
13441 {
13442   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13443   operands[5] = gen_lowpart (QImode, operands[3]);
13444   ix86_expand_clear (operands[3]);
13445 })
13446
13447 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13448
13449 (define_peephole2
13450   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13451    (set (match_operand:QI 1 "register_operand" "")
13452         (match_operator:QI 2 "ix86_comparison_operator"
13453           [(reg FLAGS_REG) (const_int 0)]))
13454    (parallel [(set (match_operand 3 "q_regs_operand" "")
13455                    (zero_extend (match_dup 1)))
13456               (clobber (reg:CC FLAGS_REG))])]
13457   "(peep2_reg_dead_p (3, operands[1])
13458     || operands_match_p (operands[1], operands[3]))
13459    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13460   [(set (match_dup 4) (match_dup 0))
13461    (set (strict_low_part (match_dup 5))
13462         (match_dup 2))]
13463 {
13464   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13465   operands[5] = gen_lowpart (QImode, operands[3]);
13466   ix86_expand_clear (operands[3]);
13467 })
13468 \f
13469 ;; Call instructions.
13470
13471 ;; The predicates normally associated with named expanders are not properly
13472 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13473 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13474
13475 ;; Call subroutine returning no value.
13476
13477 (define_expand "call_pop"
13478   [(parallel [(call (match_operand:QI 0 "" "")
13479                     (match_operand:SI 1 "" ""))
13480               (set (reg:SI SP_REG)
13481                    (plus:SI (reg:SI SP_REG)
13482                             (match_operand:SI 3 "" "")))])]
13483   "!TARGET_64BIT"
13484 {
13485   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13486   DONE;
13487 })
13488
13489 (define_insn "*call_pop_0"
13490   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13491          (match_operand:SI 1 "" ""))
13492    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13493                             (match_operand:SI 2 "immediate_operand" "")))]
13494   "!TARGET_64BIT"
13495 {
13496   if (SIBLING_CALL_P (insn))
13497     return "jmp\t%P0";
13498   else
13499     return "call\t%P0";
13500 }
13501   [(set_attr "type" "call")])
13502   
13503 (define_insn "*call_pop_1"
13504   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13505          (match_operand:SI 1 "" ""))
13506    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13507                             (match_operand:SI 2 "immediate_operand" "i")))]
13508   "!TARGET_64BIT"
13509 {
13510   if (constant_call_address_operand (operands[0], Pmode))
13511     {
13512       if (SIBLING_CALL_P (insn))
13513         return "jmp\t%P0";
13514       else
13515         return "call\t%P0";
13516     }
13517   if (SIBLING_CALL_P (insn))
13518     return "jmp\t%A0";
13519   else
13520     return "call\t%A0";
13521 }
13522   [(set_attr "type" "call")])
13523
13524 (define_expand "call"
13525   [(call (match_operand:QI 0 "" "")
13526          (match_operand 1 "" ""))
13527    (use (match_operand 2 "" ""))]
13528   ""
13529 {
13530   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13531   DONE;
13532 })
13533
13534 (define_expand "sibcall"
13535   [(call (match_operand:QI 0 "" "")
13536          (match_operand 1 "" ""))
13537    (use (match_operand 2 "" ""))]
13538   ""
13539 {
13540   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13541   DONE;
13542 })
13543
13544 (define_insn "*call_0"
13545   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13546          (match_operand 1 "" ""))]
13547   ""
13548 {
13549   if (SIBLING_CALL_P (insn))
13550     return "jmp\t%P0";
13551   else
13552     return "call\t%P0";
13553 }
13554   [(set_attr "type" "call")])
13555
13556 (define_insn "*call_1"
13557   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13558          (match_operand 1 "" ""))]
13559   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13560 {
13561   if (constant_call_address_operand (operands[0], Pmode))
13562     return "call\t%P0";
13563   return "call\t%A0";
13564 }
13565   [(set_attr "type" "call")])
13566
13567 (define_insn "*sibcall_1"
13568   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13569          (match_operand 1 "" ""))]
13570   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13571 {
13572   if (constant_call_address_operand (operands[0], Pmode))
13573     return "jmp\t%P0";
13574   return "jmp\t%A0";
13575 }
13576   [(set_attr "type" "call")])
13577
13578 (define_insn "*call_1_rex64"
13579   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13580          (match_operand 1 "" ""))]
13581   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13582 {
13583   if (constant_call_address_operand (operands[0], Pmode))
13584     return "call\t%P0";
13585   return "call\t%A0";
13586 }
13587   [(set_attr "type" "call")])
13588
13589 (define_insn "*sibcall_1_rex64"
13590   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13591          (match_operand 1 "" ""))]
13592   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13593   "jmp\t%P0"
13594   [(set_attr "type" "call")])
13595
13596 (define_insn "*sibcall_1_rex64_v"
13597   [(call (mem:QI (reg:DI 40))
13598          (match_operand 0 "" ""))]
13599   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13600   "jmp\t*%%r11"
13601   [(set_attr "type" "call")])
13602
13603
13604 ;; Call subroutine, returning value in operand 0
13605
13606 (define_expand "call_value_pop"
13607   [(parallel [(set (match_operand 0 "" "")
13608                    (call (match_operand:QI 1 "" "")
13609                          (match_operand:SI 2 "" "")))
13610               (set (reg:SI SP_REG)
13611                    (plus:SI (reg:SI SP_REG)
13612                             (match_operand:SI 4 "" "")))])]
13613   "!TARGET_64BIT"
13614 {
13615   ix86_expand_call (operands[0], operands[1], operands[2],
13616                     operands[3], operands[4], 0);
13617   DONE;
13618 })
13619
13620 (define_expand "call_value"
13621   [(set (match_operand 0 "" "")
13622         (call (match_operand:QI 1 "" "")
13623               (match_operand:SI 2 "" "")))
13624    (use (match_operand:SI 3 "" ""))]
13625   ;; Operand 2 not used on the i386.
13626   ""
13627 {
13628   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13629   DONE;
13630 })
13631
13632 (define_expand "sibcall_value"
13633   [(set (match_operand 0 "" "")
13634         (call (match_operand:QI 1 "" "")
13635               (match_operand:SI 2 "" "")))
13636    (use (match_operand:SI 3 "" ""))]
13637   ;; Operand 2 not used on the i386.
13638   ""
13639 {
13640   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13641   DONE;
13642 })
13643
13644 ;; Call subroutine returning any type.
13645
13646 (define_expand "untyped_call"
13647   [(parallel [(call (match_operand 0 "" "")
13648                     (const_int 0))
13649               (match_operand 1 "" "")
13650               (match_operand 2 "" "")])]
13651   ""
13652 {
13653   int i;
13654
13655   /* In order to give reg-stack an easier job in validating two
13656      coprocessor registers as containing a possible return value,
13657      simply pretend the untyped call returns a complex long double
13658      value.  */
13659
13660   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13661                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13662                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13663                     NULL, 0);
13664
13665   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13666     {
13667       rtx set = XVECEXP (operands[2], 0, i);
13668       emit_move_insn (SET_DEST (set), SET_SRC (set));
13669     }
13670
13671   /* The optimizer does not know that the call sets the function value
13672      registers we stored in the result block.  We avoid problems by
13673      claiming that all hard registers are used and clobbered at this
13674      point.  */
13675   emit_insn (gen_blockage (const0_rtx));
13676
13677   DONE;
13678 })
13679 \f
13680 ;; Prologue and epilogue instructions
13681
13682 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13683 ;; all of memory.  This blocks insns from being moved across this point.
13684
13685 (define_insn "blockage"
13686   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13687   ""
13688   ""
13689   [(set_attr "length" "0")])
13690
13691 ;; Insn emitted into the body of a function to return from a function.
13692 ;; This is only done if the function's epilogue is known to be simple.
13693 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13694
13695 (define_expand "return"
13696   [(return)]
13697   "ix86_can_use_return_insn_p ()"
13698 {
13699   if (current_function_pops_args)
13700     {
13701       rtx popc = GEN_INT (current_function_pops_args);
13702       emit_jump_insn (gen_return_pop_internal (popc));
13703       DONE;
13704     }
13705 })
13706
13707 (define_insn "return_internal"
13708   [(return)]
13709   "reload_completed"
13710   "ret"
13711   [(set_attr "length" "1")
13712    (set_attr "length_immediate" "0")
13713    (set_attr "modrm" "0")])
13714
13715 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13716 ;; instruction Athlon and K8 have.
13717
13718 (define_insn "return_internal_long"
13719   [(return)
13720    (unspec [(const_int 0)] UNSPEC_REP)]
13721   "reload_completed"
13722   "rep {;} ret"
13723   [(set_attr "length" "1")
13724    (set_attr "length_immediate" "0")
13725    (set_attr "prefix_rep" "1")
13726    (set_attr "modrm" "0")])
13727
13728 (define_insn "return_pop_internal"
13729   [(return)
13730    (use (match_operand:SI 0 "const_int_operand" ""))]
13731   "reload_completed"
13732   "ret\t%0"
13733   [(set_attr "length" "3")
13734    (set_attr "length_immediate" "2")
13735    (set_attr "modrm" "0")])
13736
13737 (define_insn "return_indirect_internal"
13738   [(return)
13739    (use (match_operand:SI 0 "register_operand" "r"))]
13740   "reload_completed"
13741   "jmp\t%A0"
13742   [(set_attr "type" "ibr")
13743    (set_attr "length_immediate" "0")])
13744
13745 (define_insn "nop"
13746   [(const_int 0)]
13747   ""
13748   "nop"
13749   [(set_attr "length" "1")
13750    (set_attr "length_immediate" "0")
13751    (set_attr "modrm" "0")])
13752
13753 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13754 ;; branch prediction penalty for the third jump in a 16-byte
13755 ;; block on K8.
13756
13757 (define_insn "align"
13758   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13759   ""
13760 {
13761 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13762   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13763 #else
13764   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13765      The align insn is used to avoid 3 jump instructions in the row to improve
13766      branch prediction and the benefits hardly outweight the cost of extra 8
13767      nops on the average inserted by full alignment pseudo operation.  */
13768 #endif
13769   return "";
13770 }
13771   [(set_attr "length" "16")])
13772
13773 (define_expand "prologue"
13774   [(const_int 1)]
13775   ""
13776   "ix86_expand_prologue (); DONE;")
13777
13778 (define_insn "set_got"
13779   [(set (match_operand:SI 0 "register_operand" "=r")
13780         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13781    (clobber (reg:CC FLAGS_REG))]
13782   "!TARGET_64BIT"
13783   { return output_set_got (operands[0]); }
13784   [(set_attr "type" "multi")
13785    (set_attr "length" "12")])
13786
13787 (define_insn "set_got_rex64"
13788   [(set (match_operand:DI 0 "register_operand" "=r")
13789         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13790   "TARGET_64BIT"
13791   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13792   [(set_attr "type" "lea")
13793    (set_attr "length" "6")])
13794
13795 (define_expand "epilogue"
13796   [(const_int 1)]
13797   ""
13798   "ix86_expand_epilogue (1); DONE;")
13799
13800 (define_expand "sibcall_epilogue"
13801   [(const_int 1)]
13802   ""
13803   "ix86_expand_epilogue (0); DONE;")
13804
13805 (define_expand "eh_return"
13806   [(use (match_operand 0 "register_operand" ""))]
13807   ""
13808 {
13809   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13810
13811   /* Tricky bit: we write the address of the handler to which we will
13812      be returning into someone else's stack frame, one word below the
13813      stack address we wish to restore.  */
13814   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13815   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13816   tmp = gen_rtx_MEM (Pmode, tmp);
13817   emit_move_insn (tmp, ra);
13818
13819   if (Pmode == SImode)
13820     emit_jump_insn (gen_eh_return_si (sa));
13821   else
13822     emit_jump_insn (gen_eh_return_di (sa));
13823   emit_barrier ();
13824   DONE;
13825 })
13826
13827 (define_insn_and_split "eh_return_si"
13828   [(set (pc) 
13829         (unspec [(match_operand:SI 0 "register_operand" "c")]
13830                  UNSPEC_EH_RETURN))]
13831   "!TARGET_64BIT"
13832   "#"
13833   "reload_completed"
13834   [(const_int 1)]
13835   "ix86_expand_epilogue (2); DONE;")
13836
13837 (define_insn_and_split "eh_return_di"
13838   [(set (pc) 
13839         (unspec [(match_operand:DI 0 "register_operand" "c")]
13840                  UNSPEC_EH_RETURN))]
13841   "TARGET_64BIT"
13842   "#"
13843   "reload_completed"
13844   [(const_int 1)]
13845   "ix86_expand_epilogue (2); DONE;")
13846
13847 (define_insn "leave"
13848   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13849    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13850    (clobber (mem:BLK (scratch)))]
13851   "!TARGET_64BIT"
13852   "leave"
13853   [(set_attr "type" "leave")])
13854
13855 (define_insn "leave_rex64"
13856   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13857    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13858    (clobber (mem:BLK (scratch)))]
13859   "TARGET_64BIT"
13860   "leave"
13861   [(set_attr "type" "leave")])
13862 \f
13863 (define_expand "ffssi2"
13864   [(parallel
13865      [(set (match_operand:SI 0 "register_operand" "") 
13866            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13867       (clobber (match_scratch:SI 2 ""))
13868       (clobber (reg:CC FLAGS_REG))])]
13869   ""
13870   "")
13871
13872 (define_insn_and_split "*ffs_cmove"
13873   [(set (match_operand:SI 0 "register_operand" "=r") 
13874         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13875    (clobber (match_scratch:SI 2 "=&r"))
13876    (clobber (reg:CC FLAGS_REG))]
13877   "TARGET_CMOVE"
13878   "#"
13879   "&& reload_completed"
13880   [(set (match_dup 2) (const_int -1))
13881    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13882               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13883    (set (match_dup 0) (if_then_else:SI
13884                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13885                         (match_dup 2)
13886                         (match_dup 0)))
13887    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13888               (clobber (reg:CC FLAGS_REG))])]
13889   "")
13890
13891 (define_insn_and_split "*ffs_no_cmove"
13892   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13893         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13894    (clobber (match_scratch:SI 2 "=&q"))
13895    (clobber (reg:CC FLAGS_REG))]
13896   ""
13897   "#"
13898   "reload_completed"
13899   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13900               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13901    (set (strict_low_part (match_dup 3))
13902         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13903    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13904               (clobber (reg:CC FLAGS_REG))])
13905    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13906               (clobber (reg:CC FLAGS_REG))])
13907    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13908               (clobber (reg:CC FLAGS_REG))])]
13909 {
13910   operands[3] = gen_lowpart (QImode, operands[2]);
13911   ix86_expand_clear (operands[2]);
13912 })
13913
13914 (define_insn "*ffssi_1"
13915   [(set (reg:CCZ FLAGS_REG)
13916         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13917                      (const_int 0)))
13918    (set (match_operand:SI 0 "register_operand" "=r")
13919         (ctz:SI (match_dup 1)))]
13920   ""
13921   "bsf{l}\t{%1, %0|%0, %1}"
13922   [(set_attr "prefix_0f" "1")])
13923
13924 (define_expand "ffsdi2"
13925   [(parallel
13926      [(set (match_operand:DI 0 "register_operand" "") 
13927            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13928       (clobber (match_scratch:DI 2 ""))
13929       (clobber (reg:CC FLAGS_REG))])]
13930   "TARGET_64BIT && TARGET_CMOVE"
13931   "")
13932
13933 (define_insn_and_split "*ffs_rex64"
13934   [(set (match_operand:DI 0 "register_operand" "=r") 
13935         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13936    (clobber (match_scratch:DI 2 "=&r"))
13937    (clobber (reg:CC FLAGS_REG))]
13938   "TARGET_64BIT && TARGET_CMOVE"
13939   "#"
13940   "&& reload_completed"
13941   [(set (match_dup 2) (const_int -1))
13942    (parallel [(set (reg:CCZ FLAGS_REG)
13943                    (compare:CCZ (match_dup 1) (const_int 0)))
13944               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13945    (set (match_dup 0) (if_then_else:DI
13946                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13947                         (match_dup 2)
13948                         (match_dup 0)))
13949    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13950               (clobber (reg:CC FLAGS_REG))])]
13951   "")
13952
13953 (define_insn "*ffsdi_1"
13954   [(set (reg:CCZ FLAGS_REG)
13955         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13956                      (const_int 0)))
13957    (set (match_operand:DI 0 "register_operand" "=r")
13958         (ctz:DI (match_dup 1)))]
13959   "TARGET_64BIT"
13960   "bsf{q}\t{%1, %0|%0, %1}"
13961   [(set_attr "prefix_0f" "1")])
13962
13963 (define_insn "ctzsi2"
13964   [(set (match_operand:SI 0 "register_operand" "=r")
13965         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13966    (clobber (reg:CC FLAGS_REG))]
13967   ""
13968   "bsf{l}\t{%1, %0|%0, %1}"
13969   [(set_attr "prefix_0f" "1")])
13970
13971 (define_insn "ctzdi2"
13972   [(set (match_operand:DI 0 "register_operand" "=r")
13973         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13974    (clobber (reg:CC FLAGS_REG))]
13975   "TARGET_64BIT"
13976   "bsf{q}\t{%1, %0|%0, %1}"
13977   [(set_attr "prefix_0f" "1")])
13978
13979 (define_expand "clzsi2"
13980   [(parallel
13981      [(set (match_operand:SI 0 "register_operand" "")
13982            (minus:SI (const_int 31)
13983                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13984       (clobber (reg:CC FLAGS_REG))])
13985    (parallel
13986      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13987       (clobber (reg:CC FLAGS_REG))])]
13988   ""
13989   "")
13990
13991 (define_insn "*bsr"
13992   [(set (match_operand:SI 0 "register_operand" "=r")
13993         (minus:SI (const_int 31)
13994                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13995    (clobber (reg:CC FLAGS_REG))]
13996   ""
13997   "bsr{l}\t{%1, %0|%0, %1}"
13998   [(set_attr "prefix_0f" "1")])
13999
14000 (define_expand "clzdi2"
14001   [(parallel
14002      [(set (match_operand:DI 0 "register_operand" "")
14003            (minus:DI (const_int 63)
14004                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14005       (clobber (reg:CC FLAGS_REG))])
14006    (parallel
14007      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14008       (clobber (reg:CC FLAGS_REG))])]
14009   "TARGET_64BIT"
14010   "")
14011
14012 (define_insn "*bsr_rex64"
14013   [(set (match_operand:DI 0 "register_operand" "=r")
14014         (minus:DI (const_int 63)
14015                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14016    (clobber (reg:CC FLAGS_REG))]
14017   "TARGET_64BIT"
14018   "bsr{q}\t{%1, %0|%0, %1}"
14019   [(set_attr "prefix_0f" "1")])
14020 \f
14021 ;; Thread-local storage patterns for ELF.
14022 ;;
14023 ;; Note that these code sequences must appear exactly as shown
14024 ;; in order to allow linker relaxation.
14025
14026 (define_insn "*tls_global_dynamic_32_gnu"
14027   [(set (match_operand:SI 0 "register_operand" "=a")
14028         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14029                     (match_operand:SI 2 "tls_symbolic_operand" "")
14030                     (match_operand:SI 3 "call_insn_operand" "")]
14031                     UNSPEC_TLS_GD))
14032    (clobber (match_scratch:SI 4 "=d"))
14033    (clobber (match_scratch:SI 5 "=c"))
14034    (clobber (reg:CC FLAGS_REG))]
14035   "!TARGET_64BIT && TARGET_GNU_TLS"
14036   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14037   [(set_attr "type" "multi")
14038    (set_attr "length" "12")])
14039
14040 (define_insn "*tls_global_dynamic_32_sun"
14041   [(set (match_operand:SI 0 "register_operand" "=a")
14042         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14043                     (match_operand:SI 2 "tls_symbolic_operand" "")
14044                     (match_operand:SI 3 "call_insn_operand" "")]
14045                     UNSPEC_TLS_GD))
14046    (clobber (match_scratch:SI 4 "=d"))
14047    (clobber (match_scratch:SI 5 "=c"))
14048    (clobber (reg:CC FLAGS_REG))]
14049   "!TARGET_64BIT && TARGET_SUN_TLS"
14050   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14051         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14052   [(set_attr "type" "multi")
14053    (set_attr "length" "14")])
14054
14055 (define_expand "tls_global_dynamic_32"
14056   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14057                    (unspec:SI
14058                     [(match_dup 2)
14059                      (match_operand:SI 1 "tls_symbolic_operand" "")
14060                      (match_dup 3)]
14061                     UNSPEC_TLS_GD))
14062               (clobber (match_scratch:SI 4 ""))
14063               (clobber (match_scratch:SI 5 ""))
14064               (clobber (reg:CC FLAGS_REG))])]
14065   ""
14066 {
14067   if (flag_pic)
14068     operands[2] = pic_offset_table_rtx;
14069   else
14070     {
14071       operands[2] = gen_reg_rtx (Pmode);
14072       emit_insn (gen_set_got (operands[2]));
14073     }
14074   operands[3] = ix86_tls_get_addr ();
14075 })
14076
14077 (define_insn "*tls_global_dynamic_64"
14078   [(set (match_operand:DI 0 "register_operand" "=a")
14079         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14080                       (match_operand:DI 3 "" "")))
14081    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14082               UNSPEC_TLS_GD)]
14083   "TARGET_64BIT"
14084   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14085   [(set_attr "type" "multi")
14086    (set_attr "length" "16")])
14087
14088 (define_expand "tls_global_dynamic_64"
14089   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14090                    (call (mem:QI (match_dup 2)) (const_int 0)))
14091               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14092                          UNSPEC_TLS_GD)])]
14093   ""
14094 {
14095   operands[2] = ix86_tls_get_addr ();
14096 })
14097
14098 (define_insn "*tls_local_dynamic_base_32_gnu"
14099   [(set (match_operand:SI 0 "register_operand" "=a")
14100         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14101                     (match_operand:SI 2 "call_insn_operand" "")]
14102                    UNSPEC_TLS_LD_BASE))
14103    (clobber (match_scratch:SI 3 "=d"))
14104    (clobber (match_scratch:SI 4 "=c"))
14105    (clobber (reg:CC FLAGS_REG))]
14106   "!TARGET_64BIT && TARGET_GNU_TLS"
14107   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14108   [(set_attr "type" "multi")
14109    (set_attr "length" "11")])
14110
14111 (define_insn "*tls_local_dynamic_base_32_sun"
14112   [(set (match_operand:SI 0 "register_operand" "=a")
14113         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14114                     (match_operand:SI 2 "call_insn_operand" "")]
14115                    UNSPEC_TLS_LD_BASE))
14116    (clobber (match_scratch:SI 3 "=d"))
14117    (clobber (match_scratch:SI 4 "=c"))
14118    (clobber (reg:CC FLAGS_REG))]
14119   "!TARGET_64BIT && TARGET_SUN_TLS"
14120   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14121         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14122   [(set_attr "type" "multi")
14123    (set_attr "length" "13")])
14124
14125 (define_expand "tls_local_dynamic_base_32"
14126   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14127                    (unspec:SI [(match_dup 1) (match_dup 2)]
14128                               UNSPEC_TLS_LD_BASE))
14129               (clobber (match_scratch:SI 3 ""))
14130               (clobber (match_scratch:SI 4 ""))
14131               (clobber (reg:CC FLAGS_REG))])]
14132   ""
14133 {
14134   if (flag_pic)
14135     operands[1] = pic_offset_table_rtx;
14136   else
14137     {
14138       operands[1] = gen_reg_rtx (Pmode);
14139       emit_insn (gen_set_got (operands[1]));
14140     }
14141   operands[2] = ix86_tls_get_addr ();
14142 })
14143
14144 (define_insn "*tls_local_dynamic_base_64"
14145   [(set (match_operand:DI 0 "register_operand" "=a")
14146         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14147                       (match_operand:DI 2 "" "")))
14148    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14149   "TARGET_64BIT"
14150   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14151   [(set_attr "type" "multi")
14152    (set_attr "length" "12")])
14153
14154 (define_expand "tls_local_dynamic_base_64"
14155   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14156                    (call (mem:QI (match_dup 1)) (const_int 0)))
14157               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14158   ""
14159 {
14160   operands[1] = ix86_tls_get_addr ();
14161 })
14162
14163 ;; Local dynamic of a single variable is a lose.  Show combine how
14164 ;; to convert that back to global dynamic.
14165
14166 (define_insn_and_split "*tls_local_dynamic_32_once"
14167   [(set (match_operand:SI 0 "register_operand" "=a")
14168         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14169                              (match_operand:SI 2 "call_insn_operand" "")]
14170                             UNSPEC_TLS_LD_BASE)
14171                  (const:SI (unspec:SI
14172                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14173                             UNSPEC_DTPOFF))))
14174    (clobber (match_scratch:SI 4 "=d"))
14175    (clobber (match_scratch:SI 5 "=c"))
14176    (clobber (reg:CC FLAGS_REG))]
14177   ""
14178   "#"
14179   ""
14180   [(parallel [(set (match_dup 0)
14181                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14182                               UNSPEC_TLS_GD))
14183               (clobber (match_dup 4))
14184               (clobber (match_dup 5))
14185               (clobber (reg:CC FLAGS_REG))])]
14186   "")
14187
14188 ;; Load and add the thread base pointer from %gs:0.
14189
14190 (define_insn "*load_tp_si"
14191   [(set (match_operand:SI 0 "register_operand" "=r")
14192         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14193   "!TARGET_64BIT"
14194   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14195   [(set_attr "type" "imov")
14196    (set_attr "modrm" "0")
14197    (set_attr "length" "7")
14198    (set_attr "memory" "load")
14199    (set_attr "imm_disp" "false")])
14200
14201 (define_insn "*add_tp_si"
14202   [(set (match_operand:SI 0 "register_operand" "=r")
14203         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14204                  (match_operand:SI 1 "register_operand" "0")))
14205    (clobber (reg:CC FLAGS_REG))]
14206   "!TARGET_64BIT"
14207   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14208   [(set_attr "type" "alu")
14209    (set_attr "modrm" "0")
14210    (set_attr "length" "7")
14211    (set_attr "memory" "load")
14212    (set_attr "imm_disp" "false")])
14213
14214 (define_insn "*load_tp_di"
14215   [(set (match_operand:DI 0 "register_operand" "=r")
14216         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14217   "TARGET_64BIT"
14218   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14219   [(set_attr "type" "imov")
14220    (set_attr "modrm" "0")
14221    (set_attr "length" "7")
14222    (set_attr "memory" "load")
14223    (set_attr "imm_disp" "false")])
14224
14225 (define_insn "*add_tp_di"
14226   [(set (match_operand:DI 0 "register_operand" "=r")
14227         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14228                  (match_operand:DI 1 "register_operand" "0")))
14229    (clobber (reg:CC FLAGS_REG))]
14230   "TARGET_64BIT"
14231   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14232   [(set_attr "type" "alu")
14233    (set_attr "modrm" "0")
14234    (set_attr "length" "7")
14235    (set_attr "memory" "load")
14236    (set_attr "imm_disp" "false")])
14237 \f
14238 ;; These patterns match the binary 387 instructions for addM3, subM3,
14239 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14240 ;; SFmode.  The first is the normal insn, the second the same insn but
14241 ;; with one operand a conversion, and the third the same insn but with
14242 ;; the other operand a conversion.  The conversion may be SFmode or
14243 ;; SImode if the target mode DFmode, but only SImode if the target mode
14244 ;; is SFmode.
14245
14246 ;; Gcc is slightly more smart about handling normal two address instructions
14247 ;; so use special patterns for add and mull.
14248
14249 (define_insn "*fop_sf_comm_mixed"
14250   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14251         (match_operator:SF 3 "binary_fp_operator"
14252                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14253                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14254   "TARGET_MIX_SSE_I387
14255    && COMMUTATIVE_ARITH_P (operands[3])
14256    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14257   "* return output_387_binary_op (insn, operands);"
14258   [(set (attr "type") 
14259         (if_then_else (eq_attr "alternative" "1")
14260            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14261               (const_string "ssemul")
14262               (const_string "sseadd"))
14263            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14264               (const_string "fmul")
14265               (const_string "fop"))))
14266    (set_attr "mode" "SF")])
14267
14268 (define_insn "*fop_sf_comm_sse"
14269   [(set (match_operand:SF 0 "register_operand" "=x")
14270         (match_operator:SF 3 "binary_fp_operator"
14271                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14272                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14273   "TARGET_SSE_MATH
14274    && COMMUTATIVE_ARITH_P (operands[3])
14275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276   "* return output_387_binary_op (insn, operands);"
14277   [(set (attr "type") 
14278         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14279            (const_string "ssemul")
14280            (const_string "sseadd")))
14281    (set_attr "mode" "SF")])
14282
14283 (define_insn "*fop_sf_comm_i387"
14284   [(set (match_operand:SF 0 "register_operand" "=f")
14285         (match_operator:SF 3 "binary_fp_operator"
14286                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14287                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14288   "TARGET_80387
14289    && COMMUTATIVE_ARITH_P (operands[3])
14290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14291   "* return output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14294            (const_string "fmul")
14295            (const_string "fop")))
14296    (set_attr "mode" "SF")])
14297
14298 (define_insn "*fop_sf_1_mixed"
14299   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14300         (match_operator:SF 3 "binary_fp_operator"
14301                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14302                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14303   "TARGET_MIX_SSE_I387
14304    && !COMMUTATIVE_ARITH_P (operands[3])
14305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14306   "* return output_387_binary_op (insn, operands);"
14307   [(set (attr "type") 
14308         (cond [(and (eq_attr "alternative" "2")
14309                     (match_operand:SF 3 "mult_operator" ""))
14310                  (const_string "ssemul")
14311                (and (eq_attr "alternative" "2")
14312                     (match_operand:SF 3 "div_operator" ""))
14313                  (const_string "ssediv")
14314                (eq_attr "alternative" "2")
14315                  (const_string "sseadd")
14316                (match_operand:SF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:SF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "mode" "SF")])
14323
14324 (define_insn "*fop_sf_1_sse"
14325   [(set (match_operand:SF 0 "register_operand" "=x")
14326         (match_operator:SF 3 "binary_fp_operator"
14327                         [(match_operand:SF 1 "register_operand" "0")
14328                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14329   "TARGET_SSE_MATH
14330    && !COMMUTATIVE_ARITH_P (operands[3])"
14331   "* return output_387_binary_op (insn, operands);"
14332   [(set (attr "type") 
14333         (cond [(match_operand:SF 3 "mult_operator" "")
14334                  (const_string "ssemul")
14335                (match_operand:SF 3 "div_operator" "")
14336                  (const_string "ssediv")
14337               ]
14338               (const_string "sseadd")))
14339    (set_attr "mode" "SF")])
14340
14341 ;; This pattern is not fully shadowed by the pattern above.
14342 (define_insn "*fop_sf_1_i387"
14343   [(set (match_operand:SF 0 "register_operand" "=f,f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && !COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (cond [(match_operand:SF 3 "mult_operator" "") 
14353                  (const_string "fmul")
14354                (match_operand:SF 3 "div_operator" "") 
14355                  (const_string "fdiv")
14356               ]
14357               (const_string "fop")))
14358    (set_attr "mode" "SF")])
14359
14360 ;; ??? Add SSE splitters for these!
14361 (define_insn "*fop_sf_2<mode>_i387"
14362   [(set (match_operand:SF 0 "register_operand" "=f,f")
14363         (match_operator:SF 3 "binary_fp_operator"
14364           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14365            (match_operand:SF 2 "register_operand" "0,0")]))]
14366   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14367   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14368   [(set (attr "type") 
14369         (cond [(match_operand:SF 3 "mult_operator" "") 
14370                  (const_string "fmul")
14371                (match_operand:SF 3 "div_operator" "") 
14372                  (const_string "fdiv")
14373               ]
14374               (const_string "fop")))
14375    (set_attr "fp_int_src" "true")
14376    (set_attr "mode" "<MODE>")])
14377
14378 (define_insn "*fop_sf_3<mode>_i387"
14379   [(set (match_operand:SF 0 "register_operand" "=f,f")
14380         (match_operator:SF 3 "binary_fp_operator"
14381           [(match_operand:SF 1 "register_operand" "0,0")
14382            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14383   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14384   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14385   [(set (attr "type") 
14386         (cond [(match_operand:SF 3 "mult_operator" "") 
14387                  (const_string "fmul")
14388                (match_operand:SF 3 "div_operator" "") 
14389                  (const_string "fdiv")
14390               ]
14391               (const_string "fop")))
14392    (set_attr "fp_int_src" "true")
14393    (set_attr "mode" "<MODE>")])
14394
14395 (define_insn "*fop_df_comm_mixed"
14396   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14397         (match_operator:DF 3 "binary_fp_operator"
14398                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14399                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14400   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14401    && COMMUTATIVE_ARITH_P (operands[3])
14402    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14403   "* return output_387_binary_op (insn, operands);"
14404   [(set (attr "type") 
14405         (if_then_else (eq_attr "alternative" "1")
14406            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14407               (const_string "ssemul")
14408               (const_string "sseadd"))
14409            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14410               (const_string "fmul")
14411               (const_string "fop"))))
14412    (set_attr "mode" "DF")])
14413
14414 (define_insn "*fop_df_comm_sse"
14415   [(set (match_operand:DF 0 "register_operand" "=Y")
14416         (match_operator:DF 3 "binary_fp_operator"
14417                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14418                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14419   "TARGET_SSE2 && TARGET_SSE_MATH
14420    && COMMUTATIVE_ARITH_P (operands[3])
14421    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422   "* return output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14425            (const_string "ssemul")
14426            (const_string "sseadd")))
14427    (set_attr "mode" "DF")])
14428
14429 (define_insn "*fop_df_comm_i387"
14430   [(set (match_operand:DF 0 "register_operand" "=f")
14431         (match_operator:DF 3 "binary_fp_operator"
14432                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14433                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14434   "TARGET_80387
14435    && COMMUTATIVE_ARITH_P (operands[3])
14436    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14437   "* return output_387_binary_op (insn, operands);"
14438   [(set (attr "type") 
14439         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14440            (const_string "fmul")
14441            (const_string "fop")))
14442    (set_attr "mode" "DF")])
14443
14444 (define_insn "*fop_df_1_mixed"
14445   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14446         (match_operator:DF 3 "binary_fp_operator"
14447                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14448                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14449   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14450    && !COMMUTATIVE_ARITH_P (operands[3])
14451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (cond [(and (eq_attr "alternative" "2")
14455                     (match_operand:SF 3 "mult_operator" ""))
14456                  (const_string "ssemul")
14457                (and (eq_attr "alternative" "2")
14458                     (match_operand:SF 3 "div_operator" ""))
14459                  (const_string "ssediv")
14460                (eq_attr "alternative" "2")
14461                  (const_string "sseadd")
14462                (match_operand:DF 3 "mult_operator" "") 
14463                  (const_string "fmul")
14464                (match_operand:DF 3 "div_operator" "") 
14465                  (const_string "fdiv")
14466               ]
14467               (const_string "fop")))
14468    (set_attr "mode" "DF")])
14469
14470 (define_insn "*fop_df_1_sse"
14471   [(set (match_operand:DF 0 "register_operand" "=Y")
14472         (match_operator:DF 3 "binary_fp_operator"
14473                         [(match_operand:DF 1 "register_operand" "0")
14474                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14475   "TARGET_SSE2 && TARGET_SSE_MATH
14476    && !COMMUTATIVE_ARITH_P (operands[3])"
14477   "* return output_387_binary_op (insn, operands);"
14478   [(set_attr "mode" "DF")
14479    (set (attr "type") 
14480         (cond [(match_operand:SF 3 "mult_operator" "")
14481                  (const_string "ssemul")
14482                (match_operand:SF 3 "div_operator" "")
14483                  (const_string "ssediv")
14484               ]
14485               (const_string "sseadd")))])
14486
14487 ;; This pattern is not fully shadowed by the pattern above.
14488 (define_insn "*fop_df_1_i387"
14489   [(set (match_operand:DF 0 "register_operand" "=f,f")
14490         (match_operator:DF 3 "binary_fp_operator"
14491                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14492                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14493   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14494    && !COMMUTATIVE_ARITH_P (operands[3])
14495    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14496   "* return output_387_binary_op (insn, operands);"
14497   [(set (attr "type") 
14498         (cond [(match_operand:DF 3 "mult_operator" "") 
14499                  (const_string "fmul")
14500                (match_operand:DF 3 "div_operator" "")
14501                  (const_string "fdiv")
14502               ]
14503               (const_string "fop")))
14504    (set_attr "mode" "DF")])
14505
14506 ;; ??? Add SSE splitters for these!
14507 (define_insn "*fop_df_2<mode>_i387"
14508   [(set (match_operand:DF 0 "register_operand" "=f,f")
14509         (match_operator:DF 3 "binary_fp_operator"
14510            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14511             (match_operand:DF 2 "register_operand" "0,0")]))]
14512   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14513    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14514   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14515   [(set (attr "type") 
14516         (cond [(match_operand:DF 3 "mult_operator" "") 
14517                  (const_string "fmul")
14518                (match_operand:DF 3 "div_operator" "") 
14519                  (const_string "fdiv")
14520               ]
14521               (const_string "fop")))
14522    (set_attr "fp_int_src" "true")
14523    (set_attr "mode" "<MODE>")])
14524
14525 (define_insn "*fop_df_3<mode>_i387"
14526   [(set (match_operand:DF 0 "register_operand" "=f,f")
14527         (match_operator:DF 3 "binary_fp_operator"
14528            [(match_operand:DF 1 "register_operand" "0,0")
14529             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14530   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14531    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14533   [(set (attr "type") 
14534         (cond [(match_operand:DF 3 "mult_operator" "") 
14535                  (const_string "fmul")
14536                (match_operand:DF 3 "div_operator" "") 
14537                  (const_string "fdiv")
14538               ]
14539               (const_string "fop")))
14540    (set_attr "fp_int_src" "true")
14541    (set_attr "mode" "<MODE>")])
14542
14543 (define_insn "*fop_df_4_i387"
14544   [(set (match_operand:DF 0 "register_operand" "=f,f")
14545         (match_operator:DF 3 "binary_fp_operator"
14546            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14547             (match_operand:DF 2 "register_operand" "0,f")]))]
14548   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14549    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550   "* return output_387_binary_op (insn, operands);"
14551   [(set (attr "type") 
14552         (cond [(match_operand:DF 3 "mult_operator" "") 
14553                  (const_string "fmul")
14554                (match_operand:DF 3 "div_operator" "") 
14555                  (const_string "fdiv")
14556               ]
14557               (const_string "fop")))
14558    (set_attr "mode" "SF")])
14559
14560 (define_insn "*fop_df_5_i387"
14561   [(set (match_operand:DF 0 "register_operand" "=f,f")
14562         (match_operator:DF 3 "binary_fp_operator"
14563           [(match_operand:DF 1 "register_operand" "0,f")
14564            (float_extend:DF
14565             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14566   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14567   "* return output_387_binary_op (insn, operands);"
14568   [(set (attr "type") 
14569         (cond [(match_operand:DF 3 "mult_operator" "") 
14570                  (const_string "fmul")
14571                (match_operand:DF 3 "div_operator" "") 
14572                  (const_string "fdiv")
14573               ]
14574               (const_string "fop")))
14575    (set_attr "mode" "SF")])
14576
14577 (define_insn "*fop_df_6_i387"
14578   [(set (match_operand:DF 0 "register_operand" "=f,f")
14579         (match_operator:DF 3 "binary_fp_operator"
14580           [(float_extend:DF
14581             (match_operand:SF 1 "register_operand" "0,f"))
14582            (float_extend:DF
14583             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14584   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14585   "* return output_387_binary_op (insn, operands);"
14586   [(set (attr "type") 
14587         (cond [(match_operand:DF 3 "mult_operator" "") 
14588                  (const_string "fmul")
14589                (match_operand:DF 3 "div_operator" "") 
14590                  (const_string "fdiv")
14591               ]
14592               (const_string "fop")))
14593    (set_attr "mode" "SF")])
14594
14595 (define_insn "*fop_xf_comm_i387"
14596   [(set (match_operand:XF 0 "register_operand" "=f")
14597         (match_operator:XF 3 "binary_fp_operator"
14598                         [(match_operand:XF 1 "register_operand" "%0")
14599                          (match_operand:XF 2 "register_operand" "f")]))]
14600   "TARGET_80387
14601    && COMMUTATIVE_ARITH_P (operands[3])"
14602   "* return output_387_binary_op (insn, operands);"
14603   [(set (attr "type") 
14604         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14605            (const_string "fmul")
14606            (const_string "fop")))
14607    (set_attr "mode" "XF")])
14608
14609 (define_insn "*fop_xf_1_i387"
14610   [(set (match_operand:XF 0 "register_operand" "=f,f")
14611         (match_operator:XF 3 "binary_fp_operator"
14612                         [(match_operand:XF 1 "register_operand" "0,f")
14613                          (match_operand:XF 2 "register_operand" "f,0")]))]
14614   "TARGET_80387
14615    && !COMMUTATIVE_ARITH_P (operands[3])"
14616   "* return output_387_binary_op (insn, operands);"
14617   [(set (attr "type") 
14618         (cond [(match_operand:XF 3 "mult_operator" "") 
14619                  (const_string "fmul")
14620                (match_operand:XF 3 "div_operator" "") 
14621                  (const_string "fdiv")
14622               ]
14623               (const_string "fop")))
14624    (set_attr "mode" "XF")])
14625
14626 (define_insn "*fop_xf_2<mode>_i387"
14627   [(set (match_operand:XF 0 "register_operand" "=f,f")
14628         (match_operator:XF 3 "binary_fp_operator"
14629            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14630             (match_operand:XF 2 "register_operand" "0,0")]))]
14631   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14632   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14633   [(set (attr "type") 
14634         (cond [(match_operand:XF 3 "mult_operator" "") 
14635                  (const_string "fmul")
14636                (match_operand:XF 3 "div_operator" "") 
14637                  (const_string "fdiv")
14638               ]
14639               (const_string "fop")))
14640    (set_attr "fp_int_src" "true")
14641    (set_attr "mode" "<MODE>")])
14642
14643 (define_insn "*fop_xf_3<mode>_i387"
14644   [(set (match_operand:XF 0 "register_operand" "=f,f")
14645         (match_operator:XF 3 "binary_fp_operator"
14646           [(match_operand:XF 1 "register_operand" "0,0")
14647            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14648   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14649   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14650   [(set (attr "type") 
14651         (cond [(match_operand:XF 3 "mult_operator" "") 
14652                  (const_string "fmul")
14653                (match_operand:XF 3 "div_operator" "") 
14654                  (const_string "fdiv")
14655               ]
14656               (const_string "fop")))
14657    (set_attr "fp_int_src" "true")
14658    (set_attr "mode" "<MODE>")])
14659
14660 (define_insn "*fop_xf_4_i387"
14661   [(set (match_operand:XF 0 "register_operand" "=f,f")
14662         (match_operator:XF 3 "binary_fp_operator"
14663            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14664             (match_operand:XF 2 "register_operand" "0,f")]))]
14665   "TARGET_80387"
14666   "* return output_387_binary_op (insn, operands);"
14667   [(set (attr "type") 
14668         (cond [(match_operand:XF 3 "mult_operator" "") 
14669                  (const_string "fmul")
14670                (match_operand:XF 3 "div_operator" "") 
14671                  (const_string "fdiv")
14672               ]
14673               (const_string "fop")))
14674    (set_attr "mode" "SF")])
14675
14676 (define_insn "*fop_xf_5_i387"
14677   [(set (match_operand:XF 0 "register_operand" "=f,f")
14678         (match_operator:XF 3 "binary_fp_operator"
14679           [(match_operand:XF 1 "register_operand" "0,f")
14680            (float_extend:XF
14681             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14682   "TARGET_80387"
14683   "* return output_387_binary_op (insn, operands);"
14684   [(set (attr "type") 
14685         (cond [(match_operand:XF 3 "mult_operator" "") 
14686                  (const_string "fmul")
14687                (match_operand:XF 3 "div_operator" "") 
14688                  (const_string "fdiv")
14689               ]
14690               (const_string "fop")))
14691    (set_attr "mode" "SF")])
14692
14693 (define_insn "*fop_xf_6_i387"
14694   [(set (match_operand:XF 0 "register_operand" "=f,f")
14695         (match_operator:XF 3 "binary_fp_operator"
14696           [(float_extend:XF
14697             (match_operand 1 "register_operand" "0,f"))
14698            (float_extend:XF
14699             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14700   "TARGET_80387"
14701   "* return output_387_binary_op (insn, operands);"
14702   [(set (attr "type") 
14703         (cond [(match_operand:XF 3 "mult_operator" "") 
14704                  (const_string "fmul")
14705                (match_operand:XF 3 "div_operator" "") 
14706                  (const_string "fdiv")
14707               ]
14708               (const_string "fop")))
14709    (set_attr "mode" "SF")])
14710
14711 (define_split
14712   [(set (match_operand 0 "register_operand" "")
14713         (match_operator 3 "binary_fp_operator"
14714            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14715             (match_operand 2 "register_operand" "")]))]
14716   "TARGET_80387 && reload_completed
14717    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14718   [(const_int 0)]
14719
14720   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14721   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14722   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14723                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14724                                           GET_MODE (operands[3]),
14725                                           operands[4],
14726                                           operands[2])));
14727   ix86_free_from_memory (GET_MODE (operands[1]));
14728   DONE;
14729 })
14730
14731 (define_split
14732   [(set (match_operand 0 "register_operand" "")
14733         (match_operator 3 "binary_fp_operator"
14734            [(match_operand 1 "register_operand" "")
14735             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14736   "TARGET_80387 && reload_completed
14737    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14738   [(const_int 0)]
14739 {
14740   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14741   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14742   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14743                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14744                                           GET_MODE (operands[3]),
14745                                           operands[1],
14746                                           operands[4])));
14747   ix86_free_from_memory (GET_MODE (operands[2]));
14748   DONE;
14749 })
14750 \f
14751 ;; FPU special functions.
14752
14753 (define_expand "sqrtsf2"
14754   [(set (match_operand:SF 0 "register_operand" "")
14755         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14756   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14757 {
14758   if (!TARGET_SSE_MATH)
14759     operands[1] = force_reg (SFmode, operands[1]);
14760 })
14761
14762 (define_insn "*sqrtsf2_mixed"
14763   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14764         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14765   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14766   "@
14767    fsqrt
14768    sqrtss\t{%1, %0|%0, %1}"
14769   [(set_attr "type" "fpspc,sse")
14770    (set_attr "mode" "SF,SF")
14771    (set_attr "athlon_decode" "direct,*")])
14772
14773 (define_insn "*sqrtsf2_sse"
14774   [(set (match_operand:SF 0 "register_operand" "=x")
14775         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14776   "TARGET_SSE_MATH"
14777   "sqrtss\t{%1, %0|%0, %1}"
14778   [(set_attr "type" "sse")
14779    (set_attr "mode" "SF")
14780    (set_attr "athlon_decode" "*")])
14781
14782 (define_insn "*sqrtsf2_i387"
14783   [(set (match_operand:SF 0 "register_operand" "=f")
14784         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14785   "TARGET_USE_FANCY_MATH_387"
14786   "fsqrt"
14787   [(set_attr "type" "fpspc")
14788    (set_attr "mode" "SF")
14789    (set_attr "athlon_decode" "direct")])
14790
14791 (define_expand "sqrtdf2"
14792   [(set (match_operand:DF 0 "register_operand" "")
14793         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14794   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14795 {
14796   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14797     operands[1] = force_reg (DFmode, operands[1]);
14798 })
14799
14800 (define_insn "*sqrtdf2_mixed"
14801   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14802         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14803   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14804   "@
14805    fsqrt
14806    sqrtsd\t{%1, %0|%0, %1}"
14807   [(set_attr "type" "fpspc,sse")
14808    (set_attr "mode" "DF,DF")
14809    (set_attr "athlon_decode" "direct,*")])
14810
14811 (define_insn "*sqrtdf2_sse"
14812   [(set (match_operand:DF 0 "register_operand" "=Y")
14813         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14814   "TARGET_SSE2 && TARGET_SSE_MATH"
14815   "sqrtsd\t{%1, %0|%0, %1}"
14816   [(set_attr "type" "sse")
14817    (set_attr "mode" "DF")
14818    (set_attr "athlon_decode" "*")])
14819
14820 (define_insn "*sqrtdf2_i387"
14821   [(set (match_operand:DF 0 "register_operand" "=f")
14822         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14823   "TARGET_USE_FANCY_MATH_387"
14824   "fsqrt"
14825   [(set_attr "type" "fpspc")
14826    (set_attr "mode" "DF")
14827    (set_attr "athlon_decode" "direct")])
14828
14829 (define_insn "*sqrtextendsfdf2_i387"
14830   [(set (match_operand:DF 0 "register_operand" "=f")
14831         (sqrt:DF (float_extend:DF
14832                   (match_operand:SF 1 "register_operand" "0"))))]
14833   "TARGET_USE_FANCY_MATH_387
14834    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14835   "fsqrt"
14836   [(set_attr "type" "fpspc")
14837    (set_attr "mode" "DF")
14838    (set_attr "athlon_decode" "direct")])
14839
14840 (define_insn "sqrtxf2"
14841   [(set (match_operand:XF 0 "register_operand" "=f")
14842         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14843   "TARGET_USE_FANCY_MATH_387 
14844    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14845   "fsqrt"
14846   [(set_attr "type" "fpspc")
14847    (set_attr "mode" "XF")
14848    (set_attr "athlon_decode" "direct")])
14849
14850 (define_insn "*sqrtextendsfxf2_i387"
14851   [(set (match_operand:XF 0 "register_operand" "=f")
14852         (sqrt:XF (float_extend:XF
14853                   (match_operand:SF 1 "register_operand" "0"))))]
14854   "TARGET_USE_FANCY_MATH_387"
14855   "fsqrt"
14856   [(set_attr "type" "fpspc")
14857    (set_attr "mode" "XF")
14858    (set_attr "athlon_decode" "direct")])
14859
14860 (define_insn "*sqrtextenddfxf2_i387"
14861   [(set (match_operand:XF 0 "register_operand" "=f")
14862         (sqrt:XF (float_extend:XF
14863                   (match_operand:DF 1 "register_operand" "0"))))]
14864   "TARGET_USE_FANCY_MATH_387"
14865   "fsqrt"
14866   [(set_attr "type" "fpspc")
14867    (set_attr "mode" "XF")
14868    (set_attr "athlon_decode" "direct")])
14869
14870 (define_insn "fpremxf4"
14871   [(set (match_operand:XF 0 "register_operand" "=f")
14872         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14873                     (match_operand:XF 3 "register_operand" "1")]
14874                    UNSPEC_FPREM_F))
14875    (set (match_operand:XF 1 "register_operand" "=u")
14876         (unspec:XF [(match_dup 2) (match_dup 3)]
14877                    UNSPEC_FPREM_U))
14878    (set (reg:CCFP FPSR_REG)
14879         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && flag_unsafe_math_optimizations"
14882   "fprem"
14883   [(set_attr "type" "fpspc")
14884    (set_attr "mode" "XF")])
14885
14886 (define_expand "fmodsf3"
14887   [(use (match_operand:SF 0 "register_operand" ""))
14888    (use (match_operand:SF 1 "register_operand" ""))
14889    (use (match_operand:SF 2 "register_operand" ""))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14892    && flag_unsafe_math_optimizations"
14893 {
14894   rtx label = gen_label_rtx ();
14895
14896   rtx op1 = gen_reg_rtx (XFmode);
14897   rtx op2 = gen_reg_rtx (XFmode);
14898
14899   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14900   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14901
14902   emit_label (label);
14903
14904   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14905   ix86_emit_fp_unordered_jump (label);
14906
14907   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14908   DONE;
14909 })
14910
14911 (define_expand "fmoddf3"
14912   [(use (match_operand:DF 0 "register_operand" ""))
14913    (use (match_operand:DF 1 "register_operand" ""))
14914    (use (match_operand:DF 2 "register_operand" ""))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14917    && flag_unsafe_math_optimizations"
14918 {
14919   rtx label = gen_label_rtx ();
14920
14921   rtx op1 = gen_reg_rtx (XFmode);
14922   rtx op2 = gen_reg_rtx (XFmode);
14923
14924   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14925   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14926
14927   emit_label (label);
14928
14929   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14930   ix86_emit_fp_unordered_jump (label);
14931
14932   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14933   DONE;
14934 })
14935
14936 (define_expand "fmodxf3"
14937   [(use (match_operand:XF 0 "register_operand" ""))
14938    (use (match_operand:XF 1 "register_operand" ""))
14939    (use (match_operand:XF 2 "register_operand" ""))]
14940   "TARGET_USE_FANCY_MATH_387
14941    && flag_unsafe_math_optimizations"
14942 {
14943   rtx label = gen_label_rtx ();
14944
14945   emit_label (label);
14946
14947   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14948                            operands[1], operands[2]));
14949   ix86_emit_fp_unordered_jump (label);
14950
14951   emit_move_insn (operands[0], operands[1]);
14952   DONE;
14953 })
14954
14955 (define_insn "fprem1xf4"
14956   [(set (match_operand:XF 0 "register_operand" "=f")
14957         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14958                     (match_operand:XF 3 "register_operand" "1")]
14959                    UNSPEC_FPREM1_F))
14960    (set (match_operand:XF 1 "register_operand" "=u")
14961         (unspec:XF [(match_dup 2) (match_dup 3)]
14962                    UNSPEC_FPREM1_U))
14963    (set (reg:CCFP FPSR_REG)
14964         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fprem1"
14968   [(set_attr "type" "fpspc")
14969    (set_attr "mode" "XF")])
14970
14971 (define_expand "dremsf3"
14972   [(use (match_operand:SF 0 "register_operand" ""))
14973    (use (match_operand:SF 1 "register_operand" ""))
14974    (use (match_operand:SF 2 "register_operand" ""))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14977    && flag_unsafe_math_optimizations"
14978 {
14979   rtx label = gen_label_rtx ();
14980
14981   rtx op1 = gen_reg_rtx (XFmode);
14982   rtx op2 = gen_reg_rtx (XFmode);
14983
14984   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14985   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14986
14987   emit_label (label);
14988
14989   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14990   ix86_emit_fp_unordered_jump (label);
14991
14992   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14993   DONE;
14994 })
14995
14996 (define_expand "dremdf3"
14997   [(use (match_operand:DF 0 "register_operand" ""))
14998    (use (match_operand:DF 1 "register_operand" ""))
14999    (use (match_operand:DF 2 "register_operand" ""))]
15000   "TARGET_USE_FANCY_MATH_387
15001    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15002    && flag_unsafe_math_optimizations"
15003 {
15004   rtx label = gen_label_rtx ();
15005
15006   rtx op1 = gen_reg_rtx (XFmode);
15007   rtx op2 = gen_reg_rtx (XFmode);
15008
15009   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15010   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15011
15012   emit_label (label);
15013
15014   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15015   ix86_emit_fp_unordered_jump (label);
15016
15017   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15018   DONE;
15019 })
15020
15021 (define_expand "dremxf3"
15022   [(use (match_operand:XF 0 "register_operand" ""))
15023    (use (match_operand:XF 1 "register_operand" ""))
15024    (use (match_operand:XF 2 "register_operand" ""))]
15025   "TARGET_USE_FANCY_MATH_387
15026    && flag_unsafe_math_optimizations"
15027 {
15028   rtx label = gen_label_rtx ();
15029
15030   emit_label (label);
15031
15032   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15033                             operands[1], operands[2]));
15034   ix86_emit_fp_unordered_jump (label);
15035
15036   emit_move_insn (operands[0], operands[1]);
15037   DONE;
15038 })
15039
15040 (define_insn "*sindf2"
15041   [(set (match_operand:DF 0 "register_operand" "=f")
15042         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15043   "TARGET_USE_FANCY_MATH_387
15044    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15045    && flag_unsafe_math_optimizations"
15046   "fsin"
15047   [(set_attr "type" "fpspc")
15048    (set_attr "mode" "DF")])
15049
15050 (define_insn "*sinsf2"
15051   [(set (match_operand:SF 0 "register_operand" "=f")
15052         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15055    && flag_unsafe_math_optimizations"
15056   "fsin"
15057   [(set_attr "type" "fpspc")
15058    (set_attr "mode" "SF")])
15059
15060 (define_insn "*sinextendsfdf2"
15061   [(set (match_operand:DF 0 "register_operand" "=f")
15062         (unspec:DF [(float_extend:DF
15063                      (match_operand:SF 1 "register_operand" "0"))]
15064                    UNSPEC_SIN))]
15065   "TARGET_USE_FANCY_MATH_387
15066    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15067    && flag_unsafe_math_optimizations"
15068   "fsin"
15069   [(set_attr "type" "fpspc")
15070    (set_attr "mode" "DF")])
15071
15072 (define_insn "*sinxf2"
15073   [(set (match_operand:XF 0 "register_operand" "=f")
15074         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15075   "TARGET_USE_FANCY_MATH_387
15076    && flag_unsafe_math_optimizations"
15077   "fsin"
15078   [(set_attr "type" "fpspc")
15079    (set_attr "mode" "XF")])
15080
15081 (define_insn "*cosdf2"
15082   [(set (match_operand:DF 0 "register_operand" "=f")
15083         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15086    && flag_unsafe_math_optimizations"
15087   "fcos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "DF")])
15090
15091 (define_insn "*cossf2"
15092   [(set (match_operand:SF 0 "register_operand" "=f")
15093         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15094   "TARGET_USE_FANCY_MATH_387
15095    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15096    && flag_unsafe_math_optimizations"
15097   "fcos"
15098   [(set_attr "type" "fpspc")
15099    (set_attr "mode" "SF")])
15100
15101 (define_insn "*cosextendsfdf2"
15102   [(set (match_operand:DF 0 "register_operand" "=f")
15103         (unspec:DF [(float_extend:DF
15104                      (match_operand:SF 1 "register_operand" "0"))]
15105                    UNSPEC_COS))]
15106   "TARGET_USE_FANCY_MATH_387
15107    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15108    && flag_unsafe_math_optimizations"
15109   "fcos"
15110   [(set_attr "type" "fpspc")
15111    (set_attr "mode" "DF")])
15112
15113 (define_insn "*cosxf2"
15114   [(set (match_operand:XF 0 "register_operand" "=f")
15115         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations"
15118   "fcos"
15119   [(set_attr "type" "fpspc")
15120    (set_attr "mode" "XF")])
15121
15122 ;; With sincos pattern defined, sin and cos builtin function will be
15123 ;; expanded to sincos pattern with one of its outputs left unused. 
15124 ;; Cse pass  will detected, if two sincos patterns can be combined,
15125 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15126 ;; depending on the unused output.
15127
15128 (define_insn "sincosdf3"
15129   [(set (match_operand:DF 0 "register_operand" "=f")
15130         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15131                    UNSPEC_SINCOS_COS))
15132    (set (match_operand:DF 1 "register_operand" "=u")
15133         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15136    && flag_unsafe_math_optimizations"
15137   "fsincos"
15138   [(set_attr "type" "fpspc")
15139    (set_attr "mode" "DF")])
15140
15141 (define_split
15142   [(set (match_operand:DF 0 "register_operand" "")
15143         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15144                    UNSPEC_SINCOS_COS))
15145    (set (match_operand:DF 1 "register_operand" "")
15146         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15147   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15148    && !reload_completed && !reload_in_progress"
15149   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15150   "")
15151
15152 (define_split
15153   [(set (match_operand:DF 0 "register_operand" "")
15154         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15155                    UNSPEC_SINCOS_COS))
15156    (set (match_operand:DF 1 "register_operand" "")
15157         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15158   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15159    && !reload_completed && !reload_in_progress"
15160   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15161   "")
15162
15163 (define_insn "sincossf3"
15164   [(set (match_operand:SF 0 "register_operand" "=f")
15165         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15166                    UNSPEC_SINCOS_COS))
15167    (set (match_operand:SF 1 "register_operand" "=u")
15168         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15169   "TARGET_USE_FANCY_MATH_387
15170    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15171    && flag_unsafe_math_optimizations"
15172   "fsincos"
15173   [(set_attr "type" "fpspc")
15174    (set_attr "mode" "SF")])
15175
15176 (define_split
15177   [(set (match_operand:SF 0 "register_operand" "")
15178         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15179                    UNSPEC_SINCOS_COS))
15180    (set (match_operand:SF 1 "register_operand" "")
15181         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15182   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15183    && !reload_completed && !reload_in_progress"
15184   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15185   "")
15186
15187 (define_split
15188   [(set (match_operand:SF 0 "register_operand" "")
15189         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15190                    UNSPEC_SINCOS_COS))
15191    (set (match_operand:SF 1 "register_operand" "")
15192         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15193   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15194    && !reload_completed && !reload_in_progress"
15195   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15196   "")
15197
15198 (define_insn "*sincosextendsfdf3"
15199   [(set (match_operand:DF 0 "register_operand" "=f")
15200         (unspec:DF [(float_extend:DF
15201                      (match_operand:SF 2 "register_operand" "0"))]
15202                    UNSPEC_SINCOS_COS))
15203    (set (match_operand:DF 1 "register_operand" "=u")
15204         (unspec:DF [(float_extend:DF
15205                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15206   "TARGET_USE_FANCY_MATH_387
15207    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15208    && flag_unsafe_math_optimizations"
15209   "fsincos"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "DF")])
15212
15213 (define_split
15214   [(set (match_operand:DF 0 "register_operand" "")
15215         (unspec:DF [(float_extend:DF
15216                      (match_operand:SF 2 "register_operand" ""))]
15217                    UNSPEC_SINCOS_COS))
15218    (set (match_operand:DF 1 "register_operand" "")
15219         (unspec:DF [(float_extend:DF
15220                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15221   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15222    && !reload_completed && !reload_in_progress"
15223   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15224                                    (match_dup 2))] UNSPEC_SIN))]
15225   "")
15226
15227 (define_split
15228   [(set (match_operand:DF 0 "register_operand" "")
15229         (unspec:DF [(float_extend:DF
15230                      (match_operand:SF 2 "register_operand" ""))]
15231                    UNSPEC_SINCOS_COS))
15232    (set (match_operand:DF 1 "register_operand" "")
15233         (unspec:DF [(float_extend:DF
15234                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15235   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15236    && !reload_completed && !reload_in_progress"
15237   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15238                                    (match_dup 2))] UNSPEC_COS))]
15239   "")
15240
15241 (define_insn "sincosxf3"
15242   [(set (match_operand:XF 0 "register_operand" "=f")
15243         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15244                    UNSPEC_SINCOS_COS))
15245    (set (match_operand:XF 1 "register_operand" "=u")
15246         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15247   "TARGET_USE_FANCY_MATH_387
15248    && flag_unsafe_math_optimizations"
15249   "fsincos"
15250   [(set_attr "type" "fpspc")
15251    (set_attr "mode" "XF")])
15252
15253 (define_split
15254   [(set (match_operand:XF 0 "register_operand" "")
15255         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15256                    UNSPEC_SINCOS_COS))
15257    (set (match_operand:XF 1 "register_operand" "")
15258         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15259   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15260    && !reload_completed && !reload_in_progress"
15261   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15262   "")
15263
15264 (define_split
15265   [(set (match_operand:XF 0 "register_operand" "")
15266         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15267                    UNSPEC_SINCOS_COS))
15268    (set (match_operand:XF 1 "register_operand" "")
15269         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15270   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15271    && !reload_completed && !reload_in_progress"
15272   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15273   "")
15274
15275 (define_insn "*tandf3_1"
15276   [(set (match_operand:DF 0 "register_operand" "=f")
15277         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15278                    UNSPEC_TAN_ONE))
15279    (set (match_operand:DF 1 "register_operand" "=u")
15280         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15281   "TARGET_USE_FANCY_MATH_387
15282    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15283    && flag_unsafe_math_optimizations"
15284   "fptan"
15285   [(set_attr "type" "fpspc")
15286    (set_attr "mode" "DF")])
15287
15288 ;; optimize sequence: fptan
15289 ;;                    fstp    %st(0)
15290 ;;                    fld1
15291 ;; into fptan insn.
15292
15293 (define_peephole2
15294   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15295                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15296                              UNSPEC_TAN_ONE))
15297              (set (match_operand:DF 1 "register_operand" "")
15298                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15299    (set (match_dup 0)
15300         (match_operand:DF 3 "immediate_operand" ""))]
15301   "standard_80387_constant_p (operands[3]) == 2"
15302   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15303              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15304   "")
15305
15306 (define_expand "tandf2"
15307   [(parallel [(set (match_dup 2)
15308                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15309                               UNSPEC_TAN_ONE))
15310               (set (match_operand:DF 0 "register_operand" "")
15311                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15312   "TARGET_USE_FANCY_MATH_387
15313    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15314    && flag_unsafe_math_optimizations"
15315 {
15316   operands[2] = gen_reg_rtx (DFmode);
15317 })
15318
15319 (define_insn "*tansf3_1"
15320   [(set (match_operand:SF 0 "register_operand" "=f")
15321         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15322                    UNSPEC_TAN_ONE))
15323    (set (match_operand:SF 1 "register_operand" "=u")
15324         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15327    && flag_unsafe_math_optimizations"
15328   "fptan"
15329   [(set_attr "type" "fpspc")
15330    (set_attr "mode" "SF")])
15331
15332 ;; optimize sequence: fptan
15333 ;;                    fstp    %st(0)
15334 ;;                    fld1
15335 ;; into fptan insn.
15336
15337 (define_peephole2
15338   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15339                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15340                              UNSPEC_TAN_ONE))
15341              (set (match_operand:SF 1 "register_operand" "")
15342                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15343    (set (match_dup 0)
15344         (match_operand:SF 3 "immediate_operand" ""))]
15345   "standard_80387_constant_p (operands[3]) == 2"
15346   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15347              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15348   "")
15349
15350 (define_expand "tansf2"
15351   [(parallel [(set (match_dup 2)
15352                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15353                               UNSPEC_TAN_ONE))
15354               (set (match_operand:SF 0 "register_operand" "")
15355                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15358    && flag_unsafe_math_optimizations"
15359 {
15360   operands[2] = gen_reg_rtx (SFmode);
15361 })
15362
15363 (define_insn "*tanxf3_1"
15364   [(set (match_operand:XF 0 "register_operand" "=f")
15365         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15366                    UNSPEC_TAN_ONE))
15367    (set (match_operand:XF 1 "register_operand" "=u")
15368         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15369   "TARGET_USE_FANCY_MATH_387
15370    && flag_unsafe_math_optimizations"
15371   "fptan"
15372   [(set_attr "type" "fpspc")
15373    (set_attr "mode" "XF")])
15374
15375 ;; optimize sequence: fptan
15376 ;;                    fstp    %st(0)
15377 ;;                    fld1
15378 ;; into fptan insn.
15379
15380 (define_peephole2
15381   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15382                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15383                              UNSPEC_TAN_ONE))
15384              (set (match_operand:XF 1 "register_operand" "")
15385                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15386    (set (match_dup 0)
15387         (match_operand:XF 3 "immediate_operand" ""))]
15388   "standard_80387_constant_p (operands[3]) == 2"
15389   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15390              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15391   "")
15392
15393 (define_expand "tanxf2"
15394   [(parallel [(set (match_dup 2)
15395                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15396                               UNSPEC_TAN_ONE))
15397               (set (match_operand:XF 0 "register_operand" "")
15398                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15399   "TARGET_USE_FANCY_MATH_387
15400    && flag_unsafe_math_optimizations"
15401 {
15402   operands[2] = gen_reg_rtx (XFmode);
15403 })
15404
15405 (define_insn "atan2df3_1"
15406   [(set (match_operand:DF 0 "register_operand" "=f")
15407         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15408                     (match_operand:DF 1 "register_operand" "u")]
15409                    UNSPEC_FPATAN))
15410    (clobber (match_scratch:DF 3 "=1"))]
15411   "TARGET_USE_FANCY_MATH_387
15412    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15413    && flag_unsafe_math_optimizations"
15414   "fpatan"
15415   [(set_attr "type" "fpspc")
15416    (set_attr "mode" "DF")])
15417
15418 (define_expand "atan2df3"
15419   [(use (match_operand:DF 0 "register_operand" ""))
15420    (use (match_operand:DF 2 "register_operand" ""))
15421    (use (match_operand:DF 1 "register_operand" ""))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424    && flag_unsafe_math_optimizations"
15425 {
15426   rtx copy = gen_reg_rtx (DFmode);
15427   emit_move_insn (copy, operands[1]);
15428   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15429   DONE;
15430 })
15431
15432 (define_expand "atandf2"
15433   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15434                    (unspec:DF [(match_dup 2)
15435                                (match_operand:DF 1 "register_operand" "")]
15436                     UNSPEC_FPATAN))
15437               (clobber (match_scratch:DF 3 ""))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15440    && flag_unsafe_math_optimizations"
15441 {
15442   operands[2] = gen_reg_rtx (DFmode);
15443   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15444 })
15445
15446 (define_insn "atan2sf3_1"
15447   [(set (match_operand:SF 0 "register_operand" "=f")
15448         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15449                     (match_operand:SF 1 "register_operand" "u")]
15450                    UNSPEC_FPATAN))
15451    (clobber (match_scratch:SF 3 "=1"))]
15452   "TARGET_USE_FANCY_MATH_387
15453    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15454    && flag_unsafe_math_optimizations"
15455   "fpatan"
15456   [(set_attr "type" "fpspc")
15457    (set_attr "mode" "SF")])
15458
15459 (define_expand "atan2sf3"
15460   [(use (match_operand:SF 0 "register_operand" ""))
15461    (use (match_operand:SF 2 "register_operand" ""))
15462    (use (match_operand:SF 1 "register_operand" ""))]
15463   "TARGET_USE_FANCY_MATH_387
15464    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15465    && flag_unsafe_math_optimizations"
15466 {
15467   rtx copy = gen_reg_rtx (SFmode);
15468   emit_move_insn (copy, operands[1]);
15469   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15470   DONE;
15471 })
15472
15473 (define_expand "atansf2"
15474   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15475                    (unspec:SF [(match_dup 2)
15476                                (match_operand:SF 1 "register_operand" "")]
15477                     UNSPEC_FPATAN))
15478               (clobber (match_scratch:SF 3 ""))])]
15479   "TARGET_USE_FANCY_MATH_387
15480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15481    && flag_unsafe_math_optimizations"
15482 {
15483   operands[2] = gen_reg_rtx (SFmode);
15484   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15485 })
15486
15487 (define_insn "atan2xf3_1"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490                     (match_operand:XF 1 "register_operand" "u")]
15491                    UNSPEC_FPATAN))
15492    (clobber (match_scratch:XF 3 "=1"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && flag_unsafe_math_optimizations"
15495   "fpatan"
15496   [(set_attr "type" "fpspc")
15497    (set_attr "mode" "XF")])
15498
15499 (define_expand "atan2xf3"
15500   [(use (match_operand:XF 0 "register_operand" ""))
15501    (use (match_operand:XF 2 "register_operand" ""))
15502    (use (match_operand:XF 1 "register_operand" ""))]
15503   "TARGET_USE_FANCY_MATH_387
15504    && flag_unsafe_math_optimizations"
15505 {
15506   rtx copy = gen_reg_rtx (XFmode);
15507   emit_move_insn (copy, operands[1]);
15508   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15509   DONE;
15510 })
15511
15512 (define_expand "atanxf2"
15513   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15514                    (unspec:XF [(match_dup 2)
15515                                (match_operand:XF 1 "register_operand" "")]
15516                     UNSPEC_FPATAN))
15517               (clobber (match_scratch:XF 3 ""))])]
15518   "TARGET_USE_FANCY_MATH_387
15519    && flag_unsafe_math_optimizations"
15520 {
15521   operands[2] = gen_reg_rtx (XFmode);
15522   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15523 })
15524
15525 (define_expand "asindf2"
15526   [(set (match_dup 2)
15527         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15528    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15529    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15530    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15531    (parallel [(set (match_dup 7)
15532                    (unspec:XF [(match_dup 6) (match_dup 2)]
15533                               UNSPEC_FPATAN))
15534               (clobber (match_scratch:XF 8 ""))])
15535    (set (match_operand:DF 0 "register_operand" "")
15536         (float_truncate:DF (match_dup 7)))]
15537   "TARGET_USE_FANCY_MATH_387
15538    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15539    && flag_unsafe_math_optimizations"
15540 {
15541   int i;
15542
15543   for (i=2; i<8; i++)
15544     operands[i] = gen_reg_rtx (XFmode);
15545
15546   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15547 })
15548
15549 (define_expand "asinsf2"
15550   [(set (match_dup 2)
15551         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15552    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15553    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15554    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15555    (parallel [(set (match_dup 7)
15556                    (unspec:XF [(match_dup 6) (match_dup 2)]
15557                               UNSPEC_FPATAN))
15558               (clobber (match_scratch:XF 8 ""))])
15559    (set (match_operand:SF 0 "register_operand" "")
15560         (float_truncate:SF (match_dup 7)))]
15561   "TARGET_USE_FANCY_MATH_387
15562    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15563    && flag_unsafe_math_optimizations"
15564 {
15565   int i;
15566
15567   for (i=2; i<8; i++)
15568     operands[i] = gen_reg_rtx (XFmode);
15569
15570   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15571 })
15572
15573 (define_expand "asinxf2"
15574   [(set (match_dup 2)
15575         (mult:XF (match_operand:XF 1 "register_operand" "")
15576                  (match_dup 1)))
15577    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15578    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15579    (parallel [(set (match_operand:XF 0 "register_operand" "")
15580                    (unspec:XF [(match_dup 5) (match_dup 1)]
15581                               UNSPEC_FPATAN))
15582               (clobber (match_scratch:XF 6 ""))])]
15583   "TARGET_USE_FANCY_MATH_387
15584    && flag_unsafe_math_optimizations"
15585 {
15586   int i;
15587
15588   for (i=2; i<6; i++)
15589     operands[i] = gen_reg_rtx (XFmode);
15590
15591   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15592 })
15593
15594 (define_expand "acosdf2"
15595   [(set (match_dup 2)
15596         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15597    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15598    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15599    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15600    (parallel [(set (match_dup 7)
15601                    (unspec:XF [(match_dup 2) (match_dup 6)]
15602                               UNSPEC_FPATAN))
15603               (clobber (match_scratch:XF 8 ""))])
15604    (set (match_operand:DF 0 "register_operand" "")
15605         (float_truncate:DF (match_dup 7)))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15608    && flag_unsafe_math_optimizations"
15609 {
15610   int i;
15611
15612   for (i=2; i<8; i++)
15613     operands[i] = gen_reg_rtx (XFmode);
15614
15615   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15616 })
15617
15618 (define_expand "acossf2"
15619   [(set (match_dup 2)
15620         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15621    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15622    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15623    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15624    (parallel [(set (match_dup 7)
15625                    (unspec:XF [(match_dup 2) (match_dup 6)]
15626                               UNSPEC_FPATAN))
15627               (clobber (match_scratch:XF 8 ""))])
15628    (set (match_operand:SF 0 "register_operand" "")
15629         (float_truncate:SF (match_dup 7)))]
15630   "TARGET_USE_FANCY_MATH_387
15631    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15632    && flag_unsafe_math_optimizations"
15633 {
15634   int i;
15635
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15638
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15640 })
15641
15642 (define_expand "acosxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 1) (match_dup 5)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "TARGET_USE_FANCY_MATH_387
15653    && flag_unsafe_math_optimizations"
15654 {
15655   int i;
15656
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15659
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15661 })
15662
15663 (define_insn "fyl2x_xf3"
15664   [(set (match_operand:XF 0 "register_operand" "=f")
15665         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15666                     (match_operand:XF 1 "register_operand" "u")]
15667                    UNSPEC_FYL2X))
15668    (clobber (match_scratch:XF 3 "=1"))]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15671   "fyl2x"
15672   [(set_attr "type" "fpspc")
15673    (set_attr "mode" "XF")])
15674
15675 (define_expand "logsf2"
15676   [(set (match_dup 2)
15677         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15678    (parallel [(set (match_dup 4)
15679                    (unspec:XF [(match_dup 2)
15680                                (match_dup 3)] UNSPEC_FYL2X))
15681               (clobber (match_scratch:XF 5 ""))])
15682    (set (match_operand:SF 0 "register_operand" "")
15683         (float_truncate:SF (match_dup 4)))]
15684   "TARGET_USE_FANCY_MATH_387
15685    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15686    && flag_unsafe_math_optimizations"
15687 {
15688   rtx temp;
15689
15690   operands[2] = gen_reg_rtx (XFmode);
15691   operands[3] = gen_reg_rtx (XFmode);
15692   operands[4] = gen_reg_rtx (XFmode);
15693
15694   temp = standard_80387_constant_rtx (4); /* fldln2 */
15695   emit_move_insn (operands[3], temp);
15696 })
15697
15698 (define_expand "logdf2"
15699   [(set (match_dup 2)
15700         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15701    (parallel [(set (match_dup 4)
15702                    (unspec:XF [(match_dup 2)
15703                                (match_dup 3)] UNSPEC_FYL2X))
15704               (clobber (match_scratch:XF 5 ""))])
15705    (set (match_operand:DF 0 "register_operand" "")
15706         (float_truncate:DF (match_dup 4)))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15709    && flag_unsafe_math_optimizations"
15710 {
15711   rtx temp;
15712
15713   operands[2] = gen_reg_rtx (XFmode);
15714   operands[3] = gen_reg_rtx (XFmode);
15715   operands[4] = gen_reg_rtx (XFmode);
15716
15717   temp = standard_80387_constant_rtx (4); /* fldln2 */
15718   emit_move_insn (operands[3], temp);
15719 })
15720
15721 (define_expand "logxf2"
15722   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15723                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15724                                (match_dup 2)] UNSPEC_FYL2X))
15725               (clobber (match_scratch:XF 3 ""))])]
15726   "TARGET_USE_FANCY_MATH_387
15727    && flag_unsafe_math_optimizations"
15728 {
15729   rtx temp;
15730
15731   operands[2] = gen_reg_rtx (XFmode);
15732   temp = standard_80387_constant_rtx (4); /* fldln2 */
15733   emit_move_insn (operands[2], temp);
15734 })
15735
15736 (define_expand "log10sf2"
15737   [(set (match_dup 2)
15738         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15739    (parallel [(set (match_dup 4)
15740                    (unspec:XF [(match_dup 2)
15741                                (match_dup 3)] UNSPEC_FYL2X))
15742               (clobber (match_scratch:XF 5 ""))])
15743    (set (match_operand:SF 0 "register_operand" "")
15744         (float_truncate:SF (match_dup 4)))]
15745   "TARGET_USE_FANCY_MATH_387
15746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15748 {
15749   rtx temp;
15750
15751   operands[2] = gen_reg_rtx (XFmode);
15752   operands[3] = gen_reg_rtx (XFmode);
15753   operands[4] = gen_reg_rtx (XFmode);
15754
15755   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15756   emit_move_insn (operands[3], temp);
15757 })
15758
15759 (define_expand "log10df2"
15760   [(set (match_dup 2)
15761         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15762    (parallel [(set (match_dup 4)
15763                    (unspec:XF [(match_dup 2)
15764                                (match_dup 3)] UNSPEC_FYL2X))
15765               (clobber (match_scratch:XF 5 ""))])
15766    (set (match_operand:DF 0 "register_operand" "")
15767         (float_truncate:DF (match_dup 4)))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations"
15771 {
15772   rtx temp;
15773
15774   operands[2] = gen_reg_rtx (XFmode);
15775   operands[3] = gen_reg_rtx (XFmode);
15776   operands[4] = gen_reg_rtx (XFmode);
15777
15778   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15779   emit_move_insn (operands[3], temp);
15780 })
15781
15782 (define_expand "log10xf2"
15783   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15784                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15785                                (match_dup 2)] UNSPEC_FYL2X))
15786               (clobber (match_scratch:XF 3 ""))])]
15787   "TARGET_USE_FANCY_MATH_387
15788    && flag_unsafe_math_optimizations"
15789 {
15790   rtx temp;
15791
15792   operands[2] = gen_reg_rtx (XFmode);
15793   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15794   emit_move_insn (operands[2], temp);
15795 })
15796
15797 (define_expand "log2sf2"
15798   [(set (match_dup 2)
15799         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15800    (parallel [(set (match_dup 4)
15801                    (unspec:XF [(match_dup 2)
15802                                (match_dup 3)] UNSPEC_FYL2X))
15803               (clobber (match_scratch:XF 5 ""))])
15804    (set (match_operand:SF 0 "register_operand" "")
15805         (float_truncate:SF (match_dup 4)))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15808    && flag_unsafe_math_optimizations"
15809 {
15810   operands[2] = gen_reg_rtx (XFmode);
15811   operands[3] = gen_reg_rtx (XFmode);
15812   operands[4] = gen_reg_rtx (XFmode);
15813
15814   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15815 })
15816
15817 (define_expand "log2df2"
15818   [(set (match_dup 2)
15819         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15820    (parallel [(set (match_dup 4)
15821                    (unspec:XF [(match_dup 2)
15822                                (match_dup 3)] UNSPEC_FYL2X))
15823               (clobber (match_scratch:XF 5 ""))])
15824    (set (match_operand:DF 0 "register_operand" "")
15825         (float_truncate:DF (match_dup 4)))]
15826   "TARGET_USE_FANCY_MATH_387
15827    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15828    && flag_unsafe_math_optimizations"
15829 {
15830   operands[2] = gen_reg_rtx (XFmode);
15831   operands[3] = gen_reg_rtx (XFmode);
15832   operands[4] = gen_reg_rtx (XFmode);
15833
15834   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15835 })
15836
15837 (define_expand "log2xf2"
15838   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15839                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15840                                (match_dup 2)] UNSPEC_FYL2X))
15841               (clobber (match_scratch:XF 3 ""))])]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15844 {
15845   operands[2] = gen_reg_rtx (XFmode);
15846   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15847 })
15848
15849 (define_insn "fyl2xp1_xf3"
15850   [(set (match_operand:XF 0 "register_operand" "=f")
15851         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15852                     (match_operand:XF 1 "register_operand" "u")]
15853                    UNSPEC_FYL2XP1))
15854    (clobber (match_scratch:XF 3 "=1"))]
15855   "TARGET_USE_FANCY_MATH_387
15856    && flag_unsafe_math_optimizations"
15857   "fyl2xp1"
15858   [(set_attr "type" "fpspc")
15859    (set_attr "mode" "XF")])
15860
15861 (define_expand "log1psf2"
15862   [(use (match_operand:SF 0 "register_operand" ""))
15863    (use (match_operand:SF 1 "register_operand" ""))]
15864   "TARGET_USE_FANCY_MATH_387
15865    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15866    && flag_unsafe_math_optimizations"
15867 {
15868   rtx op0 = gen_reg_rtx (XFmode);
15869   rtx op1 = gen_reg_rtx (XFmode);
15870
15871   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15872   ix86_emit_i387_log1p (op0, op1);
15873   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15874   DONE;
15875 })
15876
15877 (define_expand "log1pdf2"
15878   [(use (match_operand:DF 0 "register_operand" ""))
15879    (use (match_operand:DF 1 "register_operand" ""))]
15880   "TARGET_USE_FANCY_MATH_387
15881    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15882    && flag_unsafe_math_optimizations"
15883 {
15884   rtx op0 = gen_reg_rtx (XFmode);
15885   rtx op1 = gen_reg_rtx (XFmode);
15886
15887   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15888   ix86_emit_i387_log1p (op0, op1);
15889   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15890   DONE;
15891 })
15892
15893 (define_expand "log1pxf2"
15894   [(use (match_operand:XF 0 "register_operand" ""))
15895    (use (match_operand:XF 1 "register_operand" ""))]
15896   "TARGET_USE_FANCY_MATH_387
15897    && flag_unsafe_math_optimizations"
15898 {
15899   ix86_emit_i387_log1p (operands[0], operands[1]);
15900   DONE;
15901 })
15902
15903 (define_insn "*fxtractxf3"
15904   [(set (match_operand:XF 0 "register_operand" "=f")
15905         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15906                    UNSPEC_XTRACT_FRACT))
15907    (set (match_operand:XF 1 "register_operand" "=u")
15908         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && flag_unsafe_math_optimizations"
15911   "fxtract"
15912   [(set_attr "type" "fpspc")
15913    (set_attr "mode" "XF")])
15914
15915 (define_expand "logbsf2"
15916   [(set (match_dup 2)
15917         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15918    (parallel [(set (match_dup 3)
15919                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15920               (set (match_dup 4)
15921                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15922    (set (match_operand:SF 0 "register_operand" "")
15923         (float_truncate:SF (match_dup 4)))]
15924   "TARGET_USE_FANCY_MATH_387
15925    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15926    && flag_unsafe_math_optimizations"
15927 {
15928   operands[2] = gen_reg_rtx (XFmode);
15929   operands[3] = gen_reg_rtx (XFmode);
15930   operands[4] = gen_reg_rtx (XFmode);
15931 })
15932
15933 (define_expand "logbdf2"
15934   [(set (match_dup 2)
15935         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15936    (parallel [(set (match_dup 3)
15937                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15938               (set (match_dup 4)
15939                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15940    (set (match_operand:DF 0 "register_operand" "")
15941         (float_truncate:DF (match_dup 4)))]
15942   "TARGET_USE_FANCY_MATH_387
15943    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15944    && flag_unsafe_math_optimizations"
15945 {
15946   operands[2] = gen_reg_rtx (XFmode);
15947   operands[3] = gen_reg_rtx (XFmode);
15948   operands[4] = gen_reg_rtx (XFmode);
15949 })
15950
15951 (define_expand "logbxf2"
15952   [(parallel [(set (match_dup 2)
15953                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15954                               UNSPEC_XTRACT_FRACT))
15955               (set (match_operand:XF 0 "register_operand" "")
15956                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15957   "TARGET_USE_FANCY_MATH_387
15958    && flag_unsafe_math_optimizations"
15959 {
15960   operands[2] = gen_reg_rtx (XFmode);
15961 })
15962
15963 (define_expand "ilogbsi2"
15964   [(parallel [(set (match_dup 2)
15965                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15966                               UNSPEC_XTRACT_FRACT))
15967               (set (match_operand:XF 3 "register_operand" "")
15968                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15969    (parallel [(set (match_operand:SI 0 "register_operand" "")
15970                    (fix:SI (match_dup 3)))
15971               (clobber (reg:CC FLAGS_REG))])]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974    && flag_unsafe_math_optimizations"
15975 {
15976   operands[2] = gen_reg_rtx (XFmode);
15977   operands[3] = gen_reg_rtx (XFmode);
15978 })
15979
15980 (define_insn "*f2xm1xf2"
15981   [(set (match_operand:XF 0 "register_operand" "=f")
15982         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15983          UNSPEC_F2XM1))]
15984   "TARGET_USE_FANCY_MATH_387
15985    && flag_unsafe_math_optimizations"
15986   "f2xm1"
15987   [(set_attr "type" "fpspc")
15988    (set_attr "mode" "XF")])
15989
15990 (define_insn "*fscalexf4"
15991   [(set (match_operand:XF 0 "register_operand" "=f")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15993                     (match_operand:XF 3 "register_operand" "1")]
15994                    UNSPEC_FSCALE_FRACT))
15995    (set (match_operand:XF 1 "register_operand" "=u")
15996         (unspec:XF [(match_dup 2) (match_dup 3)]
15997                    UNSPEC_FSCALE_EXP))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16000   "fscale"
16001   [(set_attr "type" "fpspc")
16002    (set_attr "mode" "XF")])
16003
16004 (define_expand "expsf2"
16005   [(set (match_dup 2)
16006         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16007    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16008    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16009    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16010    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16011    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16012    (parallel [(set (match_dup 10)
16013                    (unspec:XF [(match_dup 9) (match_dup 5)]
16014                               UNSPEC_FSCALE_FRACT))
16015               (set (match_dup 11)
16016                    (unspec:XF [(match_dup 9) (match_dup 5)]
16017                               UNSPEC_FSCALE_EXP))])
16018    (set (match_operand:SF 0 "register_operand" "")
16019         (float_truncate:SF (match_dup 10)))]
16020   "TARGET_USE_FANCY_MATH_387
16021    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16022    && flag_unsafe_math_optimizations"
16023 {
16024   rtx temp;
16025   int i;
16026
16027   for (i=2; i<12; i++)
16028     operands[i] = gen_reg_rtx (XFmode);
16029   temp = standard_80387_constant_rtx (5); /* fldl2e */
16030   emit_move_insn (operands[3], temp);
16031   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16032 })
16033
16034 (define_expand "expdf2"
16035   [(set (match_dup 2)
16036         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16037    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16038    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16039    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16040    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16041    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16042    (parallel [(set (match_dup 10)
16043                    (unspec:XF [(match_dup 9) (match_dup 5)]
16044                               UNSPEC_FSCALE_FRACT))
16045               (set (match_dup 11)
16046                    (unspec:XF [(match_dup 9) (match_dup 5)]
16047                               UNSPEC_FSCALE_EXP))])
16048    (set (match_operand:DF 0 "register_operand" "")
16049         (float_truncate:DF (match_dup 10)))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052    && flag_unsafe_math_optimizations"
16053 {
16054   rtx temp;
16055   int i;
16056
16057   for (i=2; i<12; i++)
16058     operands[i] = gen_reg_rtx (XFmode);
16059   temp = standard_80387_constant_rtx (5); /* fldl2e */
16060   emit_move_insn (operands[3], temp);
16061   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16062 })
16063
16064 (define_expand "expxf2"
16065   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16066                                (match_dup 2)))
16067    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16068    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16069    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16070    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16071    (parallel [(set (match_operand:XF 0 "register_operand" "")
16072                    (unspec:XF [(match_dup 8) (match_dup 4)]
16073                               UNSPEC_FSCALE_FRACT))
16074               (set (match_dup 9)
16075                    (unspec:XF [(match_dup 8) (match_dup 4)]
16076                               UNSPEC_FSCALE_EXP))])]
16077   "TARGET_USE_FANCY_MATH_387
16078    && flag_unsafe_math_optimizations"
16079 {
16080   rtx temp;
16081   int i;
16082
16083   for (i=2; i<10; i++)
16084     operands[i] = gen_reg_rtx (XFmode);
16085   temp = standard_80387_constant_rtx (5); /* fldl2e */
16086   emit_move_insn (operands[2], temp);
16087   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16088 })
16089
16090 (define_expand "exp10sf2"
16091   [(set (match_dup 2)
16092         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16093    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16094    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16095    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16096    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16097    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16098    (parallel [(set (match_dup 10)
16099                    (unspec:XF [(match_dup 9) (match_dup 5)]
16100                               UNSPEC_FSCALE_FRACT))
16101               (set (match_dup 11)
16102                    (unspec:XF [(match_dup 9) (match_dup 5)]
16103                               UNSPEC_FSCALE_EXP))])
16104    (set (match_operand:SF 0 "register_operand" "")
16105         (float_truncate:SF (match_dup 10)))]
16106   "TARGET_USE_FANCY_MATH_387
16107    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16108    && flag_unsafe_math_optimizations"
16109 {
16110   rtx temp;
16111   int i;
16112
16113   for (i=2; i<12; i++)
16114     operands[i] = gen_reg_rtx (XFmode);
16115   temp = standard_80387_constant_rtx (6); /* fldl2t */
16116   emit_move_insn (operands[3], temp);
16117   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16118 })
16119
16120 (define_expand "exp10df2"
16121   [(set (match_dup 2)
16122         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16123    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16124    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16125    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16126    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16127    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16128    (parallel [(set (match_dup 10)
16129                    (unspec:XF [(match_dup 9) (match_dup 5)]
16130                               UNSPEC_FSCALE_FRACT))
16131               (set (match_dup 11)
16132                    (unspec:XF [(match_dup 9) (match_dup 5)]
16133                               UNSPEC_FSCALE_EXP))])
16134    (set (match_operand:DF 0 "register_operand" "")
16135         (float_truncate:DF (match_dup 10)))]
16136   "TARGET_USE_FANCY_MATH_387
16137    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16139 {
16140   rtx temp;
16141   int i;
16142
16143   for (i=2; i<12; i++)
16144     operands[i] = gen_reg_rtx (XFmode);
16145   temp = standard_80387_constant_rtx (6); /* fldl2t */
16146   emit_move_insn (operands[3], temp);
16147   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16148 })
16149
16150 (define_expand "exp10xf2"
16151   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16152                                (match_dup 2)))
16153    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16154    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16155    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16156    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16157    (parallel [(set (match_operand:XF 0 "register_operand" "")
16158                    (unspec:XF [(match_dup 8) (match_dup 4)]
16159                               UNSPEC_FSCALE_FRACT))
16160               (set (match_dup 9)
16161                    (unspec:XF [(match_dup 8) (match_dup 4)]
16162                               UNSPEC_FSCALE_EXP))])]
16163   "TARGET_USE_FANCY_MATH_387
16164    && flag_unsafe_math_optimizations"
16165 {
16166   rtx temp;
16167   int i;
16168
16169   for (i=2; i<10; i++)
16170     operands[i] = gen_reg_rtx (XFmode);
16171   temp = standard_80387_constant_rtx (6); /* fldl2t */
16172   emit_move_insn (operands[2], temp);
16173   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16174 })
16175
16176 (define_expand "exp2sf2"
16177   [(set (match_dup 2)
16178         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16179    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16180    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16181    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16182    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16183    (parallel [(set (match_dup 8)
16184                    (unspec:XF [(match_dup 7) (match_dup 3)]
16185                               UNSPEC_FSCALE_FRACT))
16186               (set (match_dup 9)
16187                    (unspec:XF [(match_dup 7) (match_dup 3)]
16188                               UNSPEC_FSCALE_EXP))])
16189    (set (match_operand:SF 0 "register_operand" "")
16190         (float_truncate:SF (match_dup 8)))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16193    && flag_unsafe_math_optimizations"
16194 {
16195   int i;
16196
16197   for (i=2; i<10; i++)
16198     operands[i] = gen_reg_rtx (XFmode);
16199   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16200 })
16201
16202 (define_expand "exp2df2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16206    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16207    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16208    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16209    (parallel [(set (match_dup 8)
16210                    (unspec:XF [(match_dup 7) (match_dup 3)]
16211                               UNSPEC_FSCALE_FRACT))
16212               (set (match_dup 9)
16213                    (unspec:XF [(match_dup 7) (match_dup 3)]
16214                               UNSPEC_FSCALE_EXP))])
16215    (set (match_operand:DF 0 "register_operand" "")
16216         (float_truncate:DF (match_dup 8)))]
16217   "TARGET_USE_FANCY_MATH_387
16218    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16219    && flag_unsafe_math_optimizations"
16220 {
16221   int i;
16222
16223   for (i=2; i<10; i++)
16224     operands[i] = gen_reg_rtx (XFmode);
16225   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16226 })
16227
16228 (define_expand "exp2xf2"
16229   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16230    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16231    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16232    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16233    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16234    (parallel [(set (match_operand:XF 0 "register_operand" "")
16235                    (unspec:XF [(match_dup 7) (match_dup 3)]
16236                               UNSPEC_FSCALE_FRACT))
16237               (set (match_dup 8)
16238                    (unspec:XF [(match_dup 7) (match_dup 3)]
16239                               UNSPEC_FSCALE_EXP))])]
16240   "TARGET_USE_FANCY_MATH_387
16241    && flag_unsafe_math_optimizations"
16242 {
16243   int i;
16244
16245   for (i=2; i<9; i++)
16246     operands[i] = gen_reg_rtx (XFmode);
16247   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16248 })
16249
16250 (define_expand "expm1df2"
16251   [(set (match_dup 2)
16252         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16254    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16255    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16256    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16257    (parallel [(set (match_dup 8)
16258                    (unspec:XF [(match_dup 7) (match_dup 5)]
16259                               UNSPEC_FSCALE_FRACT))
16260                    (set (match_dup 9)
16261                    (unspec:XF [(match_dup 7) (match_dup 5)]
16262                               UNSPEC_FSCALE_EXP))])
16263    (parallel [(set (match_dup 11)
16264                    (unspec:XF [(match_dup 10) (match_dup 9)]
16265                               UNSPEC_FSCALE_FRACT))
16266               (set (match_dup 12)
16267                    (unspec:XF [(match_dup 10) (match_dup 9)]
16268                               UNSPEC_FSCALE_EXP))])
16269    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16270    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16271    (set (match_operand:DF 0 "register_operand" "")
16272         (float_truncate:DF (match_dup 14)))]
16273   "TARGET_USE_FANCY_MATH_387
16274    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16275    && flag_unsafe_math_optimizations"
16276 {
16277   rtx temp;
16278   int i;
16279
16280   for (i=2; i<15; i++)
16281     operands[i] = gen_reg_rtx (XFmode);
16282   temp = standard_80387_constant_rtx (5); /* fldl2e */
16283   emit_move_insn (operands[3], temp);
16284   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16285 })
16286
16287 (define_expand "expm1sf2"
16288   [(set (match_dup 2)
16289         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16290    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16291    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16292    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16293    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16294    (parallel [(set (match_dup 8)
16295                    (unspec:XF [(match_dup 7) (match_dup 5)]
16296                               UNSPEC_FSCALE_FRACT))
16297                    (set (match_dup 9)
16298                    (unspec:XF [(match_dup 7) (match_dup 5)]
16299                               UNSPEC_FSCALE_EXP))])
16300    (parallel [(set (match_dup 11)
16301                    (unspec:XF [(match_dup 10) (match_dup 9)]
16302                               UNSPEC_FSCALE_FRACT))
16303               (set (match_dup 12)
16304                    (unspec:XF [(match_dup 10) (match_dup 9)]
16305                               UNSPEC_FSCALE_EXP))])
16306    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16307    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16308    (set (match_operand:SF 0 "register_operand" "")
16309         (float_truncate:SF (match_dup 14)))]
16310   "TARGET_USE_FANCY_MATH_387
16311    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312    && flag_unsafe_math_optimizations"
16313 {
16314   rtx temp;
16315   int i;
16316
16317   for (i=2; i<15; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319   temp = standard_80387_constant_rtx (5); /* fldl2e */
16320   emit_move_insn (operands[3], temp);
16321   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16322 })
16323
16324 (define_expand "expm1xf2"
16325   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16326                                (match_dup 2)))
16327    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16328    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16329    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16330    (parallel [(set (match_dup 7)
16331                    (unspec:XF [(match_dup 6) (match_dup 4)]
16332                               UNSPEC_FSCALE_FRACT))
16333                    (set (match_dup 8)
16334                    (unspec:XF [(match_dup 6) (match_dup 4)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (parallel [(set (match_dup 10)
16337                    (unspec:XF [(match_dup 9) (match_dup 8)]
16338                               UNSPEC_FSCALE_FRACT))
16339               (set (match_dup 11)
16340                    (unspec:XF [(match_dup 9) (match_dup 8)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16343    (set (match_operand:XF 0 "register_operand" "")
16344         (plus:XF (match_dup 12) (match_dup 7)))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && flag_unsafe_math_optimizations"
16347 {
16348   rtx temp;
16349   int i;
16350
16351   for (i=2; i<13; i++)
16352     operands[i] = gen_reg_rtx (XFmode);
16353   temp = standard_80387_constant_rtx (5); /* fldl2e */
16354   emit_move_insn (operands[2], temp);
16355   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16356 })
16357
16358 (define_expand "ldexpdf3"
16359   [(set (match_dup 3)
16360         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16361    (set (match_dup 4)
16362         (float:XF (match_operand:SI 2 "register_operand" "")))
16363    (parallel [(set (match_dup 5)
16364                    (unspec:XF [(match_dup 3) (match_dup 4)]
16365                               UNSPEC_FSCALE_FRACT))
16366               (set (match_dup 6)
16367                    (unspec:XF [(match_dup 3) (match_dup 4)]
16368                               UNSPEC_FSCALE_EXP))])
16369    (set (match_operand:DF 0 "register_operand" "")
16370         (float_truncate:DF (match_dup 5)))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16373    && flag_unsafe_math_optimizations"
16374 {
16375   int i;
16376
16377   for (i=3; i<7; i++)
16378     operands[i] = gen_reg_rtx (XFmode);
16379 })
16380
16381 (define_expand "ldexpsf3"
16382   [(set (match_dup 3)
16383         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16384    (set (match_dup 4)
16385         (float:XF (match_operand:SI 2 "register_operand" "")))
16386    (parallel [(set (match_dup 5)
16387                    (unspec:XF [(match_dup 3) (match_dup 4)]
16388                               UNSPEC_FSCALE_FRACT))
16389               (set (match_dup 6)
16390                    (unspec:XF [(match_dup 3) (match_dup 4)]
16391                               UNSPEC_FSCALE_EXP))])
16392    (set (match_operand:SF 0 "register_operand" "")
16393         (float_truncate:SF (match_dup 5)))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16397 {
16398   int i;
16399
16400   for (i=3; i<7; i++)
16401     operands[i] = gen_reg_rtx (XFmode);
16402 })
16403
16404 (define_expand "ldexpxf3"
16405   [(set (match_dup 3)
16406         (float:XF (match_operand:SI 2 "register_operand" "")))
16407    (parallel [(set (match_operand:XF 0 " register_operand" "")
16408                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16409                                (match_dup 3)]
16410                               UNSPEC_FSCALE_FRACT))
16411               (set (match_dup 4)
16412                    (unspec:XF [(match_dup 1) (match_dup 3)]
16413                               UNSPEC_FSCALE_EXP))])]
16414   "TARGET_USE_FANCY_MATH_387
16415    && flag_unsafe_math_optimizations"
16416 {
16417   int i;
16418
16419   for (i=3; i<5; i++)
16420     operands[i] = gen_reg_rtx (XFmode);
16421 })
16422 \f
16423
16424 (define_insn "frndintxf2"
16425   [(set (match_operand:XF 0 "register_operand" "=f")
16426         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16427          UNSPEC_FRNDINT))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16430   "frndint"
16431   [(set_attr "type" "fpspc")
16432    (set_attr "mode" "XF")])
16433
16434 (define_expand "rintdf2"
16435   [(use (match_operand:DF 0 "register_operand" ""))
16436    (use (match_operand:DF 1 "register_operand" ""))]
16437   "TARGET_USE_FANCY_MATH_387
16438    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16439    && flag_unsafe_math_optimizations"
16440 {
16441   rtx op0 = gen_reg_rtx (XFmode);
16442   rtx op1 = gen_reg_rtx (XFmode);
16443
16444   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16445   emit_insn (gen_frndintxf2 (op0, op1));
16446
16447   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16448   DONE;
16449 })
16450
16451 (define_expand "rintsf2"
16452   [(use (match_operand:SF 0 "register_operand" ""))
16453    (use (match_operand:SF 1 "register_operand" ""))]
16454   "TARGET_USE_FANCY_MATH_387
16455    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16456    && flag_unsafe_math_optimizations"
16457 {
16458   rtx op0 = gen_reg_rtx (XFmode);
16459   rtx op1 = gen_reg_rtx (XFmode);
16460
16461   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16462   emit_insn (gen_frndintxf2 (op0, op1));
16463
16464   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16465   DONE;
16466 })
16467
16468 (define_expand "rintxf2"
16469   [(use (match_operand:XF 0 "register_operand" ""))
16470    (use (match_operand:XF 1 "register_operand" ""))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && flag_unsafe_math_optimizations"
16473 {
16474   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16475   DONE;
16476 })
16477
16478 (define_insn_and_split "*fist<mode>2_1"
16479   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16480         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16481          UNSPEC_FIST))]
16482   "TARGET_USE_FANCY_MATH_387
16483    && flag_unsafe_math_optimizations
16484    && !(reload_completed || reload_in_progress)"
16485   "#"
16486   "&& 1"
16487   [(const_int 0)]
16488 {
16489   if (memory_operand (operands[0], VOIDmode))
16490     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16491   else
16492     {
16493       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16494       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16495                                             operands[2]));
16496     }
16497   DONE;
16498 }
16499   [(set_attr "type" "fpspc")
16500    (set_attr "mode" "<MODE>")])
16501
16502 (define_insn "fistdi2"
16503   [(set (match_operand:DI 0 "memory_operand" "=m")
16504         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16505          UNSPEC_FIST))
16506    (clobber (match_scratch:XF 2 "=&1f"))]
16507   "TARGET_USE_FANCY_MATH_387
16508    && flag_unsafe_math_optimizations"
16509   "* return output_fix_trunc (insn, operands, 0);"
16510   [(set_attr "type" "fpspc")
16511    (set_attr "mode" "DI")])
16512
16513 (define_insn "fistdi2_with_temp"
16514   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16515         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16516          UNSPEC_FIST))
16517    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16519   "TARGET_USE_FANCY_MATH_387
16520    && flag_unsafe_math_optimizations"
16521   "#"
16522   [(set_attr "type" "fpspc")
16523    (set_attr "mode" "DI")])
16524
16525 (define_split 
16526   [(set (match_operand:DI 0 "register_operand" "")
16527         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16528          UNSPEC_FIST))
16529    (clobber (match_operand:DI 2 "memory_operand" ""))
16530    (clobber (match_scratch 3 ""))]
16531   "reload_completed"
16532   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16533               (clobber (match_dup 3))])
16534    (set (match_dup 0) (match_dup 2))]
16535   "")
16536
16537 (define_split 
16538   [(set (match_operand:DI 0 "memory_operand" "")
16539         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16540          UNSPEC_FIST))
16541    (clobber (match_operand:DI 2 "memory_operand" ""))
16542    (clobber (match_scratch 3 ""))]
16543   "reload_completed"
16544   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16545               (clobber (match_dup 3))])]
16546   "")
16547
16548 (define_insn "fist<mode>2"
16549   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16550         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16551          UNSPEC_FIST))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && flag_unsafe_math_optimizations"
16554   "* return output_fix_trunc (insn, operands, 0);"
16555   [(set_attr "type" "fpspc")
16556    (set_attr "mode" "<MODE>")])
16557
16558 (define_insn "fist<mode>2_with_temp"
16559   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16560         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16561          UNSPEC_FIST))
16562    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16563   "TARGET_USE_FANCY_MATH_387
16564    && flag_unsafe_math_optimizations"
16565   "#"
16566   [(set_attr "type" "fpspc")
16567    (set_attr "mode" "<MODE>")])
16568
16569 (define_split 
16570   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16571         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16572          UNSPEC_FIST))
16573    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16574   "reload_completed"
16575   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16576                        UNSPEC_FIST))
16577    (set (match_dup 0) (match_dup 2))]
16578   "")
16579
16580 (define_split 
16581   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16582         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16583          UNSPEC_FIST))
16584    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16585   "reload_completed"
16586   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16587                        UNSPEC_FIST))]
16588   "")
16589
16590 (define_expand "lrint<mode>2"
16591   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16592         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16593          UNSPEC_FIST))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16596    && flag_unsafe_math_optimizations"
16597   "")
16598
16599 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16600 (define_insn_and_split "frndintxf2_floor"
16601   [(set (match_operand:XF 0 "register_operand" "=f")
16602         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16603          UNSPEC_FRNDINT_FLOOR))
16604    (clobber (reg:CC FLAGS_REG))]
16605   "TARGET_USE_FANCY_MATH_387
16606    && flag_unsafe_math_optimizations
16607    && !(reload_completed || reload_in_progress)"
16608   "#"
16609   "&& 1"
16610   [(const_int 0)]
16611 {
16612   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16613
16614   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16615   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16616
16617   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16618                                         operands[2], operands[3]));
16619   DONE;
16620 }
16621   [(set_attr "type" "frndint")
16622    (set_attr "i387_cw" "floor")
16623    (set_attr "mode" "XF")])
16624
16625 (define_insn "frndintxf2_floor_i387"
16626   [(set (match_operand:XF 0 "register_operand" "=f")
16627         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16628          UNSPEC_FRNDINT_FLOOR))
16629    (use (match_operand:HI 2 "memory_operand" "m"))
16630    (use (match_operand:HI 3 "memory_operand" "m"))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && flag_unsafe_math_optimizations"
16633   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16634   [(set_attr "type" "frndint")
16635    (set_attr "i387_cw" "floor")
16636    (set_attr "mode" "XF")])
16637
16638 (define_expand "floorxf2"
16639   [(use (match_operand:XF 0 "register_operand" ""))
16640    (use (match_operand:XF 1 "register_operand" ""))]
16641   "TARGET_USE_FANCY_MATH_387
16642    && flag_unsafe_math_optimizations"
16643 {
16644   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16645   DONE;
16646 })
16647
16648 (define_expand "floordf2"
16649   [(use (match_operand:DF 0 "register_operand" ""))
16650    (use (match_operand:DF 1 "register_operand" ""))]
16651   "TARGET_USE_FANCY_MATH_387
16652    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16653    && flag_unsafe_math_optimizations"
16654 {
16655   rtx op0 = gen_reg_rtx (XFmode);
16656   rtx op1 = gen_reg_rtx (XFmode);
16657
16658   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16659   emit_insn (gen_frndintxf2_floor (op0, op1));
16660
16661   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16662   DONE;
16663 })
16664
16665 (define_expand "floorsf2"
16666   [(use (match_operand:SF 0 "register_operand" ""))
16667    (use (match_operand:SF 1 "register_operand" ""))]
16668   "TARGET_USE_FANCY_MATH_387
16669    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations"
16671 {
16672   rtx op0 = gen_reg_rtx (XFmode);
16673   rtx op1 = gen_reg_rtx (XFmode);
16674
16675   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16676   emit_insn (gen_frndintxf2_floor (op0, op1));
16677
16678   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16679   DONE;
16680 })
16681
16682 (define_insn_and_split "*fist<mode>2_floor_1"
16683   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16684         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16685          UNSPEC_FIST_FLOOR))
16686    (clobber (reg:CC FLAGS_REG))]
16687   "TARGET_USE_FANCY_MATH_387
16688    && flag_unsafe_math_optimizations
16689    && !(reload_completed || reload_in_progress)"
16690   "#"
16691   "&& 1"
16692   [(const_int 0)]
16693 {
16694   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16695
16696   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16697   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16698   if (memory_operand (operands[0], VOIDmode))
16699     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16700                                       operands[2], operands[3]));
16701   else
16702     {
16703       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16704       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16705                                                   operands[2], operands[3],
16706                                                   operands[4]));
16707     }
16708   DONE;
16709 }
16710   [(set_attr "type" "fistp")
16711    (set_attr "i387_cw" "floor")
16712    (set_attr "mode" "<MODE>")])
16713
16714 (define_insn "fistdi2_floor"
16715   [(set (match_operand:DI 0 "memory_operand" "=m")
16716         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16717          UNSPEC_FIST_FLOOR))
16718    (use (match_operand:HI 2 "memory_operand" "m"))
16719    (use (match_operand:HI 3 "memory_operand" "m"))
16720    (clobber (match_scratch:XF 4 "=&1f"))]
16721   "TARGET_USE_FANCY_MATH_387
16722    && flag_unsafe_math_optimizations"
16723   "* return output_fix_trunc (insn, operands, 0);"
16724   [(set_attr "type" "fistp")
16725    (set_attr "i387_cw" "floor")
16726    (set_attr "mode" "DI")])
16727
16728 (define_insn "fistdi2_floor_with_temp"
16729   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16730         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16731          UNSPEC_FIST_FLOOR))
16732    (use (match_operand:HI 2 "memory_operand" "m,m"))
16733    (use (match_operand:HI 3 "memory_operand" "m,m"))
16734    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16735    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16736   "TARGET_USE_FANCY_MATH_387
16737    && flag_unsafe_math_optimizations"
16738   "#"
16739   [(set_attr "type" "fistp")
16740    (set_attr "i387_cw" "floor")
16741    (set_attr "mode" "DI")])
16742
16743 (define_split 
16744   [(set (match_operand:DI 0 "register_operand" "")
16745         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16746          UNSPEC_FIST_FLOOR))
16747    (use (match_operand:HI 2 "memory_operand" ""))
16748    (use (match_operand:HI 3 "memory_operand" ""))
16749    (clobber (match_operand:DI 4 "memory_operand" ""))
16750    (clobber (match_scratch 5 ""))]
16751   "reload_completed"
16752   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16753               (use (match_dup 2))
16754               (use (match_dup 3))
16755               (clobber (match_dup 5))])
16756    (set (match_dup 0) (match_dup 4))]
16757   "")
16758
16759 (define_split 
16760   [(set (match_operand:DI 0 "memory_operand" "")
16761         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16762          UNSPEC_FIST_FLOOR))
16763    (use (match_operand:HI 2 "memory_operand" ""))
16764    (use (match_operand:HI 3 "memory_operand" ""))
16765    (clobber (match_operand:DI 4 "memory_operand" ""))
16766    (clobber (match_scratch 5 ""))]
16767   "reload_completed"
16768   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16769               (use (match_dup 2))
16770               (use (match_dup 3))
16771               (clobber (match_dup 5))])]
16772   "")
16773
16774 (define_insn "fist<mode>2_floor"
16775   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16777          UNSPEC_FIST_FLOOR))
16778    (use (match_operand:HI 2 "memory_operand" "m"))
16779    (use (match_operand:HI 3 "memory_operand" "m"))]
16780   "TARGET_USE_FANCY_MATH_387
16781    && flag_unsafe_math_optimizations"
16782   "* return output_fix_trunc (insn, operands, 0);"
16783   [(set_attr "type" "fistp")
16784    (set_attr "i387_cw" "floor")
16785    (set_attr "mode" "<MODE>")])
16786
16787 (define_insn "fist<mode>2_floor_with_temp"
16788   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16789         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16790          UNSPEC_FIST_FLOOR))
16791    (use (match_operand:HI 2 "memory_operand" "m,m"))
16792    (use (match_operand:HI 3 "memory_operand" "m,m"))
16793    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16794   "TARGET_USE_FANCY_MATH_387
16795    && flag_unsafe_math_optimizations"
16796   "#"
16797   [(set_attr "type" "fistp")
16798    (set_attr "i387_cw" "floor")
16799    (set_attr "mode" "<MODE>")])
16800
16801 (define_split 
16802   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16803         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16804          UNSPEC_FIST_FLOOR))
16805    (use (match_operand:HI 2 "memory_operand" ""))
16806    (use (match_operand:HI 3 "memory_operand" ""))
16807    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16808   "reload_completed"
16809   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16810                                   UNSPEC_FIST_FLOOR))
16811               (use (match_dup 2))
16812               (use (match_dup 3))])
16813    (set (match_dup 0) (match_dup 4))]
16814   "")
16815
16816 (define_split 
16817   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16818         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16819          UNSPEC_FIST_FLOOR))
16820    (use (match_operand:HI 2 "memory_operand" ""))
16821    (use (match_operand:HI 3 "memory_operand" ""))
16822    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16823   "reload_completed"
16824   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16825                                   UNSPEC_FIST_FLOOR))
16826               (use (match_dup 2))
16827               (use (match_dup 3))])]
16828   "")
16829
16830 (define_expand "lfloor<mode>2"
16831   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16832                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16833                     UNSPEC_FIST_FLOOR))
16834               (clobber (reg:CC FLAGS_REG))])]
16835   "TARGET_USE_FANCY_MATH_387
16836    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16837    && flag_unsafe_math_optimizations"
16838   "")
16839
16840 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16841 (define_insn_and_split "frndintxf2_ceil"
16842   [(set (match_operand:XF 0 "register_operand" "=f")
16843         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16844          UNSPEC_FRNDINT_CEIL))
16845    (clobber (reg:CC FLAGS_REG))]
16846   "TARGET_USE_FANCY_MATH_387
16847    && flag_unsafe_math_optimizations
16848    && !(reload_completed || reload_in_progress)"
16849   "#"
16850   "&& 1"
16851   [(const_int 0)]
16852 {
16853   ix86_optimize_mode_switching[I387_CEIL] = 1;
16854
16855   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16856   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16857
16858   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16859                                        operands[2], operands[3]));
16860   DONE;
16861 }
16862   [(set_attr "type" "frndint")
16863    (set_attr "i387_cw" "ceil")
16864    (set_attr "mode" "XF")])
16865
16866 (define_insn "frndintxf2_ceil_i387"
16867   [(set (match_operand:XF 0 "register_operand" "=f")
16868         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16869          UNSPEC_FRNDINT_CEIL))
16870    (use (match_operand:HI 2 "memory_operand" "m"))
16871    (use (match_operand:HI 3 "memory_operand" "m"))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations"
16874   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16875   [(set_attr "type" "frndint")
16876    (set_attr "i387_cw" "ceil")
16877    (set_attr "mode" "XF")])
16878
16879 (define_expand "ceilxf2"
16880   [(use (match_operand:XF 0 "register_operand" ""))
16881    (use (match_operand:XF 1 "register_operand" ""))]
16882   "TARGET_USE_FANCY_MATH_387
16883    && flag_unsafe_math_optimizations"
16884 {
16885   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16886   DONE;
16887 })
16888
16889 (define_expand "ceildf2"
16890   [(use (match_operand:DF 0 "register_operand" ""))
16891    (use (match_operand:DF 1 "register_operand" ""))]
16892   "TARGET_USE_FANCY_MATH_387
16893    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16894    && flag_unsafe_math_optimizations"
16895 {
16896   rtx op0 = gen_reg_rtx (XFmode);
16897   rtx op1 = gen_reg_rtx (XFmode);
16898
16899   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16900   emit_insn (gen_frndintxf2_ceil (op0, op1));
16901
16902   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16903   DONE;
16904 })
16905
16906 (define_expand "ceilsf2"
16907   [(use (match_operand:SF 0 "register_operand" ""))
16908    (use (match_operand:SF 1 "register_operand" ""))]
16909   "TARGET_USE_FANCY_MATH_387
16910    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911    && flag_unsafe_math_optimizations"
16912 {
16913   rtx op0 = gen_reg_rtx (XFmode);
16914   rtx op1 = gen_reg_rtx (XFmode);
16915
16916   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16917   emit_insn (gen_frndintxf2_ceil (op0, op1));
16918
16919   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16920   DONE;
16921 })
16922
16923 (define_insn_and_split "*fist<mode>2_ceil_1"
16924   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16925         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16926          UNSPEC_FIST_CEIL))
16927    (clobber (reg:CC FLAGS_REG))]
16928   "TARGET_USE_FANCY_MATH_387
16929    && flag_unsafe_math_optimizations
16930    && !(reload_completed || reload_in_progress)"
16931   "#"
16932   "&& 1"
16933   [(const_int 0)]
16934 {
16935   ix86_optimize_mode_switching[I387_CEIL] = 1;
16936
16937   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16938   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16939   if (memory_operand (operands[0], VOIDmode))
16940     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16941                                      operands[2], operands[3]));
16942   else
16943     {
16944       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16945       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16946                                                  operands[2], operands[3],
16947                                                  operands[4]));
16948     }
16949   DONE;
16950 }
16951   [(set_attr "type" "fistp")
16952    (set_attr "i387_cw" "ceil")
16953    (set_attr "mode" "<MODE>")])
16954
16955 (define_insn "fistdi2_ceil"
16956   [(set (match_operand:DI 0 "memory_operand" "=m")
16957         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16958          UNSPEC_FIST_CEIL))
16959    (use (match_operand:HI 2 "memory_operand" "m"))
16960    (use (match_operand:HI 3 "memory_operand" "m"))
16961    (clobber (match_scratch:XF 4 "=&1f"))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && flag_unsafe_math_optimizations"
16964   "* return output_fix_trunc (insn, operands, 0);"
16965   [(set_attr "type" "fistp")
16966    (set_attr "i387_cw" "ceil")
16967    (set_attr "mode" "DI")])
16968
16969 (define_insn "fistdi2_ceil_with_temp"
16970   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16971         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16972          UNSPEC_FIST_CEIL))
16973    (use (match_operand:HI 2 "memory_operand" "m,m"))
16974    (use (match_operand:HI 3 "memory_operand" "m,m"))
16975    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16976    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16977   "TARGET_USE_FANCY_MATH_387
16978    && flag_unsafe_math_optimizations"
16979   "#"
16980   [(set_attr "type" "fistp")
16981    (set_attr "i387_cw" "ceil")
16982    (set_attr "mode" "DI")])
16983
16984 (define_split 
16985   [(set (match_operand:DI 0 "register_operand" "")
16986         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16987          UNSPEC_FIST_CEIL))
16988    (use (match_operand:HI 2 "memory_operand" ""))
16989    (use (match_operand:HI 3 "memory_operand" ""))
16990    (clobber (match_operand:DI 4 "memory_operand" ""))
16991    (clobber (match_scratch 5 ""))]
16992   "reload_completed"
16993   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16994               (use (match_dup 2))
16995               (use (match_dup 3))
16996               (clobber (match_dup 5))])
16997    (set (match_dup 0) (match_dup 4))]
16998   "")
16999
17000 (define_split 
17001   [(set (match_operand:DI 0 "memory_operand" "")
17002         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17003          UNSPEC_FIST_CEIL))
17004    (use (match_operand:HI 2 "memory_operand" ""))
17005    (use (match_operand:HI 3 "memory_operand" ""))
17006    (clobber (match_operand:DI 4 "memory_operand" ""))
17007    (clobber (match_scratch 5 ""))]
17008   "reload_completed"
17009   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17010               (use (match_dup 2))
17011               (use (match_dup 3))
17012               (clobber (match_dup 5))])]
17013   "")
17014
17015 (define_insn "fist<mode>2_ceil"
17016   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17017         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17018          UNSPEC_FIST_CEIL))
17019    (use (match_operand:HI 2 "memory_operand" "m"))
17020    (use (match_operand:HI 3 "memory_operand" "m"))]
17021   "TARGET_USE_FANCY_MATH_387
17022    && flag_unsafe_math_optimizations"
17023   "* return output_fix_trunc (insn, operands, 0);"
17024   [(set_attr "type" "fistp")
17025    (set_attr "i387_cw" "ceil")
17026    (set_attr "mode" "<MODE>")])
17027
17028 (define_insn "fist<mode>2_ceil_with_temp"
17029   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17030         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17031          UNSPEC_FIST_CEIL))
17032    (use (match_operand:HI 2 "memory_operand" "m,m"))
17033    (use (match_operand:HI 3 "memory_operand" "m,m"))
17034    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17035   "TARGET_USE_FANCY_MATH_387
17036    && flag_unsafe_math_optimizations"
17037   "#"
17038   [(set_attr "type" "fistp")
17039    (set_attr "i387_cw" "ceil")
17040    (set_attr "mode" "<MODE>")])
17041
17042 (define_split 
17043   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17044         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17045          UNSPEC_FIST_CEIL))
17046    (use (match_operand:HI 2 "memory_operand" ""))
17047    (use (match_operand:HI 3 "memory_operand" ""))
17048    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17049   "reload_completed"
17050   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17051                                   UNSPEC_FIST_CEIL))
17052               (use (match_dup 2))
17053               (use (match_dup 3))])
17054    (set (match_dup 0) (match_dup 4))]
17055   "")
17056
17057 (define_split 
17058   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17059         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17060          UNSPEC_FIST_CEIL))
17061    (use (match_operand:HI 2 "memory_operand" ""))
17062    (use (match_operand:HI 3 "memory_operand" ""))
17063    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17064   "reload_completed"
17065   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17066                                   UNSPEC_FIST_CEIL))
17067               (use (match_dup 2))
17068               (use (match_dup 3))])]
17069   "")
17070
17071 (define_expand "lceil<mode>2"
17072   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17073                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17074                     UNSPEC_FIST_CEIL))
17075               (clobber (reg:CC FLAGS_REG))])]
17076   "TARGET_USE_FANCY_MATH_387
17077    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17078    && flag_unsafe_math_optimizations"
17079   "")
17080
17081 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17082 (define_insn_and_split "frndintxf2_trunc"
17083   [(set (match_operand:XF 0 "register_operand" "=f")
17084         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17085          UNSPEC_FRNDINT_TRUNC))
17086    (clobber (reg:CC FLAGS_REG))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations
17089    && !(reload_completed || reload_in_progress)"
17090   "#"
17091   "&& 1"
17092   [(const_int 0)]
17093 {
17094   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17095
17096   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17097   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17098
17099   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17100                                         operands[2], operands[3]));
17101   DONE;
17102 }
17103   [(set_attr "type" "frndint")
17104    (set_attr "i387_cw" "trunc")
17105    (set_attr "mode" "XF")])
17106
17107 (define_insn "frndintxf2_trunc_i387"
17108   [(set (match_operand:XF 0 "register_operand" "=f")
17109         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17110          UNSPEC_FRNDINT_TRUNC))
17111    (use (match_operand:HI 2 "memory_operand" "m"))
17112    (use (match_operand:HI 3 "memory_operand" "m"))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && flag_unsafe_math_optimizations"
17115   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17116   [(set_attr "type" "frndint")
17117    (set_attr "i387_cw" "trunc")
17118    (set_attr "mode" "XF")])
17119
17120 (define_expand "btruncxf2"
17121   [(use (match_operand:XF 0 "register_operand" ""))
17122    (use (match_operand:XF 1 "register_operand" ""))]
17123   "TARGET_USE_FANCY_MATH_387
17124    && flag_unsafe_math_optimizations"
17125 {
17126   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17127   DONE;
17128 })
17129
17130 (define_expand "btruncdf2"
17131   [(use (match_operand:DF 0 "register_operand" ""))
17132    (use (match_operand:DF 1 "register_operand" ""))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17135    && flag_unsafe_math_optimizations"
17136 {
17137   rtx op0 = gen_reg_rtx (XFmode);
17138   rtx op1 = gen_reg_rtx (XFmode);
17139
17140   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17141   emit_insn (gen_frndintxf2_trunc (op0, op1));
17142
17143   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17144   DONE;
17145 })
17146
17147 (define_expand "btruncsf2"
17148   [(use (match_operand:SF 0 "register_operand" ""))
17149    (use (match_operand:SF 1 "register_operand" ""))]
17150   "TARGET_USE_FANCY_MATH_387
17151    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17152    && flag_unsafe_math_optimizations"
17153 {
17154   rtx op0 = gen_reg_rtx (XFmode);
17155   rtx op1 = gen_reg_rtx (XFmode);
17156
17157   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17158   emit_insn (gen_frndintxf2_trunc (op0, op1));
17159
17160   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17161   DONE;
17162 })
17163
17164 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17165 (define_insn_and_split "frndintxf2_mask_pm"
17166   [(set (match_operand:XF 0 "register_operand" "=f")
17167         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17168          UNSPEC_FRNDINT_MASK_PM))
17169    (clobber (reg:CC FLAGS_REG))]
17170   "TARGET_USE_FANCY_MATH_387
17171    && flag_unsafe_math_optimizations
17172    && !(reload_completed || reload_in_progress)"
17173   "#"
17174   "&& 1"
17175   [(const_int 0)]
17176 {
17177   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17178
17179   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17180   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17181
17182   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17183                                           operands[2], operands[3]));
17184   DONE;
17185 }
17186   [(set_attr "type" "frndint")
17187    (set_attr "i387_cw" "mask_pm")
17188    (set_attr "mode" "XF")])
17189
17190 (define_insn "frndintxf2_mask_pm_i387"
17191   [(set (match_operand:XF 0 "register_operand" "=f")
17192         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17193          UNSPEC_FRNDINT_MASK_PM))
17194    (use (match_operand:HI 2 "memory_operand" "m"))
17195    (use (match_operand:HI 3 "memory_operand" "m"))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && flag_unsafe_math_optimizations"
17198   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17199   [(set_attr "type" "frndint")
17200    (set_attr "i387_cw" "mask_pm")
17201    (set_attr "mode" "XF")])
17202
17203 (define_expand "nearbyintxf2"
17204   [(use (match_operand:XF 0 "register_operand" ""))
17205    (use (match_operand:XF 1 "register_operand" ""))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && flag_unsafe_math_optimizations"
17208 {
17209   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17210
17211   DONE;
17212 })
17213
17214 (define_expand "nearbyintdf2"
17215   [(use (match_operand:DF 0 "register_operand" ""))
17216    (use (match_operand:DF 1 "register_operand" ""))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17219    && flag_unsafe_math_optimizations"
17220 {
17221   rtx op0 = gen_reg_rtx (XFmode);
17222   rtx op1 = gen_reg_rtx (XFmode);
17223
17224   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17225   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17226
17227   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17228   DONE;
17229 })
17230
17231 (define_expand "nearbyintsf2"
17232   [(use (match_operand:SF 0 "register_operand" ""))
17233    (use (match_operand:SF 1 "register_operand" ""))]
17234   "TARGET_USE_FANCY_MATH_387
17235    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17236    && flag_unsafe_math_optimizations"
17237 {
17238   rtx op0 = gen_reg_rtx (XFmode);
17239   rtx op1 = gen_reg_rtx (XFmode);
17240
17241   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17242   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17243
17244   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17245   DONE;
17246 })
17247
17248 \f
17249 ;; Block operation instructions
17250
17251 (define_insn "cld"
17252  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17253  ""
17254  "cld"
17255   [(set_attr "type" "cld")])
17256
17257 (define_expand "movmemsi"
17258   [(use (match_operand:BLK 0 "memory_operand" ""))
17259    (use (match_operand:BLK 1 "memory_operand" ""))
17260    (use (match_operand:SI 2 "nonmemory_operand" ""))
17261    (use (match_operand:SI 3 "const_int_operand" ""))]
17262   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17263 {
17264  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17265    DONE;
17266  else
17267    FAIL;
17268 })
17269
17270 (define_expand "movmemdi"
17271   [(use (match_operand:BLK 0 "memory_operand" ""))
17272    (use (match_operand:BLK 1 "memory_operand" ""))
17273    (use (match_operand:DI 2 "nonmemory_operand" ""))
17274    (use (match_operand:DI 3 "const_int_operand" ""))]
17275   "TARGET_64BIT"
17276 {
17277  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17278    DONE;
17279  else
17280    FAIL;
17281 })
17282
17283 ;; Most CPUs don't like single string operations
17284 ;; Handle this case here to simplify previous expander.
17285
17286 (define_expand "strmov"
17287   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17288    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17289    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17290               (clobber (reg:CC FLAGS_REG))])
17291    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17292               (clobber (reg:CC FLAGS_REG))])]
17293   ""
17294 {
17295   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17296
17297   /* If .md ever supports :P for Pmode, these can be directly
17298      in the pattern above.  */
17299   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17300   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17301
17302   if (TARGET_SINGLE_STRINGOP || optimize_size)
17303     {
17304       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17305                                       operands[2], operands[3],
17306                                       operands[5], operands[6]));
17307       DONE;
17308     }
17309
17310   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17311 })
17312
17313 (define_expand "strmov_singleop"
17314   [(parallel [(set (match_operand 1 "memory_operand" "")
17315                    (match_operand 3 "memory_operand" ""))
17316               (set (match_operand 0 "register_operand" "")
17317                    (match_operand 4 "" ""))
17318               (set (match_operand 2 "register_operand" "")
17319                    (match_operand 5 "" ""))
17320               (use (reg:SI DIRFLAG_REG))])]
17321   "TARGET_SINGLE_STRINGOP || optimize_size"
17322   "")
17323
17324 (define_insn "*strmovdi_rex_1"
17325   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17326         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17327    (set (match_operand:DI 0 "register_operand" "=D")
17328         (plus:DI (match_dup 2)
17329                  (const_int 8)))
17330    (set (match_operand:DI 1 "register_operand" "=S")
17331         (plus:DI (match_dup 3)
17332                  (const_int 8)))
17333    (use (reg:SI DIRFLAG_REG))]
17334   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17335   "movsq"
17336   [(set_attr "type" "str")
17337    (set_attr "mode" "DI")
17338    (set_attr "memory" "both")])
17339
17340 (define_insn "*strmovsi_1"
17341   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17342         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17343    (set (match_operand:SI 0 "register_operand" "=D")
17344         (plus:SI (match_dup 2)
17345                  (const_int 4)))
17346    (set (match_operand:SI 1 "register_operand" "=S")
17347         (plus:SI (match_dup 3)
17348                  (const_int 4)))
17349    (use (reg:SI DIRFLAG_REG))]
17350   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17351   "{movsl|movsd}"
17352   [(set_attr "type" "str")
17353    (set_attr "mode" "SI")
17354    (set_attr "memory" "both")])
17355
17356 (define_insn "*strmovsi_rex_1"
17357   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17358         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17359    (set (match_operand:DI 0 "register_operand" "=D")
17360         (plus:DI (match_dup 2)
17361                  (const_int 4)))
17362    (set (match_operand:DI 1 "register_operand" "=S")
17363         (plus:DI (match_dup 3)
17364                  (const_int 4)))
17365    (use (reg:SI DIRFLAG_REG))]
17366   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17367   "{movsl|movsd}"
17368   [(set_attr "type" "str")
17369    (set_attr "mode" "SI")
17370    (set_attr "memory" "both")])
17371
17372 (define_insn "*strmovhi_1"
17373   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17374         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17375    (set (match_operand:SI 0 "register_operand" "=D")
17376         (plus:SI (match_dup 2)
17377                  (const_int 2)))
17378    (set (match_operand:SI 1 "register_operand" "=S")
17379         (plus:SI (match_dup 3)
17380                  (const_int 2)))
17381    (use (reg:SI DIRFLAG_REG))]
17382   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17383   "movsw"
17384   [(set_attr "type" "str")
17385    (set_attr "memory" "both")
17386    (set_attr "mode" "HI")])
17387
17388 (define_insn "*strmovhi_rex_1"
17389   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17390         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17391    (set (match_operand:DI 0 "register_operand" "=D")
17392         (plus:DI (match_dup 2)
17393                  (const_int 2)))
17394    (set (match_operand:DI 1 "register_operand" "=S")
17395         (plus:DI (match_dup 3)
17396                  (const_int 2)))
17397    (use (reg:SI DIRFLAG_REG))]
17398   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17399   "movsw"
17400   [(set_attr "type" "str")
17401    (set_attr "memory" "both")
17402    (set_attr "mode" "HI")])
17403
17404 (define_insn "*strmovqi_1"
17405   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17406         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17407    (set (match_operand:SI 0 "register_operand" "=D")
17408         (plus:SI (match_dup 2)
17409                  (const_int 1)))
17410    (set (match_operand:SI 1 "register_operand" "=S")
17411         (plus:SI (match_dup 3)
17412                  (const_int 1)))
17413    (use (reg:SI DIRFLAG_REG))]
17414   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17415   "movsb"
17416   [(set_attr "type" "str")
17417    (set_attr "memory" "both")
17418    (set_attr "mode" "QI")])
17419
17420 (define_insn "*strmovqi_rex_1"
17421   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17422         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17423    (set (match_operand:DI 0 "register_operand" "=D")
17424         (plus:DI (match_dup 2)
17425                  (const_int 1)))
17426    (set (match_operand:DI 1 "register_operand" "=S")
17427         (plus:DI (match_dup 3)
17428                  (const_int 1)))
17429    (use (reg:SI DIRFLAG_REG))]
17430   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17431   "movsb"
17432   [(set_attr "type" "str")
17433    (set_attr "memory" "both")
17434    (set_attr "mode" "QI")])
17435
17436 (define_expand "rep_mov"
17437   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17438               (set (match_operand 0 "register_operand" "")
17439                    (match_operand 5 "" ""))
17440               (set (match_operand 2 "register_operand" "")
17441                    (match_operand 6 "" ""))
17442               (set (match_operand 1 "memory_operand" "")
17443                    (match_operand 3 "memory_operand" ""))
17444               (use (match_dup 4))
17445               (use (reg:SI DIRFLAG_REG))])]
17446   ""
17447   "")
17448
17449 (define_insn "*rep_movdi_rex64"
17450   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17451    (set (match_operand:DI 0 "register_operand" "=D") 
17452         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17453                             (const_int 3))
17454                  (match_operand:DI 3 "register_operand" "0")))
17455    (set (match_operand:DI 1 "register_operand" "=S") 
17456         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17457                  (match_operand:DI 4 "register_operand" "1")))
17458    (set (mem:BLK (match_dup 3))
17459         (mem:BLK (match_dup 4)))
17460    (use (match_dup 5))
17461    (use (reg:SI DIRFLAG_REG))]
17462   "TARGET_64BIT"
17463   "{rep\;movsq|rep movsq}"
17464   [(set_attr "type" "str")
17465    (set_attr "prefix_rep" "1")
17466    (set_attr "memory" "both")
17467    (set_attr "mode" "DI")])
17468
17469 (define_insn "*rep_movsi"
17470   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17471    (set (match_operand:SI 0 "register_operand" "=D") 
17472         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17473                             (const_int 2))
17474                  (match_operand:SI 3 "register_operand" "0")))
17475    (set (match_operand:SI 1 "register_operand" "=S") 
17476         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17477                  (match_operand:SI 4 "register_operand" "1")))
17478    (set (mem:BLK (match_dup 3))
17479         (mem:BLK (match_dup 4)))
17480    (use (match_dup 5))
17481    (use (reg:SI DIRFLAG_REG))]
17482   "!TARGET_64BIT"
17483   "{rep\;movsl|rep movsd}"
17484   [(set_attr "type" "str")
17485    (set_attr "prefix_rep" "1")
17486    (set_attr "memory" "both")
17487    (set_attr "mode" "SI")])
17488
17489 (define_insn "*rep_movsi_rex64"
17490   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17491    (set (match_operand:DI 0 "register_operand" "=D") 
17492         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17493                             (const_int 2))
17494                  (match_operand:DI 3 "register_operand" "0")))
17495    (set (match_operand:DI 1 "register_operand" "=S") 
17496         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17497                  (match_operand:DI 4 "register_operand" "1")))
17498    (set (mem:BLK (match_dup 3))
17499         (mem:BLK (match_dup 4)))
17500    (use (match_dup 5))
17501    (use (reg:SI DIRFLAG_REG))]
17502   "TARGET_64BIT"
17503   "{rep\;movsl|rep movsd}"
17504   [(set_attr "type" "str")
17505    (set_attr "prefix_rep" "1")
17506    (set_attr "memory" "both")
17507    (set_attr "mode" "SI")])
17508
17509 (define_insn "*rep_movqi"
17510   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17511    (set (match_operand:SI 0 "register_operand" "=D") 
17512         (plus:SI (match_operand:SI 3 "register_operand" "0")
17513                  (match_operand:SI 5 "register_operand" "2")))
17514    (set (match_operand:SI 1 "register_operand" "=S") 
17515         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17516    (set (mem:BLK (match_dup 3))
17517         (mem:BLK (match_dup 4)))
17518    (use (match_dup 5))
17519    (use (reg:SI DIRFLAG_REG))]
17520   "!TARGET_64BIT"
17521   "{rep\;movsb|rep movsb}"
17522   [(set_attr "type" "str")
17523    (set_attr "prefix_rep" "1")
17524    (set_attr "memory" "both")
17525    (set_attr "mode" "SI")])
17526
17527 (define_insn "*rep_movqi_rex64"
17528   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17529    (set (match_operand:DI 0 "register_operand" "=D") 
17530         (plus:DI (match_operand:DI 3 "register_operand" "0")
17531                  (match_operand:DI 5 "register_operand" "2")))
17532    (set (match_operand:DI 1 "register_operand" "=S") 
17533         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17534    (set (mem:BLK (match_dup 3))
17535         (mem:BLK (match_dup 4)))
17536    (use (match_dup 5))
17537    (use (reg:SI DIRFLAG_REG))]
17538   "TARGET_64BIT"
17539   "{rep\;movsb|rep movsb}"
17540   [(set_attr "type" "str")
17541    (set_attr "prefix_rep" "1")
17542    (set_attr "memory" "both")
17543    (set_attr "mode" "SI")])
17544
17545 (define_expand "setmemsi"
17546    [(use (match_operand:BLK 0 "memory_operand" ""))
17547     (use (match_operand:SI 1 "nonmemory_operand" ""))
17548     (use (match_operand 2 "const_int_operand" ""))
17549     (use (match_operand 3 "const_int_operand" ""))]
17550   ""
17551 {
17552  /* If value to set is not zero, use the library routine.  */
17553  if (operands[2] != const0_rtx)
17554    FAIL;
17555
17556  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17557    DONE;
17558  else
17559    FAIL;
17560 })
17561
17562 (define_expand "setmemdi"
17563    [(use (match_operand:BLK 0 "memory_operand" ""))
17564     (use (match_operand:DI 1 "nonmemory_operand" ""))
17565     (use (match_operand 2 "const_int_operand" ""))
17566     (use (match_operand 3 "const_int_operand" ""))]
17567   "TARGET_64BIT"
17568 {
17569  /* If value to set is not zero, use the library routine.  */
17570  if (operands[2] != const0_rtx)
17571    FAIL;
17572
17573  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17574    DONE;
17575  else
17576    FAIL;
17577 })
17578
17579 ;; Most CPUs don't like single string operations
17580 ;; Handle this case here to simplify previous expander.
17581
17582 (define_expand "strset"
17583   [(set (match_operand 1 "memory_operand" "")
17584         (match_operand 2 "register_operand" ""))
17585    (parallel [(set (match_operand 0 "register_operand" "")
17586                    (match_dup 3))
17587               (clobber (reg:CC FLAGS_REG))])]
17588   ""
17589 {
17590   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17591     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17592
17593   /* If .md ever supports :P for Pmode, this can be directly
17594      in the pattern above.  */
17595   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17596                               GEN_INT (GET_MODE_SIZE (GET_MODE
17597                                                       (operands[2]))));
17598   if (TARGET_SINGLE_STRINGOP || optimize_size)
17599     {
17600       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17601                                       operands[3]));
17602       DONE;
17603     }
17604 })
17605
17606 (define_expand "strset_singleop"
17607   [(parallel [(set (match_operand 1 "memory_operand" "")
17608                    (match_operand 2 "register_operand" ""))
17609               (set (match_operand 0 "register_operand" "")
17610                    (match_operand 3 "" ""))
17611               (use (reg:SI DIRFLAG_REG))])]
17612   "TARGET_SINGLE_STRINGOP || optimize_size"
17613   "")
17614
17615 (define_insn "*strsetdi_rex_1"
17616   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17617         (match_operand:DI 2 "register_operand" "a"))
17618    (set (match_operand:DI 0 "register_operand" "=D")
17619         (plus:DI (match_dup 1)
17620                  (const_int 8)))
17621    (use (reg:SI DIRFLAG_REG))]
17622   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17623   "stosq"
17624   [(set_attr "type" "str")
17625    (set_attr "memory" "store")
17626    (set_attr "mode" "DI")])
17627
17628 (define_insn "*strsetsi_1"
17629   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17630         (match_operand:SI 2 "register_operand" "a"))
17631    (set (match_operand:SI 0 "register_operand" "=D")
17632         (plus:SI (match_dup 1)
17633                  (const_int 4)))
17634    (use (reg:SI DIRFLAG_REG))]
17635   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17636   "{stosl|stosd}"
17637   [(set_attr "type" "str")
17638    (set_attr "memory" "store")
17639    (set_attr "mode" "SI")])
17640
17641 (define_insn "*strsetsi_rex_1"
17642   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17643         (match_operand:SI 2 "register_operand" "a"))
17644    (set (match_operand:DI 0 "register_operand" "=D")
17645         (plus:DI (match_dup 1)
17646                  (const_int 4)))
17647    (use (reg:SI DIRFLAG_REG))]
17648   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17649   "{stosl|stosd}"
17650   [(set_attr "type" "str")
17651    (set_attr "memory" "store")
17652    (set_attr "mode" "SI")])
17653
17654 (define_insn "*strsethi_1"
17655   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17656         (match_operand:HI 2 "register_operand" "a"))
17657    (set (match_operand:SI 0 "register_operand" "=D")
17658         (plus:SI (match_dup 1)
17659                  (const_int 2)))
17660    (use (reg:SI DIRFLAG_REG))]
17661   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17662   "stosw"
17663   [(set_attr "type" "str")
17664    (set_attr "memory" "store")
17665    (set_attr "mode" "HI")])
17666
17667 (define_insn "*strsethi_rex_1"
17668   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17669         (match_operand:HI 2 "register_operand" "a"))
17670    (set (match_operand:DI 0 "register_operand" "=D")
17671         (plus:DI (match_dup 1)
17672                  (const_int 2)))
17673    (use (reg:SI DIRFLAG_REG))]
17674   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17675   "stosw"
17676   [(set_attr "type" "str")
17677    (set_attr "memory" "store")
17678    (set_attr "mode" "HI")])
17679
17680 (define_insn "*strsetqi_1"
17681   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17682         (match_operand:QI 2 "register_operand" "a"))
17683    (set (match_operand:SI 0 "register_operand" "=D")
17684         (plus:SI (match_dup 1)
17685                  (const_int 1)))
17686    (use (reg:SI DIRFLAG_REG))]
17687   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17688   "stosb"
17689   [(set_attr "type" "str")
17690    (set_attr "memory" "store")
17691    (set_attr "mode" "QI")])
17692
17693 (define_insn "*strsetqi_rex_1"
17694   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17695         (match_operand:QI 2 "register_operand" "a"))
17696    (set (match_operand:DI 0 "register_operand" "=D")
17697         (plus:DI (match_dup 1)
17698                  (const_int 1)))
17699    (use (reg:SI DIRFLAG_REG))]
17700   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17701   "stosb"
17702   [(set_attr "type" "str")
17703    (set_attr "memory" "store")
17704    (set_attr "mode" "QI")])
17705
17706 (define_expand "rep_stos"
17707   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17708               (set (match_operand 0 "register_operand" "")
17709                    (match_operand 4 "" ""))
17710               (set (match_operand 2 "memory_operand" "") (const_int 0))
17711               (use (match_operand 3 "register_operand" ""))
17712               (use (match_dup 1))
17713               (use (reg:SI DIRFLAG_REG))])]
17714   ""
17715   "")
17716
17717 (define_insn "*rep_stosdi_rex64"
17718   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17719    (set (match_operand:DI 0 "register_operand" "=D") 
17720         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17721                             (const_int 3))
17722                  (match_operand:DI 3 "register_operand" "0")))
17723    (set (mem:BLK (match_dup 3))
17724         (const_int 0))
17725    (use (match_operand:DI 2 "register_operand" "a"))
17726    (use (match_dup 4))
17727    (use (reg:SI DIRFLAG_REG))]
17728   "TARGET_64BIT"
17729   "{rep\;stosq|rep stosq}"
17730   [(set_attr "type" "str")
17731    (set_attr "prefix_rep" "1")
17732    (set_attr "memory" "store")
17733    (set_attr "mode" "DI")])
17734
17735 (define_insn "*rep_stossi"
17736   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17737    (set (match_operand:SI 0 "register_operand" "=D") 
17738         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17739                             (const_int 2))
17740                  (match_operand:SI 3 "register_operand" "0")))
17741    (set (mem:BLK (match_dup 3))
17742         (const_int 0))
17743    (use (match_operand:SI 2 "register_operand" "a"))
17744    (use (match_dup 4))
17745    (use (reg:SI DIRFLAG_REG))]
17746   "!TARGET_64BIT"
17747   "{rep\;stosl|rep stosd}"
17748   [(set_attr "type" "str")
17749    (set_attr "prefix_rep" "1")
17750    (set_attr "memory" "store")
17751    (set_attr "mode" "SI")])
17752
17753 (define_insn "*rep_stossi_rex64"
17754   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17755    (set (match_operand:DI 0 "register_operand" "=D") 
17756         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17757                             (const_int 2))
17758                  (match_operand:DI 3 "register_operand" "0")))
17759    (set (mem:BLK (match_dup 3))
17760         (const_int 0))
17761    (use (match_operand:SI 2 "register_operand" "a"))
17762    (use (match_dup 4))
17763    (use (reg:SI DIRFLAG_REG))]
17764   "TARGET_64BIT"
17765   "{rep\;stosl|rep stosd}"
17766   [(set_attr "type" "str")
17767    (set_attr "prefix_rep" "1")
17768    (set_attr "memory" "store")
17769    (set_attr "mode" "SI")])
17770
17771 (define_insn "*rep_stosqi"
17772   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17773    (set (match_operand:SI 0 "register_operand" "=D") 
17774         (plus:SI (match_operand:SI 3 "register_operand" "0")
17775                  (match_operand:SI 4 "register_operand" "1")))
17776    (set (mem:BLK (match_dup 3))
17777         (const_int 0))
17778    (use (match_operand:QI 2 "register_operand" "a"))
17779    (use (match_dup 4))
17780    (use (reg:SI DIRFLAG_REG))]
17781   "!TARGET_64BIT"
17782   "{rep\;stosb|rep stosb}"
17783   [(set_attr "type" "str")
17784    (set_attr "prefix_rep" "1")
17785    (set_attr "memory" "store")
17786    (set_attr "mode" "QI")])
17787
17788 (define_insn "*rep_stosqi_rex64"
17789   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17790    (set (match_operand:DI 0 "register_operand" "=D") 
17791         (plus:DI (match_operand:DI 3 "register_operand" "0")
17792                  (match_operand:DI 4 "register_operand" "1")))
17793    (set (mem:BLK (match_dup 3))
17794         (const_int 0))
17795    (use (match_operand:QI 2 "register_operand" "a"))
17796    (use (match_dup 4))
17797    (use (reg:SI DIRFLAG_REG))]
17798   "TARGET_64BIT"
17799   "{rep\;stosb|rep stosb}"
17800   [(set_attr "type" "str")
17801    (set_attr "prefix_rep" "1")
17802    (set_attr "memory" "store")
17803    (set_attr "mode" "QI")])
17804
17805 (define_expand "cmpstrnsi"
17806   [(set (match_operand:SI 0 "register_operand" "")
17807         (compare:SI (match_operand:BLK 1 "general_operand" "")
17808                     (match_operand:BLK 2 "general_operand" "")))
17809    (use (match_operand 3 "general_operand" ""))
17810    (use (match_operand 4 "immediate_operand" ""))]
17811   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17812 {
17813   rtx addr1, addr2, out, outlow, count, countreg, align;
17814
17815   /* Can't use this if the user has appropriated esi or edi.  */
17816   if (global_regs[4] || global_regs[5])
17817     FAIL;
17818
17819   out = operands[0];
17820   if (GET_CODE (out) != REG)
17821     out = gen_reg_rtx (SImode);
17822
17823   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17824   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17825   if (addr1 != XEXP (operands[1], 0))
17826     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17827   if (addr2 != XEXP (operands[2], 0))
17828     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17829
17830   count = operands[3];
17831   countreg = ix86_zero_extend_to_Pmode (count);
17832
17833   /* %%% Iff we are testing strict equality, we can use known alignment
17834      to good advantage.  This may be possible with combine, particularly
17835      once cc0 is dead.  */
17836   align = operands[4];
17837
17838   emit_insn (gen_cld ());
17839   if (GET_CODE (count) == CONST_INT)
17840     {
17841       if (INTVAL (count) == 0)
17842         {
17843           emit_move_insn (operands[0], const0_rtx);
17844           DONE;
17845         }
17846       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17847                                      operands[1], operands[2]));
17848     }
17849   else
17850     {
17851       if (TARGET_64BIT)
17852         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17853       else
17854         emit_insn (gen_cmpsi_1 (countreg, countreg));
17855       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17856                                   operands[1], operands[2]));
17857     }
17858
17859   outlow = gen_lowpart (QImode, out);
17860   emit_insn (gen_cmpintqi (outlow));
17861   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17862
17863   if (operands[0] != out)
17864     emit_move_insn (operands[0], out);
17865
17866   DONE;
17867 })
17868
17869 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17870
17871 (define_expand "cmpintqi"
17872   [(set (match_dup 1)
17873         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17874    (set (match_dup 2)
17875         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17876    (parallel [(set (match_operand:QI 0 "register_operand" "")
17877                    (minus:QI (match_dup 1)
17878                              (match_dup 2)))
17879               (clobber (reg:CC FLAGS_REG))])]
17880   ""
17881   "operands[1] = gen_reg_rtx (QImode);
17882    operands[2] = gen_reg_rtx (QImode);")
17883
17884 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17885 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17886
17887 (define_expand "cmpstrnqi_nz_1"
17888   [(parallel [(set (reg:CC FLAGS_REG)
17889                    (compare:CC (match_operand 4 "memory_operand" "")
17890                                (match_operand 5 "memory_operand" "")))
17891               (use (match_operand 2 "register_operand" ""))
17892               (use (match_operand:SI 3 "immediate_operand" ""))
17893               (use (reg:SI DIRFLAG_REG))
17894               (clobber (match_operand 0 "register_operand" ""))
17895               (clobber (match_operand 1 "register_operand" ""))
17896               (clobber (match_dup 2))])]
17897   ""
17898   "")
17899
17900 (define_insn "*cmpstrnqi_nz_1"
17901   [(set (reg:CC FLAGS_REG)
17902         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17903                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17904    (use (match_operand:SI 6 "register_operand" "2"))
17905    (use (match_operand:SI 3 "immediate_operand" "i"))
17906    (use (reg:SI DIRFLAG_REG))
17907    (clobber (match_operand:SI 0 "register_operand" "=S"))
17908    (clobber (match_operand:SI 1 "register_operand" "=D"))
17909    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17910   "!TARGET_64BIT"
17911   "repz{\;| }cmpsb"
17912   [(set_attr "type" "str")
17913    (set_attr "mode" "QI")
17914    (set_attr "prefix_rep" "1")])
17915
17916 (define_insn "*cmpstrnqi_nz_rex_1"
17917   [(set (reg:CC FLAGS_REG)
17918         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17919                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17920    (use (match_operand:DI 6 "register_operand" "2"))
17921    (use (match_operand:SI 3 "immediate_operand" "i"))
17922    (use (reg:SI DIRFLAG_REG))
17923    (clobber (match_operand:DI 0 "register_operand" "=S"))
17924    (clobber (match_operand:DI 1 "register_operand" "=D"))
17925    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17926   "TARGET_64BIT"
17927   "repz{\;| }cmpsb"
17928   [(set_attr "type" "str")
17929    (set_attr "mode" "QI")
17930    (set_attr "prefix_rep" "1")])
17931
17932 ;; The same, but the count is not known to not be zero.
17933
17934 (define_expand "cmpstrnqi_1"
17935   [(parallel [(set (reg:CC FLAGS_REG)
17936                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17937                                      (const_int 0))
17938                   (compare:CC (match_operand 4 "memory_operand" "")
17939                               (match_operand 5 "memory_operand" ""))
17940                   (const_int 0)))
17941               (use (match_operand:SI 3 "immediate_operand" ""))
17942               (use (reg:CC FLAGS_REG))
17943               (use (reg:SI DIRFLAG_REG))
17944               (clobber (match_operand 0 "register_operand" ""))
17945               (clobber (match_operand 1 "register_operand" ""))
17946               (clobber (match_dup 2))])]
17947   ""
17948   "")
17949
17950 (define_insn "*cmpstrnqi_1"
17951   [(set (reg:CC FLAGS_REG)
17952         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17953                              (const_int 0))
17954           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17955                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17956           (const_int 0)))
17957    (use (match_operand:SI 3 "immediate_operand" "i"))
17958    (use (reg:CC FLAGS_REG))
17959    (use (reg:SI DIRFLAG_REG))
17960    (clobber (match_operand:SI 0 "register_operand" "=S"))
17961    (clobber (match_operand:SI 1 "register_operand" "=D"))
17962    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17963   "!TARGET_64BIT"
17964   "repz{\;| }cmpsb"
17965   [(set_attr "type" "str")
17966    (set_attr "mode" "QI")
17967    (set_attr "prefix_rep" "1")])
17968
17969 (define_insn "*cmpstrnqi_rex_1"
17970   [(set (reg:CC FLAGS_REG)
17971         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17972                              (const_int 0))
17973           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17974                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17975           (const_int 0)))
17976    (use (match_operand:SI 3 "immediate_operand" "i"))
17977    (use (reg:CC FLAGS_REG))
17978    (use (reg:SI DIRFLAG_REG))
17979    (clobber (match_operand:DI 0 "register_operand" "=S"))
17980    (clobber (match_operand:DI 1 "register_operand" "=D"))
17981    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17982   "TARGET_64BIT"
17983   "repz{\;| }cmpsb"
17984   [(set_attr "type" "str")
17985    (set_attr "mode" "QI")
17986    (set_attr "prefix_rep" "1")])
17987
17988 (define_expand "strlensi"
17989   [(set (match_operand:SI 0 "register_operand" "")
17990         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17991                     (match_operand:QI 2 "immediate_operand" "")
17992                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17993   ""
17994 {
17995  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17996    DONE;
17997  else
17998    FAIL;
17999 })
18000
18001 (define_expand "strlendi"
18002   [(set (match_operand:DI 0 "register_operand" "")
18003         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18004                     (match_operand:QI 2 "immediate_operand" "")
18005                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18006   ""
18007 {
18008  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18009    DONE;
18010  else
18011    FAIL;
18012 })
18013
18014 (define_expand "strlenqi_1"
18015   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18016               (use (reg:SI DIRFLAG_REG))
18017               (clobber (match_operand 1 "register_operand" ""))
18018               (clobber (reg:CC FLAGS_REG))])]
18019   ""
18020   "")
18021
18022 (define_insn "*strlenqi_1"
18023   [(set (match_operand:SI 0 "register_operand" "=&c")
18024         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18025                     (match_operand:QI 2 "register_operand" "a")
18026                     (match_operand:SI 3 "immediate_operand" "i")
18027                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18028    (use (reg:SI DIRFLAG_REG))
18029    (clobber (match_operand:SI 1 "register_operand" "=D"))
18030    (clobber (reg:CC FLAGS_REG))]
18031   "!TARGET_64BIT"
18032   "repnz{\;| }scasb"
18033   [(set_attr "type" "str")
18034    (set_attr "mode" "QI")
18035    (set_attr "prefix_rep" "1")])
18036
18037 (define_insn "*strlenqi_rex_1"
18038   [(set (match_operand:DI 0 "register_operand" "=&c")
18039         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18040                     (match_operand:QI 2 "register_operand" "a")
18041                     (match_operand:DI 3 "immediate_operand" "i")
18042                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18043    (use (reg:SI DIRFLAG_REG))
18044    (clobber (match_operand:DI 1 "register_operand" "=D"))
18045    (clobber (reg:CC FLAGS_REG))]
18046   "TARGET_64BIT"
18047   "repnz{\;| }scasb"
18048   [(set_attr "type" "str")
18049    (set_attr "mode" "QI")
18050    (set_attr "prefix_rep" "1")])
18051
18052 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18053 ;; handled in combine, but it is not currently up to the task.
18054 ;; When used for their truth value, the cmpstrn* expanders generate
18055 ;; code like this:
18056 ;;
18057 ;;   repz cmpsb
18058 ;;   seta       %al
18059 ;;   setb       %dl
18060 ;;   cmpb       %al, %dl
18061 ;;   jcc        label
18062 ;;
18063 ;; The intermediate three instructions are unnecessary.
18064
18065 ;; This one handles cmpstrn*_nz_1...
18066 (define_peephole2
18067   [(parallel[
18068      (set (reg:CC FLAGS_REG)
18069           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18070                       (mem:BLK (match_operand 5 "register_operand" ""))))
18071      (use (match_operand 6 "register_operand" ""))
18072      (use (match_operand:SI 3 "immediate_operand" ""))
18073      (use (reg:SI DIRFLAG_REG))
18074      (clobber (match_operand 0 "register_operand" ""))
18075      (clobber (match_operand 1 "register_operand" ""))
18076      (clobber (match_operand 2 "register_operand" ""))])
18077    (set (match_operand:QI 7 "register_operand" "")
18078         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18079    (set (match_operand:QI 8 "register_operand" "")
18080         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18081    (set (reg FLAGS_REG)
18082         (compare (match_dup 7) (match_dup 8)))
18083   ]
18084   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18085   [(parallel[
18086      (set (reg:CC FLAGS_REG)
18087           (compare:CC (mem:BLK (match_dup 4))
18088                       (mem:BLK (match_dup 5))))
18089      (use (match_dup 6))
18090      (use (match_dup 3))
18091      (use (reg:SI DIRFLAG_REG))
18092      (clobber (match_dup 0))
18093      (clobber (match_dup 1))
18094      (clobber (match_dup 2))])]
18095   "")
18096
18097 ;; ...and this one handles cmpstrn*_1.
18098 (define_peephole2
18099   [(parallel[
18100      (set (reg:CC FLAGS_REG)
18101           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18102                                (const_int 0))
18103             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18104                         (mem:BLK (match_operand 5 "register_operand" "")))
18105             (const_int 0)))
18106      (use (match_operand:SI 3 "immediate_operand" ""))
18107      (use (reg:CC FLAGS_REG))
18108      (use (reg:SI DIRFLAG_REG))
18109      (clobber (match_operand 0 "register_operand" ""))
18110      (clobber (match_operand 1 "register_operand" ""))
18111      (clobber (match_operand 2 "register_operand" ""))])
18112    (set (match_operand:QI 7 "register_operand" "")
18113         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18114    (set (match_operand:QI 8 "register_operand" "")
18115         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18116    (set (reg FLAGS_REG)
18117         (compare (match_dup 7) (match_dup 8)))
18118   ]
18119   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18120   [(parallel[
18121      (set (reg:CC FLAGS_REG)
18122           (if_then_else:CC (ne (match_dup 6)
18123                                (const_int 0))
18124             (compare:CC (mem:BLK (match_dup 4))
18125                         (mem:BLK (match_dup 5)))
18126             (const_int 0)))
18127      (use (match_dup 3))
18128      (use (reg:CC FLAGS_REG))
18129      (use (reg:SI DIRFLAG_REG))
18130      (clobber (match_dup 0))
18131      (clobber (match_dup 1))
18132      (clobber (match_dup 2))])]
18133   "")
18134
18135
18136 \f
18137 ;; Conditional move instructions.
18138
18139 (define_expand "movdicc"
18140   [(set (match_operand:DI 0 "register_operand" "")
18141         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18142                          (match_operand:DI 2 "general_operand" "")
18143                          (match_operand:DI 3 "general_operand" "")))]
18144   "TARGET_64BIT"
18145   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18146
18147 (define_insn "x86_movdicc_0_m1_rex64"
18148   [(set (match_operand:DI 0 "register_operand" "=r")
18149         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18150           (const_int -1)
18151           (const_int 0)))
18152    (clobber (reg:CC FLAGS_REG))]
18153   "TARGET_64BIT"
18154   "sbb{q}\t%0, %0"
18155   ; Since we don't have the proper number of operands for an alu insn,
18156   ; fill in all the blanks.
18157   [(set_attr "type" "alu")
18158    (set_attr "pent_pair" "pu")
18159    (set_attr "memory" "none")
18160    (set_attr "imm_disp" "false")
18161    (set_attr "mode" "DI")
18162    (set_attr "length_immediate" "0")])
18163
18164 (define_insn "*movdicc_c_rex64"
18165   [(set (match_operand:DI 0 "register_operand" "=r,r")
18166         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18167                                 [(reg FLAGS_REG) (const_int 0)])
18168                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18169                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18170   "TARGET_64BIT && TARGET_CMOVE
18171    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18172   "@
18173    cmov%O2%C1\t{%2, %0|%0, %2}
18174    cmov%O2%c1\t{%3, %0|%0, %3}"
18175   [(set_attr "type" "icmov")
18176    (set_attr "mode" "DI")])
18177
18178 (define_expand "movsicc"
18179   [(set (match_operand:SI 0 "register_operand" "")
18180         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18181                          (match_operand:SI 2 "general_operand" "")
18182                          (match_operand:SI 3 "general_operand" "")))]
18183   ""
18184   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18185
18186 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18187 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18188 ;; So just document what we're doing explicitly.
18189
18190 (define_insn "x86_movsicc_0_m1"
18191   [(set (match_operand:SI 0 "register_operand" "=r")
18192         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18193           (const_int -1)
18194           (const_int 0)))
18195    (clobber (reg:CC FLAGS_REG))]
18196   ""
18197   "sbb{l}\t%0, %0"
18198   ; Since we don't have the proper number of operands for an alu insn,
18199   ; fill in all the blanks.
18200   [(set_attr "type" "alu")
18201    (set_attr "pent_pair" "pu")
18202    (set_attr "memory" "none")
18203    (set_attr "imm_disp" "false")
18204    (set_attr "mode" "SI")
18205    (set_attr "length_immediate" "0")])
18206
18207 (define_insn "*movsicc_noc"
18208   [(set (match_operand:SI 0 "register_operand" "=r,r")
18209         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18210                                 [(reg FLAGS_REG) (const_int 0)])
18211                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18212                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18213   "TARGET_CMOVE
18214    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18215   "@
18216    cmov%O2%C1\t{%2, %0|%0, %2}
18217    cmov%O2%c1\t{%3, %0|%0, %3}"
18218   [(set_attr "type" "icmov")
18219    (set_attr "mode" "SI")])
18220
18221 (define_expand "movhicc"
18222   [(set (match_operand:HI 0 "register_operand" "")
18223         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18224                          (match_operand:HI 2 "general_operand" "")
18225                          (match_operand:HI 3 "general_operand" "")))]
18226   "TARGET_HIMODE_MATH"
18227   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18228
18229 (define_insn "*movhicc_noc"
18230   [(set (match_operand:HI 0 "register_operand" "=r,r")
18231         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18232                                 [(reg FLAGS_REG) (const_int 0)])
18233                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18234                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18235   "TARGET_CMOVE
18236    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18237   "@
18238    cmov%O2%C1\t{%2, %0|%0, %2}
18239    cmov%O2%c1\t{%3, %0|%0, %3}"
18240   [(set_attr "type" "icmov")
18241    (set_attr "mode" "HI")])
18242
18243 (define_expand "movqicc"
18244   [(set (match_operand:QI 0 "register_operand" "")
18245         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18246                          (match_operand:QI 2 "general_operand" "")
18247                          (match_operand:QI 3 "general_operand" "")))]
18248   "TARGET_QIMODE_MATH"
18249   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18250
18251 (define_insn_and_split "*movqicc_noc"
18252   [(set (match_operand:QI 0 "register_operand" "=r,r")
18253         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18254                                 [(match_operand 4 "flags_reg_operand" "")
18255                                  (const_int 0)])
18256                       (match_operand:QI 2 "register_operand" "r,0")
18257                       (match_operand:QI 3 "register_operand" "0,r")))]
18258   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18259   "#"
18260   "&& reload_completed"
18261   [(set (match_dup 0)
18262         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18263                       (match_dup 2)
18264                       (match_dup 3)))]
18265   "operands[0] = gen_lowpart (SImode, operands[0]);
18266    operands[2] = gen_lowpart (SImode, operands[2]);
18267    operands[3] = gen_lowpart (SImode, operands[3]);"
18268   [(set_attr "type" "icmov")
18269    (set_attr "mode" "SI")])
18270
18271 (define_expand "movsfcc"
18272   [(set (match_operand:SF 0 "register_operand" "")
18273         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18274                          (match_operand:SF 2 "register_operand" "")
18275                          (match_operand:SF 3 "register_operand" "")))]
18276   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18277   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18278
18279 (define_insn "*movsfcc_1_387"
18280   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18281         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18282                                 [(reg FLAGS_REG) (const_int 0)])
18283                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18284                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18285   "TARGET_80387 && TARGET_CMOVE
18286    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18287   "@
18288    fcmov%F1\t{%2, %0|%0, %2}
18289    fcmov%f1\t{%3, %0|%0, %3}
18290    cmov%O2%C1\t{%2, %0|%0, %2}
18291    cmov%O2%c1\t{%3, %0|%0, %3}"
18292   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18293    (set_attr "mode" "SF,SF,SI,SI")])
18294
18295 (define_expand "movdfcc"
18296   [(set (match_operand:DF 0 "register_operand" "")
18297         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18298                          (match_operand:DF 2 "register_operand" "")
18299                          (match_operand:DF 3 "register_operand" "")))]
18300   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18301   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18302
18303 (define_insn "*movdfcc_1"
18304   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18305         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18306                                 [(reg FLAGS_REG) (const_int 0)])
18307                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18308                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18309   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18310    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18311   "@
18312    fcmov%F1\t{%2, %0|%0, %2}
18313    fcmov%f1\t{%3, %0|%0, %3}
18314    #
18315    #"
18316   [(set_attr "type" "fcmov,fcmov,multi,multi")
18317    (set_attr "mode" "DF")])
18318
18319 (define_insn "*movdfcc_1_rex64"
18320   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18321         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18322                                 [(reg FLAGS_REG) (const_int 0)])
18323                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18324                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18325   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18326    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18327   "@
18328    fcmov%F1\t{%2, %0|%0, %2}
18329    fcmov%f1\t{%3, %0|%0, %3}
18330    cmov%O2%C1\t{%2, %0|%0, %2}
18331    cmov%O2%c1\t{%3, %0|%0, %3}"
18332   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18333    (set_attr "mode" "DF")])
18334
18335 (define_split
18336   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18337         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18338                                 [(match_operand 4 "flags_reg_operand" "")
18339                                  (const_int 0)])
18340                       (match_operand:DF 2 "nonimmediate_operand" "")
18341                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18342   "!TARGET_64BIT && reload_completed"
18343   [(set (match_dup 2)
18344         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18345                       (match_dup 5)
18346                       (match_dup 7)))
18347    (set (match_dup 3)
18348         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18349                       (match_dup 6)
18350                       (match_dup 8)))]
18351   "split_di (operands+2, 1, operands+5, operands+6);
18352    split_di (operands+3, 1, operands+7, operands+8);
18353    split_di (operands, 1, operands+2, operands+3);")
18354
18355 (define_expand "movxfcc"
18356   [(set (match_operand:XF 0 "register_operand" "")
18357         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18358                          (match_operand:XF 2 "register_operand" "")
18359                          (match_operand:XF 3 "register_operand" "")))]
18360   "TARGET_80387 && TARGET_CMOVE"
18361   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18362
18363 (define_insn "*movxfcc_1"
18364   [(set (match_operand:XF 0 "register_operand" "=f,f")
18365         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18366                                 [(reg FLAGS_REG) (const_int 0)])
18367                       (match_operand:XF 2 "register_operand" "f,0")
18368                       (match_operand:XF 3 "register_operand" "0,f")))]
18369   "TARGET_80387 && TARGET_CMOVE"
18370   "@
18371    fcmov%F1\t{%2, %0|%0, %2}
18372    fcmov%f1\t{%3, %0|%0, %3}"
18373   [(set_attr "type" "fcmov")
18374    (set_attr "mode" "XF")])
18375
18376 ;; These versions of the min/max patterns are intentionally ignorant of
18377 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18378 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18379 ;; are undefined in this condition, we're certain this is correct.
18380
18381 (define_insn "sminsf3"
18382   [(set (match_operand:SF 0 "register_operand" "=x")
18383         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18384                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18385   "TARGET_SSE_MATH"
18386   "minss\t{%2, %0|%0, %2}"
18387   [(set_attr "type" "sseadd")
18388    (set_attr "mode" "SF")])
18389
18390 (define_insn "smaxsf3"
18391   [(set (match_operand:SF 0 "register_operand" "=x")
18392         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18393                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18394   "TARGET_SSE_MATH"
18395   "maxss\t{%2, %0|%0, %2}"
18396   [(set_attr "type" "sseadd")
18397    (set_attr "mode" "SF")])
18398
18399 (define_insn "smindf3"
18400   [(set (match_operand:DF 0 "register_operand" "=x")
18401         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18402                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18403   "TARGET_SSE2 && TARGET_SSE_MATH"
18404   "minsd\t{%2, %0|%0, %2}"
18405   [(set_attr "type" "sseadd")
18406    (set_attr "mode" "DF")])
18407
18408 (define_insn "smaxdf3"
18409   [(set (match_operand:DF 0 "register_operand" "=x")
18410         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18411                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18412   "TARGET_SSE2 && TARGET_SSE_MATH"
18413   "maxsd\t{%2, %0|%0, %2}"
18414   [(set_attr "type" "sseadd")
18415    (set_attr "mode" "DF")])
18416
18417 ;; These versions of the min/max patterns implement exactly the operations
18418 ;;   min = (op1 < op2 ? op1 : op2)
18419 ;;   max = (!(op1 < op2) ? op1 : op2)
18420 ;; Their operands are not commutative, and thus they may be used in the
18421 ;; presence of -0.0 and NaN.
18422
18423 (define_insn "*ieee_sminsf3"
18424   [(set (match_operand:SF 0 "register_operand" "=x")
18425         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18426                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18427                    UNSPEC_IEEE_MIN))]
18428   "TARGET_SSE_MATH"
18429   "minss\t{%2, %0|%0, %2}"
18430   [(set_attr "type" "sseadd")
18431    (set_attr "mode" "SF")])
18432
18433 (define_insn "*ieee_smaxsf3"
18434   [(set (match_operand:SF 0 "register_operand" "=x")
18435         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18436                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18437                    UNSPEC_IEEE_MAX))]
18438   "TARGET_SSE_MATH"
18439   "maxss\t{%2, %0|%0, %2}"
18440   [(set_attr "type" "sseadd")
18441    (set_attr "mode" "SF")])
18442
18443 (define_insn "*ieee_smindf3"
18444   [(set (match_operand:DF 0 "register_operand" "=x")
18445         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18446                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18447                    UNSPEC_IEEE_MIN))]
18448   "TARGET_SSE2 && TARGET_SSE_MATH"
18449   "minsd\t{%2, %0|%0, %2}"
18450   [(set_attr "type" "sseadd")
18451    (set_attr "mode" "DF")])
18452
18453 (define_insn "*ieee_smaxdf3"
18454   [(set (match_operand:DF 0 "register_operand" "=x")
18455         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18456                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18457                    UNSPEC_IEEE_MAX))]
18458   "TARGET_SSE2 && TARGET_SSE_MATH"
18459   "maxsd\t{%2, %0|%0, %2}"
18460   [(set_attr "type" "sseadd")
18461    (set_attr "mode" "DF")])
18462
18463 ;; Conditional addition patterns
18464 (define_expand "addqicc"
18465   [(match_operand:QI 0 "register_operand" "")
18466    (match_operand 1 "comparison_operator" "")
18467    (match_operand:QI 2 "register_operand" "")
18468    (match_operand:QI 3 "const_int_operand" "")]
18469   ""
18470   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18471
18472 (define_expand "addhicc"
18473   [(match_operand:HI 0 "register_operand" "")
18474    (match_operand 1 "comparison_operator" "")
18475    (match_operand:HI 2 "register_operand" "")
18476    (match_operand:HI 3 "const_int_operand" "")]
18477   ""
18478   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18479
18480 (define_expand "addsicc"
18481   [(match_operand:SI 0 "register_operand" "")
18482    (match_operand 1 "comparison_operator" "")
18483    (match_operand:SI 2 "register_operand" "")
18484    (match_operand:SI 3 "const_int_operand" "")]
18485   ""
18486   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18487
18488 (define_expand "adddicc"
18489   [(match_operand:DI 0 "register_operand" "")
18490    (match_operand 1 "comparison_operator" "")
18491    (match_operand:DI 2 "register_operand" "")
18492    (match_operand:DI 3 "const_int_operand" "")]
18493   "TARGET_64BIT"
18494   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18495
18496 \f
18497 ;; Misc patterns (?)
18498
18499 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18500 ;; Otherwise there will be nothing to keep
18501 ;; 
18502 ;; [(set (reg ebp) (reg esp))]
18503 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18504 ;;  (clobber (eflags)]
18505 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18506 ;;
18507 ;; in proper program order.
18508 (define_insn "pro_epilogue_adjust_stack_1"
18509   [(set (match_operand:SI 0 "register_operand" "=r,r")
18510         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18511                  (match_operand:SI 2 "immediate_operand" "i,i")))
18512    (clobber (reg:CC FLAGS_REG))
18513    (clobber (mem:BLK (scratch)))]
18514   "!TARGET_64BIT"
18515 {
18516   switch (get_attr_type (insn))
18517     {
18518     case TYPE_IMOV:
18519       return "mov{l}\t{%1, %0|%0, %1}";
18520
18521     case TYPE_ALU:
18522       if (GET_CODE (operands[2]) == CONST_INT
18523           && (INTVAL (operands[2]) == 128
18524               || (INTVAL (operands[2]) < 0
18525                   && INTVAL (operands[2]) != -128)))
18526         {
18527           operands[2] = GEN_INT (-INTVAL (operands[2]));
18528           return "sub{l}\t{%2, %0|%0, %2}";
18529         }
18530       return "add{l}\t{%2, %0|%0, %2}";
18531
18532     case TYPE_LEA:
18533       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18534       return "lea{l}\t{%a2, %0|%0, %a2}";
18535
18536     default:
18537       gcc_unreachable ();
18538     }
18539 }
18540   [(set (attr "type")
18541         (cond [(eq_attr "alternative" "0")
18542                  (const_string "alu")
18543                (match_operand:SI 2 "const0_operand" "")
18544                  (const_string "imov")
18545               ]
18546               (const_string "lea")))
18547    (set_attr "mode" "SI")])
18548
18549 (define_insn "pro_epilogue_adjust_stack_rex64"
18550   [(set (match_operand:DI 0 "register_operand" "=r,r")
18551         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18552                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18553    (clobber (reg:CC FLAGS_REG))
18554    (clobber (mem:BLK (scratch)))]
18555   "TARGET_64BIT"
18556 {
18557   switch (get_attr_type (insn))
18558     {
18559     case TYPE_IMOV:
18560       return "mov{q}\t{%1, %0|%0, %1}";
18561
18562     case TYPE_ALU:
18563       if (GET_CODE (operands[2]) == CONST_INT
18564           /* Avoid overflows.  */
18565           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18566           && (INTVAL (operands[2]) == 128
18567               || (INTVAL (operands[2]) < 0
18568                   && INTVAL (operands[2]) != -128)))
18569         {
18570           operands[2] = GEN_INT (-INTVAL (operands[2]));
18571           return "sub{q}\t{%2, %0|%0, %2}";
18572         }
18573       return "add{q}\t{%2, %0|%0, %2}";
18574
18575     case TYPE_LEA:
18576       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18577       return "lea{q}\t{%a2, %0|%0, %a2}";
18578
18579     default:
18580       gcc_unreachable ();
18581     }
18582 }
18583   [(set (attr "type")
18584         (cond [(eq_attr "alternative" "0")
18585                  (const_string "alu")
18586                (match_operand:DI 2 "const0_operand" "")
18587                  (const_string "imov")
18588               ]
18589               (const_string "lea")))
18590    (set_attr "mode" "DI")])
18591
18592 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18593   [(set (match_operand:DI 0 "register_operand" "=r,r")
18594         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18595                  (match_operand:DI 3 "immediate_operand" "i,i")))
18596    (use (match_operand:DI 2 "register_operand" "r,r"))
18597    (clobber (reg:CC FLAGS_REG))
18598    (clobber (mem:BLK (scratch)))]
18599   "TARGET_64BIT"
18600 {
18601   switch (get_attr_type (insn))
18602     {
18603     case TYPE_ALU:
18604       return "add{q}\t{%2, %0|%0, %2}";
18605
18606     case TYPE_LEA:
18607       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18608       return "lea{q}\t{%a2, %0|%0, %a2}";
18609
18610     default:
18611       gcc_unreachable ();
18612     }
18613 }
18614   [(set_attr "type" "alu,lea")
18615    (set_attr "mode" "DI")])
18616
18617 (define_expand "allocate_stack_worker"
18618   [(match_operand:SI 0 "register_operand" "")]
18619   "TARGET_STACK_PROBE"
18620 {
18621   if (reload_completed)
18622     {
18623       if (TARGET_64BIT)
18624         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18625       else
18626         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18627     }
18628   else
18629     {
18630       if (TARGET_64BIT)
18631         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18632       else
18633         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18634     }
18635   DONE;
18636 })
18637
18638 (define_insn "allocate_stack_worker_1"
18639   [(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_scratch:SI 1 "=0"))
18643    (clobber (reg:CC FLAGS_REG))]
18644   "!TARGET_64BIT && TARGET_STACK_PROBE"
18645   "call\t__alloca"
18646   [(set_attr "type" "multi")
18647    (set_attr "length" "5")])
18648
18649 (define_expand "allocate_stack_worker_postreload"
18650   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18651                                     UNSPECV_STACK_PROBE)
18652               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18653               (clobber (match_dup 0))
18654               (clobber (reg:CC FLAGS_REG))])]
18655   ""
18656   "")
18657
18658 (define_insn "allocate_stack_worker_rex64"
18659   [(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_scratch:DI 1 "=0"))
18663    (clobber (reg:CC FLAGS_REG))]
18664   "TARGET_64BIT && TARGET_STACK_PROBE"
18665   "call\t__alloca"
18666   [(set_attr "type" "multi")
18667    (set_attr "length" "5")])
18668
18669 (define_expand "allocate_stack_worker_rex64_postreload"
18670   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18671                                     UNSPECV_STACK_PROBE)
18672               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18673               (clobber (match_dup 0))
18674               (clobber (reg:CC FLAGS_REG))])]
18675   ""
18676   "")
18677
18678 (define_expand "allocate_stack"
18679   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18680                    (minus:SI (reg:SI SP_REG)
18681                              (match_operand:SI 1 "general_operand" "")))
18682               (clobber (reg:CC FLAGS_REG))])
18683    (parallel [(set (reg:SI SP_REG)
18684                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18685               (clobber (reg:CC FLAGS_REG))])]
18686   "TARGET_STACK_PROBE"
18687 {
18688 #ifdef CHECK_STACK_LIMIT
18689   if (GET_CODE (operands[1]) == CONST_INT
18690       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18691     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18692                            operands[1]));
18693   else 
18694 #endif
18695     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18696                                                             operands[1])));
18697
18698   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18699   DONE;
18700 })
18701
18702 (define_expand "builtin_setjmp_receiver"
18703   [(label_ref (match_operand 0 "" ""))]
18704   "!TARGET_64BIT && flag_pic"
18705 {
18706   emit_insn (gen_set_got (pic_offset_table_rtx));
18707   DONE;
18708 })
18709 \f
18710 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18711
18712 (define_split
18713   [(set (match_operand 0 "register_operand" "")
18714         (match_operator 3 "promotable_binary_operator"
18715            [(match_operand 1 "register_operand" "")
18716             (match_operand 2 "aligned_operand" "")]))
18717    (clobber (reg:CC FLAGS_REG))]
18718   "! TARGET_PARTIAL_REG_STALL && reload_completed
18719    && ((GET_MODE (operands[0]) == HImode 
18720         && ((!optimize_size && !TARGET_FAST_PREFIX)
18721             || GET_CODE (operands[2]) != CONST_INT
18722             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18723        || (GET_MODE (operands[0]) == QImode 
18724            && (TARGET_PROMOTE_QImode || optimize_size)))"
18725   [(parallel [(set (match_dup 0)
18726                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18727               (clobber (reg:CC FLAGS_REG))])]
18728   "operands[0] = gen_lowpart (SImode, operands[0]);
18729    operands[1] = gen_lowpart (SImode, operands[1]);
18730    if (GET_CODE (operands[3]) != ASHIFT)
18731      operands[2] = gen_lowpart (SImode, operands[2]);
18732    PUT_MODE (operands[3], SImode);")
18733
18734 ; Promote the QImode tests, as i386 has encoding of the AND
18735 ; instruction with 32-bit sign-extended immediate and thus the
18736 ; instruction size is unchanged, except in the %eax case for
18737 ; which it is increased by one byte, hence the ! optimize_size.
18738 (define_split
18739   [(set (match_operand 0 "flags_reg_operand" "")
18740         (match_operator 2 "compare_operator"
18741           [(and (match_operand 3 "aligned_operand" "")
18742                 (match_operand 4 "const_int_operand" ""))
18743            (const_int 0)]))
18744    (set (match_operand 1 "register_operand" "")
18745         (and (match_dup 3) (match_dup 4)))]
18746   "! TARGET_PARTIAL_REG_STALL && reload_completed
18747    /* Ensure that the operand will remain sign-extended immediate.  */
18748    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18749    && ! optimize_size
18750    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18751        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18752   [(parallel [(set (match_dup 0)
18753                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18754                                     (const_int 0)]))
18755               (set (match_dup 1)
18756                    (and:SI (match_dup 3) (match_dup 4)))])]
18757 {
18758   operands[4]
18759     = gen_int_mode (INTVAL (operands[4])
18760                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18761   operands[1] = gen_lowpart (SImode, operands[1]);
18762   operands[3] = gen_lowpart (SImode, operands[3]);
18763 })
18764
18765 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18766 ; the TEST instruction with 32-bit sign-extended immediate and thus
18767 ; the instruction size would at least double, which is not what we
18768 ; want even with ! optimize_size.
18769 (define_split
18770   [(set (match_operand 0 "flags_reg_operand" "")
18771         (match_operator 1 "compare_operator"
18772           [(and (match_operand:HI 2 "aligned_operand" "")
18773                 (match_operand:HI 3 "const_int_operand" ""))
18774            (const_int 0)]))]
18775   "! TARGET_PARTIAL_REG_STALL && reload_completed
18776    /* Ensure that the operand will remain sign-extended immediate.  */
18777    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18778    && ! TARGET_FAST_PREFIX
18779    && ! optimize_size"
18780   [(set (match_dup 0)
18781         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18782                          (const_int 0)]))]
18783 {
18784   operands[3]
18785     = gen_int_mode (INTVAL (operands[3])
18786                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18787   operands[2] = gen_lowpart (SImode, operands[2]);
18788 })
18789
18790 (define_split
18791   [(set (match_operand 0 "register_operand" "")
18792         (neg (match_operand 1 "register_operand" "")))
18793    (clobber (reg:CC FLAGS_REG))]
18794   "! TARGET_PARTIAL_REG_STALL && reload_completed
18795    && (GET_MODE (operands[0]) == HImode
18796        || (GET_MODE (operands[0]) == QImode 
18797            && (TARGET_PROMOTE_QImode || optimize_size)))"
18798   [(parallel [(set (match_dup 0)
18799                    (neg:SI (match_dup 1)))
18800               (clobber (reg:CC FLAGS_REG))])]
18801   "operands[0] = gen_lowpart (SImode, operands[0]);
18802    operands[1] = gen_lowpart (SImode, operands[1]);")
18803
18804 (define_split
18805   [(set (match_operand 0 "register_operand" "")
18806         (not (match_operand 1 "register_operand" "")))]
18807   "! TARGET_PARTIAL_REG_STALL && reload_completed
18808    && (GET_MODE (operands[0]) == HImode
18809        || (GET_MODE (operands[0]) == QImode 
18810            && (TARGET_PROMOTE_QImode || optimize_size)))"
18811   [(set (match_dup 0)
18812         (not:SI (match_dup 1)))]
18813   "operands[0] = gen_lowpart (SImode, operands[0]);
18814    operands[1] = gen_lowpart (SImode, operands[1]);")
18815
18816 (define_split 
18817   [(set (match_operand 0 "register_operand" "")
18818         (if_then_else (match_operator 1 "comparison_operator" 
18819                                 [(reg FLAGS_REG) (const_int 0)])
18820                       (match_operand 2 "register_operand" "")
18821                       (match_operand 3 "register_operand" "")))]
18822   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18823    && (GET_MODE (operands[0]) == HImode
18824        || (GET_MODE (operands[0]) == QImode 
18825            && (TARGET_PROMOTE_QImode || optimize_size)))"
18826   [(set (match_dup 0)
18827         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18828   "operands[0] = gen_lowpart (SImode, operands[0]);
18829    operands[2] = gen_lowpart (SImode, operands[2]);
18830    operands[3] = gen_lowpart (SImode, operands[3]);")
18831                         
18832 \f
18833 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18834 ;; transform a complex memory operation into two memory to register operations.
18835
18836 ;; Don't push memory operands
18837 (define_peephole2
18838   [(set (match_operand:SI 0 "push_operand" "")
18839         (match_operand:SI 1 "memory_operand" ""))
18840    (match_scratch:SI 2 "r")]
18841   "! optimize_size && ! TARGET_PUSH_MEMORY"
18842   [(set (match_dup 2) (match_dup 1))
18843    (set (match_dup 0) (match_dup 2))]
18844   "")
18845
18846 (define_peephole2
18847   [(set (match_operand:DI 0 "push_operand" "")
18848         (match_operand:DI 1 "memory_operand" ""))
18849    (match_scratch:DI 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 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18856 ;; SImode pushes.
18857 (define_peephole2
18858   [(set (match_operand:SF 0 "push_operand" "")
18859         (match_operand:SF 1 "memory_operand" ""))
18860    (match_scratch:SF 2 "r")]
18861   "! optimize_size && ! TARGET_PUSH_MEMORY"
18862   [(set (match_dup 2) (match_dup 1))
18863    (set (match_dup 0) (match_dup 2))]
18864   "")
18865
18866 (define_peephole2
18867   [(set (match_operand:HI 0 "push_operand" "")
18868         (match_operand:HI 1 "memory_operand" ""))
18869    (match_scratch:HI 2 "r")]
18870   "! optimize_size && ! TARGET_PUSH_MEMORY"
18871   [(set (match_dup 2) (match_dup 1))
18872    (set (match_dup 0) (match_dup 2))]
18873   "")
18874
18875 (define_peephole2
18876   [(set (match_operand:QI 0 "push_operand" "")
18877         (match_operand:QI 1 "memory_operand" ""))
18878    (match_scratch:QI 2 "q")]
18879   "! optimize_size && ! TARGET_PUSH_MEMORY"
18880   [(set (match_dup 2) (match_dup 1))
18881    (set (match_dup 0) (match_dup 2))]
18882   "")
18883
18884 ;; Don't move an immediate directly to memory when the instruction
18885 ;; gets too big.
18886 (define_peephole2
18887   [(match_scratch:SI 1 "r")
18888    (set (match_operand:SI 0 "memory_operand" "")
18889         (const_int 0))]
18890   "! optimize_size
18891    && ! TARGET_USE_MOV0
18892    && TARGET_SPLIT_LONG_MOVES
18893    && get_attr_length (insn) >= ix86_cost->large_insn
18894    && peep2_regno_dead_p (0, FLAGS_REG)"
18895   [(parallel [(set (match_dup 1) (const_int 0))
18896               (clobber (reg:CC FLAGS_REG))])
18897    (set (match_dup 0) (match_dup 1))]
18898   "")
18899
18900 (define_peephole2
18901   [(match_scratch:HI 1 "r")
18902    (set (match_operand:HI 0 "memory_operand" "")
18903         (const_int 0))]
18904   "! optimize_size
18905    && ! TARGET_USE_MOV0
18906    && TARGET_SPLIT_LONG_MOVES
18907    && get_attr_length (insn) >= ix86_cost->large_insn
18908    && peep2_regno_dead_p (0, FLAGS_REG)"
18909   [(parallel [(set (match_dup 2) (const_int 0))
18910               (clobber (reg:CC FLAGS_REG))])
18911    (set (match_dup 0) (match_dup 1))]
18912   "operands[2] = gen_lowpart (SImode, operands[1]);")
18913
18914 (define_peephole2
18915   [(match_scratch:QI 1 "q")
18916    (set (match_operand:QI 0 "memory_operand" "")
18917         (const_int 0))]
18918   "! optimize_size
18919    && ! TARGET_USE_MOV0
18920    && TARGET_SPLIT_LONG_MOVES
18921    && get_attr_length (insn) >= ix86_cost->large_insn
18922    && peep2_regno_dead_p (0, FLAGS_REG)"
18923   [(parallel [(set (match_dup 2) (const_int 0))
18924               (clobber (reg:CC FLAGS_REG))])
18925    (set (match_dup 0) (match_dup 1))]
18926   "operands[2] = gen_lowpart (SImode, operands[1]);")
18927
18928 (define_peephole2
18929   [(match_scratch:SI 2 "r")
18930    (set (match_operand:SI 0 "memory_operand" "")
18931         (match_operand:SI 1 "immediate_operand" ""))]
18932   "! optimize_size
18933    && get_attr_length (insn) >= ix86_cost->large_insn
18934    && TARGET_SPLIT_LONG_MOVES"
18935   [(set (match_dup 2) (match_dup 1))
18936    (set (match_dup 0) (match_dup 2))]
18937   "")
18938
18939 (define_peephole2
18940   [(match_scratch:HI 2 "r")
18941    (set (match_operand:HI 0 "memory_operand" "")
18942         (match_operand:HI 1 "immediate_operand" ""))]
18943   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18944   && TARGET_SPLIT_LONG_MOVES"
18945   [(set (match_dup 2) (match_dup 1))
18946    (set (match_dup 0) (match_dup 2))]
18947   "")
18948
18949 (define_peephole2
18950   [(match_scratch:QI 2 "q")
18951    (set (match_operand:QI 0 "memory_operand" "")
18952         (match_operand:QI 1 "immediate_operand" ""))]
18953   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18954   && TARGET_SPLIT_LONG_MOVES"
18955   [(set (match_dup 2) (match_dup 1))
18956    (set (match_dup 0) (match_dup 2))]
18957   "")
18958
18959 ;; Don't compare memory with zero, load and use a test instead.
18960 (define_peephole2
18961   [(set (match_operand 0 "flags_reg_operand" "")
18962         (match_operator 1 "compare_operator"
18963           [(match_operand:SI 2 "memory_operand" "")
18964            (const_int 0)]))
18965    (match_scratch:SI 3 "r")]
18966   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18967   [(set (match_dup 3) (match_dup 2))
18968    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18969   "")
18970
18971 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18972 ;; Don't split NOTs with a displacement operand, because resulting XOR
18973 ;; will not be pairable anyway.
18974 ;;
18975 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18976 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18977 ;; so this split helps here as well.
18978 ;;
18979 ;; Note: Can't do this as a regular split because we can't get proper
18980 ;; lifetime information then.
18981
18982 (define_peephole2
18983   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18984         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18985   "!optimize_size
18986    && peep2_regno_dead_p (0, FLAGS_REG)
18987    && ((TARGET_PENTIUM 
18988         && (GET_CODE (operands[0]) != MEM
18989             || !memory_displacement_operand (operands[0], SImode)))
18990        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18991   [(parallel [(set (match_dup 0)
18992                    (xor:SI (match_dup 1) (const_int -1)))
18993               (clobber (reg:CC FLAGS_REG))])]
18994   "")
18995
18996 (define_peephole2
18997   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18998         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18999   "!optimize_size
19000    && peep2_regno_dead_p (0, FLAGS_REG)
19001    && ((TARGET_PENTIUM 
19002         && (GET_CODE (operands[0]) != MEM
19003             || !memory_displacement_operand (operands[0], HImode)))
19004        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19005   [(parallel [(set (match_dup 0)
19006                    (xor:HI (match_dup 1) (const_int -1)))
19007               (clobber (reg:CC FLAGS_REG))])]
19008   "")
19009
19010 (define_peephole2
19011   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19012         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19013   "!optimize_size
19014    && peep2_regno_dead_p (0, FLAGS_REG)
19015    && ((TARGET_PENTIUM 
19016         && (GET_CODE (operands[0]) != MEM
19017             || !memory_displacement_operand (operands[0], QImode)))
19018        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19019   [(parallel [(set (match_dup 0)
19020                    (xor:QI (match_dup 1) (const_int -1)))
19021               (clobber (reg:CC FLAGS_REG))])]
19022   "")
19023
19024 ;; Non pairable "test imm, reg" instructions can be translated to
19025 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19026 ;; byte opcode instead of two, have a short form for byte operands),
19027 ;; so do it for other CPUs as well.  Given that the value was dead,
19028 ;; this should not create any new dependencies.  Pass on the sub-word
19029 ;; versions if we're concerned about partial register stalls.
19030
19031 (define_peephole2
19032   [(set (match_operand 0 "flags_reg_operand" "")
19033         (match_operator 1 "compare_operator"
19034           [(and:SI (match_operand:SI 2 "register_operand" "")
19035                    (match_operand:SI 3 "immediate_operand" ""))
19036            (const_int 0)]))]
19037   "ix86_match_ccmode (insn, CCNOmode)
19038    && (true_regnum (operands[2]) != 0
19039        || (GET_CODE (operands[3]) == CONST_INT
19040            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19041    && peep2_reg_dead_p (1, operands[2])"
19042   [(parallel
19043      [(set (match_dup 0)
19044            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19045                             (const_int 0)]))
19046       (set (match_dup 2)
19047            (and:SI (match_dup 2) (match_dup 3)))])]
19048   "")
19049
19050 ;; We don't need to handle HImode case, because it will be promoted to SImode
19051 ;; on ! TARGET_PARTIAL_REG_STALL
19052
19053 (define_peephole2
19054   [(set (match_operand 0 "flags_reg_operand" "")
19055         (match_operator 1 "compare_operator"
19056           [(and:QI (match_operand:QI 2 "register_operand" "")
19057                    (match_operand:QI 3 "immediate_operand" ""))
19058            (const_int 0)]))]
19059   "! TARGET_PARTIAL_REG_STALL
19060    && ix86_match_ccmode (insn, CCNOmode)
19061    && true_regnum (operands[2]) != 0
19062    && peep2_reg_dead_p (1, operands[2])"
19063   [(parallel
19064      [(set (match_dup 0)
19065            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19066                             (const_int 0)]))
19067       (set (match_dup 2)
19068            (and:QI (match_dup 2) (match_dup 3)))])]
19069   "")
19070
19071 (define_peephole2
19072   [(set (match_operand 0 "flags_reg_operand" "")
19073         (match_operator 1 "compare_operator"
19074           [(and:SI
19075              (zero_extract:SI
19076                (match_operand 2 "ext_register_operand" "")
19077                (const_int 8)
19078                (const_int 8))
19079              (match_operand 3 "const_int_operand" ""))
19080            (const_int 0)]))]
19081   "! TARGET_PARTIAL_REG_STALL
19082    && ix86_match_ccmode (insn, CCNOmode)
19083    && true_regnum (operands[2]) != 0
19084    && peep2_reg_dead_p (1, operands[2])"
19085   [(parallel [(set (match_dup 0)
19086                    (match_op_dup 1
19087                      [(and:SI
19088                         (zero_extract:SI
19089                           (match_dup 2)
19090                           (const_int 8)
19091                           (const_int 8))
19092                         (match_dup 3))
19093                       (const_int 0)]))
19094               (set (zero_extract:SI (match_dup 2)
19095                                     (const_int 8)
19096                                     (const_int 8))
19097                    (and:SI 
19098                      (zero_extract:SI
19099                        (match_dup 2)
19100                        (const_int 8)
19101                        (const_int 8))
19102                      (match_dup 3)))])]
19103   "")
19104
19105 ;; Don't do logical operations with memory inputs.
19106 (define_peephole2
19107   [(match_scratch:SI 2 "r")
19108    (parallel [(set (match_operand:SI 0 "register_operand" "")
19109                    (match_operator:SI 3 "arith_or_logical_operator"
19110                      [(match_dup 0)
19111                       (match_operand:SI 1 "memory_operand" "")]))
19112               (clobber (reg:CC FLAGS_REG))])]
19113   "! optimize_size && ! TARGET_READ_MODIFY"
19114   [(set (match_dup 2) (match_dup 1))
19115    (parallel [(set (match_dup 0)
19116                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19117               (clobber (reg:CC FLAGS_REG))])]
19118   "")
19119
19120 (define_peephole2
19121   [(match_scratch:SI 2 "r")
19122    (parallel [(set (match_operand:SI 0 "register_operand" "")
19123                    (match_operator:SI 3 "arith_or_logical_operator"
19124                      [(match_operand:SI 1 "memory_operand" "")
19125                       (match_dup 0)]))
19126               (clobber (reg:CC FLAGS_REG))])]
19127   "! optimize_size && ! TARGET_READ_MODIFY"
19128   [(set (match_dup 2) (match_dup 1))
19129    (parallel [(set (match_dup 0)
19130                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19131               (clobber (reg:CC FLAGS_REG))])]
19132   "")
19133
19134 ; Don't do logical operations with memory outputs
19135 ;
19136 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19137 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19138 ; the same decoder scheduling characteristics as the original.
19139
19140 (define_peephole2
19141   [(match_scratch:SI 2 "r")
19142    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19143                    (match_operator:SI 3 "arith_or_logical_operator"
19144                      [(match_dup 0)
19145                       (match_operand:SI 1 "nonmemory_operand" "")]))
19146               (clobber (reg:CC FLAGS_REG))])]
19147   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19148   [(set (match_dup 2) (match_dup 0))
19149    (parallel [(set (match_dup 2)
19150                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19151               (clobber (reg:CC FLAGS_REG))])
19152    (set (match_dup 0) (match_dup 2))]
19153   "")
19154
19155 (define_peephole2
19156   [(match_scratch:SI 2 "r")
19157    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19158                    (match_operator:SI 3 "arith_or_logical_operator"
19159                      [(match_operand:SI 1 "nonmemory_operand" "")
19160                       (match_dup 0)]))
19161               (clobber (reg:CC FLAGS_REG))])]
19162   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19163   [(set (match_dup 2) (match_dup 0))
19164    (parallel [(set (match_dup 2)
19165                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19166               (clobber (reg:CC FLAGS_REG))])
19167    (set (match_dup 0) (match_dup 2))]
19168   "")
19169
19170 ;; Attempt to always use XOR for zeroing registers.
19171 (define_peephole2
19172   [(set (match_operand 0 "register_operand" "")
19173         (match_operand 1 "const0_operand" ""))]
19174   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19175    && (! TARGET_USE_MOV0 || optimize_size)
19176    && GENERAL_REG_P (operands[0])
19177    && peep2_regno_dead_p (0, FLAGS_REG)"
19178   [(parallel [(set (match_dup 0) (const_int 0))
19179               (clobber (reg:CC FLAGS_REG))])]
19180 {
19181   operands[0] = gen_lowpart (word_mode, operands[0]);
19182 })
19183
19184 (define_peephole2
19185   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19186         (const_int 0))]
19187   "(GET_MODE (operands[0]) == QImode
19188     || GET_MODE (operands[0]) == HImode)
19189    && (! TARGET_USE_MOV0 || optimize_size)
19190    && peep2_regno_dead_p (0, FLAGS_REG)"
19191   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19192               (clobber (reg:CC FLAGS_REG))])])
19193
19194 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19195 (define_peephole2
19196   [(set (match_operand 0 "register_operand" "")
19197         (const_int -1))]
19198   "(GET_MODE (operands[0]) == HImode
19199     || GET_MODE (operands[0]) == SImode 
19200     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19201    && (optimize_size || TARGET_PENTIUM)
19202    && peep2_regno_dead_p (0, FLAGS_REG)"
19203   [(parallel [(set (match_dup 0) (const_int -1))
19204               (clobber (reg:CC FLAGS_REG))])]
19205   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19206                               operands[0]);")
19207
19208 ;; Attempt to convert simple leas to adds. These can be created by
19209 ;; move expanders.
19210 (define_peephole2
19211   [(set (match_operand:SI 0 "register_operand" "")
19212         (plus:SI (match_dup 0)
19213                  (match_operand:SI 1 "nonmemory_operand" "")))]
19214   "peep2_regno_dead_p (0, FLAGS_REG)"
19215   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19216               (clobber (reg:CC FLAGS_REG))])]
19217   "")
19218
19219 (define_peephole2
19220   [(set (match_operand:SI 0 "register_operand" "")
19221         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19222                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19223   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19224   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19225               (clobber (reg:CC FLAGS_REG))])]
19226   "operands[2] = gen_lowpart (SImode, operands[2]);")
19227
19228 (define_peephole2
19229   [(set (match_operand:DI 0 "register_operand" "")
19230         (plus:DI (match_dup 0)
19231                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19232   "peep2_regno_dead_p (0, FLAGS_REG)"
19233   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19234               (clobber (reg:CC FLAGS_REG))])]
19235   "")
19236
19237 (define_peephole2
19238   [(set (match_operand:SI 0 "register_operand" "")
19239         (mult:SI (match_dup 0)
19240                  (match_operand:SI 1 "const_int_operand" "")))]
19241   "exact_log2 (INTVAL (operands[1])) >= 0
19242    && peep2_regno_dead_p (0, FLAGS_REG)"
19243   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19244               (clobber (reg:CC FLAGS_REG))])]
19245   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19246
19247 (define_peephole2
19248   [(set (match_operand:DI 0 "register_operand" "")
19249         (mult:DI (match_dup 0)
19250                  (match_operand:DI 1 "const_int_operand" "")))]
19251   "exact_log2 (INTVAL (operands[1])) >= 0
19252    && peep2_regno_dead_p (0, FLAGS_REG)"
19253   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19256
19257 (define_peephole2
19258   [(set (match_operand:SI 0 "register_operand" "")
19259         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19260                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19261   "exact_log2 (INTVAL (operands[2])) >= 0
19262    && REGNO (operands[0]) == REGNO (operands[1])
19263    && peep2_regno_dead_p (0, FLAGS_REG)"
19264   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19265               (clobber (reg:CC FLAGS_REG))])]
19266   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19267
19268 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19269 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19270 ;; many CPUs it is also faster, since special hardware to avoid esp
19271 ;; dependencies is present.
19272
19273 ;; While some of these conversions may be done using splitters, we use peepholes
19274 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19275
19276 ;; Convert prologue esp subtractions to push.
19277 ;; We need register to push.  In order to keep verify_flow_info happy we have
19278 ;; two choices
19279 ;; - use scratch and clobber it in order to avoid dependencies
19280 ;; - use already live register
19281 ;; We can't use the second way right now, since there is no reliable way how to
19282 ;; verify that given register is live.  First choice will also most likely in
19283 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19284 ;; call clobbered registers are dead.  We may want to use base pointer as an
19285 ;; alternative when no register is available later.
19286
19287 (define_peephole2
19288   [(match_scratch:SI 0 "r")
19289    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19290               (clobber (reg:CC FLAGS_REG))
19291               (clobber (mem:BLK (scratch)))])]
19292   "optimize_size || !TARGET_SUB_ESP_4"
19293   [(clobber (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 (define_peephole2
19298   [(match_scratch:SI 0 "r")
19299    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19300               (clobber (reg:CC FLAGS_REG))
19301               (clobber (mem:BLK (scratch)))])]
19302   "optimize_size || !TARGET_SUB_ESP_8"
19303   [(clobber (match_dup 0))
19304    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19305    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19306               (clobber (mem:BLK (scratch)))])])
19307
19308 ;; Convert esp subtractions to push.
19309 (define_peephole2
19310   [(match_scratch:SI 0 "r")
19311    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19312               (clobber (reg:CC FLAGS_REG))])]
19313   "optimize_size || !TARGET_SUB_ESP_4"
19314   [(clobber (match_dup 0))
19315    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19316
19317 (define_peephole2
19318   [(match_scratch:SI 0 "r")
19319    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "optimize_size || !TARGET_SUB_ESP_8"
19322   [(clobber (match_dup 0))
19323    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19324    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19325
19326 ;; Convert epilogue deallocator to pop.
19327 (define_peephole2
19328   [(match_scratch:SI 0 "r")
19329    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19330               (clobber (reg:CC FLAGS_REG))
19331               (clobber (mem:BLK (scratch)))])]
19332   "optimize_size || !TARGET_ADD_ESP_4"
19333   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19334               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19335               (clobber (mem:BLK (scratch)))])]
19336   "")
19337
19338 ;; Two pops case is tricky, since pop causes dependency on destination register.
19339 ;; We use two registers if available.
19340 (define_peephole2
19341   [(match_scratch:SI 0 "r")
19342    (match_scratch:SI 1 "r")
19343    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19344               (clobber (reg:CC FLAGS_REG))
19345               (clobber (mem:BLK (scratch)))])]
19346   "optimize_size || !TARGET_ADD_ESP_8"
19347   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19348               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19349               (clobber (mem:BLK (scratch)))])
19350    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19351               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19352   "")
19353
19354 (define_peephole2
19355   [(match_scratch:SI 0 "r")
19356    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19357               (clobber (reg:CC FLAGS_REG))
19358               (clobber (mem:BLK (scratch)))])]
19359   "optimize_size"
19360   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19361               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19362               (clobber (mem:BLK (scratch)))])
19363    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19364               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19365   "")
19366
19367 ;; Convert esp additions to pop.
19368 (define_peephole2
19369   [(match_scratch:SI 0 "r")
19370    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19371               (clobber (reg:CC FLAGS_REG))])]
19372   ""
19373   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19374               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19375   "")
19376
19377 ;; Two pops case is tricky, since pop causes dependency on destination register.
19378 ;; We use two registers if available.
19379 (define_peephole2
19380   [(match_scratch:SI 0 "r")
19381    (match_scratch:SI 1 "r")
19382    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19383               (clobber (reg:CC FLAGS_REG))])]
19384   ""
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 1) (mem:SI (reg:SI SP_REG)))
19388               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19389   "")
19390
19391 (define_peephole2
19392   [(match_scratch:SI 0 "r")
19393    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19394               (clobber (reg:CC FLAGS_REG))])]
19395   "optimize_size"
19396   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19397               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19398    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19399               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19400   "")
19401 \f
19402 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19403 ;; required and register dies.  Similarly for 128 to plus -128.
19404 (define_peephole2
19405   [(set (match_operand 0 "flags_reg_operand" "")
19406         (match_operator 1 "compare_operator"
19407           [(match_operand 2 "register_operand" "")
19408            (match_operand 3 "const_int_operand" "")]))]
19409   "(INTVAL (operands[3]) == -1
19410     || INTVAL (operands[3]) == 1
19411     || INTVAL (operands[3]) == 128)
19412    && ix86_match_ccmode (insn, CCGCmode)
19413    && peep2_reg_dead_p (1, operands[2])"
19414   [(parallel [(set (match_dup 0)
19415                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19416               (clobber (match_dup 2))])]
19417   "")
19418 \f
19419 (define_peephole2
19420   [(match_scratch:DI 0 "r")
19421    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19422               (clobber (reg:CC FLAGS_REG))
19423               (clobber (mem:BLK (scratch)))])]
19424   "optimize_size || !TARGET_SUB_ESP_4"
19425   [(clobber (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 (define_peephole2
19430   [(match_scratch:DI 0 "r")
19431    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19432               (clobber (reg:CC FLAGS_REG))
19433               (clobber (mem:BLK (scratch)))])]
19434   "optimize_size || !TARGET_SUB_ESP_8"
19435   [(clobber (match_dup 0))
19436    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19437    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19438               (clobber (mem:BLK (scratch)))])])
19439
19440 ;; Convert esp subtractions to push.
19441 (define_peephole2
19442   [(match_scratch:DI 0 "r")
19443    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19444               (clobber (reg:CC FLAGS_REG))])]
19445   "optimize_size || !TARGET_SUB_ESP_4"
19446   [(clobber (match_dup 0))
19447    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19448
19449 (define_peephole2
19450   [(match_scratch:DI 0 "r")
19451    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19452               (clobber (reg:CC FLAGS_REG))])]
19453   "optimize_size || !TARGET_SUB_ESP_8"
19454   [(clobber (match_dup 0))
19455    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19456    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19457
19458 ;; Convert epilogue deallocator to pop.
19459 (define_peephole2
19460   [(match_scratch:DI 0 "r")
19461    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19462               (clobber (reg:CC FLAGS_REG))
19463               (clobber (mem:BLK (scratch)))])]
19464   "optimize_size || !TARGET_ADD_ESP_4"
19465   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19466               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19467               (clobber (mem:BLK (scratch)))])]
19468   "")
19469
19470 ;; Two pops case is tricky, since pop causes dependency on destination register.
19471 ;; We use two registers if available.
19472 (define_peephole2
19473   [(match_scratch:DI 0 "r")
19474    (match_scratch:DI 1 "r")
19475    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19476               (clobber (reg:CC FLAGS_REG))
19477               (clobber (mem:BLK (scratch)))])]
19478   "optimize_size || !TARGET_ADD_ESP_8"
19479   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19480               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19481               (clobber (mem:BLK (scratch)))])
19482    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19483               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19484   "")
19485
19486 (define_peephole2
19487   [(match_scratch:DI 0 "r")
19488    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19489               (clobber (reg:CC FLAGS_REG))
19490               (clobber (mem:BLK (scratch)))])]
19491   "optimize_size"
19492   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19493               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19494               (clobber (mem:BLK (scratch)))])
19495    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19496               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19497   "")
19498
19499 ;; Convert esp additions to pop.
19500 (define_peephole2
19501   [(match_scratch:DI 0 "r")
19502    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19503               (clobber (reg:CC FLAGS_REG))])]
19504   ""
19505   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19506               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19507   "")
19508
19509 ;; Two pops case is tricky, since pop causes dependency on destination register.
19510 ;; We use two registers if available.
19511 (define_peephole2
19512   [(match_scratch:DI 0 "r")
19513    (match_scratch:DI 1 "r")
19514    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19515               (clobber (reg:CC FLAGS_REG))])]
19516   ""
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 1) (mem:DI (reg:DI SP_REG)))
19520               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19521   "")
19522
19523 (define_peephole2
19524   [(match_scratch:DI 0 "r")
19525    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19526               (clobber (reg:CC FLAGS_REG))])]
19527   "optimize_size"
19528   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19529               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19530    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19531               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19532   "")
19533 \f
19534 ;; Convert imul by three, five and nine into lea
19535 (define_peephole2
19536   [(parallel
19537     [(set (match_operand:SI 0 "register_operand" "")
19538           (mult:SI (match_operand:SI 1 "register_operand" "")
19539                    (match_operand:SI 2 "const_int_operand" "")))
19540      (clobber (reg:CC FLAGS_REG))])]
19541   "INTVAL (operands[2]) == 3
19542    || INTVAL (operands[2]) == 5
19543    || INTVAL (operands[2]) == 9"
19544   [(set (match_dup 0)
19545         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19546                  (match_dup 1)))]
19547   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19548
19549 (define_peephole2
19550   [(parallel
19551     [(set (match_operand:SI 0 "register_operand" "")
19552           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19553                    (match_operand:SI 2 "const_int_operand" "")))
19554      (clobber (reg:CC FLAGS_REG))])]
19555   "!optimize_size 
19556    && (INTVAL (operands[2]) == 3
19557        || INTVAL (operands[2]) == 5
19558        || INTVAL (operands[2]) == 9)"
19559   [(set (match_dup 0) (match_dup 1))
19560    (set (match_dup 0)
19561         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19562                  (match_dup 0)))]
19563   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19564
19565 (define_peephole2
19566   [(parallel
19567     [(set (match_operand:DI 0 "register_operand" "")
19568           (mult:DI (match_operand:DI 1 "register_operand" "")
19569                    (match_operand:DI 2 "const_int_operand" "")))
19570      (clobber (reg:CC FLAGS_REG))])]
19571   "TARGET_64BIT
19572    && (INTVAL (operands[2]) == 3
19573        || INTVAL (operands[2]) == 5
19574        || INTVAL (operands[2]) == 9)"
19575   [(set (match_dup 0)
19576         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19577                  (match_dup 1)))]
19578   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19579
19580 (define_peephole2
19581   [(parallel
19582     [(set (match_operand:DI 0 "register_operand" "")
19583           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19584                    (match_operand:DI 2 "const_int_operand" "")))
19585      (clobber (reg:CC FLAGS_REG))])]
19586   "TARGET_64BIT
19587    && !optimize_size 
19588    && (INTVAL (operands[2]) == 3
19589        || INTVAL (operands[2]) == 5
19590        || INTVAL (operands[2]) == 9)"
19591   [(set (match_dup 0) (match_dup 1))
19592    (set (match_dup 0)
19593         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19594                  (match_dup 0)))]
19595   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19596
19597 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19598 ;; imul $32bit_imm, reg, reg is direct decoded.
19599 (define_peephole2
19600   [(match_scratch:DI 3 "r")
19601    (parallel [(set (match_operand:DI 0 "register_operand" "")
19602                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19603                             (match_operand:DI 2 "immediate_operand" "")))
19604               (clobber (reg:CC FLAGS_REG))])]
19605   "TARGET_K8 && !optimize_size
19606    && (GET_CODE (operands[2]) != CONST_INT
19607        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19608   [(set (match_dup 3) (match_dup 1))
19609    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19610               (clobber (reg:CC FLAGS_REG))])]
19611 "")
19612
19613 (define_peephole2
19614   [(match_scratch:SI 3 "r")
19615    (parallel [(set (match_operand:SI 0 "register_operand" "")
19616                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19617                             (match_operand:SI 2 "immediate_operand" "")))
19618               (clobber (reg:CC FLAGS_REG))])]
19619   "TARGET_K8 && !optimize_size
19620    && (GET_CODE (operands[2]) != CONST_INT
19621        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19622   [(set (match_dup 3) (match_dup 1))
19623    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19624               (clobber (reg:CC FLAGS_REG))])]
19625 "")
19626
19627 (define_peephole2
19628   [(match_scratch:SI 3 "r")
19629    (parallel [(set (match_operand:DI 0 "register_operand" "")
19630                    (zero_extend:DI
19631                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19632                               (match_operand:SI 2 "immediate_operand" ""))))
19633               (clobber (reg:CC FLAGS_REG))])]
19634   "TARGET_K8 && !optimize_size
19635    && (GET_CODE (operands[2]) != CONST_INT
19636        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19637   [(set (match_dup 3) (match_dup 1))
19638    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19639               (clobber (reg:CC FLAGS_REG))])]
19640 "")
19641
19642 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19643 ;; Convert it into imul reg, reg
19644 ;; It would be better to force assembler to encode instruction using long
19645 ;; immediate, but there is apparently no way to do so.
19646 (define_peephole2
19647   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19648                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19649                             (match_operand:DI 2 "const_int_operand" "")))
19650               (clobber (reg:CC FLAGS_REG))])
19651    (match_scratch:DI 3 "r")]
19652   "TARGET_K8 && !optimize_size
19653    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19654   [(set (match_dup 3) (match_dup 2))
19655    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19656               (clobber (reg:CC FLAGS_REG))])]
19657 {
19658   if (!rtx_equal_p (operands[0], operands[1]))
19659     emit_move_insn (operands[0], operands[1]);
19660 })
19661
19662 (define_peephole2
19663   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19664                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19665                             (match_operand:SI 2 "const_int_operand" "")))
19666               (clobber (reg:CC FLAGS_REG))])
19667    (match_scratch:SI 3 "r")]
19668   "TARGET_K8 && !optimize_size
19669    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19670   [(set (match_dup 3) (match_dup 2))
19671    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19672               (clobber (reg:CC FLAGS_REG))])]
19673 {
19674   if (!rtx_equal_p (operands[0], operands[1]))
19675     emit_move_insn (operands[0], operands[1]);
19676 })
19677
19678 (define_peephole2
19679   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19680                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19681                             (match_operand:HI 2 "immediate_operand" "")))
19682               (clobber (reg:CC FLAGS_REG))])
19683    (match_scratch:HI 3 "r")]
19684   "TARGET_K8 && !optimize_size"
19685   [(set (match_dup 3) (match_dup 2))
19686    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19687               (clobber (reg:CC FLAGS_REG))])]
19688 {
19689   if (!rtx_equal_p (operands[0], operands[1]))
19690     emit_move_insn (operands[0], operands[1]);
19691 })
19692 \f
19693 ;; Call-value patterns last so that the wildcard operand does not
19694 ;; disrupt insn-recog's switch tables.
19695
19696 (define_insn "*call_value_pop_0"
19697   [(set (match_operand 0 "" "")
19698         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19699               (match_operand:SI 2 "" "")))
19700    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19701                             (match_operand:SI 3 "immediate_operand" "")))]
19702   "!TARGET_64BIT"
19703 {
19704   if (SIBLING_CALL_P (insn))
19705     return "jmp\t%P1";
19706   else
19707     return "call\t%P1";
19708 }
19709   [(set_attr "type" "callv")])
19710
19711 (define_insn "*call_value_pop_1"
19712   [(set (match_operand 0 "" "")
19713         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19714               (match_operand:SI 2 "" "")))
19715    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19716                             (match_operand:SI 3 "immediate_operand" "i")))]
19717   "!TARGET_64BIT"
19718 {
19719   if (constant_call_address_operand (operands[1], Pmode))
19720     {
19721       if (SIBLING_CALL_P (insn))
19722         return "jmp\t%P1";
19723       else
19724         return "call\t%P1";
19725     }
19726   if (SIBLING_CALL_P (insn))
19727     return "jmp\t%A1";
19728   else
19729     return "call\t%A1";
19730 }
19731   [(set_attr "type" "callv")])
19732
19733 (define_insn "*call_value_0"
19734   [(set (match_operand 0 "" "")
19735         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19736               (match_operand:SI 2 "" "")))]
19737   "!TARGET_64BIT"
19738 {
19739   if (SIBLING_CALL_P (insn))
19740     return "jmp\t%P1";
19741   else
19742     return "call\t%P1";
19743 }
19744   [(set_attr "type" "callv")])
19745
19746 (define_insn "*call_value_0_rex64"
19747   [(set (match_operand 0 "" "")
19748         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19749               (match_operand:DI 2 "const_int_operand" "")))]
19750   "TARGET_64BIT"
19751 {
19752   if (SIBLING_CALL_P (insn))
19753     return "jmp\t%P1";
19754   else
19755     return "call\t%P1";
19756 }
19757   [(set_attr "type" "callv")])
19758
19759 (define_insn "*call_value_1"
19760   [(set (match_operand 0 "" "")
19761         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19762               (match_operand:SI 2 "" "")))]
19763   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19764 {
19765   if (constant_call_address_operand (operands[1], Pmode))
19766     return "call\t%P1";
19767   return "call\t%A1";
19768 }
19769   [(set_attr "type" "callv")])
19770
19771 (define_insn "*sibcall_value_1"
19772   [(set (match_operand 0 "" "")
19773         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19774               (match_operand:SI 2 "" "")))]
19775   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19776 {
19777   if (constant_call_address_operand (operands[1], Pmode))
19778     return "jmp\t%P1";
19779   return "jmp\t%A1";
19780 }
19781   [(set_attr "type" "callv")])
19782
19783 (define_insn "*call_value_1_rex64"
19784   [(set (match_operand 0 "" "")
19785         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19786               (match_operand:DI 2 "" "")))]
19787   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19788 {
19789   if (constant_call_address_operand (operands[1], Pmode))
19790     return "call\t%P1";
19791   return "call\t%A1";
19792 }
19793   [(set_attr "type" "callv")])
19794
19795 (define_insn "*sibcall_value_1_rex64"
19796   [(set (match_operand 0 "" "")
19797         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19798               (match_operand:DI 2 "" "")))]
19799   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19800   "jmp\t%P1"
19801   [(set_attr "type" "callv")])
19802
19803 (define_insn "*sibcall_value_1_rex64_v"
19804   [(set (match_operand 0 "" "")
19805         (call (mem:QI (reg:DI 40))
19806               (match_operand:DI 1 "" "")))]
19807   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19808   "jmp\t*%%r11"
19809   [(set_attr "type" "callv")])
19810 \f
19811 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19812 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19813 ;; caught for use by garbage collectors and the like.  Using an insn that
19814 ;; maps to SIGILL makes it more likely the program will rightfully die.
19815 ;; Keeping with tradition, "6" is in honor of #UD.
19816 (define_insn "trap"
19817   [(trap_if (const_int 1) (const_int 6))]
19818   ""
19819   ".word\t0x0b0f"
19820   [(set_attr "length" "2")])
19821
19822 (define_expand "sse_prologue_save"
19823   [(parallel [(set (match_operand:BLK 0 "" "")
19824                    (unspec:BLK [(reg:DI 21)
19825                                 (reg:DI 22)
19826                                 (reg:DI 23)
19827                                 (reg:DI 24)
19828                                 (reg:DI 25)
19829                                 (reg:DI 26)
19830                                 (reg:DI 27)
19831                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19832               (use (match_operand:DI 1 "register_operand" ""))
19833               (use (match_operand:DI 2 "immediate_operand" ""))
19834               (use (label_ref:DI (match_operand 3 "" "")))])]
19835   "TARGET_64BIT"
19836   "")
19837
19838 (define_insn "*sse_prologue_save_insn"
19839   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19840                           (match_operand:DI 4 "const_int_operand" "n")))
19841         (unspec:BLK [(reg:DI 21)
19842                      (reg:DI 22)
19843                      (reg:DI 23)
19844                      (reg:DI 24)
19845                      (reg:DI 25)
19846                      (reg:DI 26)
19847                      (reg:DI 27)
19848                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19849    (use (match_operand:DI 1 "register_operand" "r"))
19850    (use (match_operand:DI 2 "const_int_operand" "i"))
19851    (use (label_ref:DI (match_operand 3 "" "X")))]
19852   "TARGET_64BIT
19853    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19854    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19855   "*
19856 {
19857   int i;
19858   operands[0] = gen_rtx_MEM (Pmode,
19859                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19860   output_asm_insn (\"jmp\\t%A1\", operands);
19861   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19862     {
19863       operands[4] = adjust_address (operands[0], DImode, i*16);
19864       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19865       PUT_MODE (operands[4], TImode);
19866       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19867         output_asm_insn (\"rex\", operands);
19868       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19869     }
19870   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19871                              CODE_LABEL_NUMBER (operands[3]));
19872   RET;
19873 }
19874   "
19875   [(set_attr "type" "other")
19876    (set_attr "length_immediate" "0")
19877    (set_attr "length_address" "0")
19878    (set_attr "length" "135")
19879    (set_attr "memory" "store")
19880    (set_attr "modrm" "0")
19881    (set_attr "mode" "DI")])
19882
19883 (define_expand "prefetch"
19884   [(prefetch (match_operand 0 "address_operand" "")
19885              (match_operand:SI 1 "const_int_operand" "")
19886              (match_operand:SI 2 "const_int_operand" ""))]
19887   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19888 {
19889   int rw = INTVAL (operands[1]);
19890   int locality = INTVAL (operands[2]);
19891
19892   gcc_assert (rw == 0 || rw == 1);
19893   gcc_assert (locality >= 0 && locality <= 3);
19894   gcc_assert (GET_MODE (operands[0]) == Pmode
19895               || GET_MODE (operands[0]) == VOIDmode);
19896
19897   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19898      supported by SSE counterpart or the SSE prefetch is not available
19899      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19900      of locality.  */
19901   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19902     operands[2] = GEN_INT (3);
19903   else
19904     operands[1] = const0_rtx;
19905 })
19906
19907 (define_insn "*prefetch_sse"
19908   [(prefetch (match_operand:SI 0 "address_operand" "p")
19909              (const_int 0)
19910              (match_operand:SI 1 "const_int_operand" ""))]
19911   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19912 {
19913   static const char * const patterns[4] = {
19914    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19915   };
19916
19917   int locality = INTVAL (operands[1]);
19918   gcc_assert (locality >= 0 && locality <= 3);
19919
19920   return patterns[locality];  
19921 }
19922   [(set_attr "type" "sse")
19923    (set_attr "memory" "none")])
19924
19925 (define_insn "*prefetch_sse_rex"
19926   [(prefetch (match_operand:DI 0 "address_operand" "p")
19927              (const_int 0)
19928              (match_operand:SI 1 "const_int_operand" ""))]
19929   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19930 {
19931   static const char * const patterns[4] = {
19932    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19933   };
19934
19935   int locality = INTVAL (operands[1]);
19936   gcc_assert (locality >= 0 && locality <= 3);
19937
19938   return patterns[locality];  
19939 }
19940   [(set_attr "type" "sse")
19941    (set_attr "memory" "none")])
19942
19943 (define_insn "*prefetch_3dnow"
19944   [(prefetch (match_operand:SI 0 "address_operand" "p")
19945              (match_operand:SI 1 "const_int_operand" "n")
19946              (const_int 3))]
19947   "TARGET_3DNOW && !TARGET_64BIT"
19948 {
19949   if (INTVAL (operands[1]) == 0)
19950     return "prefetch\t%a0";
19951   else
19952     return "prefetchw\t%a0";
19953 }
19954   [(set_attr "type" "mmx")
19955    (set_attr "memory" "none")])
19956
19957 (define_insn "*prefetch_3dnow_rex"
19958   [(prefetch (match_operand:DI 0 "address_operand" "p")
19959              (match_operand:SI 1 "const_int_operand" "n")
19960              (const_int 3))]
19961   "TARGET_3DNOW && TARGET_64BIT"
19962 {
19963   if (INTVAL (operands[1]) == 0)
19964     return "prefetch\t%a0";
19965   else
19966     return "prefetchw\t%a0";
19967 }
19968   [(set_attr "type" "mmx")
19969    (set_attr "memory" "none")])
19970
19971 (define_expand "stack_protect_set"
19972   [(match_operand 0 "memory_operand" "")
19973    (match_operand 1 "memory_operand" "")]
19974   ""
19975 {
19976 #ifdef TARGET_THREAD_SSP_OFFSET
19977   if (TARGET_64BIT)
19978     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19979                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19980   else
19981     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19982                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19983 #else
19984   if (TARGET_64BIT)
19985     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19986   else
19987     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19988 #endif
19989   DONE;
19990 })
19991
19992 (define_insn "stack_protect_set_si"
19993   [(set (match_operand:SI 0 "memory_operand" "=m")
19994         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19995    (set (match_scratch:SI 2 "=&r") (const_int 0))
19996    (clobber (reg:CC FLAGS_REG))]
19997   ""
19998   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19999   [(set_attr "type" "multi")])
20000
20001 (define_insn "stack_protect_set_di"
20002   [(set (match_operand:DI 0 "memory_operand" "=m")
20003         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20004    (set (match_scratch:DI 2 "=&r") (const_int 0))
20005    (clobber (reg:CC FLAGS_REG))]
20006   "TARGET_64BIT"
20007   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20008   [(set_attr "type" "multi")])
20009
20010 (define_insn "stack_tls_protect_set_si"
20011   [(set (match_operand:SI 0 "memory_operand" "=m")
20012         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20013    (set (match_scratch:SI 2 "=&r") (const_int 0))
20014    (clobber (reg:CC FLAGS_REG))]
20015   ""
20016   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20017   [(set_attr "type" "multi")])
20018
20019 (define_insn "stack_tls_protect_set_di"
20020   [(set (match_operand:DI 0 "memory_operand" "=m")
20021         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20022    (set (match_scratch:DI 2 "=&r") (const_int 0))
20023    (clobber (reg:CC FLAGS_REG))]
20024   "TARGET_64BIT"
20025   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20026   [(set_attr "type" "multi")])
20027
20028 (define_expand "stack_protect_test"
20029   [(match_operand 0 "memory_operand" "")
20030    (match_operand 1 "memory_operand" "")
20031    (match_operand 2 "" "")]
20032   ""
20033 {
20034   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20035   ix86_compare_op0 = operands[0];
20036   ix86_compare_op1 = operands[1];
20037   ix86_compare_emitted = flags;
20038
20039 #ifdef TARGET_THREAD_SSP_OFFSET
20040   if (TARGET_64BIT)
20041     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20042                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20043   else
20044     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20045                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20046 #else
20047   if (TARGET_64BIT)
20048     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20049   else
20050     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20051 #endif
20052   emit_jump_insn (gen_beq (operands[2]));
20053   DONE;
20054 })
20055
20056 (define_insn "stack_protect_test_si"
20057   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20058         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20059                      (match_operand:SI 2 "memory_operand" "m")]
20060                     UNSPEC_SP_TEST))
20061    (clobber (match_scratch:SI 3 "=&r"))]
20062   ""
20063   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20064   [(set_attr "type" "multi")])
20065
20066 (define_insn "stack_protect_test_di"
20067   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20068         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20069                      (match_operand:DI 2 "memory_operand" "m")]
20070                     UNSPEC_SP_TEST))
20071    (clobber (match_scratch:DI 3 "=&r"))]
20072   "TARGET_64BIT"
20073   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20074   [(set_attr "type" "multi")])
20075
20076 (define_insn "stack_tls_protect_test_si"
20077   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20078         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20079                      (match_operand:SI 2 "const_int_operand" "i")]
20080                     UNSPEC_SP_TLS_TEST))
20081    (clobber (match_scratch:SI 3 "=r"))]
20082   ""
20083   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20084   [(set_attr "type" "multi")])
20085
20086 (define_insn "stack_tls_protect_test_di"
20087   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20088         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20089                      (match_operand:DI 2 "const_int_operand" "i")]
20090                     UNSPEC_SP_TLS_TEST))
20091    (clobber (match_scratch:DI 3 "=r"))]
20092   "TARGET_64BIT"
20093   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20094   [(set_attr "type" "multi")])
20095
20096 (include "sse.md")
20097 (include "mmx.md")
20098 (include "sync.md")