Import a stripped down version of gcc-4.1.1
[dragonfly.git] / contrib / gcc-4.1 / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 20)
79    (UNSPEC_FNSTSW               21)
80    (UNSPEC_SAHF                 22)
81    (UNSPEC_FSTCW                23)
82    (UNSPEC_ADD_CARRY            24)
83    (UNSPEC_FLDCW                25)
84    (UNSPEC_REP                  26)
85    (UNSPEC_EH_RETURN            27)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDQQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121
122    ; x87 Rounding
123    (UNSPEC_FRNDINT_FLOOR        70)
124    (UNSPEC_FRNDINT_CEIL         71)
125    (UNSPEC_FRNDINT_TRUNC        72)
126    (UNSPEC_FRNDINT_MASK_PM      73)
127    (UNSPEC_FIST_FLOOR           74)
128    (UNSPEC_FIST_CEIL            75)
129
130    ; x87 Double output FP
131    (UNSPEC_SINCOS_COS           80)
132    (UNSPEC_SINCOS_SIN           81)
133    (UNSPEC_TAN_ONE              82)
134    (UNSPEC_TAN_TAN              83)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149   ])
150
151 (define_constants
152   [(UNSPECV_BLOCKAGE            0)
153    (UNSPECV_STACK_PROBE         1)
154    (UNSPECV_EMMS                2)
155    (UNSPECV_LDMXCSR             3)
156    (UNSPECV_STMXCSR             4)
157    (UNSPECV_FEMMS               5)
158    (UNSPECV_CLFLUSH             6)
159    (UNSPECV_ALIGN               7)
160    (UNSPECV_MONITOR             8)
161    (UNSPECV_MWAIT               9)
162    (UNSPECV_CMPXCHG_1           10)
163    (UNSPECV_CMPXCHG_2           11)
164    (UNSPECV_XCHG                12)
165    (UNSPECV_LOCK                13)
166   ])
167
168 ;; Registers by name.
169 (define_constants
170   [(BP_REG                       6)
171    (SP_REG                       7)
172    (FLAGS_REG                   17)
173    (FPSR_REG                    18)
174    (DIRFLAG_REG                 19)
175   ])
176
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; from i386.c.
179
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first.  This allows for better optimization.  For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
184
185 \f
186 ;; Processor type.  This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189   (const (symbol_ref "ix86_tune")))
190
191 ;; A basic instruction type.  Refinements due to arguments to be
192 ;; provided in other attributes.
193 (define_attr "type"
194   "other,multi,
195    alu,alu1,negnot,imov,imovx,lea,
196    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197    icmp,test,ibr,setcc,icmov,
198    push,pop,call,callv,leave,
199    str,cld,
200    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201    sselog,sselog1,sseiadd,sseishft,sseimul,
202    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204   (const_string "other"))
205
206 ;; Main data type used by the insn
207 (define_attr "mode"
208   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209   (const_string "unknown"))
210
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214            (const_string "i387")
215          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
217            (const_string "sse")
218          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
219            (const_string "mmx")
220          (eq_attr "type" "other")
221            (const_string "unknown")]
222          (const_string "integer")))
223
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
227            (const_int 0)
228          (eq_attr "unit" "i387,sse,mmx")
229            (const_int 0)
230          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
231                           imul,icmp,push,pop")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233          (eq_attr "type" "imov,test")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235          (eq_attr "type" "call")
236            (if_then_else (match_operand 0 "constant_call_address_operand" "")
237              (const_int 4)
238              (const_int 0))
239          (eq_attr "type" "callv")
240            (if_then_else (match_operand 1 "constant_call_address_operand" "")
241              (const_int 4)
242              (const_int 0))
243          ;; We don't know the size before shorten_branches.  Expect
244          ;; the instruction to fit for better scheduling.
245          (eq_attr "type" "ibr")
246            (const_int 1)
247          ]
248          (symbol_ref "/* Update immediate_length and other attributes! */
249                       gcc_unreachable (),1")))
250
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
254            (const_int 0)
255          (and (eq_attr "type" "call")
256               (match_operand 0 "constant_call_address_operand" ""))
257              (const_int 0)
258          (and (eq_attr "type" "callv")
259               (match_operand 1 "constant_call_address_operand" ""))
260              (const_int 0)
261          ]
262          (symbol_ref "ix86_attr_length_address_default (insn)")))
263
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266   (if_then_else (ior (eq_attr "mode" "HI")
267                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" "" 
273   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
274     (const_int 1)
275     (const_int 0)))
276
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
279   (if_then_else 
280     (ior (eq_attr "type" "imovx,setcc,icmov")
281          (eq_attr "unit" "sse,mmx"))
282     (const_int 1)
283     (const_int 0)))
284
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287   (cond [(and (eq_attr "mode" "DI")
288               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
289            (const_int 1)
290          (and (eq_attr "mode" "QI")
291               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292                   (const_int 0)))
293            (const_int 1)
294          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
295              (const_int 0))
296            (const_int 1)
297         ]
298         (const_int 0)))
299
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302   (cond [(eq_attr "type" "str,cld,leave")
303            (const_int 0)
304          (eq_attr "unit" "i387")
305            (const_int 0)
306          (and (eq_attr "type" "incdec")
307               (ior (match_operand:SI 1 "register_operand" "")
308                    (match_operand:HI 1 "register_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "push")
311               (not (match_operand 1 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "pop")
314               (not (match_operand 0 "memory_operand" "")))
315            (const_int 0)
316          (and (eq_attr "type" "imov")
317               (and (match_operand 0 "register_operand" "")
318                    (match_operand 1 "immediate_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "call")
321               (match_operand 0 "constant_call_address_operand" ""))
322              (const_int 0)
323          (and (eq_attr "type" "callv")
324               (match_operand 1 "constant_call_address_operand" ""))
325              (const_int 0)
326          ]
327          (const_int 1)))
328
329 ;; The (bounding maximum) length of an instruction in bytes.
330 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
331 ;; Later we may want to split them and compute proper length as for
332 ;; other insns.
333 (define_attr "length" ""
334   (cond [(eq_attr "type" "other,multi,fistp,frndint")
335            (const_int 16)
336          (eq_attr "type" "fcmp")
337            (const_int 4)
338          (eq_attr "unit" "i387")
339            (plus (const_int 2)
340                  (plus (attr "prefix_data16")
341                        (attr "length_address")))]
342          (plus (plus (attr "modrm")
343                      (plus (attr "prefix_0f")
344                            (plus (attr "prefix_rex")
345                                  (const_int 1))))
346                (plus (attr "prefix_rep")
347                      (plus (attr "prefix_data16")
348                            (plus (attr "length_immediate")
349                                  (attr "length_address")))))))
350
351 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
352 ;; `store' if there is a simple memory reference therein, or `unknown'
353 ;; if the instruction is complex.
354
355 (define_attr "memory" "none,load,store,both,unknown"
356   (cond [(eq_attr "type" "other,multi,str")
357            (const_string "unknown")
358          (eq_attr "type" "lea,fcmov,fpspc,cld")
359            (const_string "none")
360          (eq_attr "type" "fistp,leave")
361            (const_string "both")
362          (eq_attr "type" "frndint")
363            (const_string "load")
364          (eq_attr "type" "push")
365            (if_then_else (match_operand 1 "memory_operand" "")
366              (const_string "both")
367              (const_string "store"))
368          (eq_attr "type" "pop")
369            (if_then_else (match_operand 0 "memory_operand" "")
370              (const_string "both")
371              (const_string "load"))
372          (eq_attr "type" "setcc")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "store")
375              (const_string "none"))
376          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
377            (if_then_else (ior (match_operand 0 "memory_operand" "")
378                               (match_operand 1 "memory_operand" ""))
379              (const_string "load")
380              (const_string "none"))
381          (eq_attr "type" "ibr")
382            (if_then_else (match_operand 0 "memory_operand" "")
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "call")
386            (if_then_else (match_operand 0 "constant_call_address_operand" "")
387              (const_string "none")
388              (const_string "load"))
389          (eq_attr "type" "callv")
390            (if_then_else (match_operand 1 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
394               (match_operand 1 "memory_operand" ""))
395            (const_string "both")
396          (and (match_operand 0 "memory_operand" "")
397               (match_operand 1 "memory_operand" ""))
398            (const_string "both")
399          (match_operand 0 "memory_operand" "")
400            (const_string "store")
401          (match_operand 1 "memory_operand" "")
402            (const_string "load")
403          (and (eq_attr "type"
404                  "!alu1,negnot,ishift1,
405                    imov,imovx,icmp,test,
406                    fmov,fcmp,fsgn,
407                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
408                    mmx,mmxmov,mmxcmp,mmxcvt")
409               (match_operand 2 "memory_operand" ""))
410            (const_string "load")
411          (and (eq_attr "type" "icmov")
412               (match_operand 3 "memory_operand" ""))
413            (const_string "load")
414         ]
415         (const_string "none")))
416
417 ;; Indicates if an instruction has both an immediate and a displacement.
418
419 (define_attr "imm_disp" "false,true,unknown"
420   (cond [(eq_attr "type" "other,multi")
421            (const_string "unknown")
422          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
423               (and (match_operand 0 "memory_displacement_operand" "")
424                    (match_operand 1 "immediate_operand" "")))
425            (const_string "true")
426          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 2 "immediate_operand" "")))
429            (const_string "true")
430         ]
431         (const_string "false")))
432
433 ;; Indicates if an FP operation has an integer source.
434
435 (define_attr "fp_int_src" "false,true"
436   (const_string "false"))
437
438 ;; Defines rounding mode of an FP operation.
439
440 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
441   (const_string "any"))
442
443 ;; Describe a user's asm statement.
444 (define_asm_attributes
445   [(set_attr "length" "128")
446    (set_attr "type" "multi")])
447
448 ;; All x87 floating point modes
449 (define_mode_macro X87MODEF [SF DF XF])
450  
451 ;; All integer modes handled by x87 fisttp operator.
452 (define_mode_macro X87MODEI [HI SI DI])
453
454 ;; All integer modes handled by integer x87 operators.
455 (define_mode_macro X87MODEI12 [HI SI])
456
457 ;; All SSE floating point modes
458 (define_mode_macro SSEMODEF [SF DF])
459  
460 ;; All integer modes handled by SSE cvtts?2si* operators.
461 (define_mode_macro SSEMODEI24 [SI DI])
462
463 \f
464 ;; Scheduling descriptions
465
466 (include "pentium.md")
467 (include "ppro.md")
468 (include "k6.md")
469 (include "athlon.md")
470
471 \f
472 ;; Operand and operator predicates
473
474 (include "predicates.md")
475
476 \f
477 ;; Compare instructions.
478
479 ;; All compare insns have expanders that save the operands away without
480 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
481 ;; after the cmp) will actually emit the cmpM.
482
483 (define_expand "cmpti"
484   [(set (reg:CC FLAGS_REG)
485         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
486                     (match_operand:TI 1 "x86_64_general_operand" "")))]
487   "TARGET_64BIT"
488 {
489   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
490     operands[0] = force_reg (TImode, operands[0]);
491   ix86_compare_op0 = operands[0];
492   ix86_compare_op1 = operands[1];
493   DONE;
494 })
495
496 (define_expand "cmpdi"
497   [(set (reg:CC FLAGS_REG)
498         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
499                     (match_operand:DI 1 "x86_64_general_operand" "")))]
500   ""
501 {
502   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503     operands[0] = force_reg (DImode, operands[0]);
504   ix86_compare_op0 = operands[0];
505   ix86_compare_op1 = operands[1];
506   DONE;
507 })
508
509 (define_expand "cmpsi"
510   [(set (reg:CC FLAGS_REG)
511         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
512                     (match_operand:SI 1 "general_operand" "")))]
513   ""
514 {
515   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516     operands[0] = force_reg (SImode, operands[0]);
517   ix86_compare_op0 = operands[0];
518   ix86_compare_op1 = operands[1];
519   DONE;
520 })
521
522 (define_expand "cmphi"
523   [(set (reg:CC FLAGS_REG)
524         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
525                     (match_operand:HI 1 "general_operand" "")))]
526   ""
527 {
528   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529     operands[0] = force_reg (HImode, operands[0]);
530   ix86_compare_op0 = operands[0];
531   ix86_compare_op1 = operands[1];
532   DONE;
533 })
534
535 (define_expand "cmpqi"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
538                     (match_operand:QI 1 "general_operand" "")))]
539   "TARGET_QIMODE_MATH"
540 {
541   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542     operands[0] = force_reg (QImode, operands[0]);
543   ix86_compare_op0 = operands[0];
544   ix86_compare_op1 = operands[1];
545   DONE;
546 })
547
548 (define_insn "cmpdi_ccno_1_rex64"
549   [(set (reg FLAGS_REG)
550         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
551                  (match_operand:DI 1 "const0_operand" "n,n")))]
552   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
553   "@
554    test{q}\t{%0, %0|%0, %0}
555    cmp{q}\t{%1, %0|%0, %1}"
556   [(set_attr "type" "test,icmp")
557    (set_attr "length_immediate" "0,1")
558    (set_attr "mode" "DI")])
559
560 (define_insn "*cmpdi_minus_1_rex64"
561   [(set (reg FLAGS_REG)
562         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
563                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
564                  (const_int 0)))]
565   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
566   "cmp{q}\t{%1, %0|%0, %1}"
567   [(set_attr "type" "icmp")
568    (set_attr "mode" "DI")])
569
570 (define_expand "cmpdi_1_rex64"
571   [(set (reg:CC FLAGS_REG)
572         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
573                     (match_operand:DI 1 "general_operand" "")))]
574   "TARGET_64BIT"
575   "")
576
577 (define_insn "cmpdi_1_insn_rex64"
578   [(set (reg FLAGS_REG)
579         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
580                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
581   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
582   "cmp{q}\t{%1, %0|%0, %1}"
583   [(set_attr "type" "icmp")
584    (set_attr "mode" "DI")])
585
586
587 (define_insn "*cmpsi_ccno_1"
588   [(set (reg FLAGS_REG)
589         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
590                  (match_operand:SI 1 "const0_operand" "n,n")))]
591   "ix86_match_ccmode (insn, CCNOmode)"
592   "@
593    test{l}\t{%0, %0|%0, %0}
594    cmp{l}\t{%1, %0|%0, %1}"
595   [(set_attr "type" "test,icmp")
596    (set_attr "length_immediate" "0,1")
597    (set_attr "mode" "SI")])
598
599 (define_insn "*cmpsi_minus_1"
600   [(set (reg FLAGS_REG)
601         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
602                            (match_operand:SI 1 "general_operand" "ri,mr"))
603                  (const_int 0)))]
604   "ix86_match_ccmode (insn, CCGOCmode)"
605   "cmp{l}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "SI")])
608
609 (define_expand "cmpsi_1"
610   [(set (reg:CC FLAGS_REG)
611         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
612                     (match_operand:SI 1 "general_operand" "ri,mr")))]
613   ""
614   "")
615
616 (define_insn "*cmpsi_1_insn"
617   [(set (reg FLAGS_REG)
618         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                  (match_operand:SI 1 "general_operand" "ri,mr")))]
620   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621     && ix86_match_ccmode (insn, CCmode)"
622   "cmp{l}\t{%1, %0|%0, %1}"
623   [(set_attr "type" "icmp")
624    (set_attr "mode" "SI")])
625
626 (define_insn "*cmphi_ccno_1"
627   [(set (reg FLAGS_REG)
628         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
629                  (match_operand:HI 1 "const0_operand" "n,n")))]
630   "ix86_match_ccmode (insn, CCNOmode)"
631   "@
632    test{w}\t{%0, %0|%0, %0}
633    cmp{w}\t{%1, %0|%0, %1}"
634   [(set_attr "type" "test,icmp")
635    (set_attr "length_immediate" "0,1")
636    (set_attr "mode" "HI")])
637
638 (define_insn "*cmphi_minus_1"
639   [(set (reg FLAGS_REG)
640         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
641                            (match_operand:HI 1 "general_operand" "ri,mr"))
642                  (const_int 0)))]
643   "ix86_match_ccmode (insn, CCGOCmode)"
644   "cmp{w}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "HI")])
647
648 (define_insn "*cmphi_1"
649   [(set (reg FLAGS_REG)
650         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
651                  (match_operand:HI 1 "general_operand" "ri,mr")))]
652   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
653    && ix86_match_ccmode (insn, CCmode)"
654   "cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "icmp")
656    (set_attr "mode" "HI")])
657
658 (define_insn "*cmpqi_ccno_1"
659   [(set (reg FLAGS_REG)
660         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
661                  (match_operand:QI 1 "const0_operand" "n,n")))]
662   "ix86_match_ccmode (insn, CCNOmode)"
663   "@
664    test{b}\t{%0, %0|%0, %0}
665    cmp{b}\t{$0, %0|%0, 0}"
666   [(set_attr "type" "test,icmp")
667    (set_attr "length_immediate" "0,1")
668    (set_attr "mode" "QI")])
669
670 (define_insn "*cmpqi_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
673                  (match_operand:QI 1 "general_operand" "qi,mq")))]
674   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675     && ix86_match_ccmode (insn, CCmode)"
676   "cmp{b}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "QI")])
679
680 (define_insn "*cmpqi_minus_1"
681   [(set (reg FLAGS_REG)
682         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
683                            (match_operand:QI 1 "general_operand" "qi,mq"))
684                  (const_int 0)))]
685   "ix86_match_ccmode (insn, CCGOCmode)"
686   "cmp{b}\t{%1, %0|%0, %1}"
687   [(set_attr "type" "icmp")
688    (set_attr "mode" "QI")])
689
690 (define_insn "*cmpqi_ext_1"
691   [(set (reg FLAGS_REG)
692         (compare
693           (match_operand:QI 0 "general_operand" "Qm")
694           (subreg:QI
695             (zero_extract:SI
696               (match_operand 1 "ext_register_operand" "Q")
697               (const_int 8)
698               (const_int 8)) 0)))]
699   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
700   "cmp{b}\t{%h1, %0|%0, %h1}"
701   [(set_attr "type" "icmp")
702    (set_attr "mode" "QI")])
703
704 (define_insn "*cmpqi_ext_1_rex64"
705   [(set (reg FLAGS_REG)
706         (compare
707           (match_operand:QI 0 "register_operand" "Q")
708           (subreg:QI
709             (zero_extract:SI
710               (match_operand 1 "ext_register_operand" "Q")
711               (const_int 8)
712               (const_int 8)) 0)))]
713   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
714   "cmp{b}\t{%h1, %0|%0, %h1}"
715   [(set_attr "type" "icmp")
716    (set_attr "mode" "QI")])
717
718 (define_insn "*cmpqi_ext_2"
719   [(set (reg FLAGS_REG)
720         (compare
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 0 "ext_register_operand" "Q")
724               (const_int 8)
725               (const_int 8)) 0)
726           (match_operand:QI 1 "const0_operand" "n")))]
727   "ix86_match_ccmode (insn, CCNOmode)"
728   "test{b}\t%h0, %h0"
729   [(set_attr "type" "test")
730    (set_attr "length_immediate" "0")
731    (set_attr "mode" "QI")])
732
733 (define_expand "cmpqi_ext_3"
734   [(set (reg:CC FLAGS_REG)
735         (compare:CC
736           (subreg:QI
737             (zero_extract:SI
738               (match_operand 0 "ext_register_operand" "")
739               (const_int 8)
740               (const_int 8)) 0)
741           (match_operand:QI 1 "general_operand" "")))]
742   ""
743   "")
744
745 (define_insn "cmpqi_ext_3_insn"
746   [(set (reg FLAGS_REG)
747         (compare
748           (subreg:QI
749             (zero_extract:SI
750               (match_operand 0 "ext_register_operand" "Q")
751               (const_int 8)
752               (const_int 8)) 0)
753           (match_operand:QI 1 "general_operand" "Qmn")))]
754   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755   "cmp{b}\t{%1, %h0|%h0, %1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "QI")])
758
759 (define_insn "cmpqi_ext_3_insn_rex64"
760   [(set (reg FLAGS_REG)
761         (compare
762           (subreg:QI
763             (zero_extract:SI
764               (match_operand 0 "ext_register_operand" "Q")
765               (const_int 8)
766               (const_int 8)) 0)
767           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
768   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769   "cmp{b}\t{%1, %h0|%h0, %1}"
770   [(set_attr "type" "icmp")
771    (set_attr "mode" "QI")])
772
773 (define_insn "*cmpqi_ext_4"
774   [(set (reg FLAGS_REG)
775         (compare
776           (subreg:QI
777             (zero_extract:SI
778               (match_operand 0 "ext_register_operand" "Q")
779               (const_int 8)
780               (const_int 8)) 0)
781           (subreg:QI
782             (zero_extract:SI
783               (match_operand 1 "ext_register_operand" "Q")
784               (const_int 8)
785               (const_int 8)) 0)))]
786   "ix86_match_ccmode (insn, CCmode)"
787   "cmp{b}\t{%h1, %h0|%h0, %h1}"
788   [(set_attr "type" "icmp")
789    (set_attr "mode" "QI")])
790
791 ;; These implement float point compares.
792 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
793 ;; which would allow mix and match FP modes on the compares.  Which is what
794 ;; the old patterns did, but with many more of them.
795
796 (define_expand "cmpxf"
797   [(set (reg:CC FLAGS_REG)
798         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
799                     (match_operand:XF 1 "nonmemory_operand" "")))]
800   "TARGET_80387"
801 {
802   ix86_compare_op0 = operands[0];
803   ix86_compare_op1 = operands[1];
804   DONE;
805 })
806
807 (define_expand "cmpdf"
808   [(set (reg:CC FLAGS_REG)
809         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
810                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
811   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
812 {
813   ix86_compare_op0 = operands[0];
814   ix86_compare_op1 = operands[1];
815   DONE;
816 })
817
818 (define_expand "cmpsf"
819   [(set (reg:CC FLAGS_REG)
820         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
821                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
822   "TARGET_80387 || TARGET_SSE_MATH"
823 {
824   ix86_compare_op0 = operands[0];
825   ix86_compare_op1 = operands[1];
826   DONE;
827 })
828
829 ;; FP compares, step 1:
830 ;; Set the FP condition codes.
831 ;;
832 ;; CCFPmode     compare with exceptions
833 ;; CCFPUmode    compare with no exceptions
834
835 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
836 ;; used to manage the reg stack popping would not be preserved.
837
838 (define_insn "*cmpfp_0"
839   [(set (match_operand:HI 0 "register_operand" "=a")
840         (unspec:HI
841           [(compare:CCFP
842              (match_operand 1 "register_operand" "f")
843              (match_operand 2 "const0_operand" "X"))]
844         UNSPEC_FNSTSW))]
845   "TARGET_80387
846    && FLOAT_MODE_P (GET_MODE (operands[1]))
847    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
848   "* return output_fp_compare (insn, operands, 0, 0);"
849   [(set_attr "type" "multi")
850    (set_attr "unit" "i387")
851    (set (attr "mode")
852      (cond [(match_operand:SF 1 "" "")
853               (const_string "SF")
854             (match_operand:DF 1 "" "")
855               (const_string "DF")
856            ]
857            (const_string "XF")))])
858
859 (define_insn "*cmpfp_sf"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand:SF 1 "register_operand" "f")
864              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
865           UNSPEC_FNSTSW))]
866   "TARGET_80387"
867   "* return output_fp_compare (insn, operands, 0, 0);"
868   [(set_attr "type" "multi")
869    (set_attr "unit" "i387")
870    (set_attr "mode" "SF")])
871
872 (define_insn "*cmpfp_df"
873   [(set (match_operand:HI 0 "register_operand" "=a")
874         (unspec:HI
875           [(compare:CCFP
876              (match_operand:DF 1 "register_operand" "f")
877              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
878           UNSPEC_FNSTSW))]
879   "TARGET_80387"
880   "* return output_fp_compare (insn, operands, 0, 0);"
881   [(set_attr "type" "multi")
882    (set_attr "unit" "i387")
883    (set_attr "mode" "DF")])
884
885 (define_insn "*cmpfp_xf"
886   [(set (match_operand:HI 0 "register_operand" "=a")
887         (unspec:HI
888           [(compare:CCFP
889              (match_operand:XF 1 "register_operand" "f")
890              (match_operand:XF 2 "register_operand" "f"))]
891           UNSPEC_FNSTSW))]
892   "TARGET_80387"
893   "* return output_fp_compare (insn, operands, 0, 0);"
894   [(set_attr "type" "multi")
895    (set_attr "unit" "i387")
896    (set_attr "mode" "XF")])
897
898 (define_insn "*cmpfp_u"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFPU
902              (match_operand 1 "register_operand" "f")
903              (match_operand 2 "register_operand" "f"))]
904           UNSPEC_FNSTSW))]
905   "TARGET_80387
906    && FLOAT_MODE_P (GET_MODE (operands[1]))
907    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
908   "* return output_fp_compare (insn, operands, 0, 1);"
909   [(set_attr "type" "multi")
910    (set_attr "unit" "i387")
911    (set (attr "mode")
912      (cond [(match_operand:SF 1 "" "")
913               (const_string "SF")
914             (match_operand:DF 1 "" "")
915               (const_string "DF")
916            ]
917            (const_string "XF")))])
918
919 (define_insn "*cmpfp_<mode>"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFP
923              (match_operand 1 "register_operand" "f")
924              (match_operator 3 "float_operator"
925                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
928    && FLOAT_MODE_P (GET_MODE (operands[1]))
929    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
930   "* return output_fp_compare (insn, operands, 0, 0);"
931   [(set_attr "type" "multi")
932    (set_attr "unit" "i387")
933    (set_attr "fp_int_src" "true")
934    (set_attr "mode" "<MODE>")])
935
936 ;; FP compares, step 2
937 ;; Move the fpsw to ax.
938
939 (define_insn "x86_fnstsw_1"
940   [(set (match_operand:HI 0 "register_operand" "=a")
941         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
942   "TARGET_80387"
943   "fnstsw\t%0"
944   [(set_attr "length" "2")
945    (set_attr "mode" "SI")
946    (set_attr "unit" "i387")])
947
948 ;; FP compares, step 3
949 ;; Get ax into flags, general case.
950
951 (define_insn "x86_sahf_1"
952   [(set (reg:CC FLAGS_REG)
953         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
954   "!TARGET_64BIT"
955   "sahf"
956   [(set_attr "length" "1")
957    (set_attr "athlon_decode" "vector")
958    (set_attr "mode" "SI")])
959
960 ;; Pentium Pro can do steps 1 through 3 in one go.
961
962 (define_insn "*cmpfp_i_mixed"
963   [(set (reg:CCFP FLAGS_REG)
964         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
965                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
966   "TARGET_MIX_SSE_I387
967    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969   "* return output_fp_compare (insn, operands, 1, 0);"
970   [(set_attr "type" "fcmp,ssecomi")
971    (set (attr "mode")
972      (if_then_else (match_operand:SF 1 "" "")
973         (const_string "SF")
974         (const_string "DF")))
975    (set_attr "athlon_decode" "vector")])
976
977 (define_insn "*cmpfp_i_sse"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "x")
980                       (match_operand 1 "nonimmediate_operand" "xm")))]
981   "TARGET_SSE_MATH
982    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984   "* return output_fp_compare (insn, operands, 1, 0);"
985   [(set_attr "type" "ssecomi")
986    (set (attr "mode")
987      (if_then_else (match_operand:SF 1 "" "")
988         (const_string "SF")
989         (const_string "DF")))
990    (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_i_i387"
993   [(set (reg:CCFP FLAGS_REG)
994         (compare:CCFP (match_operand 0 "register_operand" "f")
995                       (match_operand 1 "register_operand" "f")))]
996   "TARGET_80387 && TARGET_CMOVE
997    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
998    && FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp")
1002    (set (attr "mode")
1003      (cond [(match_operand:SF 1 "" "")
1004               (const_string "SF")
1005             (match_operand:DF 1 "" "")
1006               (const_string "DF")
1007            ]
1008            (const_string "XF")))
1009    (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_iu_mixed"
1012   [(set (reg:CCFPU FLAGS_REG)
1013         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1014                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1015   "TARGET_MIX_SSE_I387
1016    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018   "* return output_fp_compare (insn, operands, 1, 1);"
1019   [(set_attr "type" "fcmp,ssecomi")
1020    (set (attr "mode")
1021      (if_then_else (match_operand:SF 1 "" "")
1022         (const_string "SF")
1023         (const_string "DF")))
1024    (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_sse"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "x")
1029                        (match_operand 1 "nonimmediate_operand" "xm")))]
1030   "TARGET_SSE_MATH
1031    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 1);"
1034   [(set_attr "type" "ssecomi")
1035    (set (attr "mode")
1036      (if_then_else (match_operand:SF 1 "" "")
1037         (const_string "SF")
1038         (const_string "DF")))
1039    (set_attr "athlon_decode" "vector")])
1040
1041 (define_insn "*cmpfp_iu_387"
1042   [(set (reg:CCFPU FLAGS_REG)
1043         (compare:CCFPU (match_operand 0 "register_operand" "f")
1044                        (match_operand 1 "register_operand" "f")))]
1045   "TARGET_80387 && TARGET_CMOVE
1046    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1047    && FLOAT_MODE_P (GET_MODE (operands[0]))
1048    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1049   "* return output_fp_compare (insn, operands, 1, 1);"
1050   [(set_attr "type" "fcmp")
1051    (set (attr "mode")
1052      (cond [(match_operand:SF 1 "" "")
1053               (const_string "SF")
1054             (match_operand:DF 1 "" "")
1055               (const_string "DF")
1056            ]
1057            (const_string "XF")))
1058    (set_attr "athlon_decode" "vector")])
1059 \f
1060 ;; Move instructions.
1061
1062 ;; General case of fullword move.
1063
1064 (define_expand "movsi"
1065   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1066         (match_operand:SI 1 "general_operand" ""))]
1067   ""
1068   "ix86_expand_move (SImode, operands); DONE;")
1069
1070 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1071 ;; general_operand.
1072 ;;
1073 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1074 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1075 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1076 ;; targets without our curiosities, and it is just as easy to represent
1077 ;; this differently.
1078
1079 (define_insn "*pushsi2"
1080   [(set (match_operand:SI 0 "push_operand" "=<")
1081         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1082   "!TARGET_64BIT"
1083   "push{l}\t%1"
1084   [(set_attr "type" "push")
1085    (set_attr "mode" "SI")])
1086
1087 ;; For 64BIT abi we always round up to 8 bytes.
1088 (define_insn "*pushsi2_rex64"
1089   [(set (match_operand:SI 0 "push_operand" "=X")
1090         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1091   "TARGET_64BIT"
1092   "push{q}\t%q1"
1093   [(set_attr "type" "push")
1094    (set_attr "mode" "SI")])
1095
1096 (define_insn "*pushsi2_prologue"
1097   [(set (match_operand:SI 0 "push_operand" "=<")
1098         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1099    (clobber (mem:BLK (scratch)))]
1100   "!TARGET_64BIT"
1101   "push{l}\t%1"
1102   [(set_attr "type" "push")
1103    (set_attr "mode" "SI")])
1104
1105 (define_insn "*popsi1_epilogue"
1106   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1107         (mem:SI (reg:SI SP_REG)))
1108    (set (reg:SI SP_REG)
1109         (plus:SI (reg:SI SP_REG) (const_int 4)))
1110    (clobber (mem:BLK (scratch)))]
1111   "!TARGET_64BIT"
1112   "pop{l}\t%0"
1113   [(set_attr "type" "pop")
1114    (set_attr "mode" "SI")])
1115
1116 (define_insn "popsi1"
1117   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1118         (mem:SI (reg:SI SP_REG)))
1119    (set (reg:SI SP_REG)
1120         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1121   "!TARGET_64BIT"
1122   "pop{l}\t%0"
1123   [(set_attr "type" "pop")
1124    (set_attr "mode" "SI")])
1125
1126 (define_insn "*movsi_xor"
1127   [(set (match_operand:SI 0 "register_operand" "=r")
1128         (match_operand:SI 1 "const0_operand" "i"))
1129    (clobber (reg:CC FLAGS_REG))]
1130   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1131   "xor{l}\t{%0, %0|%0, %0}"
1132   [(set_attr "type" "alu1")
1133    (set_attr "mode" "SI")
1134    (set_attr "length_immediate" "0")])
1135  
1136 (define_insn "*movsi_or"
1137   [(set (match_operand:SI 0 "register_operand" "=r")
1138         (match_operand:SI 1 "immediate_operand" "i"))
1139    (clobber (reg:CC FLAGS_REG))]
1140   "reload_completed
1141    && operands[1] == constm1_rtx
1142    && (TARGET_PENTIUM || optimize_size)"
1143 {
1144   operands[1] = constm1_rtx;
1145   return "or{l}\t{%1, %0|%0, %1}";
1146 }
1147   [(set_attr "type" "alu1")
1148    (set_attr "mode" "SI")
1149    (set_attr "length_immediate" "1")])
1150
1151 (define_insn "*movsi_1"
1152   [(set (match_operand:SI 0 "nonimmediate_operand"
1153                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1154         (match_operand:SI 1 "general_operand"
1155                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1156   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1157 {
1158   switch (get_attr_type (insn))
1159     {
1160     case TYPE_SSELOG1:
1161       if (get_attr_mode (insn) == MODE_TI)
1162         return "pxor\t%0, %0";
1163       return "xorps\t%0, %0";
1164
1165     case TYPE_SSEMOV:
1166       switch (get_attr_mode (insn))
1167         {
1168         case MODE_TI:
1169           return "movdqa\t{%1, %0|%0, %1}";
1170         case MODE_V4SF:
1171           return "movaps\t{%1, %0|%0, %1}";
1172         case MODE_SI:
1173           return "movd\t{%1, %0|%0, %1}";
1174         case MODE_SF:
1175           return "movss\t{%1, %0|%0, %1}";
1176         default:
1177           gcc_unreachable ();
1178         }
1179
1180     case TYPE_MMXADD:
1181       return "pxor\t%0, %0";
1182
1183     case TYPE_MMXMOV:
1184       if (get_attr_mode (insn) == MODE_DI)
1185         return "movq\t{%1, %0|%0, %1}";
1186       return "movd\t{%1, %0|%0, %1}";
1187
1188     case TYPE_LEA:
1189       return "lea{l}\t{%1, %0|%0, %1}";
1190
1191     default:
1192       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1193       return "mov{l}\t{%1, %0|%0, %1}";
1194     }
1195 }
1196   [(set (attr "type")
1197      (cond [(eq_attr "alternative" "2")
1198               (const_string "mmxadd")
1199             (eq_attr "alternative" "3,4,5")
1200               (const_string "mmxmov")
1201             (eq_attr "alternative" "6")
1202               (const_string "sselog1")
1203             (eq_attr "alternative" "7,8,9,10,11")
1204               (const_string "ssemov")
1205             (match_operand:DI 1 "pic_32bit_operand" "")
1206               (const_string "lea")
1207            ]
1208            (const_string "imov")))
1209    (set (attr "mode")
1210      (cond [(eq_attr "alternative" "2,3")
1211               (const_string "DI")
1212             (eq_attr "alternative" "6,7")
1213               (if_then_else
1214                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1215                 (const_string "V4SF")
1216                 (const_string "TI"))
1217             (and (eq_attr "alternative" "8,9,10,11")
1218                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1219               (const_string "SF")
1220            ]
1221            (const_string "SI")))])
1222
1223 ;; Stores and loads of ax to arbitrary constant address.
1224 ;; We fake an second form of instruction to force reload to load address
1225 ;; into register when rax is not available
1226 (define_insn "*movabssi_1_rex64"
1227   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1228         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1229   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1230   "@
1231    movabs{l}\t{%1, %P0|%P0, %1}
1232    mov{l}\t{%1, %a0|%a0, %1}"
1233   [(set_attr "type" "imov")
1234    (set_attr "modrm" "0,*")
1235    (set_attr "length_address" "8,0")
1236    (set_attr "length_immediate" "0,*")
1237    (set_attr "memory" "store")
1238    (set_attr "mode" "SI")])
1239
1240 (define_insn "*movabssi_2_rex64"
1241   [(set (match_operand:SI 0 "register_operand" "=a,r")
1242         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1243   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1244   "@
1245    movabs{l}\t{%P1, %0|%0, %P1}
1246    mov{l}\t{%a1, %0|%0, %a1}"
1247   [(set_attr "type" "imov")
1248    (set_attr "modrm" "0,*")
1249    (set_attr "length_address" "8,0")
1250    (set_attr "length_immediate" "0")
1251    (set_attr "memory" "load")
1252    (set_attr "mode" "SI")])
1253
1254 (define_insn "*swapsi"
1255   [(set (match_operand:SI 0 "register_operand" "+r")
1256         (match_operand:SI 1 "register_operand" "+r"))
1257    (set (match_dup 1)
1258         (match_dup 0))]
1259   ""
1260   "xchg{l}\t%1, %0"
1261   [(set_attr "type" "imov")
1262    (set_attr "mode" "SI")
1263    (set_attr "pent_pair" "np")
1264    (set_attr "athlon_decode" "vector")])
1265
1266 (define_expand "movhi"
1267   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268         (match_operand:HI 1 "general_operand" ""))]
1269   ""
1270   "ix86_expand_move (HImode, operands); DONE;")
1271
1272 (define_insn "*pushhi2"
1273   [(set (match_operand:HI 0 "push_operand" "=X")
1274         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1275   "!TARGET_64BIT"
1276   "push{l}\t%k1"
1277   [(set_attr "type" "push")
1278    (set_attr "mode" "SI")])
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" "DI")])
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 pushl, which has the effect
1433 ;; of rounding the amount pushed up to a word.
1434
1435 (define_insn "*pushqi2"
1436   [(set (match_operand:QI 0 "push_operand" "=X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1438   "!TARGET_64BIT"
1439   "push{l}\t%k1"
1440   [(set_attr "type" "push")
1441    (set_attr "mode" "SI")])
1442
1443 ;; For 64BIT abi we always round up to 8 bytes.
1444 (define_insn "*pushqi2_rex64"
1445   [(set (match_operand:QI 0 "push_operand" "=X")
1446         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1447   "TARGET_64BIT"
1448   "push{q}\t%q1"
1449   [(set_attr "type" "push")
1450    (set_attr "mode" "DI")])
1451
1452 ;; Situation is quite tricky about when to choose full sized (SImode) move
1453 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1454 ;; partial register dependency machines (such as AMD Athlon), where QImode
1455 ;; moves issue extra dependency and for partial register stalls machines
1456 ;; that don't use QImode patterns (and QImode move cause stall on the next
1457 ;; instruction).
1458 ;;
1459 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1460 ;; register stall machines with, where we use QImode instructions, since
1461 ;; partial register stall can be caused there.  Then we use movzx.
1462 (define_insn "*movqi_1"
1463   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1464         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1465   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1466 {
1467   switch (get_attr_type (insn))
1468     {
1469     case TYPE_IMOVX:
1470       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1471       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1472     default:
1473       if (get_attr_mode (insn) == MODE_SI)
1474         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1475       else
1476         return "mov{b}\t{%1, %0|%0, %1}";
1477     }
1478 }
1479   [(set (attr "type")
1480      (cond [(and (eq_attr "alternative" "5")
1481                  (not (match_operand:QI 1 "aligned_operand" "")))
1482               (const_string "imovx")
1483             (ne (symbol_ref "optimize_size") (const_int 0))
1484               (const_string "imov")
1485             (and (eq_attr "alternative" "3")
1486                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1487                           (const_int 0))
1488                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1489                           (const_int 0))))
1490               (const_string "imov")
1491             (eq_attr "alternative" "3,5")
1492               (const_string "imovx")
1493             (and (ne (symbol_ref "TARGET_MOVX")
1494                      (const_int 0))
1495                  (eq_attr "alternative" "2"))
1496               (const_string "imovx")
1497            ]
1498            (const_string "imov")))
1499    (set (attr "mode")
1500       (cond [(eq_attr "alternative" "3,4,5")
1501                (const_string "SI")
1502              (eq_attr "alternative" "6")
1503                (const_string "QI")
1504              (eq_attr "type" "imovx")
1505                (const_string "SI")
1506              (and (eq_attr "type" "imov")
1507                   (and (eq_attr "alternative" "0,1")
1508                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1509                            (const_int 0))))
1510                (const_string "SI")
1511              ;; Avoid partial register stalls when not using QImode arithmetic
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515                                 (const_int 0))
1516                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1517                                 (const_int 0)))))
1518                (const_string "SI")
1519            ]
1520            (const_string "QI")))])
1521
1522 (define_expand "reload_outqi"
1523   [(parallel [(match_operand:QI 0 "" "=m")
1524               (match_operand:QI 1 "register_operand" "r")
1525               (match_operand:QI 2 "register_operand" "=&q")])]
1526   ""
1527 {
1528   rtx op0, op1, op2;
1529   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1530
1531   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1532   if (! q_regs_operand (op1, QImode))
1533     {
1534       emit_insn (gen_movqi (op2, op1));
1535       op1 = op2;
1536     }
1537   emit_insn (gen_movqi (op0, op1));
1538   DONE;
1539 })
1540
1541 (define_insn "*swapqi_1"
1542   [(set (match_operand:QI 0 "register_operand" "+r")
1543         (match_operand:QI 1 "register_operand" "+r"))
1544    (set (match_dup 1)
1545         (match_dup 0))]
1546   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1547   "xchg{l}\t%k1, %k0"
1548   [(set_attr "type" "imov")
1549    (set_attr "mode" "SI")
1550    (set_attr "pent_pair" "np")
1551    (set_attr "athlon_decode" "vector")])
1552
1553 (define_insn "*swapqi_2"
1554   [(set (match_operand:QI 0 "register_operand" "+q")
1555         (match_operand:QI 1 "register_operand" "+q"))
1556    (set (match_dup 1)
1557         (match_dup 0))]
1558   "TARGET_PARTIAL_REG_STALL"
1559   "xchg{b}\t%1, %0"
1560   [(set_attr "type" "imov")
1561    (set_attr "mode" "QI")
1562    (set_attr "pent_pair" "np")
1563    (set_attr "athlon_decode" "vector")])
1564
1565 (define_expand "movstrictqi"
1566   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1567         (match_operand:QI 1 "general_operand" ""))]
1568   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1569 {
1570   /* Don't generate memory->memory moves, go through a register.  */
1571   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572     operands[1] = force_reg (QImode, operands[1]);
1573 })
1574
1575 (define_insn "*movstrictqi_1"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1577         (match_operand:QI 1 "general_operand" "*qn,m"))]
1578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580   "mov{b}\t{%1, %0|%0, %1}"
1581   [(set_attr "type" "imov")
1582    (set_attr "mode" "QI")])
1583
1584 (define_insn "*movstrictqi_xor"
1585   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1586         (match_operand:QI 1 "const0_operand" "i"))
1587    (clobber (reg:CC FLAGS_REG))]
1588   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589   "xor{b}\t{%0, %0|%0, %0}"
1590   [(set_attr "type" "alu1")
1591    (set_attr "mode" "QI")
1592    (set_attr "length_immediate" "0")])
1593
1594 (define_insn "*movsi_extv_1"
1595   [(set (match_operand:SI 0 "register_operand" "=R")
1596         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1597                          (const_int 8)
1598                          (const_int 8)))]
1599   ""
1600   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1601   [(set_attr "type" "imovx")
1602    (set_attr "mode" "SI")])
1603
1604 (define_insn "*movhi_extv_1"
1605   [(set (match_operand:HI 0 "register_operand" "=R")
1606         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1613
1614 (define_insn "*movqi_extv_1"
1615   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1616         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   "!TARGET_64BIT"
1620 {
1621   switch (get_attr_type (insn))
1622     {
1623     case TYPE_IMOVX:
1624       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1625     default:
1626       return "mov{b}\t{%h1, %0|%0, %h1}";
1627     }
1628 }
1629   [(set (attr "type")
1630      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1631                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1632                              (ne (symbol_ref "TARGET_MOVX")
1633                                  (const_int 0))))
1634         (const_string "imovx")
1635         (const_string "imov")))
1636    (set (attr "mode")
1637      (if_then_else (eq_attr "type" "imovx")
1638         (const_string "SI")
1639         (const_string "QI")))])
1640
1641 (define_insn "*movqi_extv_1_rex64"
1642   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1643         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   "TARGET_64BIT"
1647 {
1648   switch (get_attr_type (insn))
1649     {
1650     case TYPE_IMOVX:
1651       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652     default:
1653       return "mov{b}\t{%h1, %0|%0, %h1}";
1654     }
1655 }
1656   [(set (attr "type")
1657      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659                              (ne (symbol_ref "TARGET_MOVX")
1660                                  (const_int 0))))
1661         (const_string "imovx")
1662         (const_string "imov")))
1663    (set (attr "mode")
1664      (if_then_else (eq_attr "type" "imovx")
1665         (const_string "SI")
1666         (const_string "QI")))])
1667
1668 ;; Stores and loads of ax to arbitrary constant address.
1669 ;; We fake an second form of instruction to force reload to load address
1670 ;; into register when rax is not available
1671 (define_insn "*movabsqi_1_rex64"
1672   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1673         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1675   "@
1676    movabs{b}\t{%1, %P0|%P0, %1}
1677    mov{b}\t{%1, %a0|%a0, %1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0,*")
1682    (set_attr "memory" "store")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movabsqi_2_rex64"
1686   [(set (match_operand:QI 0 "register_operand" "=a,r")
1687         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1688   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1689   "@
1690    movabs{b}\t{%P1, %0|%0, %P1}
1691    mov{b}\t{%a1, %0|%0, %a1}"
1692   [(set_attr "type" "imov")
1693    (set_attr "modrm" "0,*")
1694    (set_attr "length_address" "8,0")
1695    (set_attr "length_immediate" "0")
1696    (set_attr "memory" "load")
1697    (set_attr "mode" "QI")])
1698
1699 (define_insn "*movdi_extzv_1"
1700   [(set (match_operand:DI 0 "register_operand" "=R")
1701         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1702                          (const_int 8)
1703                          (const_int 8)))]
1704   "TARGET_64BIT"
1705   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1706   [(set_attr "type" "imovx")
1707    (set_attr "mode" "DI")])
1708
1709 (define_insn "*movsi_extzv_1"
1710   [(set (match_operand:SI 0 "register_operand" "=R")
1711         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1712                          (const_int 8)
1713                          (const_int 8)))]
1714   ""
1715   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1716   [(set_attr "type" "imovx")
1717    (set_attr "mode" "SI")])
1718
1719 (define_insn "*movqi_extzv_2"
1720   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1721         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722                                     (const_int 8)
1723                                     (const_int 8)) 0))]
1724   "!TARGET_64BIT"
1725 {
1726   switch (get_attr_type (insn))
1727     {
1728     case TYPE_IMOVX:
1729       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730     default:
1731       return "mov{b}\t{%h1, %0|%0, %h1}";
1732     }
1733 }
1734   [(set (attr "type")
1735      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1736                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1737                              (ne (symbol_ref "TARGET_MOVX")
1738                                  (const_int 0))))
1739         (const_string "imovx")
1740         (const_string "imov")))
1741    (set (attr "mode")
1742      (if_then_else (eq_attr "type" "imovx")
1743         (const_string "SI")
1744         (const_string "QI")))])
1745
1746 (define_insn "*movqi_extzv_2_rex64"
1747   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1748         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1749                                     (const_int 8)
1750                                     (const_int 8)) 0))]
1751   "TARGET_64BIT"
1752 {
1753   switch (get_attr_type (insn))
1754     {
1755     case TYPE_IMOVX:
1756       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757     default:
1758       return "mov{b}\t{%h1, %0|%0, %h1}";
1759     }
1760 }
1761   [(set (attr "type")
1762      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763                         (ne (symbol_ref "TARGET_MOVX")
1764                             (const_int 0)))
1765         (const_string "imovx")
1766         (const_string "imov")))
1767    (set (attr "mode")
1768      (if_then_else (eq_attr "type" "imovx")
1769         (const_string "SI")
1770         (const_string "QI")))])
1771
1772 (define_insn "movsi_insv_1"
1773   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774                          (const_int 8)
1775                          (const_int 8))
1776         (match_operand:SI 1 "general_operand" "Qmn"))]
1777   "!TARGET_64BIT"
1778   "mov{b}\t{%b1, %h0|%h0, %b1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "mode" "QI")])
1781
1782 (define_insn "movdi_insv_1_rex64"
1783   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1787   "TARGET_64BIT"
1788   "mov{b}\t{%b1, %h0|%h0, %b1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1791
1792 (define_insn "*movqi_insv_2"
1793   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1794                          (const_int 8)
1795                          (const_int 8))
1796         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1797                      (const_int 8)))]
1798   ""
1799   "mov{b}\t{%h1, %h0|%h0, %h1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1802
1803 (define_expand "movdi"
1804   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1805         (match_operand:DI 1 "general_operand" ""))]
1806   ""
1807   "ix86_expand_move (DImode, operands); DONE;")
1808
1809 (define_insn "*pushdi"
1810   [(set (match_operand:DI 0 "push_operand" "=<")
1811         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1812   "!TARGET_64BIT"
1813   "#")
1814
1815 (define_insn "*pushdi2_rex64"
1816   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1817         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1818   "TARGET_64BIT"
1819   "@
1820    push{q}\t%1
1821    #"
1822   [(set_attr "type" "push,multi")
1823    (set_attr "mode" "DI")])
1824
1825 ;; Convert impossible pushes of immediate to existing instructions.
1826 ;; First try to get scratch register and go through it.  In case this
1827 ;; fails, push sign extended lower part first and then overwrite
1828 ;; upper part by 32bit move.
1829 (define_peephole2
1830   [(match_scratch:DI 2 "r")
1831    (set (match_operand:DI 0 "push_operand" "")
1832         (match_operand:DI 1 "immediate_operand" ""))]
1833   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1834    && !x86_64_immediate_operand (operands[1], DImode)"
1835   [(set (match_dup 2) (match_dup 1))
1836    (set (match_dup 0) (match_dup 2))]
1837   "")
1838
1839 ;; We need to define this as both peepholer and splitter for case
1840 ;; peephole2 pass is not run.
1841 ;; "&& 1" is needed to keep it from matching the previous pattern.
1842 (define_peephole2
1843   [(set (match_operand:DI 0 "push_operand" "")
1844         (match_operand:DI 1 "immediate_operand" ""))]
1845   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1847   [(set (match_dup 0) (match_dup 1))
1848    (set (match_dup 2) (match_dup 3))]
1849   "split_di (operands + 1, 1, operands + 2, operands + 3);
1850    operands[1] = gen_lowpart (DImode, operands[2]);
1851    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1852                                                     GEN_INT (4)));
1853   ")
1854
1855 (define_split
1856   [(set (match_operand:DI 0 "push_operand" "")
1857         (match_operand:DI 1 "immediate_operand" ""))]
1858   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1859                     ? 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 "mmxadd")
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 && ((optimize > 0 && flag_peephole2)
2089                     ? flow2_completed : reload_completed)
2090    && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode)"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096 (define_insn "*swapdi_rex64"
2097   [(set (match_operand:DI 0 "register_operand" "+r")
2098         (match_operand:DI 1 "register_operand" "+r"))
2099    (set (match_dup 1)
2100         (match_dup 0))]
2101   "TARGET_64BIT"
2102   "xchg{q}\t%1, %0"
2103   [(set_attr "type" "imov")
2104    (set_attr "mode" "DI")
2105    (set_attr "pent_pair" "np")
2106    (set_attr "athlon_decode" "vector")])
2107
2108 (define_expand "movti"
2109   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2110         (match_operand:TI 1 "nonimmediate_operand" ""))]
2111   "TARGET_SSE || TARGET_64BIT"
2112 {
2113   if (TARGET_64BIT)
2114     ix86_expand_move (TImode, operands);
2115   else
2116     ix86_expand_vector_move (TImode, operands);
2117   DONE;
2118 })
2119
2120 (define_insn "*movti_internal"
2121   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2122         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2123   "TARGET_SSE && !TARGET_64BIT
2124    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2125 {
2126   switch (which_alternative)
2127     {
2128     case 0:
2129       if (get_attr_mode (insn) == MODE_V4SF)
2130         return "xorps\t%0, %0";
2131       else
2132         return "pxor\t%0, %0";
2133     case 1:
2134     case 2:
2135       if (get_attr_mode (insn) == MODE_V4SF)
2136         return "movaps\t{%1, %0|%0, %1}";
2137       else
2138         return "movdqa\t{%1, %0|%0, %1}";
2139     default:
2140       gcc_unreachable ();
2141     }
2142 }
2143   [(set_attr "type" "ssemov,ssemov,ssemov")
2144    (set (attr "mode")
2145         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2146                  (const_string "V4SF")
2147
2148                (eq_attr "alternative" "0,1")
2149                  (if_then_else
2150                    (ne (symbol_ref "optimize_size")
2151                        (const_int 0))
2152                    (const_string "V4SF")
2153                    (const_string "TI"))
2154                (eq_attr "alternative" "2")
2155                  (if_then_else
2156                    (ne (symbol_ref "optimize_size")
2157                        (const_int 0))
2158                    (const_string "V4SF")
2159                    (const_string "TI"))]
2160                (const_string "TI")))])
2161
2162 (define_insn "*movti_rex64"
2163   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2164         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2165   "TARGET_64BIT
2166    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2167 {
2168   switch (which_alternative)
2169     {
2170     case 0:
2171     case 1:
2172       return "#";
2173     case 2:
2174       if (get_attr_mode (insn) == MODE_V4SF)
2175         return "xorps\t%0, %0";
2176       else
2177         return "pxor\t%0, %0";
2178     case 3:
2179     case 4:
2180       if (get_attr_mode (insn) == MODE_V4SF)
2181         return "movaps\t{%1, %0|%0, %1}";
2182       else
2183         return "movdqa\t{%1, %0|%0, %1}";
2184     default:
2185       gcc_unreachable ();
2186     }
2187 }
2188   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2189    (set (attr "mode")
2190         (cond [(eq_attr "alternative" "2,3")
2191                  (if_then_else
2192                    (ne (symbol_ref "optimize_size")
2193                        (const_int 0))
2194                    (const_string "V4SF")
2195                    (const_string "TI"))
2196                (eq_attr "alternative" "4")
2197                  (if_then_else
2198                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2199                             (const_int 0))
2200                         (ne (symbol_ref "optimize_size")
2201                             (const_int 0)))
2202                    (const_string "V4SF")
2203                    (const_string "TI"))]
2204                (const_string "DI")))])
2205
2206 (define_split
2207   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2208         (match_operand:TI 1 "general_operand" ""))]
2209   "reload_completed && !SSE_REG_P (operands[0])
2210    && !SSE_REG_P (operands[1])"
2211   [(const_int 0)]
2212   "ix86_split_long_move (operands); DONE;")
2213
2214 (define_expand "movsf"
2215   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2216         (match_operand:SF 1 "general_operand" ""))]
2217   ""
2218   "ix86_expand_move (SFmode, operands); DONE;")
2219
2220 (define_insn "*pushsf"
2221   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2222         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2223   "!TARGET_64BIT"
2224 {
2225   /* Anything else should be already split before reg-stack.  */
2226   gcc_assert (which_alternative == 1);
2227   return "push{l}\t%1";
2228 }
2229   [(set_attr "type" "multi,push,multi")
2230    (set_attr "unit" "i387,*,*")
2231    (set_attr "mode" "SF,SI,SF")])
2232
2233 (define_insn "*pushsf_rex64"
2234   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2235         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2236   "TARGET_64BIT"
2237 {
2238   /* Anything else should be already split before reg-stack.  */
2239   gcc_assert (which_alternative == 1);
2240   return "push{q}\t%q1";
2241 }
2242   [(set_attr "type" "multi,push,multi")
2243    (set_attr "unit" "i387,*,*")
2244    (set_attr "mode" "SF,DI,SF")])
2245
2246 (define_split
2247   [(set (match_operand:SF 0 "push_operand" "")
2248         (match_operand:SF 1 "memory_operand" ""))]
2249   "reload_completed
2250    && GET_CODE (operands[1]) == MEM
2251    && constant_pool_reference_p (operands[1])"
2252   [(set (match_dup 0)
2253         (match_dup 1))]
2254   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2255
2256
2257 ;; %%% Kill this when call knows how to work this out.
2258 (define_split
2259   [(set (match_operand:SF 0 "push_operand" "")
2260         (match_operand:SF 1 "any_fp_register_operand" ""))]
2261   "!TARGET_64BIT"
2262   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2263    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2264
2265 (define_split
2266   [(set (match_operand:SF 0 "push_operand" "")
2267         (match_operand:SF 1 "any_fp_register_operand" ""))]
2268   "TARGET_64BIT"
2269   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2270    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2271
2272 (define_insn "*movsf_1"
2273   [(set (match_operand:SF 0 "nonimmediate_operand"
2274           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2275         (match_operand:SF 1 "general_operand"
2276           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2277   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2278    && (reload_in_progress || reload_completed
2279        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2280        || GET_CODE (operands[1]) != CONST_DOUBLE
2281        || memory_operand (operands[0], SFmode))" 
2282 {
2283   switch (which_alternative)
2284     {
2285     case 0:
2286       return output_387_reg_move (insn, operands);
2287
2288     case 1:
2289       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290         return "fstp%z0\t%y0";
2291       else
2292         return "fst%z0\t%y0";
2293
2294     case 2:
2295       return standard_80387_constant_opcode (operands[1]);
2296
2297     case 3:
2298     case 4:
2299       return "mov{l}\t{%1, %0|%0, %1}";
2300     case 5:
2301       if (get_attr_mode (insn) == MODE_TI)
2302         return "pxor\t%0, %0";
2303       else
2304         return "xorps\t%0, %0";
2305     case 6:
2306       if (get_attr_mode (insn) == MODE_V4SF)
2307         return "movaps\t{%1, %0|%0, %1}";
2308       else
2309         return "movss\t{%1, %0|%0, %1}";
2310     case 7:
2311     case 8:
2312       return "movss\t{%1, %0|%0, %1}";
2313
2314     case 9:
2315     case 10:
2316       return "movd\t{%1, %0|%0, %1}";
2317
2318     case 11:
2319       return "movq\t{%1, %0|%0, %1}";
2320
2321     default:
2322       gcc_unreachable ();
2323     }
2324 }
2325   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2326    (set (attr "mode")
2327         (cond [(eq_attr "alternative" "3,4,9,10")
2328                  (const_string "SI")
2329                (eq_attr "alternative" "5")
2330                  (if_then_else
2331                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2332                                  (const_int 0))
2333                              (ne (symbol_ref "TARGET_SSE2")
2334                                  (const_int 0)))
2335                         (eq (symbol_ref "optimize_size")
2336                             (const_int 0)))
2337                    (const_string "TI")
2338                    (const_string "V4SF"))
2339                /* For architectures resolving dependencies on
2340                   whole SSE registers use APS move to break dependency
2341                   chains, otherwise use short move to avoid extra work. 
2342
2343                   Do the same for architectures resolving dependencies on
2344                   the parts.  While in DF mode it is better to always handle
2345                   just register parts, the SF mode is different due to lack
2346                   of instructions to load just part of the register.  It is
2347                   better to maintain the whole registers in single format
2348                   to avoid problems on using packed logical operations.  */
2349                (eq_attr "alternative" "6")
2350                  (if_then_else
2351                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2352                             (const_int 0))
2353                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2354                             (const_int 0)))
2355                    (const_string "V4SF")
2356                    (const_string "SF"))
2357                (eq_attr "alternative" "11")
2358                  (const_string "DI")]
2359                (const_string "SF")))])
2360
2361 (define_insn "*swapsf"
2362   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2363         (match_operand:SF 1 "fp_register_operand" "+f"))
2364    (set (match_dup 1)
2365         (match_dup 0))]
2366   "reload_completed || TARGET_80387"
2367 {
2368   if (STACK_TOP_P (operands[0]))
2369     return "fxch\t%1";
2370   else
2371     return "fxch\t%0";
2372 }
2373   [(set_attr "type" "fxch")
2374    (set_attr "mode" "SF")])
2375
2376 (define_expand "movdf"
2377   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2378         (match_operand:DF 1 "general_operand" ""))]
2379   ""
2380   "ix86_expand_move (DFmode, operands); DONE;")
2381
2382 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2383 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2384 ;; On the average, pushdf using integers can be still shorter.  Allow this
2385 ;; pattern for optimize_size too.
2386
2387 (define_insn "*pushdf_nointeger"
2388   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2389         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2390   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2391 {
2392   /* This insn should be already split before reg-stack.  */
2393   gcc_unreachable ();
2394 }
2395   [(set_attr "type" "multi")
2396    (set_attr "unit" "i387,*,*,*")
2397    (set_attr "mode" "DF,SI,SI,DF")])
2398
2399 (define_insn "*pushdf_integer"
2400   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2401         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2402   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2403 {
2404   /* This insn should be already split before reg-stack.  */
2405   gcc_unreachable ();
2406 }
2407   [(set_attr "type" "multi")
2408    (set_attr "unit" "i387,*,*")
2409    (set_attr "mode" "DF,SI,DF")])
2410
2411 ;; %%% Kill this when call knows how to work this out.
2412 (define_split
2413   [(set (match_operand:DF 0 "push_operand" "")
2414         (match_operand:DF 1 "any_fp_register_operand" ""))]
2415   "!TARGET_64BIT && reload_completed"
2416   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2417    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2418   "")
2419
2420 (define_split
2421   [(set (match_operand:DF 0 "push_operand" "")
2422         (match_operand:DF 1 "any_fp_register_operand" ""))]
2423   "TARGET_64BIT && reload_completed"
2424   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2425    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2426   "")
2427
2428 (define_split
2429   [(set (match_operand:DF 0 "push_operand" "")
2430         (match_operand:DF 1 "general_operand" ""))]
2431   "reload_completed"
2432   [(const_int 0)]
2433   "ix86_split_long_move (operands); DONE;")
2434
2435 ;; Moving is usually shorter when only FP registers are used. This separate
2436 ;; movdf pattern avoids the use of integer registers for FP operations
2437 ;; when optimizing for size.
2438
2439 (define_insn "*movdf_nointeger"
2440   [(set (match_operand:DF 0 "nonimmediate_operand"
2441                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2442         (match_operand:DF 1 "general_operand"
2443                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2444   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2445    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2446    && (reload_in_progress || reload_completed
2447        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2448        || GET_CODE (operands[1]) != CONST_DOUBLE
2449        || memory_operand (operands[0], DFmode))" 
2450 {
2451   switch (which_alternative)
2452     {
2453     case 0:
2454       return output_387_reg_move (insn, operands);
2455
2456     case 1:
2457       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2458         return "fstp%z0\t%y0";
2459       else
2460         return "fst%z0\t%y0";
2461
2462     case 2:
2463       return standard_80387_constant_opcode (operands[1]);
2464
2465     case 3:
2466     case 4:
2467       return "#";
2468     case 5:
2469       switch (get_attr_mode (insn))
2470         {
2471         case MODE_V4SF:
2472           return "xorps\t%0, %0";
2473         case MODE_V2DF:
2474           return "xorpd\t%0, %0";
2475         case MODE_TI:
2476           return "pxor\t%0, %0";
2477         default:
2478           gcc_unreachable ();
2479         }
2480     case 6:
2481     case 7:
2482     case 8:
2483       switch (get_attr_mode (insn))
2484         {
2485         case MODE_V4SF:
2486           return "movaps\t{%1, %0|%0, %1}";
2487         case MODE_V2DF:
2488           return "movapd\t{%1, %0|%0, %1}";
2489         case MODE_TI:
2490           return "movdqa\t{%1, %0|%0, %1}";
2491         case MODE_DI:
2492           return "movq\t{%1, %0|%0, %1}";
2493         case MODE_DF:
2494           return "movsd\t{%1, %0|%0, %1}";
2495         case MODE_V1DF:
2496           return "movlpd\t{%1, %0|%0, %1}";
2497         case MODE_V2SF:
2498           return "movlps\t{%1, %0|%0, %1}";
2499         default:
2500           gcc_unreachable ();
2501         }
2502
2503     default:
2504       gcc_unreachable ();
2505     }
2506 }
2507   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2508    (set (attr "mode")
2509         (cond [(eq_attr "alternative" "0,1,2")
2510                  (const_string "DF")
2511                (eq_attr "alternative" "3,4")
2512                  (const_string "SI")
2513
2514                /* For SSE1, we have many fewer alternatives.  */
2515                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2516                  (cond [(eq_attr "alternative" "5,6")
2517                           (const_string "V4SF")
2518                        ]
2519                    (const_string "V2SF"))
2520
2521                /* xorps is one byte shorter.  */
2522                (eq_attr "alternative" "5")
2523                  (cond [(ne (symbol_ref "optimize_size")
2524                             (const_int 0))
2525                           (const_string "V4SF")
2526                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2527                             (const_int 0))
2528                           (const_string "TI")
2529                        ]
2530                        (const_string "V2DF"))
2531
2532                /* For architectures resolving dependencies on
2533                   whole SSE registers use APD move to break dependency
2534                   chains, otherwise use short move to avoid extra work.
2535
2536                   movaps encodes one byte shorter.  */
2537                (eq_attr "alternative" "6")
2538                  (cond
2539                    [(ne (symbol_ref "optimize_size")
2540                         (const_int 0))
2541                       (const_string "V4SF")
2542                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2543                         (const_int 0))
2544                       (const_string "V2DF")
2545                    ]
2546                    (const_string "DF"))
2547                /* For architectures resolving dependencies on register
2548                   parts we may avoid extra work to zero out upper part
2549                   of register.  */
2550                (eq_attr "alternative" "7")
2551                  (if_then_else
2552                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2553                        (const_int 0))
2554                    (const_string "V1DF")
2555                    (const_string "DF"))
2556               ]
2557               (const_string "DF")))])
2558
2559 (define_insn "*movdf_integer"
2560   [(set (match_operand:DF 0 "nonimmediate_operand"
2561                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2562         (match_operand:DF 1 "general_operand"
2563                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2564   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2566    && (reload_in_progress || reload_completed
2567        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568        || GET_CODE (operands[1]) != CONST_DOUBLE
2569        || memory_operand (operands[0], DFmode))" 
2570 {
2571   switch (which_alternative)
2572     {
2573     case 0:
2574       return output_387_reg_move (insn, operands);
2575
2576     case 1:
2577       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578         return "fstp%z0\t%y0";
2579       else
2580         return "fst%z0\t%y0";
2581
2582     case 2:
2583       return standard_80387_constant_opcode (operands[1]);
2584
2585     case 3:
2586     case 4:
2587       return "#";
2588
2589     case 5:
2590       switch (get_attr_mode (insn))
2591         {
2592         case MODE_V4SF:
2593           return "xorps\t%0, %0";
2594         case MODE_V2DF:
2595           return "xorpd\t%0, %0";
2596         case MODE_TI:
2597           return "pxor\t%0, %0";
2598         default:
2599           gcc_unreachable ();
2600         }
2601     case 6:
2602     case 7:
2603     case 8:
2604       switch (get_attr_mode (insn))
2605         {
2606         case MODE_V4SF:
2607           return "movaps\t{%1, %0|%0, %1}";
2608         case MODE_V2DF:
2609           return "movapd\t{%1, %0|%0, %1}";
2610         case MODE_TI:
2611           return "movdqa\t{%1, %0|%0, %1}";
2612         case MODE_DI:
2613           return "movq\t{%1, %0|%0, %1}";
2614         case MODE_DF:
2615           return "movsd\t{%1, %0|%0, %1}";
2616         case MODE_V1DF:
2617           return "movlpd\t{%1, %0|%0, %1}";
2618         case MODE_V2SF:
2619           return "movlps\t{%1, %0|%0, %1}";
2620         default:
2621           gcc_unreachable ();
2622         }
2623
2624     default:
2625       gcc_unreachable();
2626     }
2627 }
2628   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2629    (set (attr "mode")
2630         (cond [(eq_attr "alternative" "0,1,2")
2631                  (const_string "DF")
2632                (eq_attr "alternative" "3,4")
2633                  (const_string "SI")
2634
2635                /* For SSE1, we have many fewer alternatives.  */
2636                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637                  (cond [(eq_attr "alternative" "5,6")
2638                           (const_string "V4SF")
2639                        ]
2640                    (const_string "V2SF"))
2641
2642                /* xorps is one byte shorter.  */
2643                (eq_attr "alternative" "5")
2644                  (cond [(ne (symbol_ref "optimize_size")
2645                             (const_int 0))
2646                           (const_string "V4SF")
2647                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2648                             (const_int 0))
2649                           (const_string "TI")
2650                        ]
2651                        (const_string "V2DF"))
2652
2653                /* For architectures resolving dependencies on
2654                   whole SSE registers use APD move to break dependency
2655                   chains, otherwise use short move to avoid extra work.
2656
2657                   movaps encodes one byte shorter.  */
2658                (eq_attr "alternative" "6")
2659                  (cond
2660                    [(ne (symbol_ref "optimize_size")
2661                         (const_int 0))
2662                       (const_string "V4SF")
2663                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664                         (const_int 0))
2665                       (const_string "V2DF")
2666                    ]
2667                    (const_string "DF"))
2668                /* For architectures resolving dependencies on register
2669                   parts we may avoid extra work to zero out upper part
2670                   of register.  */
2671                (eq_attr "alternative" "7")
2672                  (if_then_else
2673                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2674                        (const_int 0))
2675                    (const_string "V1DF")
2676                    (const_string "DF"))
2677               ]
2678               (const_string "DF")))])
2679
2680 (define_split
2681   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2682         (match_operand:DF 1 "general_operand" ""))]
2683   "reload_completed
2684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685    && ! (ANY_FP_REG_P (operands[0]) || 
2686          (GET_CODE (operands[0]) == SUBREG
2687           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2688    && ! (ANY_FP_REG_P (operands[1]) || 
2689          (GET_CODE (operands[1]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2691   [(const_int 0)]
2692   "ix86_split_long_move (operands); DONE;")
2693
2694 (define_insn "*swapdf"
2695   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2696         (match_operand:DF 1 "fp_register_operand" "+f"))
2697    (set (match_dup 1)
2698         (match_dup 0))]
2699   "reload_completed || TARGET_80387"
2700 {
2701   if (STACK_TOP_P (operands[0]))
2702     return "fxch\t%1";
2703   else
2704     return "fxch\t%0";
2705 }
2706   [(set_attr "type" "fxch")
2707    (set_attr "mode" "DF")])
2708
2709 (define_expand "movxf"
2710   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2711         (match_operand:XF 1 "general_operand" ""))]
2712   ""
2713   "ix86_expand_move (XFmode, operands); DONE;")
2714
2715 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2717 ;; Pushing using integer instructions is longer except for constants
2718 ;; and direct memory references.
2719 ;; (assuming that any given constant is pushed only once, but this ought to be
2720 ;;  handled elsewhere).
2721
2722 (define_insn "*pushxf_nointeger"
2723   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2724         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2725   "optimize_size"
2726 {
2727   /* This insn should be already split before reg-stack.  */
2728   gcc_unreachable ();
2729 }
2730   [(set_attr "type" "multi")
2731    (set_attr "unit" "i387,*,*")
2732    (set_attr "mode" "XF,SI,SI")])
2733
2734 (define_insn "*pushxf_integer"
2735   [(set (match_operand:XF 0 "push_operand" "=<,<")
2736         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737   "!optimize_size"
2738 {
2739   /* This insn should be already split before reg-stack.  */
2740   gcc_unreachable ();
2741 }
2742   [(set_attr "type" "multi")
2743    (set_attr "unit" "i387,*")
2744    (set_attr "mode" "XF,SI")])
2745
2746 (define_split
2747   [(set (match_operand 0 "push_operand" "")
2748         (match_operand 1 "general_operand" ""))]
2749   "reload_completed
2750    && (GET_MODE (operands[0]) == XFmode
2751        || GET_MODE (operands[0]) == DFmode)
2752    && !ANY_FP_REG_P (operands[1])"
2753   [(const_int 0)]
2754   "ix86_split_long_move (operands); DONE;")
2755
2756 (define_split
2757   [(set (match_operand:XF 0 "push_operand" "")
2758         (match_operand:XF 1 "any_fp_register_operand" ""))]
2759   "!TARGET_64BIT"
2760   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2761    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2762   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "TARGET_64BIT"
2768   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2769    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 ;; Do not use integer registers when optimizing for size
2773 (define_insn "*movxf_nointeger"
2774   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2776   "optimize_size
2777    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778    && (reload_in_progress || reload_completed
2779        || GET_CODE (operands[1]) != CONST_DOUBLE
2780        || memory_operand (operands[0], XFmode))" 
2781 {
2782   switch (which_alternative)
2783     {
2784     case 0:
2785       return output_387_reg_move (insn, operands);
2786
2787     case 1:
2788       /* There is no non-popping store to memory for XFmode.  So if
2789          we need one, follow the store with a load.  */
2790       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2791         return "fstp%z0\t%y0\;fld%z0\t%y0";
2792       else
2793         return "fstp%z0\t%y0";
2794
2795     case 2:
2796       return standard_80387_constant_opcode (operands[1]);
2797
2798     case 3: case 4:
2799       return "#";
2800     default:
2801       gcc_unreachable ();
2802     }
2803 }
2804   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2805    (set_attr "mode" "XF,XF,XF,SI,SI")])
2806
2807 (define_insn "*movxf_integer"
2808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2809         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2810   "!optimize_size
2811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812    && (reload_in_progress || reload_completed
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))" 
2815 {
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2820
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2828
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2831
2832     case 3: case 4:
2833       return "#";
2834
2835     default:
2836       gcc_unreachable ();
2837     }
2838 }
2839   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840    (set_attr "mode" "XF,XF,XF,SI,SI")])
2841
2842 (define_split
2843   [(set (match_operand 0 "nonimmediate_operand" "")
2844         (match_operand 1 "general_operand" ""))]
2845   "reload_completed
2846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2847    && GET_MODE (operands[0]) == XFmode
2848    && ! (ANY_FP_REG_P (operands[0]) || 
2849          (GET_CODE (operands[0]) == SUBREG
2850           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2851    && ! (ANY_FP_REG_P (operands[1]) || 
2852          (GET_CODE (operands[1]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2854   [(const_int 0)]
2855   "ix86_split_long_move (operands); DONE;")
2856
2857 (define_split
2858   [(set (match_operand 0 "register_operand" "")
2859         (match_operand 1 "memory_operand" ""))]
2860   "reload_completed
2861    && GET_CODE (operands[1]) == MEM
2862    && (GET_MODE (operands[0]) == XFmode
2863        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2864    && constant_pool_reference_p (operands[1])"
2865   [(set (match_dup 0) (match_dup 1))]
2866 {
2867   rtx c = avoid_constant_pool_reference (operands[1]);
2868   rtx r = operands[0];
2869
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2872
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2885
2886   operands[1] = c;
2887 })
2888
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2895 {
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2900 }
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2903
2904 (define_expand "movtf"
2905   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2906         (match_operand:TF 1 "nonimmediate_operand" ""))]
2907   "TARGET_64BIT"
2908 {
2909   ix86_expand_move (TFmode, operands);
2910   DONE;
2911 })
2912
2913 (define_insn "*movtf_internal"
2914   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2915         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2916   "TARGET_64BIT
2917    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2918 {
2919   switch (which_alternative)
2920     {
2921     case 0:
2922     case 1:
2923       return "#";
2924     case 2:
2925       if (get_attr_mode (insn) == MODE_V4SF)
2926         return "xorps\t%0, %0";
2927       else
2928         return "pxor\t%0, %0";
2929     case 3:
2930     case 4:
2931       if (get_attr_mode (insn) == MODE_V4SF)
2932         return "movaps\t{%1, %0|%0, %1}";
2933       else
2934         return "movdqa\t{%1, %0|%0, %1}";
2935     default:
2936       gcc_unreachable ();
2937     }
2938 }
2939   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2940    (set (attr "mode")
2941         (cond [(eq_attr "alternative" "2,3")
2942                  (if_then_else
2943                    (ne (symbol_ref "optimize_size")
2944                        (const_int 0))
2945                    (const_string "V4SF")
2946                    (const_string "TI"))
2947                (eq_attr "alternative" "4")
2948                  (if_then_else
2949                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2950                             (const_int 0))
2951                         (ne (symbol_ref "optimize_size")
2952                             (const_int 0)))
2953                    (const_string "V4SF")
2954                    (const_string "TI"))]
2955                (const_string "DI")))])
2956
2957 (define_split
2958   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2959         (match_operand:TF 1 "general_operand" ""))]
2960   "reload_completed && !SSE_REG_P (operands[0])
2961    && !SSE_REG_P (operands[1])"
2962   [(const_int 0)]
2963   "ix86_split_long_move (operands); DONE;")
2964 \f
2965 ;; Zero extension instructions
2966
2967 (define_expand "zero_extendhisi2"
2968   [(set (match_operand:SI 0 "register_operand" "")
2969      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2970   ""
2971 {
2972   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2973     {
2974       operands[1] = force_reg (HImode, operands[1]);
2975       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2976       DONE;
2977     }
2978 })
2979
2980 (define_insn "zero_extendhisi2_and"
2981   [(set (match_operand:SI 0 "register_operand" "=r")
2982      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2985   "#"
2986   [(set_attr "type" "alu1")
2987    (set_attr "mode" "SI")])
2988
2989 (define_split
2990   [(set (match_operand:SI 0 "register_operand" "")
2991         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2992    (clobber (reg:CC FLAGS_REG))]
2993   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2995               (clobber (reg:CC FLAGS_REG))])]
2996   "")
2997
2998 (define_insn "*zero_extendhisi2_movzwl"
2999   [(set (match_operand:SI 0 "register_operand" "=r")
3000      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3001   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3002   "movz{wl|x}\t{%1, %0|%0, %1}"
3003   [(set_attr "type" "imovx")
3004    (set_attr "mode" "SI")])
3005
3006 (define_expand "zero_extendqihi2"
3007   [(parallel
3008     [(set (match_operand:HI 0 "register_operand" "")
3009        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3010      (clobber (reg:CC FLAGS_REG))])]
3011   ""
3012   "")
3013
3014 (define_insn "*zero_extendqihi2_and"
3015   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3016      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3017    (clobber (reg:CC FLAGS_REG))]
3018   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3019   "#"
3020   [(set_attr "type" "alu1")
3021    (set_attr "mode" "HI")])
3022
3023 (define_insn "*zero_extendqihi2_movzbw_and"
3024   [(set (match_operand:HI 0 "register_operand" "=r,r")
3025      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3028   "#"
3029   [(set_attr "type" "imovx,alu1")
3030    (set_attr "mode" "HI")])
3031
3032 (define_insn "*zero_extendqihi2_movzbw"
3033   [(set (match_operand:HI 0 "register_operand" "=r")
3034      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3035   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3036   "movz{bw|x}\t{%1, %0|%0, %1}"
3037   [(set_attr "type" "imovx")
3038    (set_attr "mode" "HI")])
3039
3040 ;; For the movzbw case strip only the clobber
3041 (define_split
3042   [(set (match_operand:HI 0 "register_operand" "")
3043         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "reload_completed 
3046    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3047    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3048   [(set (match_operand:HI 0 "register_operand" "")
3049         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3050
3051 ;; When source and destination does not overlap, clear destination
3052 ;; first and then do the movb
3053 (define_split
3054   [(set (match_operand:HI 0 "register_operand" "")
3055         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "reload_completed
3058    && ANY_QI_REG_P (operands[0])
3059    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3060    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3061   [(set (match_dup 0) (const_int 0))
3062    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3063   "operands[2] = gen_lowpart (QImode, operands[0]);")
3064
3065 ;; Rest is handled by single and.
3066 (define_split
3067   [(set (match_operand:HI 0 "register_operand" "")
3068         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3069    (clobber (reg:CC FLAGS_REG))]
3070   "reload_completed
3071    && true_regnum (operands[0]) == true_regnum (operands[1])"
3072   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3073               (clobber (reg:CC FLAGS_REG))])]
3074   "")
3075
3076 (define_expand "zero_extendqisi2"
3077   [(parallel
3078     [(set (match_operand:SI 0 "register_operand" "")
3079        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3080      (clobber (reg:CC FLAGS_REG))])]
3081   ""
3082   "")
3083
3084 (define_insn "*zero_extendqisi2_and"
3085   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3086      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3089   "#"
3090   [(set_attr "type" "alu1")
3091    (set_attr "mode" "SI")])
3092
3093 (define_insn "*zero_extendqisi2_movzbw_and"
3094   [(set (match_operand:SI 0 "register_operand" "=r,r")
3095      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3096    (clobber (reg:CC FLAGS_REG))]
3097   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3098   "#"
3099   [(set_attr "type" "imovx,alu1")
3100    (set_attr "mode" "SI")])
3101
3102 (define_insn "*zero_extendqisi2_movzbw"
3103   [(set (match_operand:SI 0 "register_operand" "=r")
3104      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3105   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3106   "movz{bl|x}\t{%1, %0|%0, %1}"
3107   [(set_attr "type" "imovx")
3108    (set_attr "mode" "SI")])
3109
3110 ;; For the movzbl case strip only the clobber
3111 (define_split
3112   [(set (match_operand:SI 0 "register_operand" "")
3113         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114    (clobber (reg:CC FLAGS_REG))]
3115   "reload_completed 
3116    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3117    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3118   [(set (match_dup 0)
3119         (zero_extend:SI (match_dup 1)))])
3120
3121 ;; When source and destination does not overlap, clear destination
3122 ;; first and then do the movb
3123 (define_split
3124   [(set (match_operand:SI 0 "register_operand" "")
3125         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126    (clobber (reg:CC FLAGS_REG))]
3127   "reload_completed
3128    && ANY_QI_REG_P (operands[0])
3129    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3130    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3131    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3132   [(set (match_dup 0) (const_int 0))
3133    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3134   "operands[2] = gen_lowpart (QImode, operands[0]);")
3135
3136 ;; Rest is handled by single and.
3137 (define_split
3138   [(set (match_operand:SI 0 "register_operand" "")
3139         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "reload_completed
3142    && true_regnum (operands[0]) == true_regnum (operands[1])"
3143   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3144               (clobber (reg:CC FLAGS_REG))])]
3145   "")
3146
3147 ;; %%% Kill me once multi-word ops are sane.
3148 (define_expand "zero_extendsidi2"
3149   [(set (match_operand:DI 0 "register_operand" "=r")
3150      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3151   ""
3152   "if (!TARGET_64BIT)
3153      {
3154        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3155        DONE;
3156      }
3157   ")
3158
3159 (define_insn "zero_extendsidi2_32"
3160   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3161         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3162    (clobber (reg:CC FLAGS_REG))]
3163   "!TARGET_64BIT"
3164   "@
3165    #
3166    #
3167    #
3168    movd\t{%1, %0|%0, %1}
3169    movd\t{%1, %0|%0, %1}"
3170   [(set_attr "mode" "SI,SI,SI,DI,TI")
3171    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3172
3173 (define_insn "zero_extendsidi2_rex64"
3174   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3175      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3176   "TARGET_64BIT"
3177   "@
3178    mov\t{%k1, %k0|%k0, %k1}
3179    #
3180    movd\t{%1, %0|%0, %1}
3181    movd\t{%1, %0|%0, %1}"
3182   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3183    (set_attr "mode" "SI,DI,SI,SI")])
3184
3185 (define_split
3186   [(set (match_operand:DI 0 "memory_operand" "")
3187      (zero_extend:DI (match_dup 0)))]
3188   "TARGET_64BIT"
3189   [(set (match_dup 4) (const_int 0))]
3190   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191
3192 (define_split 
3193   [(set (match_operand:DI 0 "register_operand" "")
3194         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))]
3196   "!TARGET_64BIT && reload_completed
3197    && true_regnum (operands[0]) == true_regnum (operands[1])"
3198   [(set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_split 
3202   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3203         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "!TARGET_64BIT && reload_completed
3206    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3207   [(set (match_dup 3) (match_dup 1))
3208    (set (match_dup 4) (const_int 0))]
3209   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210
3211 (define_insn "zero_extendhidi2"
3212   [(set (match_operand:DI 0 "register_operand" "=r")
3213      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3214   "TARGET_64BIT"
3215   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3216   [(set_attr "type" "imovx")
3217    (set_attr "mode" "DI")])
3218
3219 (define_insn "zero_extendqidi2"
3220   [(set (match_operand:DI 0 "register_operand" "=r")
3221      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3222   "TARGET_64BIT"
3223   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "DI")])
3226 \f
3227 ;; Sign extension instructions
3228
3229 (define_expand "extendsidi2"
3230   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3231                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3232               (clobber (reg:CC FLAGS_REG))
3233               (clobber (match_scratch:SI 2 ""))])]
3234   ""
3235 {
3236   if (TARGET_64BIT)
3237     {
3238       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3239       DONE;
3240     }
3241 })
3242
3243 (define_insn "*extendsidi2_1"
3244   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3245         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3246    (clobber (reg:CC FLAGS_REG))
3247    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3248   "!TARGET_64BIT"
3249   "#")
3250
3251 (define_insn "extendsidi2_rex64"
3252   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3253         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3254   "TARGET_64BIT"
3255   "@
3256    {cltq|cdqe}
3257    movs{lq|x}\t{%1,%0|%0, %1}"
3258   [(set_attr "type" "imovx")
3259    (set_attr "mode" "DI")
3260    (set_attr "prefix_0f" "0")
3261    (set_attr "modrm" "0,1")])
3262
3263 (define_insn "extendhidi2"
3264   [(set (match_operand:DI 0 "register_operand" "=r")
3265         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3266   "TARGET_64BIT"
3267   "movs{wq|x}\t{%1,%0|%0, %1}"
3268   [(set_attr "type" "imovx")
3269    (set_attr "mode" "DI")])
3270
3271 (define_insn "extendqidi2"
3272   [(set (match_operand:DI 0 "register_operand" "=r")
3273         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3274   "TARGET_64BIT"
3275   "movs{bq|x}\t{%1,%0|%0, %1}"
3276    [(set_attr "type" "imovx")
3277     (set_attr "mode" "DI")])
3278
3279 ;; Extend to memory case when source register does die.
3280 (define_split 
3281   [(set (match_operand:DI 0 "memory_operand" "")
3282         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3283    (clobber (reg:CC FLAGS_REG))
3284    (clobber (match_operand:SI 2 "register_operand" ""))]
3285   "(reload_completed
3286     && dead_or_set_p (insn, operands[1])
3287     && !reg_mentioned_p (operands[1], operands[0]))"
3288   [(set (match_dup 3) (match_dup 1))
3289    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3290               (clobber (reg:CC FLAGS_REG))])
3291    (set (match_dup 4) (match_dup 1))]
3292   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293
3294 ;; Extend to memory case when source register does not die.
3295 (define_split 
3296   [(set (match_operand:DI 0 "memory_operand" "")
3297         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3298    (clobber (reg:CC FLAGS_REG))
3299    (clobber (match_operand:SI 2 "register_operand" ""))]
3300   "reload_completed"
3301   [(const_int 0)]
3302 {
3303   split_di (&operands[0], 1, &operands[3], &operands[4]);
3304
3305   emit_move_insn (operands[3], operands[1]);
3306
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[1]) == 0
3309       && true_regnum (operands[2]) == 1
3310       && (optimize_size || TARGET_USE_CLTD))
3311     {
3312       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3313     }
3314   else
3315     {
3316       emit_move_insn (operands[2], operands[1]);
3317       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3318     }
3319   emit_move_insn (operands[4], operands[2]);
3320   DONE;
3321 })
3322
3323 ;; Extend to register case.  Optimize case where source and destination
3324 ;; registers match and cases where we can use cltd.
3325 (define_split 
3326   [(set (match_operand:DI 0 "register_operand" "")
3327         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3328    (clobber (reg:CC FLAGS_REG))
3329    (clobber (match_scratch:SI 2 ""))]
3330   "reload_completed"
3331   [(const_int 0)]
3332 {
3333   split_di (&operands[0], 1, &operands[3], &operands[4]);
3334
3335   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3336     emit_move_insn (operands[3], operands[1]);
3337
3338   /* Generate a cltd if possible and doing so it profitable.  */
3339   if (true_regnum (operands[3]) == 0
3340       && (optimize_size || TARGET_USE_CLTD))
3341     {
3342       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3343       DONE;
3344     }
3345
3346   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3347     emit_move_insn (operands[4], operands[1]);
3348
3349   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3350   DONE;
3351 })
3352
3353 (define_insn "extendhisi2"
3354   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3355         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3356   ""
3357 {
3358   switch (get_attr_prefix_0f (insn))
3359     {
3360     case 0:
3361       return "{cwtl|cwde}";
3362     default:
3363       return "movs{wl|x}\t{%1,%0|%0, %1}";
3364     }
3365 }
3366   [(set_attr "type" "imovx")
3367    (set_attr "mode" "SI")
3368    (set (attr "prefix_0f")
3369      ;; movsx is short decodable while cwtl is vector decoded.
3370      (if_then_else (and (eq_attr "cpu" "!k6")
3371                         (eq_attr "alternative" "0"))
3372         (const_string "0")
3373         (const_string "1")))
3374    (set (attr "modrm")
3375      (if_then_else (eq_attr "prefix_0f" "0")
3376         (const_string "0")
3377         (const_string "1")))])
3378
3379 (define_insn "*extendhisi2_zext"
3380   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3381         (zero_extend:DI
3382           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3383   "TARGET_64BIT"
3384 {
3385   switch (get_attr_prefix_0f (insn))
3386     {
3387     case 0:
3388       return "{cwtl|cwde}";
3389     default:
3390       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3391     }
3392 }
3393   [(set_attr "type" "imovx")
3394    (set_attr "mode" "SI")
3395    (set (attr "prefix_0f")
3396      ;; movsx is short decodable while cwtl is vector decoded.
3397      (if_then_else (and (eq_attr "cpu" "!k6")
3398                         (eq_attr "alternative" "0"))
3399         (const_string "0")
3400         (const_string "1")))
3401    (set (attr "modrm")
3402      (if_then_else (eq_attr "prefix_0f" "0")
3403         (const_string "0")
3404         (const_string "1")))])
3405
3406 (define_insn "extendqihi2"
3407   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3408         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3409   ""
3410 {
3411   switch (get_attr_prefix_0f (insn))
3412     {
3413     case 0:
3414       return "{cbtw|cbw}";
3415     default:
3416       return "movs{bw|x}\t{%1,%0|%0, %1}";
3417     }
3418 }
3419   [(set_attr "type" "imovx")
3420    (set_attr "mode" "HI")
3421    (set (attr "prefix_0f")
3422      ;; movsx is short decodable while cwtl is vector decoded.
3423      (if_then_else (and (eq_attr "cpu" "!k6")
3424                         (eq_attr "alternative" "0"))
3425         (const_string "0")
3426         (const_string "1")))
3427    (set (attr "modrm")
3428      (if_then_else (eq_attr "prefix_0f" "0")
3429         (const_string "0")
3430         (const_string "1")))])
3431
3432 (define_insn "extendqisi2"
3433   [(set (match_operand:SI 0 "register_operand" "=r")
3434         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3435   ""
3436   "movs{bl|x}\t{%1,%0|%0, %1}"
3437    [(set_attr "type" "imovx")
3438     (set_attr "mode" "SI")])
3439
3440 (define_insn "*extendqisi2_zext"
3441   [(set (match_operand:DI 0 "register_operand" "=r")
3442         (zero_extend:DI
3443           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3444   "TARGET_64BIT"
3445   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3446    [(set_attr "type" "imovx")
3447     (set_attr "mode" "SI")])
3448 \f
3449 ;; Conversions between float and double.
3450
3451 ;; These are all no-ops in the model used for the 80387.  So just
3452 ;; emit moves.
3453
3454 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3455 (define_insn "*dummy_extendsfdf2"
3456   [(set (match_operand:DF 0 "push_operand" "=<")
3457         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3458   "0"
3459   "#")
3460
3461 (define_split
3462   [(set (match_operand:DF 0 "push_operand" "")
3463         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3464   "!TARGET_64BIT"
3465   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3466    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3467
3468 (define_split
3469   [(set (match_operand:DF 0 "push_operand" "")
3470         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3471   "TARGET_64BIT"
3472   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3473    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3474
3475 (define_insn "*dummy_extendsfxf2"
3476   [(set (match_operand:XF 0 "push_operand" "=<")
3477         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3478   "0"
3479   "#")
3480
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484   ""
3485   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3486    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492   "TARGET_64BIT"
3493   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3494    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496
3497 (define_split
3498   [(set (match_operand:XF 0 "push_operand" "")
3499         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500   ""
3501   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3502    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3503   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3504
3505 (define_split
3506   [(set (match_operand:XF 0 "push_operand" "")
3507         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508   "TARGET_64BIT"
3509   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3510    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3511   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3512
3513 (define_expand "extendsfdf2"
3514   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3515         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3517 {
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (SFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extendsfdf2_mixed"
3527   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3528         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3529   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 1:
3538       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3539         return "fstp%z0\t%y0";
3540       else
3541         return "fst%z0\t%y0";
3542
3543     case 2:
3544       return "cvtss2sd\t{%1, %0|%0, %1}";
3545
3546     default:
3547       gcc_unreachable ();
3548     }
3549 }
3550   [(set_attr "type" "fmov,fmov,ssecvt")
3551    (set_attr "mode" "SF,XF,DF")])
3552
3553 (define_insn "*extendsfdf2_sse"
3554   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3555         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3556   "TARGET_SSE2 && TARGET_SSE_MATH
3557    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3558   "cvtss2sd\t{%1, %0|%0, %1}"
3559   [(set_attr "type" "ssecvt")
3560    (set_attr "mode" "DF")])
3561
3562 (define_insn "*extendsfdf2_i387"
3563   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3564         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3565   "TARGET_80387
3566    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567 {
3568   switch (which_alternative)
3569     {
3570     case 0:
3571       return output_387_reg_move (insn, operands);
3572
3573     case 1:
3574       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3575         return "fstp%z0\t%y0";
3576       else
3577         return "fst%z0\t%y0";
3578
3579     default:
3580       gcc_unreachable ();
3581     }
3582 }
3583   [(set_attr "type" "fmov")
3584    (set_attr "mode" "SF,XF")])
3585
3586 (define_expand "extendsfxf2"
3587   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3588         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3589   "TARGET_80387"
3590 {
3591   /* ??? Needed for compress_float_constant since all fp constants
3592      are LEGITIMATE_CONSTANT_P.  */
3593   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3594     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3595   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3596     operands[1] = force_reg (SFmode, operands[1]);
3597 })
3598
3599 (define_insn "*extendsfxf2_i387"
3600   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3601         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3602   "TARGET_80387
3603    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3604 {
3605   switch (which_alternative)
3606     {
3607     case 0:
3608       return output_387_reg_move (insn, operands);
3609
3610     case 1:
3611       /* There is no non-popping store to memory for XFmode.  So if
3612          we need one, follow the store with a load.  */
3613       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614         return "fstp%z0\t%y0";
3615       else
3616         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3617
3618     default:
3619       gcc_unreachable ();
3620     }
3621 }
3622   [(set_attr "type" "fmov")
3623    (set_attr "mode" "SF,XF")])
3624
3625 (define_expand "extenddfxf2"
3626   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3628   "TARGET_80387"
3629 {
3630   /* ??? Needed for compress_float_constant since all fp constants
3631      are LEGITIMATE_CONSTANT_P.  */
3632   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3634   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3635     operands[1] = force_reg (DFmode, operands[1]);
3636 })
3637
3638 (define_insn "*extenddfxf2_i387"
3639   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3640         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3641   "TARGET_80387
3642    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3643 {
3644   switch (which_alternative)
3645     {
3646     case 0:
3647       return output_387_reg_move (insn, operands);
3648
3649     case 1:
3650       /* There is no non-popping store to memory for XFmode.  So if
3651          we need one, follow the store with a load.  */
3652       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3653         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3654       else
3655         return "fstp%z0\t%y0";
3656
3657     default:
3658       gcc_unreachable ();
3659     }
3660 }
3661   [(set_attr "type" "fmov")
3662    (set_attr "mode" "DF,XF")])
3663
3664 ;; %%% This seems bad bad news.
3665 ;; This cannot output into an f-reg because there is no way to be sure
3666 ;; of truncating in that case.  Otherwise this is just like a simple move
3667 ;; insn.  So we pretend we can output to a reg in order to get better
3668 ;; register preferencing, but we really use a stack slot.
3669
3670 ;; Conversion from DFmode to SFmode.
3671
3672 (define_expand "truncdfsf2"
3673   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3674         (float_truncate:SF
3675           (match_operand:DF 1 "nonimmediate_operand" "")))]
3676   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3677 {
3678   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3679     operands[1] = force_reg (DFmode, operands[1]);
3680
3681   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3682     ;
3683   else if (flag_unsafe_math_optimizations)
3684     ;
3685   else
3686     {
3687       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3688       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3689       DONE;
3690     }
3691 })
3692
3693 (define_expand "truncdfsf2_with_temp"
3694   [(parallel [(set (match_operand:SF 0 "" "")
3695                    (float_truncate:SF (match_operand:DF 1 "" "")))
3696               (clobber (match_operand:SF 2 "" ""))])]
3697   "")
3698
3699 (define_insn "*truncdfsf_fast_mixed"
3700   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3701         (float_truncate:SF
3702           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3703   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3704 {
3705   switch (which_alternative)
3706     {
3707     case 0:
3708       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3709         return "fstp%z0\t%y0";
3710       else
3711         return "fst%z0\t%y0";
3712     case 1:
3713       return output_387_reg_move (insn, operands);
3714     case 2:
3715       return "cvtsd2ss\t{%1, %0|%0, %1}";
3716     default:
3717       gcc_unreachable ();
3718     }
3719 }
3720   [(set_attr "type" "fmov,fmov,ssecvt")
3721    (set_attr "mode" "SF")])
3722
3723 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3724 ;; because nothing we do here is unsafe.
3725 (define_insn "*truncdfsf_fast_sse"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3729   "TARGET_SSE2 && TARGET_SSE_MATH"
3730   "cvtsd2ss\t{%1, %0|%0, %1}"
3731   [(set_attr "type" "ssecvt")
3732    (set_attr "mode" "SF")])
3733
3734 (define_insn "*truncdfsf_fast_i387"
3735   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3736         (float_truncate:SF
3737           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3738   "TARGET_80387 && flag_unsafe_math_optimizations"
3739   "* return output_387_reg_move (insn, operands);"
3740   [(set_attr "type" "fmov")
3741    (set_attr "mode" "SF")])
3742
3743 (define_insn "*truncdfsf_mixed"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3747    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3748   "TARGET_MIX_SSE_I387"
3749 {
3750   switch (which_alternative)
3751     {
3752     case 0:
3753       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754         return "fstp%z0\t%y0";
3755       else
3756         return "fst%z0\t%y0";
3757     case 1:
3758       return "#";
3759     case 2:
3760       return "cvtsd2ss\t{%1, %0|%0, %1}";
3761     default:
3762       gcc_unreachable ();
3763     }
3764 }
3765   [(set_attr "type" "fmov,multi,ssecvt")
3766    (set_attr "unit" "*,i387,*")
3767    (set_attr "mode" "SF")])
3768
3769 (define_insn "*truncdfsf_i387"
3770   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3771         (float_truncate:SF
3772           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3773    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3774   "TARGET_80387"
3775 {
3776   switch (which_alternative)
3777     {
3778     case 0:
3779       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780         return "fstp%z0\t%y0";
3781       else
3782         return "fst%z0\t%y0";
3783     case 1:
3784       return "#";
3785     default:
3786       gcc_unreachable ();
3787     }
3788 }
3789   [(set_attr "type" "fmov,multi")
3790    (set_attr "unit" "*,i387")
3791    (set_attr "mode" "SF")])
3792
3793 (define_insn "*truncdfsf2_i387_1"
3794   [(set (match_operand:SF 0 "memory_operand" "=m")
3795         (float_truncate:SF
3796           (match_operand:DF 1 "register_operand" "f")))]
3797   "TARGET_80387
3798    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3799    && !TARGET_MIX_SSE_I387"
3800 {
3801   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802     return "fstp%z0\t%y0";
3803   else
3804     return "fst%z0\t%y0";
3805 }
3806   [(set_attr "type" "fmov")
3807    (set_attr "mode" "SF")])
3808
3809 (define_split
3810   [(set (match_operand:SF 0 "register_operand" "")
3811         (float_truncate:SF
3812          (match_operand:DF 1 "fp_register_operand" "")))
3813    (clobber (match_operand 2 "" ""))]
3814   "reload_completed"
3815   [(set (match_dup 2) (match_dup 1))
3816    (set (match_dup 0) (match_dup 2))]
3817 {
3818   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3819 })
3820
3821 ;; Conversion from XFmode to SFmode.
3822
3823 (define_expand "truncxfsf2"
3824   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3825                    (float_truncate:SF
3826                     (match_operand:XF 1 "register_operand" "")))
3827               (clobber (match_dup 2))])]
3828   "TARGET_80387"
3829 {
3830   if (flag_unsafe_math_optimizations)
3831     {
3832       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3833       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3834       if (reg != operands[0])
3835         emit_move_insn (operands[0], reg);
3836       DONE;
3837     }
3838   else
3839     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3840 })
3841
3842 (define_insn "*truncxfsf2_mixed"
3843   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3844         (float_truncate:SF
3845          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3846    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3847   "TARGET_MIX_SSE_I387"
3848 {
3849   gcc_assert (!which_alternative);
3850   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3851     return "fstp%z0\t%y0";
3852   else
3853     return "fst%z0\t%y0";
3854 }
3855   [(set_attr "type" "fmov,multi,multi,multi")
3856    (set_attr "unit" "*,i387,i387,i387")
3857    (set_attr "mode" "SF")])
3858
3859 (define_insn "truncxfsf2_i387_noop"
3860   [(set (match_operand:SF 0 "register_operand" "=f")
3861         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3862   "TARGET_80387 && flag_unsafe_math_optimizations"
3863 {
3864   return output_387_reg_move (insn, operands);
3865 }
3866   [(set_attr "type" "fmov")
3867    (set_attr "mode" "SF")])
3868
3869 (define_insn "*truncxfsf2_i387"
3870   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "f,f,f")))
3873    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3874   "TARGET_80387"
3875 {
3876   gcc_assert (!which_alternative);
3877   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3878     return "fstp%z0\t%y0";
3879    else
3880      return "fst%z0\t%y0";
3881 }
3882   [(set_attr "type" "fmov,multi,multi")
3883    (set_attr "unit" "*,i387,i387")
3884    (set_attr "mode" "SF")])
3885
3886 (define_insn "*truncxfsf2_i387_1"
3887   [(set (match_operand:SF 0 "memory_operand" "=m")
3888         (float_truncate:SF
3889          (match_operand:XF 1 "register_operand" "f")))]
3890   "TARGET_80387"
3891 {
3892   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3893     return "fstp%z0\t%y0";
3894   else
3895     return "fst%z0\t%y0";
3896 }
3897   [(set_attr "type" "fmov")
3898    (set_attr "mode" "SF")])
3899
3900 (define_split
3901   [(set (match_operand:SF 0 "register_operand" "")
3902         (float_truncate:SF
3903          (match_operand:XF 1 "register_operand" "")))
3904    (clobber (match_operand:SF 2 "memory_operand" ""))]
3905   "TARGET_80387 && reload_completed"
3906   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3907    (set (match_dup 0) (match_dup 2))]
3908   "")
3909
3910 (define_split
3911   [(set (match_operand:SF 0 "memory_operand" "")
3912         (float_truncate:SF
3913          (match_operand:XF 1 "register_operand" "")))
3914    (clobber (match_operand:SF 2 "memory_operand" ""))]
3915   "TARGET_80387"
3916   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3917   "")
3918
3919 ;; Conversion from XFmode to DFmode.
3920
3921 (define_expand "truncxfdf2"
3922   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923                    (float_truncate:DF
3924                     (match_operand:XF 1 "register_operand" "")))
3925               (clobber (match_dup 2))])]
3926   "TARGET_80387"
3927 {
3928   if (flag_unsafe_math_optimizations)
3929     {
3930       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3931       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3932       if (reg != operands[0])
3933         emit_move_insn (operands[0], reg);
3934       DONE;
3935     }
3936   else
3937     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3938 })
3939
3940 (define_insn "*truncxfdf2_mixed"
3941   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3942         (float_truncate:DF
3943          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3944    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3945   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946 {
3947   gcc_assert (!which_alternative);
3948   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949     return "fstp%z0\t%y0";
3950   else
3951     return "fst%z0\t%y0";
3952 }
3953   [(set_attr "type" "fmov,multi,multi,multi")
3954    (set_attr "unit" "*,i387,i387,i387")
3955    (set_attr "mode" "DF")])
3956
3957 (define_insn "truncxfdf2_i387_noop"
3958   [(set (match_operand:DF 0 "register_operand" "=f")
3959         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960   "TARGET_80387 && flag_unsafe_math_optimizations"
3961 {
3962   return output_387_reg_move (insn, operands);
3963 }
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "DF")])
3966
3967 (define_insn "*truncxfdf2_i387"
3968   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "f,f,f")))
3971    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3972   "TARGET_80387"
3973 {
3974   gcc_assert (!which_alternative);
3975   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3976     return "fstp%z0\t%y0";
3977   else
3978     return "fst%z0\t%y0";
3979 }
3980   [(set_attr "type" "fmov,multi,multi")
3981    (set_attr "unit" "*,i387,i387")
3982    (set_attr "mode" "DF")])
3983
3984 (define_insn "*truncxfdf2_i387_1"
3985   [(set (match_operand:DF 0 "memory_operand" "=m")
3986         (float_truncate:DF
3987           (match_operand:XF 1 "register_operand" "f")))]
3988   "TARGET_80387"
3989 {
3990   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991     return "fstp%z0\t%y0";
3992   else
3993     return "fst%z0\t%y0";
3994 }
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "DF")])
3997
3998 (define_split
3999   [(set (match_operand:DF 0 "register_operand" "")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "")))
4002    (clobber (match_operand:DF 2 "memory_operand" ""))]
4003   "TARGET_80387 && reload_completed"
4004   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4005    (set (match_dup 0) (match_dup 2))]
4006   "")
4007
4008 (define_split
4009   [(set (match_operand:DF 0 "memory_operand" "")
4010         (float_truncate:DF
4011          (match_operand:XF 1 "register_operand" "")))
4012    (clobber (match_operand:DF 2 "memory_operand" ""))]
4013   "TARGET_80387"
4014   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4015   "")
4016 \f
4017 ;; Signed conversion to DImode.
4018
4019 (define_expand "fix_truncxfdi2"
4020   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4022               (clobber (reg:CC FLAGS_REG))])]
4023   "TARGET_80387"
4024 {
4025   if (TARGET_FISTTP)
4026    {
4027      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4028      DONE;
4029    }
4030 })
4031
4032 (define_expand "fix_trunc<mode>di2"
4033   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4035               (clobber (reg:CC FLAGS_REG))])]
4036   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4037 {
4038   if (TARGET_FISTTP
4039       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4040    {
4041      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4042      DONE;
4043    }
4044   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4045    {
4046      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4047      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4048      if (out != operands[0])
4049         emit_move_insn (operands[0], out);
4050      DONE;
4051    }
4052 })
4053
4054 ;; Signed conversion to SImode.
4055
4056 (define_expand "fix_truncxfsi2"
4057   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4058                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4059               (clobber (reg:CC FLAGS_REG))])]
4060   "TARGET_80387"
4061 {
4062   if (TARGET_FISTTP)
4063    {
4064      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4065      DONE;
4066    }
4067 })
4068
4069 (define_expand "fix_trunc<mode>si2"
4070   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4071                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4072               (clobber (reg:CC FLAGS_REG))])]
4073   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4074 {
4075   if (TARGET_FISTTP
4076       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4077    {
4078      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4079      DONE;
4080    }
4081   if (SSE_FLOAT_MODE_P (<MODE>mode))
4082    {
4083      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4084      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4085      if (out != operands[0])
4086         emit_move_insn (operands[0], out);
4087      DONE;
4088    }
4089 })
4090
4091 ;; Signed conversion to HImode.
4092
4093 (define_expand "fix_trunc<mode>hi2"
4094   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4095                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4096               (clobber (reg:CC FLAGS_REG))])]
4097   "TARGET_80387
4098    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4099 {
4100   if (TARGET_FISTTP)
4101    {
4102      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4103      DONE;
4104    }
4105 })
4106
4107 ;; When SSE is available, it is always faster to use it!
4108 (define_insn "fix_truncsfdi_sse"
4109   [(set (match_operand:DI 0 "register_operand" "=r,r")
4110         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4111   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4112   "cvttss2si{q}\t{%1, %0|%0, %1}"
4113   [(set_attr "type" "sseicvt")
4114    (set_attr "mode" "SF")
4115    (set_attr "athlon_decode" "double,vector")])
4116
4117 (define_insn "fix_truncdfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4120   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4121   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "DF")
4124    (set_attr "athlon_decode" "double,vector")])
4125
4126 (define_insn "fix_truncsfsi_sse"
4127   [(set (match_operand:SI 0 "register_operand" "=r,r")
4128         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttss2si\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "DF")
4133    (set_attr "athlon_decode" "double,vector")])
4134
4135 (define_insn "fix_truncdfsi_sse"
4136   [(set (match_operand:SI 0 "register_operand" "=r,r")
4137         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttsd2si\t{%1, %0|%0, %1}"
4140   [(set_attr "type" "sseicvt")
4141    (set_attr "mode" "DF")
4142    (set_attr "athlon_decode" "double,vector")])
4143
4144 ;; Avoid vector decoded forms of the instruction.
4145 (define_peephole2
4146   [(match_scratch:DF 2 "Y")
4147    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4148         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4149   "TARGET_K8 && !optimize_size"
4150   [(set (match_dup 2) (match_dup 1))
4151    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4152   "")
4153
4154 (define_peephole2
4155   [(match_scratch:SF 2 "x")
4156    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4157         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4158   "TARGET_K8 && !optimize_size"
4159   [(set (match_dup 2) (match_dup 1))
4160    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4161   "")
4162
4163 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4164   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4165         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4166   "TARGET_FISTTP
4167    && FLOAT_MODE_P (GET_MODE (operands[1]))
4168    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4169          && (TARGET_64BIT || <MODE>mode != DImode))
4170         && TARGET_SSE_MATH)
4171    && !(reload_completed || reload_in_progress)"
4172   "#"
4173   "&& 1"
4174   [(const_int 0)]
4175 {
4176   if (memory_operand (operands[0], VOIDmode))
4177     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4178   else
4179     {
4180       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4181       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4182                                                             operands[1],
4183                                                             operands[2]));
4184     }
4185   DONE;
4186 }
4187   [(set_attr "type" "fisttp")
4188    (set_attr "mode" "<MODE>")])
4189
4190 (define_insn "fix_trunc<mode>_i387_fisttp"
4191   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4192         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4193    (clobber (match_scratch:XF 2 "=&1f"))]
4194   "TARGET_FISTTP
4195    && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4197          && (TARGET_64BIT || <MODE>mode != DImode))
4198         && TARGET_SSE_MATH)"
4199   "* return output_fix_trunc (insn, operands, 1);"
4200   [(set_attr "type" "fisttp")
4201    (set_attr "mode" "<MODE>")])
4202
4203 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4204   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4205         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4206    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4207    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4208   "TARGET_FISTTP
4209    && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4211         && (TARGET_64BIT || <MODE>mode != DImode))
4212         && TARGET_SSE_MATH)"
4213   "#"
4214   [(set_attr "type" "fisttp")
4215    (set_attr "mode" "<MODE>")])
4216
4217 (define_split
4218   [(set (match_operand:X87MODEI 0 "register_operand" "")
4219         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4220    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4221    (clobber (match_scratch 3 ""))]
4222   "reload_completed"
4223   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4224               (clobber (match_dup 3))])
4225    (set (match_dup 0) (match_dup 2))]
4226   "")
4227
4228 (define_split
4229   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4230         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4231    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4232    (clobber (match_scratch 3 ""))]
4233   "reload_completed"
4234   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4235               (clobber (match_dup 3))])]
4236   "")
4237
4238 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4239 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4240 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4241 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4242 ;; function in i386.c.
4243 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4244   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4245         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4246    (clobber (reg:CC FLAGS_REG))]
4247   "TARGET_80387 && !TARGET_FISTTP
4248    && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250          && (TARGET_64BIT || <MODE>mode != DImode))
4251    && !(reload_completed || reload_in_progress)"
4252   "#"
4253   "&& 1"
4254   [(const_int 0)]
4255 {
4256   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4257
4258   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4259   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4260   if (memory_operand (operands[0], VOIDmode))
4261     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4262                                          operands[2], operands[3]));
4263   else
4264     {
4265       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4266       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4267                                                      operands[2], operands[3],
4268                                                      operands[4]));
4269     }
4270   DONE;
4271 }
4272   [(set_attr "type" "fistp")
4273    (set_attr "i387_cw" "trunc")
4274    (set_attr "mode" "<MODE>")])
4275
4276 (define_insn "fix_truncdi_i387"
4277   [(set (match_operand:DI 0 "memory_operand" "=m")
4278         (fix:DI (match_operand 1 "register_operand" "f")))
4279    (use (match_operand:HI 2 "memory_operand" "m"))
4280    (use (match_operand:HI 3 "memory_operand" "m"))
4281    (clobber (match_scratch:XF 4 "=&1f"))]
4282   "TARGET_80387 && !TARGET_FISTTP
4283    && FLOAT_MODE_P (GET_MODE (operands[1]))
4284    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4285   "* return output_fix_trunc (insn, operands, 0);"
4286   [(set_attr "type" "fistp")
4287    (set_attr "i387_cw" "trunc")
4288    (set_attr "mode" "DI")])
4289
4290 (define_insn "fix_truncdi_i387_with_temp"
4291   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:DI (match_operand 1 "register_operand" "f,f")))
4293    (use (match_operand:HI 2 "memory_operand" "m,m"))
4294    (use (match_operand:HI 3 "memory_operand" "m,m"))
4295    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4296    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4297   "TARGET_80387 && !TARGET_FISTTP
4298    && FLOAT_MODE_P (GET_MODE (operands[1]))
4299    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4300   "#"
4301   [(set_attr "type" "fistp")
4302    (set_attr "i387_cw" "trunc")
4303    (set_attr "mode" "DI")])
4304
4305 (define_split 
4306   [(set (match_operand:DI 0 "register_operand" "")
4307         (fix:DI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:DI 4 "memory_operand" ""))
4311    (clobber (match_scratch 5 ""))]
4312   "reload_completed"
4313   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4314               (use (match_dup 2))
4315               (use (match_dup 3))
4316               (clobber (match_dup 5))])
4317    (set (match_dup 0) (match_dup 4))]
4318   "")
4319
4320 (define_split 
4321   [(set (match_operand:DI 0 "memory_operand" "")
4322         (fix:DI (match_operand 1 "register_operand" "")))
4323    (use (match_operand:HI 2 "memory_operand" ""))
4324    (use (match_operand:HI 3 "memory_operand" ""))
4325    (clobber (match_operand:DI 4 "memory_operand" ""))
4326    (clobber (match_scratch 5 ""))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4329               (use (match_dup 2))
4330               (use (match_dup 3))
4331               (clobber (match_dup 5))])]
4332   "")
4333
4334 (define_insn "fix_trunc<mode>_i387"
4335   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4336         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4337    (use (match_operand:HI 2 "memory_operand" "m"))
4338    (use (match_operand:HI 3 "memory_operand" "m"))]
4339   "TARGET_80387 && !TARGET_FISTTP
4340    && FLOAT_MODE_P (GET_MODE (operands[1]))
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "* return output_fix_trunc (insn, operands, 0);"
4343   [(set_attr "type" "fistp")
4344    (set_attr "i387_cw" "trunc")
4345    (set_attr "mode" "<MODE>")])
4346
4347 (define_insn "fix_trunc<mode>_i387_with_temp"
4348   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4349         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4350    (use (match_operand:HI 2 "memory_operand" "m,m"))
4351    (use (match_operand:HI 3 "memory_operand" "m,m"))
4352    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4353   "TARGET_80387 && !TARGET_FISTTP
4354    && FLOAT_MODE_P (GET_MODE (operands[1]))
4355    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356   "#"
4357   [(set_attr "type" "fistp")
4358    (set_attr "i387_cw" "trunc")
4359    (set_attr "mode" "<MODE>")])
4360
4361 (define_split 
4362   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4363         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4364    (use (match_operand:HI 2 "memory_operand" ""))
4365    (use (match_operand:HI 3 "memory_operand" ""))
4366    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4367   "reload_completed"
4368   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4369               (use (match_dup 2))
4370               (use (match_dup 3))])
4371    (set (match_dup 0) (match_dup 4))]
4372   "")
4373
4374 (define_split 
4375   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4376         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4380   "reload_completed"
4381   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4382               (use (match_dup 2))
4383               (use (match_dup 3))])]
4384   "")
4385
4386 (define_insn "x86_fnstcw_1"
4387   [(set (match_operand:HI 0 "memory_operand" "=m")
4388         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4389   "TARGET_80387"
4390   "fnstcw\t%0"
4391   [(set_attr "length" "2")
4392    (set_attr "mode" "HI")
4393    (set_attr "unit" "i387")])
4394
4395 (define_insn "x86_fldcw_1"
4396   [(set (reg:HI FPSR_REG)
4397         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4398   "TARGET_80387"
4399   "fldcw\t%0"
4400   [(set_attr "length" "2")
4401    (set_attr "mode" "HI")
4402    (set_attr "unit" "i387")
4403    (set_attr "athlon_decode" "vector")])
4404 \f
4405 ;; Conversion between fixed point and floating point.
4406
4407 ;; Even though we only accept memory inputs, the backend _really_
4408 ;; wants to be able to do this between registers.
4409
4410 (define_expand "floathisf2"
4411   [(set (match_operand:SF 0 "register_operand" "")
4412         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4413   "TARGET_80387 || TARGET_SSE_MATH"
4414 {
4415   if (TARGET_SSE_MATH)
4416     {
4417       emit_insn (gen_floatsisf2 (operands[0],
4418                                  convert_to_mode (SImode, operands[1], 0)));
4419       DONE;
4420     }
4421 })
4422
4423 (define_insn "*floathisf2_i387"
4424   [(set (match_operand:SF 0 "register_operand" "=f,f")
4425         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4426   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4427   "@
4428    fild%z1\t%1
4429    #"
4430   [(set_attr "type" "fmov,multi")
4431    (set_attr "mode" "SF")
4432    (set_attr "unit" "*,i387")
4433    (set_attr "fp_int_src" "true")])
4434
4435 (define_expand "floatsisf2"
4436   [(set (match_operand:SF 0 "register_operand" "")
4437         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4438   "TARGET_80387 || TARGET_SSE_MATH"
4439   "")
4440
4441 (define_insn "*floatsisf2_mixed"
4442   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4443         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4444   "TARGET_MIX_SSE_I387"
4445   "@
4446    fild%z1\t%1
4447    #
4448    cvtsi2ss\t{%1, %0|%0, %1}
4449    cvtsi2ss\t{%1, %0|%0, %1}"
4450   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4451    (set_attr "mode" "SF")
4452    (set_attr "unit" "*,i387,*,*")
4453    (set_attr "athlon_decode" "*,*,vector,double")
4454    (set_attr "fp_int_src" "true")])
4455
4456 (define_insn "*floatsisf2_sse"
4457   [(set (match_operand:SF 0 "register_operand" "=x,x")
4458         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4459   "TARGET_SSE_MATH"
4460   "cvtsi2ss\t{%1, %0|%0, %1}"
4461   [(set_attr "type" "sseicvt")
4462    (set_attr "mode" "SF")
4463    (set_attr "athlon_decode" "vector,double")
4464    (set_attr "fp_int_src" "true")])
4465
4466 (define_insn "*floatsisf2_i387"
4467   [(set (match_operand:SF 0 "register_operand" "=f,f")
4468         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4469   "TARGET_80387"
4470   "@
4471    fild%z1\t%1
4472    #"
4473   [(set_attr "type" "fmov,multi")
4474    (set_attr "mode" "SF")
4475    (set_attr "unit" "*,i387")
4476    (set_attr "fp_int_src" "true")])
4477
4478 (define_expand "floatdisf2"
4479   [(set (match_operand:SF 0 "register_operand" "")
4480         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4482   "")
4483
4484 (define_insn "*floatdisf2_mixed"
4485   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488   "@
4489    fild%z1\t%1
4490    #
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}
4492    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "unit" "*,i387,*,*")
4496    (set_attr "athlon_decode" "*,*,vector,double")
4497    (set_attr "fp_int_src" "true")])
4498
4499 (define_insn "*floatdisf2_sse"
4500   [(set (match_operand:SF 0 "register_operand" "=x,x")
4501         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4502   "TARGET_64BIT && TARGET_SSE_MATH"
4503   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4504   [(set_attr "type" "sseicvt")
4505    (set_attr "mode" "SF")
4506    (set_attr "athlon_decode" "vector,double")
4507    (set_attr "fp_int_src" "true")])
4508
4509 (define_insn "*floatdisf2_i387"
4510   [(set (match_operand:SF 0 "register_operand" "=f,f")
4511         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4512   "TARGET_80387"
4513   "@
4514    fild%z1\t%1
4515    #"
4516   [(set_attr "type" "fmov,multi")
4517    (set_attr "mode" "SF")
4518    (set_attr "unit" "*,i387")
4519    (set_attr "fp_int_src" "true")])
4520
4521 (define_expand "floathidf2"
4522   [(set (match_operand:DF 0 "register_operand" "")
4523         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4524   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4525 {
4526   if (TARGET_SSE2 && TARGET_SSE_MATH)
4527     {
4528       emit_insn (gen_floatsidf2 (operands[0],
4529                                  convert_to_mode (SImode, operands[1], 0)));
4530       DONE;
4531     }
4532 })
4533
4534 (define_insn "*floathidf2_i387"
4535   [(set (match_operand:DF 0 "register_operand" "=f,f")
4536         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4537   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4538   "@
4539    fild%z1\t%1
4540    #"
4541   [(set_attr "type" "fmov,multi")
4542    (set_attr "mode" "DF")
4543    (set_attr "unit" "*,i387")
4544    (set_attr "fp_int_src" "true")])
4545
4546 (define_expand "floatsidf2"
4547   [(set (match_operand:DF 0 "register_operand" "")
4548         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4549   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4550   "")
4551
4552 (define_insn "*floatsidf2_mixed"
4553   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4554         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4555   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4556   "@
4557    fild%z1\t%1
4558    #
4559    cvtsi2sd\t{%1, %0|%0, %1}
4560    cvtsi2sd\t{%1, %0|%0, %1}"
4561   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4562    (set_attr "mode" "DF")
4563    (set_attr "unit" "*,i387,*,*")
4564    (set_attr "athlon_decode" "*,*,double,direct")
4565    (set_attr "fp_int_src" "true")])
4566
4567 (define_insn "*floatsidf2_sse"
4568   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4569         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4570   "TARGET_SSE2 && TARGET_SSE_MATH"
4571   "cvtsi2sd\t{%1, %0|%0, %1}"
4572   [(set_attr "type" "sseicvt")
4573    (set_attr "mode" "DF")
4574    (set_attr "athlon_decode" "double,direct")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_insn "*floatsidf2_i387"
4578   [(set (match_operand:DF 0 "register_operand" "=f,f")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "DF")
4586    (set_attr "unit" "*,i387")
4587    (set_attr "fp_int_src" "true")])
4588
4589 (define_expand "floatdidf2"
4590   [(set (match_operand:DF 0 "register_operand" "")
4591         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4593   "")
4594
4595 (define_insn "*floatdidf2_mixed"
4596   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4597         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4598   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4599   "@
4600    fild%z1\t%1
4601    #
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}
4603    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4604   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4605    (set_attr "mode" "DF")
4606    (set_attr "unit" "*,i387,*,*")
4607    (set_attr "athlon_decode" "*,*,double,direct")
4608    (set_attr "fp_int_src" "true")])
4609
4610 (define_insn "*floatdidf2_sse"
4611   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4612         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4613   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4614   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4615   [(set_attr "type" "sseicvt")
4616    (set_attr "mode" "DF")
4617    (set_attr "athlon_decode" "double,direct")
4618    (set_attr "fp_int_src" "true")])
4619
4620 (define_insn "*floatdidf2_i387"
4621   [(set (match_operand:DF 0 "register_operand" "=f,f")
4622         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4623   "TARGET_80387"
4624   "@
4625    fild%z1\t%1
4626    #"
4627   [(set_attr "type" "fmov,multi")
4628    (set_attr "mode" "DF")
4629    (set_attr "unit" "*,i387")
4630    (set_attr "fp_int_src" "true")])
4631
4632 (define_insn "floathixf2"
4633   [(set (match_operand:XF 0 "register_operand" "=f,f")
4634         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4635   "TARGET_80387"
4636   "@
4637    fild%z1\t%1
4638    #"
4639   [(set_attr "type" "fmov,multi")
4640    (set_attr "mode" "XF")
4641    (set_attr "unit" "*,i387")
4642    (set_attr "fp_int_src" "true")])
4643
4644 (define_insn "floatsixf2"
4645   [(set (match_operand:XF 0 "register_operand" "=f,f")
4646         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4647   "TARGET_80387"
4648   "@
4649    fild%z1\t%1
4650    #"
4651   [(set_attr "type" "fmov,multi")
4652    (set_attr "mode" "XF")
4653    (set_attr "unit" "*,i387")
4654    (set_attr "fp_int_src" "true")])
4655
4656 (define_insn "floatdixf2"
4657   [(set (match_operand:XF 0 "register_operand" "=f,f")
4658         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4659   "TARGET_80387"
4660   "@
4661    fild%z1\t%1
4662    #"
4663   [(set_attr "type" "fmov,multi")
4664    (set_attr "mode" "XF")
4665    (set_attr "unit" "*,i387")
4666    (set_attr "fp_int_src" "true")])
4667
4668 ;; %%% Kill these when reload knows how to do it.
4669 (define_split
4670   [(set (match_operand 0 "fp_register_operand" "")
4671         (float (match_operand 1 "register_operand" "")))]
4672   "reload_completed
4673    && TARGET_80387
4674    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4675   [(const_int 0)]
4676 {
4677   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4678   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4679   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4680   ix86_free_from_memory (GET_MODE (operands[1]));
4681   DONE;
4682 })
4683
4684 (define_expand "floatunssisf2"
4685   [(use (match_operand:SF 0 "register_operand" ""))
4686    (use (match_operand:SI 1 "register_operand" ""))]
4687   "!TARGET_64BIT && TARGET_SSE_MATH"
4688   "x86_emit_floatuns (operands); DONE;")
4689
4690 (define_expand "floatunsdisf2"
4691   [(use (match_operand:SF 0 "register_operand" ""))
4692    (use (match_operand:DI 1 "register_operand" ""))]
4693   "TARGET_64BIT && TARGET_SSE_MATH"
4694   "x86_emit_floatuns (operands); DONE;")
4695
4696 (define_expand "floatunsdidf2"
4697   [(use (match_operand:DF 0 "register_operand" ""))
4698    (use (match_operand:DI 1 "register_operand" ""))]
4699   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700   "x86_emit_floatuns (operands); DONE;")
4701 \f
4702 ;; SSE extract/set expanders
4703
4704 \f
4705 ;; Add instructions
4706
4707 ;; %%% splits for addditi3
4708
4709 (define_expand "addti3"
4710   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4711         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4712                  (match_operand:TI 2 "x86_64_general_operand" "")))
4713    (clobber (reg:CC FLAGS_REG))]
4714   "TARGET_64BIT"
4715   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4716
4717 (define_insn "*addti3_1"
4718   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4720                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4721    (clobber (reg:CC FLAGS_REG))]
4722   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4723   "#")
4724
4725 (define_split
4726   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4727         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4728                  (match_operand:TI 2 "general_operand" "")))
4729    (clobber (reg:CC FLAGS_REG))]
4730   "TARGET_64BIT && reload_completed"
4731   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4732                                           UNSPEC_ADD_CARRY))
4733               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4734    (parallel [(set (match_dup 3)
4735                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4736                                      (match_dup 4))
4737                             (match_dup 5)))
4738               (clobber (reg:CC FLAGS_REG))])]
4739   "split_ti (operands+0, 1, operands+0, operands+3);
4740    split_ti (operands+1, 1, operands+1, operands+4);
4741    split_ti (operands+2, 1, operands+2, operands+5);")
4742
4743 ;; %%% splits for addsidi3
4744 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4746 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4747
4748 (define_expand "adddi3"
4749   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4750         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4751                  (match_operand:DI 2 "x86_64_general_operand" "")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   ""
4754   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4755
4756 (define_insn "*adddi3_1"
4757   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4758         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4759                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4762   "#")
4763
4764 (define_split
4765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4766         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4767                  (match_operand:DI 2 "general_operand" "")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "!TARGET_64BIT && reload_completed"
4770   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771                                           UNSPEC_ADD_CARRY))
4772               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4773    (parallel [(set (match_dup 3)
4774                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4775                                      (match_dup 4))
4776                             (match_dup 5)))
4777               (clobber (reg:CC FLAGS_REG))])]
4778   "split_di (operands+0, 1, operands+0, operands+3);
4779    split_di (operands+1, 1, operands+1, operands+4);
4780    split_di (operands+2, 1, operands+2, operands+5);")
4781
4782 (define_insn "adddi3_carry_rex64"
4783   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4784           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4785                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4786                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4787    (clobber (reg:CC FLAGS_REG))]
4788   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4789   "adc{q}\t{%2, %0|%0, %2}"
4790   [(set_attr "type" "alu")
4791    (set_attr "pent_pair" "pu")
4792    (set_attr "mode" "DI")])
4793
4794 (define_insn "*adddi3_cc_rex64"
4795   [(set (reg:CC FLAGS_REG)
4796         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4798                    UNSPEC_ADD_CARRY))
4799    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4800         (plus:DI (match_dup 1) (match_dup 2)))]
4801   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4802   "add{q}\t{%2, %0|%0, %2}"
4803   [(set_attr "type" "alu")
4804    (set_attr "mode" "DI")])
4805
4806 (define_insn "addqi3_carry"
4807   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4808           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4809                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4810                    (match_operand:QI 2 "general_operand" "qi,qm")))
4811    (clobber (reg:CC FLAGS_REG))]
4812   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4813   "adc{b}\t{%2, %0|%0, %2}"
4814   [(set_attr "type" "alu")
4815    (set_attr "pent_pair" "pu")
4816    (set_attr "mode" "QI")])
4817
4818 (define_insn "addhi3_carry"
4819   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4820           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4821                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4822                    (match_operand:HI 2 "general_operand" "ri,rm")))
4823    (clobber (reg:CC FLAGS_REG))]
4824   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4825   "adc{w}\t{%2, %0|%0, %2}"
4826   [(set_attr "type" "alu")
4827    (set_attr "pent_pair" "pu")
4828    (set_attr "mode" "HI")])
4829
4830 (define_insn "addsi3_carry"
4831   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4832           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4833                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4834                    (match_operand:SI 2 "general_operand" "ri,rm")))
4835    (clobber (reg:CC FLAGS_REG))]
4836   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4837   "adc{l}\t{%2, %0|%0, %2}"
4838   [(set_attr "type" "alu")
4839    (set_attr "pent_pair" "pu")
4840    (set_attr "mode" "SI")])
4841
4842 (define_insn "*addsi3_carry_zext"
4843   [(set (match_operand:DI 0 "register_operand" "=r")
4844           (zero_extend:DI 
4845             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4846                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4847                      (match_operand:SI 2 "general_operand" "rim"))))
4848    (clobber (reg:CC FLAGS_REG))]
4849   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4850   "adc{l}\t{%2, %k0|%k0, %2}"
4851   [(set_attr "type" "alu")
4852    (set_attr "pent_pair" "pu")
4853    (set_attr "mode" "SI")])
4854
4855 (define_insn "*addsi3_cc"
4856   [(set (reg:CC FLAGS_REG)
4857         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4858                     (match_operand:SI 2 "general_operand" "ri,rm")]
4859                    UNSPEC_ADD_CARRY))
4860    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4861         (plus:SI (match_dup 1) (match_dup 2)))]
4862   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4863   "add{l}\t{%2, %0|%0, %2}"
4864   [(set_attr "type" "alu")
4865    (set_attr "mode" "SI")])
4866
4867 (define_insn "addqi3_cc"
4868   [(set (reg:CC FLAGS_REG)
4869         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4870                     (match_operand:QI 2 "general_operand" "qi,qm")]
4871                    UNSPEC_ADD_CARRY))
4872    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4873         (plus:QI (match_dup 1) (match_dup 2)))]
4874   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4875   "add{b}\t{%2, %0|%0, %2}"
4876   [(set_attr "type" "alu")
4877    (set_attr "mode" "QI")])
4878
4879 (define_expand "addsi3"
4880   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4881                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4882                             (match_operand:SI 2 "general_operand" "")))
4883               (clobber (reg:CC FLAGS_REG))])]
4884   ""
4885   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4886
4887 (define_insn "*lea_1"
4888   [(set (match_operand:SI 0 "register_operand" "=r")
4889         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4890   "!TARGET_64BIT"
4891   "lea{l}\t{%a1, %0|%0, %a1}"
4892   [(set_attr "type" "lea")
4893    (set_attr "mode" "SI")])
4894
4895 (define_insn "*lea_1_rex64"
4896   [(set (match_operand:SI 0 "register_operand" "=r")
4897         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4898   "TARGET_64BIT"
4899   "lea{l}\t{%a1, %0|%0, %a1}"
4900   [(set_attr "type" "lea")
4901    (set_attr "mode" "SI")])
4902
4903 (define_insn "*lea_1_zext"
4904   [(set (match_operand:DI 0 "register_operand" "=r")
4905         (zero_extend:DI
4906          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4907   "TARGET_64BIT"
4908   "lea{l}\t{%a1, %k0|%k0, %a1}"
4909   [(set_attr "type" "lea")
4910    (set_attr "mode" "SI")])
4911
4912 (define_insn "*lea_2_rex64"
4913   [(set (match_operand:DI 0 "register_operand" "=r")
4914         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4915   "TARGET_64BIT"
4916   "lea{q}\t{%a1, %0|%0, %a1}"
4917   [(set_attr "type" "lea")
4918    (set_attr "mode" "DI")])
4919
4920 ;; The lea patterns for non-Pmodes needs to be matched by several
4921 ;; insns converted to real lea by splitters.
4922
4923 (define_insn_and_split "*lea_general_1"
4924   [(set (match_operand 0 "register_operand" "=r")
4925         (plus (plus (match_operand 1 "index_register_operand" "l")
4926                     (match_operand 2 "register_operand" "r"))
4927               (match_operand 3 "immediate_operand" "i")))]
4928   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4929     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4930    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4931    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4932    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4933    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4934        || GET_MODE (operands[3]) == VOIDmode)"
4935   "#"
4936   "&& reload_completed"
4937   [(const_int 0)]
4938 {
4939   rtx pat;
4940   operands[0] = gen_lowpart (SImode, operands[0]);
4941   operands[1] = gen_lowpart (Pmode, operands[1]);
4942   operands[2] = gen_lowpart (Pmode, operands[2]);
4943   operands[3] = gen_lowpart (Pmode, operands[3]);
4944   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4945                       operands[3]);
4946   if (Pmode != SImode)
4947     pat = gen_rtx_SUBREG (SImode, pat, 0);
4948   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4949   DONE;
4950 }
4951   [(set_attr "type" "lea")
4952    (set_attr "mode" "SI")])
4953
4954 (define_insn_and_split "*lea_general_1_zext"
4955   [(set (match_operand:DI 0 "register_operand" "=r")
4956         (zero_extend:DI
4957           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4958                             (match_operand:SI 2 "register_operand" "r"))
4959                    (match_operand:SI 3 "immediate_operand" "i"))))]
4960   "TARGET_64BIT"
4961   "#"
4962   "&& reload_completed"
4963   [(set (match_dup 0)
4964         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4965                                                      (match_dup 2))
4966                                             (match_dup 3)) 0)))]
4967 {
4968   operands[1] = gen_lowpart (Pmode, operands[1]);
4969   operands[2] = gen_lowpart (Pmode, operands[2]);
4970   operands[3] = gen_lowpart (Pmode, operands[3]);
4971 }
4972   [(set_attr "type" "lea")
4973    (set_attr "mode" "SI")])
4974
4975 (define_insn_and_split "*lea_general_2"
4976   [(set (match_operand 0 "register_operand" "=r")
4977         (plus (mult (match_operand 1 "index_register_operand" "l")
4978                     (match_operand 2 "const248_operand" "i"))
4979               (match_operand 3 "nonmemory_operand" "ri")))]
4980   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4981     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4982    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4983    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985        || GET_MODE (operands[3]) == VOIDmode)"
4986   "#"
4987   "&& reload_completed"
4988   [(const_int 0)]
4989 {
4990   rtx pat;
4991   operands[0] = gen_lowpart (SImode, operands[0]);
4992   operands[1] = gen_lowpart (Pmode, operands[1]);
4993   operands[3] = gen_lowpart (Pmode, operands[3]);
4994   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4995                       operands[3]);
4996   if (Pmode != SImode)
4997     pat = gen_rtx_SUBREG (SImode, pat, 0);
4998   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4999   DONE;
5000 }
5001   [(set_attr "type" "lea")
5002    (set_attr "mode" "SI")])
5003
5004 (define_insn_and_split "*lea_general_2_zext"
5005   [(set (match_operand:DI 0 "register_operand" "=r")
5006         (zero_extend:DI
5007           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5008                             (match_operand:SI 2 "const248_operand" "n"))
5009                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5010   "TARGET_64BIT"
5011   "#"
5012   "&& reload_completed"
5013   [(set (match_dup 0)
5014         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5015                                                      (match_dup 2))
5016                                             (match_dup 3)) 0)))]
5017 {
5018   operands[1] = gen_lowpart (Pmode, operands[1]);
5019   operands[3] = gen_lowpart (Pmode, operands[3]);
5020 }
5021   [(set_attr "type" "lea")
5022    (set_attr "mode" "SI")])
5023
5024 (define_insn_and_split "*lea_general_3"
5025   [(set (match_operand 0 "register_operand" "=r")
5026         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5027                           (match_operand 2 "const248_operand" "i"))
5028                     (match_operand 3 "register_operand" "r"))
5029               (match_operand 4 "immediate_operand" "i")))]
5030   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5031     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5032    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5033    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5034    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5035   "#"
5036   "&& reload_completed"
5037   [(const_int 0)]
5038 {
5039   rtx pat;
5040   operands[0] = gen_lowpart (SImode, operands[0]);
5041   operands[1] = gen_lowpart (Pmode, operands[1]);
5042   operands[3] = gen_lowpart (Pmode, operands[3]);
5043   operands[4] = gen_lowpart (Pmode, operands[4]);
5044   pat = gen_rtx_PLUS (Pmode,
5045                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5046                                                          operands[2]),
5047                                     operands[3]),
5048                       operands[4]);
5049   if (Pmode != SImode)
5050     pat = gen_rtx_SUBREG (SImode, pat, 0);
5051   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052   DONE;
5053 }
5054   [(set_attr "type" "lea")
5055    (set_attr "mode" "SI")])
5056
5057 (define_insn_and_split "*lea_general_3_zext"
5058   [(set (match_operand:DI 0 "register_operand" "=r")
5059         (zero_extend:DI
5060           (plus:SI (plus:SI (mult:SI
5061                               (match_operand:SI 1 "index_register_operand" "l")
5062                               (match_operand:SI 2 "const248_operand" "n"))
5063                             (match_operand:SI 3 "register_operand" "r"))
5064                    (match_operand:SI 4 "immediate_operand" "i"))))]
5065   "TARGET_64BIT"
5066   "#"
5067   "&& reload_completed"
5068   [(set (match_dup 0)
5069         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5070                                                               (match_dup 2))
5071                                                      (match_dup 3))
5072                                             (match_dup 4)) 0)))]
5073 {
5074   operands[1] = gen_lowpart (Pmode, operands[1]);
5075   operands[3] = gen_lowpart (Pmode, operands[3]);
5076   operands[4] = gen_lowpart (Pmode, operands[4]);
5077 }
5078   [(set_attr "type" "lea")
5079    (set_attr "mode" "SI")])
5080
5081 (define_insn "*adddi_1_rex64"
5082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5083         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5084                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5085    (clobber (reg:CC FLAGS_REG))]
5086   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5087 {
5088   switch (get_attr_type (insn))
5089     {
5090     case TYPE_LEA:
5091       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5092       return "lea{q}\t{%a2, %0|%0, %a2}";
5093
5094     case TYPE_INCDEC:
5095       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5096       if (operands[2] == const1_rtx)
5097         return "inc{q}\t%0";
5098       else
5099         {
5100           gcc_assert (operands[2] == constm1_rtx);
5101           return "dec{q}\t%0";
5102         }
5103
5104     default:
5105       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5106
5107       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5108          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5109       if (GET_CODE (operands[2]) == CONST_INT
5110           /* Avoid overflows.  */
5111           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5112           && (INTVAL (operands[2]) == 128
5113               || (INTVAL (operands[2]) < 0
5114                   && INTVAL (operands[2]) != -128)))
5115         {
5116           operands[2] = GEN_INT (-INTVAL (operands[2]));
5117           return "sub{q}\t{%2, %0|%0, %2}";
5118         }
5119       return "add{q}\t{%2, %0|%0, %2}";
5120     }
5121 }
5122   [(set (attr "type")
5123      (cond [(eq_attr "alternative" "2")
5124               (const_string "lea")
5125             ; Current assemblers are broken and do not allow @GOTOFF in
5126             ; ought but a memory context.
5127             (match_operand:DI 2 "pic_symbolic_operand" "")
5128               (const_string "lea")
5129             (match_operand:DI 2 "incdec_operand" "")
5130               (const_string "incdec")
5131            ]
5132            (const_string "alu")))
5133    (set_attr "mode" "DI")])
5134
5135 ;; Convert lea to the lea pattern to avoid flags dependency.
5136 (define_split
5137   [(set (match_operand:DI 0 "register_operand" "")
5138         (plus:DI (match_operand:DI 1 "register_operand" "")
5139                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5140    (clobber (reg:CC FLAGS_REG))]
5141   "TARGET_64BIT && reload_completed
5142    && true_regnum (operands[0]) != true_regnum (operands[1])"
5143   [(set (match_dup 0)
5144         (plus:DI (match_dup 1)
5145                  (match_dup 2)))]
5146   "")
5147
5148 (define_insn "*adddi_2_rex64"
5149   [(set (reg FLAGS_REG)
5150         (compare
5151           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5152                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153           (const_int 0)))                       
5154    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5155         (plus:DI (match_dup 1) (match_dup 2)))]
5156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5157    && ix86_binary_operator_ok (PLUS, DImode, operands)
5158    /* Current assemblers are broken and do not allow @GOTOFF in
5159       ought but a memory context.  */
5160    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5161 {
5162   switch (get_attr_type (insn))
5163     {
5164     case TYPE_INCDEC:
5165       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5166       if (operands[2] == const1_rtx)
5167         return "inc{q}\t%0";
5168       else
5169         {
5170           gcc_assert (operands[2] == constm1_rtx);
5171           return "dec{q}\t%0";
5172         }
5173
5174     default:
5175       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5176       /* ???? We ought to handle there the 32bit case too
5177          - do we need new constraint?  */
5178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5179          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5180       if (GET_CODE (operands[2]) == CONST_INT
5181           /* Avoid overflows.  */
5182           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5183           && (INTVAL (operands[2]) == 128
5184               || (INTVAL (operands[2]) < 0
5185                   && INTVAL (operands[2]) != -128)))
5186         {
5187           operands[2] = GEN_INT (-INTVAL (operands[2]));
5188           return "sub{q}\t{%2, %0|%0, %2}";
5189         }
5190       return "add{q}\t{%2, %0|%0, %2}";
5191     }
5192 }
5193   [(set (attr "type")
5194      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5195         (const_string "incdec")
5196         (const_string "alu")))
5197    (set_attr "mode" "DI")])
5198
5199 (define_insn "*adddi_3_rex64"
5200   [(set (reg FLAGS_REG)
5201         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5202                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5203    (clobber (match_scratch:DI 0 "=r"))]
5204   "TARGET_64BIT
5205    && ix86_match_ccmode (insn, CCZmode)
5206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5207    /* Current assemblers are broken and do not allow @GOTOFF in
5208       ought but a memory context.  */
5209    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5210 {
5211   switch (get_attr_type (insn))
5212     {
5213     case TYPE_INCDEC:
5214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5215       if (operands[2] == const1_rtx)
5216         return "inc{q}\t%0";
5217       else
5218         {
5219           gcc_assert (operands[2] == constm1_rtx);
5220           return "dec{q}\t%0";
5221         }
5222
5223     default:
5224       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5225       /* ???? We ought to handle there the 32bit case too
5226          - do we need new constraint?  */
5227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5229       if (GET_CODE (operands[2]) == CONST_INT
5230           /* Avoid overflows.  */
5231           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5232           && (INTVAL (operands[2]) == 128
5233               || (INTVAL (operands[2]) < 0
5234                   && INTVAL (operands[2]) != -128)))
5235         {
5236           operands[2] = GEN_INT (-INTVAL (operands[2]));
5237           return "sub{q}\t{%2, %0|%0, %2}";
5238         }
5239       return "add{q}\t{%2, %0|%0, %2}";
5240     }
5241 }
5242   [(set (attr "type")
5243      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5244         (const_string "incdec")
5245         (const_string "alu")))
5246    (set_attr "mode" "DI")])
5247
5248 ; For comparisons against 1, -1 and 128, we may generate better code
5249 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5250 ; is matched then.  We can't accept general immediate, because for
5251 ; case of overflows,  the result is messed up.
5252 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5253 ; when negated.
5254 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5255 ; only for comparisons not depending on it.
5256 (define_insn "*adddi_4_rex64"
5257   [(set (reg FLAGS_REG)
5258         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5259                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5260    (clobber (match_scratch:DI 0 "=rm"))]
5261   "TARGET_64BIT
5262    &&  ix86_match_ccmode (insn, CCGCmode)"
5263 {
5264   switch (get_attr_type (insn))
5265     {
5266     case TYPE_INCDEC:
5267       if (operands[2] == constm1_rtx)
5268         return "inc{q}\t%0";
5269       else
5270         {
5271           gcc_assert (operands[2] == const1_rtx);
5272           return "dec{q}\t%0";
5273         }
5274
5275     default:
5276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5278          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5279       if ((INTVAL (operands[2]) == -128
5280            || (INTVAL (operands[2]) > 0
5281                && INTVAL (operands[2]) != 128))
5282           /* Avoid overflows.  */
5283           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5284         return "sub{q}\t{%2, %0|%0, %2}";
5285       operands[2] = GEN_INT (-INTVAL (operands[2]));
5286       return "add{q}\t{%2, %0|%0, %2}";
5287     }
5288 }
5289   [(set (attr "type")
5290      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291         (const_string "incdec")
5292         (const_string "alu")))
5293    (set_attr "mode" "DI")])
5294
5295 (define_insn "*adddi_5_rex64"
5296   [(set (reg FLAGS_REG)
5297         (compare
5298           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5299                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5300           (const_int 0)))                       
5301    (clobber (match_scratch:DI 0 "=r"))]
5302   "TARGET_64BIT
5303    && ix86_match_ccmode (insn, CCGOCmode)
5304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5305    /* Current assemblers are broken and do not allow @GOTOFF in
5306       ought but a memory context.  */
5307    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5308 {
5309   switch (get_attr_type (insn))
5310     {
5311     case TYPE_INCDEC:
5312       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313       if (operands[2] == const1_rtx)
5314         return "inc{q}\t%0";
5315       else
5316         {
5317           gcc_assert (operands[2] == constm1_rtx);
5318           return "dec{q}\t%0";
5319         }
5320
5321     default:
5322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5325       if (GET_CODE (operands[2]) == CONST_INT
5326           /* Avoid overflows.  */
5327           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5328           && (INTVAL (operands[2]) == 128
5329               || (INTVAL (operands[2]) < 0
5330                   && INTVAL (operands[2]) != -128)))
5331         {
5332           operands[2] = GEN_INT (-INTVAL (operands[2]));
5333           return "sub{q}\t{%2, %0|%0, %2}";
5334         }
5335       return "add{q}\t{%2, %0|%0, %2}";
5336     }
5337 }
5338   [(set (attr "type")
5339      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5340         (const_string "incdec")
5341         (const_string "alu")))
5342    (set_attr "mode" "DI")])
5343
5344
5345 (define_insn "*addsi_1"
5346   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5347         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5348                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5349    (clobber (reg:CC FLAGS_REG))]
5350   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5351 {
5352   switch (get_attr_type (insn))
5353     {
5354     case TYPE_LEA:
5355       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5356       return "lea{l}\t{%a2, %0|%0, %a2}";
5357
5358     case TYPE_INCDEC:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360       if (operands[2] == const1_rtx)
5361         return "inc{l}\t%0";
5362       else
5363         {
5364           gcc_assert (operands[2] == constm1_rtx);
5365           return "dec{l}\t%0";
5366         }
5367
5368     default:
5369       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370
5371       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5372          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5373       if (GET_CODE (operands[2]) == CONST_INT
5374           && (INTVAL (operands[2]) == 128
5375               || (INTVAL (operands[2]) < 0
5376                   && INTVAL (operands[2]) != -128)))
5377         {
5378           operands[2] = GEN_INT (-INTVAL (operands[2]));
5379           return "sub{l}\t{%2, %0|%0, %2}";
5380         }
5381       return "add{l}\t{%2, %0|%0, %2}";
5382     }
5383 }
5384   [(set (attr "type")
5385      (cond [(eq_attr "alternative" "2")
5386               (const_string "lea")
5387             ; Current assemblers are broken and do not allow @GOTOFF in
5388             ; ought but a memory context.
5389             (match_operand:SI 2 "pic_symbolic_operand" "")
5390               (const_string "lea")
5391             (match_operand:SI 2 "incdec_operand" "")
5392               (const_string "incdec")
5393            ]
5394            (const_string "alu")))
5395    (set_attr "mode" "SI")])
5396
5397 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 (define_split
5399   [(set (match_operand 0 "register_operand" "")
5400         (plus (match_operand 1 "register_operand" "")
5401               (match_operand 2 "nonmemory_operand" "")))
5402    (clobber (reg:CC FLAGS_REG))]
5403   "reload_completed
5404    && true_regnum (operands[0]) != true_regnum (operands[1])"
5405   [(const_int 0)]
5406 {
5407   rtx pat;
5408   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5409      may confuse gen_lowpart.  */
5410   if (GET_MODE (operands[0]) != Pmode)
5411     {
5412       operands[1] = gen_lowpart (Pmode, operands[1]);
5413       operands[2] = gen_lowpart (Pmode, operands[2]);
5414     }
5415   operands[0] = gen_lowpart (SImode, operands[0]);
5416   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5417   if (Pmode != SImode)
5418     pat = gen_rtx_SUBREG (SImode, pat, 0);
5419   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420   DONE;
5421 })
5422
5423 ;; It may seem that nonimmediate operand is proper one for operand 1.
5424 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5425 ;; we take care in ix86_binary_operator_ok to not allow two memory
5426 ;; operands so proper swapping will be done in reload.  This allow
5427 ;; patterns constructed from addsi_1 to match.
5428 (define_insn "addsi_1_zext"
5429   [(set (match_operand:DI 0 "register_operand" "=r,r")
5430         (zero_extend:DI
5431           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5432                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5433    (clobber (reg:CC FLAGS_REG))]
5434   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435 {
5436   switch (get_attr_type (insn))
5437     {
5438     case TYPE_LEA:
5439       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5441
5442     case TYPE_INCDEC:
5443       if (operands[2] == const1_rtx)
5444         return "inc{l}\t%k0";
5445       else
5446         {
5447           gcc_assert (operands[2] == constm1_rtx);
5448           return "dec{l}\t%k0";
5449         }
5450
5451     default:
5452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454       if (GET_CODE (operands[2]) == CONST_INT
5455           && (INTVAL (operands[2]) == 128
5456               || (INTVAL (operands[2]) < 0
5457                   && INTVAL (operands[2]) != -128)))
5458         {
5459           operands[2] = GEN_INT (-INTVAL (operands[2]));
5460           return "sub{l}\t{%2, %k0|%k0, %2}";
5461         }
5462       return "add{l}\t{%2, %k0|%k0, %2}";
5463     }
5464 }
5465   [(set (attr "type")
5466      (cond [(eq_attr "alternative" "1")
5467               (const_string "lea")
5468             ; Current assemblers are broken and do not allow @GOTOFF in
5469             ; ought but a memory context.
5470             (match_operand:SI 2 "pic_symbolic_operand" "")
5471               (const_string "lea")
5472             (match_operand:SI 2 "incdec_operand" "")
5473               (const_string "incdec")
5474            ]
5475            (const_string "alu")))
5476    (set_attr "mode" "SI")])
5477
5478 ;; Convert lea to the lea pattern to avoid flags dependency.
5479 (define_split
5480   [(set (match_operand:DI 0 "register_operand" "")
5481         (zero_extend:DI
5482           (plus:SI (match_operand:SI 1 "register_operand" "")
5483                    (match_operand:SI 2 "nonmemory_operand" ""))))
5484    (clobber (reg:CC FLAGS_REG))]
5485   "TARGET_64BIT && reload_completed
5486    && true_regnum (operands[0]) != true_regnum (operands[1])"
5487   [(set (match_dup 0)
5488         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5489 {
5490   operands[1] = gen_lowpart (Pmode, operands[1]);
5491   operands[2] = gen_lowpart (Pmode, operands[2]);
5492 })
5493
5494 (define_insn "*addsi_2"
5495   [(set (reg FLAGS_REG)
5496         (compare
5497           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5498                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5499           (const_int 0)))                       
5500    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5501         (plus:SI (match_dup 1) (match_dup 2)))]
5502   "ix86_match_ccmode (insn, CCGOCmode)
5503    && ix86_binary_operator_ok (PLUS, SImode, operands)
5504    /* Current assemblers are broken and do not allow @GOTOFF in
5505       ought but a memory context.  */
5506    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5507 {
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_INCDEC:
5511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512       if (operands[2] == const1_rtx)
5513         return "inc{l}\t%0";
5514       else
5515         {
5516           gcc_assert (operands[2] == constm1_rtx);
5517           return "dec{l}\t%0";
5518         }
5519
5520     default:
5521       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5522       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5524       if (GET_CODE (operands[2]) == CONST_INT
5525           && (INTVAL (operands[2]) == 128
5526               || (INTVAL (operands[2]) < 0
5527                   && INTVAL (operands[2]) != -128)))
5528         {
5529           operands[2] = GEN_INT (-INTVAL (operands[2]));
5530           return "sub{l}\t{%2, %0|%0, %2}";
5531         }
5532       return "add{l}\t{%2, %0|%0, %2}";
5533     }
5534 }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "SI")])
5540
5541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5542 (define_insn "*addsi_2_zext"
5543   [(set (reg FLAGS_REG)
5544         (compare
5545           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5546                    (match_operand:SI 2 "general_operand" "rmni"))
5547           (const_int 0)))                       
5548    (set (match_operand:DI 0 "register_operand" "=r")
5549         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5551    && ix86_binary_operator_ok (PLUS, SImode, operands)
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       if (operands[2] == const1_rtx)
5560         return "inc{l}\t%k0";
5561       else
5562         {
5563           gcc_assert (operands[2] == constm1_rtx);
5564           return "dec{l}\t%k0";
5565         }
5566
5567     default:
5568       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5569          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5570       if (GET_CODE (operands[2]) == CONST_INT
5571           && (INTVAL (operands[2]) == 128
5572               || (INTVAL (operands[2]) < 0
5573                   && INTVAL (operands[2]) != -128)))
5574         {
5575           operands[2] = GEN_INT (-INTVAL (operands[2]));
5576           return "sub{l}\t{%2, %k0|%k0, %2}";
5577         }
5578       return "add{l}\t{%2, %k0|%k0, %2}";
5579     }
5580 }
5581   [(set (attr "type")
5582      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5583         (const_string "incdec")
5584         (const_string "alu")))
5585    (set_attr "mode" "SI")])
5586
5587 (define_insn "*addsi_3"
5588   [(set (reg FLAGS_REG)
5589         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5590                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5591    (clobber (match_scratch:SI 0 "=r"))]
5592   "ix86_match_ccmode (insn, CCZmode)
5593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5594    /* Current assemblers are broken and do not allow @GOTOFF in
5595       ought but a memory context.  */
5596    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597 {
5598   switch (get_attr_type (insn))
5599     {
5600     case TYPE_INCDEC:
5601       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%0";
5604       else
5605         {
5606           gcc_assert (operands[2] == constm1_rtx);
5607           return "dec{l}\t%0";
5608         }
5609
5610     default:
5611       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5612       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5614       if (GET_CODE (operands[2]) == CONST_INT
5615           && (INTVAL (operands[2]) == 128
5616               || (INTVAL (operands[2]) < 0
5617                   && INTVAL (operands[2]) != -128)))
5618         {
5619           operands[2] = GEN_INT (-INTVAL (operands[2]));
5620           return "sub{l}\t{%2, %0|%0, %2}";
5621         }
5622       return "add{l}\t{%2, %0|%0, %2}";
5623     }
5624 }
5625   [(set (attr "type")
5626      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627         (const_string "incdec")
5628         (const_string "alu")))
5629    (set_attr "mode" "SI")])
5630
5631 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5632 (define_insn "*addsi_3_zext"
5633   [(set (reg FLAGS_REG)
5634         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5635                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5636    (set (match_operand:DI 0 "register_operand" "=r")
5637         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5639    && ix86_binary_operator_ok (PLUS, SImode, operands)
5640    /* Current assemblers are broken and do not allow @GOTOFF in
5641       ought but a memory context.  */
5642    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643 {
5644   switch (get_attr_type (insn))
5645     {
5646     case TYPE_INCDEC:
5647       if (operands[2] == const1_rtx)
5648         return "inc{l}\t%k0";
5649       else
5650         {
5651           gcc_assert (operands[2] == constm1_rtx);
5652           return "dec{l}\t%k0";
5653         }
5654
5655     default:
5656       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5658       if (GET_CODE (operands[2]) == CONST_INT
5659           && (INTVAL (operands[2]) == 128
5660               || (INTVAL (operands[2]) < 0
5661                   && INTVAL (operands[2]) != -128)))
5662         {
5663           operands[2] = GEN_INT (-INTVAL (operands[2]));
5664           return "sub{l}\t{%2, %k0|%k0, %2}";
5665         }
5666       return "add{l}\t{%2, %k0|%k0, %2}";
5667     }
5668 }
5669   [(set (attr "type")
5670      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671         (const_string "incdec")
5672         (const_string "alu")))
5673    (set_attr "mode" "SI")])
5674
5675 ; For comparisons against 1, -1 and 128, we may generate better code
5676 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5677 ; is matched then.  We can't accept general immediate, because for
5678 ; case of overflows,  the result is messed up.
5679 ; This pattern also don't hold of 0x80000000, since the value overflows
5680 ; when negated.
5681 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5682 ; only for comparisons not depending on it.
5683 (define_insn "*addsi_4"
5684   [(set (reg FLAGS_REG)
5685         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5686                  (match_operand:SI 2 "const_int_operand" "n")))
5687    (clobber (match_scratch:SI 0 "=rm"))]
5688   "ix86_match_ccmode (insn, CCGCmode)
5689    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5690 {
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (operands[2] == constm1_rtx)
5695         return "inc{l}\t%0";
5696       else
5697         {
5698           gcc_assert (operands[2] == const1_rtx);
5699           return "dec{l}\t%0";
5700         }
5701
5702     default:
5703       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5704       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5705          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5706       if ((INTVAL (operands[2]) == -128
5707            || (INTVAL (operands[2]) > 0
5708                && INTVAL (operands[2]) != 128)))
5709         return "sub{l}\t{%2, %0|%0, %2}";
5710       operands[2] = GEN_INT (-INTVAL (operands[2]));
5711       return "add{l}\t{%2, %0|%0, %2}";
5712     }
5713 }
5714   [(set (attr "type")
5715      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5716         (const_string "incdec")
5717         (const_string "alu")))
5718    (set_attr "mode" "SI")])
5719
5720 (define_insn "*addsi_5"
5721   [(set (reg FLAGS_REG)
5722         (compare
5723           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5724                    (match_operand:SI 2 "general_operand" "rmni"))
5725           (const_int 0)))                       
5726    (clobber (match_scratch:SI 0 "=r"))]
5727   "ix86_match_ccmode (insn, CCGOCmode)
5728    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5729    /* Current assemblers are broken and do not allow @GOTOFF in
5730       ought but a memory context.  */
5731    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732 {
5733   switch (get_attr_type (insn))
5734     {
5735     case TYPE_INCDEC:
5736       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5737       if (operands[2] == const1_rtx)
5738         return "inc{l}\t%0";
5739       else
5740         {
5741           gcc_assert (operands[2] == constm1_rtx);
5742           return "dec{l}\t%0";
5743         }
5744
5745     default:
5746       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5747       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5748          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5749       if (GET_CODE (operands[2]) == CONST_INT
5750           && (INTVAL (operands[2]) == 128
5751               || (INTVAL (operands[2]) < 0
5752                   && INTVAL (operands[2]) != -128)))
5753         {
5754           operands[2] = GEN_INT (-INTVAL (operands[2]));
5755           return "sub{l}\t{%2, %0|%0, %2}";
5756         }
5757       return "add{l}\t{%2, %0|%0, %2}";
5758     }
5759 }
5760   [(set (attr "type")
5761      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762         (const_string "incdec")
5763         (const_string "alu")))
5764    (set_attr "mode" "SI")])
5765
5766 (define_expand "addhi3"
5767   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5768                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5769                             (match_operand:HI 2 "general_operand" "")))
5770               (clobber (reg:CC FLAGS_REG))])]
5771   "TARGET_HIMODE_MATH"
5772   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773
5774 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5775 ;; type optimizations enabled by define-splits.  This is not important
5776 ;; for PII, and in fact harmful because of partial register stalls.
5777
5778 (define_insn "*addhi_1_lea"
5779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5780         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5781                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "!TARGET_PARTIAL_REG_STALL
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_LEA:
5789       return "#";
5790     case TYPE_INCDEC:
5791       if (operands[2] == const1_rtx)
5792         return "inc{w}\t%0";
5793       else
5794         {
5795           gcc_assert (operands[2] == constm1_rtx);
5796           return "dec{w}\t%0";
5797         }
5798
5799     default:
5800       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5802       if (GET_CODE (operands[2]) == CONST_INT
5803           && (INTVAL (operands[2]) == 128
5804               || (INTVAL (operands[2]) < 0
5805                   && INTVAL (operands[2]) != -128)))
5806         {
5807           operands[2] = GEN_INT (-INTVAL (operands[2]));
5808           return "sub{w}\t{%2, %0|%0, %2}";
5809         }
5810       return "add{w}\t{%2, %0|%0, %2}";
5811     }
5812 }
5813   [(set (attr "type")
5814      (if_then_else (eq_attr "alternative" "2")
5815         (const_string "lea")
5816         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5817            (const_string "incdec")
5818            (const_string "alu"))))
5819    (set_attr "mode" "HI,HI,SI")])
5820
5821 (define_insn "*addhi_1"
5822   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5823         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5824                  (match_operand:HI 2 "general_operand" "ri,rm")))
5825    (clobber (reg:CC FLAGS_REG))]
5826   "TARGET_PARTIAL_REG_STALL
5827    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5828 {
5829   switch (get_attr_type (insn))
5830     {
5831     case TYPE_INCDEC:
5832       if (operands[2] == const1_rtx)
5833         return "inc{w}\t%0";
5834       else
5835         {
5836           gcc_assert (operands[2] == constm1_rtx);
5837           return "dec{w}\t%0";
5838         }
5839
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{w}\t{%2, %0|%0, %2}";
5850         }
5851       return "add{w}\t{%2, %0|%0, %2}";
5852     }
5853 }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "HI")])
5859
5860 (define_insn "*addhi_2"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5864                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5865           (const_int 0)))                       
5866    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5867         (plus:HI (match_dup 1) (match_dup 2)))]
5868   "ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870 {
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{w}\t%0";
5876       else
5877         {
5878           gcc_assert (operands[2] == constm1_rtx);
5879           return "dec{w}\t%0";
5880         }
5881
5882     default:
5883       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5884          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5885       if (GET_CODE (operands[2]) == CONST_INT
5886           && (INTVAL (operands[2]) == 128
5887               || (INTVAL (operands[2]) < 0
5888                   && INTVAL (operands[2]) != -128)))
5889         {
5890           operands[2] = GEN_INT (-INTVAL (operands[2]));
5891           return "sub{w}\t{%2, %0|%0, %2}";
5892         }
5893       return "add{w}\t{%2, %0|%0, %2}";
5894     }
5895 }
5896   [(set (attr "type")
5897      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5898         (const_string "incdec")
5899         (const_string "alu")))
5900    (set_attr "mode" "HI")])
5901
5902 (define_insn "*addhi_3"
5903   [(set (reg FLAGS_REG)
5904         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5905                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5906    (clobber (match_scratch:HI 0 "=r"))]
5907   "ix86_match_ccmode (insn, CCZmode)
5908    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5909 {
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return "dec{w}\t%0";
5919         }
5920
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{w}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{w}\t{%2, %0|%0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "HI")])
5940
5941 ; See comments above addsi_4 for details.
5942 (define_insn "*addhi_4"
5943   [(set (reg FLAGS_REG)
5944         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5945                  (match_operand:HI 2 "const_int_operand" "n")))
5946    (clobber (match_scratch:HI 0 "=rm"))]
5947   "ix86_match_ccmode (insn, CCGCmode)
5948    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5949 {
5950   switch (get_attr_type (insn))
5951     {
5952     case TYPE_INCDEC:
5953       if (operands[2] == constm1_rtx)
5954         return "inc{w}\t%0";
5955       else
5956         {
5957           gcc_assert (operands[2] == const1_rtx);
5958           return "dec{w}\t%0";
5959         }
5960
5961     default:
5962       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5963       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5965       if ((INTVAL (operands[2]) == -128
5966            || (INTVAL (operands[2]) > 0
5967                && INTVAL (operands[2]) != 128)))
5968         return "sub{w}\t{%2, %0|%0, %2}";
5969       operands[2] = GEN_INT (-INTVAL (operands[2]));
5970       return "add{w}\t{%2, %0|%0, %2}";
5971     }
5972 }
5973   [(set (attr "type")
5974      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975         (const_string "incdec")
5976         (const_string "alu")))
5977    (set_attr "mode" "SI")])
5978
5979
5980 (define_insn "*addhi_5"
5981   [(set (reg FLAGS_REG)
5982         (compare
5983           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5984                    (match_operand:HI 2 "general_operand" "rmni"))
5985           (const_int 0)))                       
5986    (clobber (match_scratch:HI 0 "=r"))]
5987   "ix86_match_ccmode (insn, CCGOCmode)
5988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5989 {
5990   switch (get_attr_type (insn))
5991     {
5992     case TYPE_INCDEC:
5993       if (operands[2] == const1_rtx)
5994         return "inc{w}\t%0";
5995       else
5996         {
5997           gcc_assert (operands[2] == constm1_rtx);
5998           return "dec{w}\t%0";
5999         }
6000
6001     default:
6002       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004       if (GET_CODE (operands[2]) == CONST_INT
6005           && (INTVAL (operands[2]) == 128
6006               || (INTVAL (operands[2]) < 0
6007                   && INTVAL (operands[2]) != -128)))
6008         {
6009           operands[2] = GEN_INT (-INTVAL (operands[2]));
6010           return "sub{w}\t{%2, %0|%0, %2}";
6011         }
6012       return "add{w}\t{%2, %0|%0, %2}";
6013     }
6014 }
6015   [(set (attr "type")
6016      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6017         (const_string "incdec")
6018         (const_string "alu")))
6019    (set_attr "mode" "HI")])
6020
6021 (define_expand "addqi3"
6022   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6023                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6024                             (match_operand:QI 2 "general_operand" "")))
6025               (clobber (reg:CC FLAGS_REG))])]
6026   "TARGET_QIMODE_MATH"
6027   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6028
6029 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6030 (define_insn "*addqi_1_lea"
6031   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6032         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6033                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6034    (clobber (reg:CC FLAGS_REG))]
6035   "!TARGET_PARTIAL_REG_STALL
6036    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6037 {
6038   int widen = (which_alternative == 2);
6039   switch (get_attr_type (insn))
6040     {
6041     case TYPE_LEA:
6042       return "#";
6043     case TYPE_INCDEC:
6044       if (operands[2] == const1_rtx)
6045         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6046       else
6047         {
6048           gcc_assert (operands[2] == constm1_rtx);
6049           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6050         }
6051
6052     default:
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (GET_CODE (operands[2]) == CONST_INT
6056           && (INTVAL (operands[2]) == 128
6057               || (INTVAL (operands[2]) < 0
6058                   && INTVAL (operands[2]) != -128)))
6059         {
6060           operands[2] = GEN_INT (-INTVAL (operands[2]));
6061           if (widen)
6062             return "sub{l}\t{%2, %k0|%k0, %2}";
6063           else
6064             return "sub{b}\t{%2, %0|%0, %2}";
6065         }
6066       if (widen)
6067         return "add{l}\t{%k2, %k0|%k0, %k2}";
6068       else
6069         return "add{b}\t{%2, %0|%0, %2}";
6070     }
6071 }
6072   [(set (attr "type")
6073      (if_then_else (eq_attr "alternative" "3")
6074         (const_string "lea")
6075         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6076            (const_string "incdec")
6077            (const_string "alu"))))
6078    (set_attr "mode" "QI,QI,SI,SI")])
6079
6080 (define_insn "*addqi_1"
6081   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6082         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6083                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "TARGET_PARTIAL_REG_STALL
6086    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6087 {
6088   int widen = (which_alternative == 2);
6089   switch (get_attr_type (insn))
6090     {
6091     case TYPE_INCDEC:
6092       if (operands[2] == const1_rtx)
6093         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6094       else
6095         {
6096           gcc_assert (operands[2] == constm1_rtx);
6097           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6098         }
6099
6100     default:
6101       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6102          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6103       if (GET_CODE (operands[2]) == CONST_INT
6104           && (INTVAL (operands[2]) == 128
6105               || (INTVAL (operands[2]) < 0
6106                   && INTVAL (operands[2]) != -128)))
6107         {
6108           operands[2] = GEN_INT (-INTVAL (operands[2]));
6109           if (widen)
6110             return "sub{l}\t{%2, %k0|%k0, %2}";
6111           else
6112             return "sub{b}\t{%2, %0|%0, %2}";
6113         }
6114       if (widen)
6115         return "add{l}\t{%k2, %k0|%k0, %k2}";
6116       else
6117         return "add{b}\t{%2, %0|%0, %2}";
6118     }
6119 }
6120   [(set (attr "type")
6121      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6122         (const_string "incdec")
6123         (const_string "alu")))
6124    (set_attr "mode" "QI,QI,SI")])
6125
6126 (define_insn "*addqi_1_slp"
6127   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6128         (plus:QI (match_dup 0)
6129                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6130    (clobber (reg:CC FLAGS_REG))]
6131   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6132    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6133 {
6134   switch (get_attr_type (insn))
6135     {
6136     case TYPE_INCDEC:
6137       if (operands[1] == const1_rtx)
6138         return "inc{b}\t%0";
6139       else
6140         {
6141           gcc_assert (operands[1] == constm1_rtx);
6142           return "dec{b}\t%0";
6143         }
6144
6145     default:
6146       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6147       if (GET_CODE (operands[1]) == CONST_INT
6148           && INTVAL (operands[1]) < 0)
6149         {
6150           operands[1] = GEN_INT (-INTVAL (operands[1]));
6151           return "sub{b}\t{%1, %0|%0, %1}";
6152         }
6153       return "add{b}\t{%1, %0|%0, %1}";
6154     }
6155 }
6156   [(set (attr "type")
6157      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6158         (const_string "incdec")
6159         (const_string "alu1")))
6160    (set (attr "memory")
6161      (if_then_else (match_operand 1 "memory_operand" "")
6162         (const_string "load")
6163         (const_string "none")))
6164    (set_attr "mode" "QI")])
6165
6166 (define_insn "*addqi_2"
6167   [(set (reg FLAGS_REG)
6168         (compare
6169           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6170                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6171           (const_int 0)))
6172    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6173         (plus:QI (match_dup 1) (match_dup 2)))]
6174   "ix86_match_ccmode (insn, CCGOCmode)
6175    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176 {
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{b}\t%0";
6182       else
6183         {
6184           gcc_assert (operands[2] == constm1_rtx
6185                       || (GET_CODE (operands[2]) == CONST_INT
6186                           && INTVAL (operands[2]) == 255));
6187           return "dec{b}\t%0";
6188         }
6189
6190     default:
6191       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6192       if (GET_CODE (operands[2]) == CONST_INT
6193           && INTVAL (operands[2]) < 0)
6194         {
6195           operands[2] = GEN_INT (-INTVAL (operands[2]));
6196           return "sub{b}\t{%2, %0|%0, %2}";
6197         }
6198       return "add{b}\t{%2, %0|%0, %2}";
6199     }
6200 }
6201   [(set (attr "type")
6202      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6203         (const_string "incdec")
6204         (const_string "alu")))
6205    (set_attr "mode" "QI")])
6206
6207 (define_insn "*addqi_3"
6208   [(set (reg FLAGS_REG)
6209         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6210                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6211    (clobber (match_scratch:QI 0 "=q"))]
6212   "ix86_match_ccmode (insn, CCZmode)
6213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6214 {
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_INCDEC:
6218       if (operands[2] == const1_rtx)
6219         return "inc{b}\t%0";
6220       else
6221         {
6222           gcc_assert (operands[2] == constm1_rtx
6223                       || (GET_CODE (operands[2]) == CONST_INT
6224                           && INTVAL (operands[2]) == 255));
6225           return "dec{b}\t%0";
6226         }
6227
6228     default:
6229       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6230       if (GET_CODE (operands[2]) == CONST_INT
6231           && INTVAL (operands[2]) < 0)
6232         {
6233           operands[2] = GEN_INT (-INTVAL (operands[2]));
6234           return "sub{b}\t{%2, %0|%0, %2}";
6235         }
6236       return "add{b}\t{%2, %0|%0, %2}";
6237     }
6238 }
6239   [(set (attr "type")
6240      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241         (const_string "incdec")
6242         (const_string "alu")))
6243    (set_attr "mode" "QI")])
6244
6245 ; See comments above addsi_4 for details.
6246 (define_insn "*addqi_4"
6247   [(set (reg FLAGS_REG)
6248         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6249                  (match_operand:QI 2 "const_int_operand" "n")))
6250    (clobber (match_scratch:QI 0 "=qm"))]
6251   "ix86_match_ccmode (insn, CCGCmode)
6252    && (INTVAL (operands[2]) & 0xff) != 0x80"
6253 {
6254   switch (get_attr_type (insn))
6255     {
6256     case TYPE_INCDEC:
6257       if (operands[2] == constm1_rtx
6258           || (GET_CODE (operands[2]) == CONST_INT
6259               && INTVAL (operands[2]) == 255))
6260         return "inc{b}\t%0";
6261       else
6262         {
6263           gcc_assert (operands[2] == const1_rtx);
6264           return "dec{b}\t%0";
6265         }
6266
6267     default:
6268       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6269       if (INTVAL (operands[2]) < 0)
6270         {
6271           operands[2] = GEN_INT (-INTVAL (operands[2]));
6272           return "add{b}\t{%2, %0|%0, %2}";
6273         }
6274       return "sub{b}\t{%2, %0|%0, %2}";
6275     }
6276 }
6277   [(set (attr "type")
6278      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6279         (const_string "incdec")
6280         (const_string "alu")))
6281    (set_attr "mode" "QI")])
6282
6283
6284 (define_insn "*addqi_5"
6285   [(set (reg FLAGS_REG)
6286         (compare
6287           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6288                    (match_operand:QI 2 "general_operand" "qmni"))
6289           (const_int 0)))
6290    (clobber (match_scratch:QI 0 "=q"))]
6291   "ix86_match_ccmode (insn, CCGOCmode)
6292    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6293 {
6294   switch (get_attr_type (insn))
6295     {
6296     case TYPE_INCDEC:
6297       if (operands[2] == const1_rtx)
6298         return "inc{b}\t%0";
6299       else
6300         {
6301           gcc_assert (operands[2] == constm1_rtx
6302                       || (GET_CODE (operands[2]) == CONST_INT
6303                           && INTVAL (operands[2]) == 255));
6304           return "dec{b}\t%0";
6305         }
6306
6307     default:
6308       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6309       if (GET_CODE (operands[2]) == CONST_INT
6310           && INTVAL (operands[2]) < 0)
6311         {
6312           operands[2] = GEN_INT (-INTVAL (operands[2]));
6313           return "sub{b}\t{%2, %0|%0, %2}";
6314         }
6315       return "add{b}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "QI")])
6323
6324
6325 (define_insn "addqi_ext_1"
6326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6327                          (const_int 8)
6328                          (const_int 8))
6329         (plus:SI
6330           (zero_extract:SI
6331             (match_operand 1 "ext_register_operand" "0")
6332             (const_int 8)
6333             (const_int 8))
6334           (match_operand:QI 2 "general_operand" "Qmn")))
6335    (clobber (reg:CC FLAGS_REG))]
6336   "!TARGET_64BIT"
6337 {
6338   switch (get_attr_type (insn))
6339     {
6340     case TYPE_INCDEC:
6341       if (operands[2] == const1_rtx)
6342         return "inc{b}\t%h0";
6343       else
6344         {
6345           gcc_assert (operands[2] == constm1_rtx
6346                       || (GET_CODE (operands[2]) == CONST_INT
6347                           && INTVAL (operands[2]) == 255));
6348           return "dec{b}\t%h0";
6349         }
6350
6351     default:
6352       return "add{b}\t{%2, %h0|%h0, %2}";
6353     }
6354 }
6355   [(set (attr "type")
6356      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357         (const_string "incdec")
6358         (const_string "alu")))
6359    (set_attr "mode" "QI")])
6360
6361 (define_insn "*addqi_ext_1_rex64"
6362   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363                          (const_int 8)
6364                          (const_int 8))
6365         (plus:SI
6366           (zero_extract:SI
6367             (match_operand 1 "ext_register_operand" "0")
6368             (const_int 8)
6369             (const_int 8))
6370           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6371    (clobber (reg:CC FLAGS_REG))]
6372   "TARGET_64BIT"
6373 {
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[2] == const1_rtx)
6378         return "inc{b}\t%h0";
6379       else
6380         {
6381           gcc_assert (operands[2] == constm1_rtx
6382                       || (GET_CODE (operands[2]) == CONST_INT
6383                           && INTVAL (operands[2]) == 255));
6384           return "dec{b}\t%h0";
6385         }
6386
6387     default:
6388       return "add{b}\t{%2, %h0|%h0, %2}";
6389     }
6390 }
6391   [(set (attr "type")
6392      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6393         (const_string "incdec")
6394         (const_string "alu")))
6395    (set_attr "mode" "QI")])
6396
6397 (define_insn "*addqi_ext_2"
6398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399                          (const_int 8)
6400                          (const_int 8))
6401         (plus:SI
6402           (zero_extract:SI
6403             (match_operand 1 "ext_register_operand" "%0")
6404             (const_int 8)
6405             (const_int 8))
6406           (zero_extract:SI
6407             (match_operand 2 "ext_register_operand" "Q")
6408             (const_int 8)
6409             (const_int 8))))
6410    (clobber (reg:CC FLAGS_REG))]
6411   ""
6412   "add{b}\t{%h2, %h0|%h0, %h2}"
6413   [(set_attr "type" "alu")
6414    (set_attr "mode" "QI")])
6415
6416 ;; The patterns that match these are at the end of this file.
6417
6418 (define_expand "addxf3"
6419   [(set (match_operand:XF 0 "register_operand" "")
6420         (plus:XF (match_operand:XF 1 "register_operand" "")
6421                  (match_operand:XF 2 "register_operand" "")))]
6422   "TARGET_80387"
6423   "")
6424
6425 (define_expand "adddf3"
6426   [(set (match_operand:DF 0 "register_operand" "")
6427         (plus:DF (match_operand:DF 1 "register_operand" "")
6428                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6429   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6430   "")
6431
6432 (define_expand "addsf3"
6433   [(set (match_operand:SF 0 "register_operand" "")
6434         (plus:SF (match_operand:SF 1 "register_operand" "")
6435                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6436   "TARGET_80387 || TARGET_SSE_MATH"
6437   "")
6438 \f
6439 ;; Subtract instructions
6440
6441 ;; %%% splits for subditi3
6442
6443 (define_expand "subti3"
6444   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6445                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6446                              (match_operand:TI 2 "x86_64_general_operand" "")))
6447               (clobber (reg:CC FLAGS_REG))])]
6448   "TARGET_64BIT"
6449   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6450
6451 (define_insn "*subti3_1"
6452   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6453         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6454                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6455    (clobber (reg:CC FLAGS_REG))]
6456   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6457   "#")
6458
6459 (define_split
6460   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6461         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6462                   (match_operand:TI 2 "general_operand" "")))
6463    (clobber (reg:CC FLAGS_REG))]
6464   "TARGET_64BIT && reload_completed"
6465   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6466               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6467    (parallel [(set (match_dup 3)
6468                    (minus:DI (match_dup 4)
6469                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6470                                       (match_dup 5))))
6471               (clobber (reg:CC FLAGS_REG))])]
6472   "split_ti (operands+0, 1, operands+0, operands+3);
6473    split_ti (operands+1, 1, operands+1, operands+4);
6474    split_ti (operands+2, 1, operands+2, operands+5);")
6475
6476 ;; %%% splits for subsidi3
6477
6478 (define_expand "subdi3"
6479   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6480                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6481                              (match_operand:DI 2 "x86_64_general_operand" "")))
6482               (clobber (reg:CC FLAGS_REG))])]
6483   ""
6484   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6485
6486 (define_insn "*subdi3_1"
6487   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6488         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6489                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6490    (clobber (reg:CC FLAGS_REG))]
6491   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6492   "#")
6493
6494 (define_split
6495   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6496         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6497                   (match_operand:DI 2 "general_operand" "")))
6498    (clobber (reg:CC FLAGS_REG))]
6499   "!TARGET_64BIT && reload_completed"
6500   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6501               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6502    (parallel [(set (match_dup 3)
6503                    (minus:SI (match_dup 4)
6504                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6505                                       (match_dup 5))))
6506               (clobber (reg:CC FLAGS_REG))])]
6507   "split_di (operands+0, 1, operands+0, operands+3);
6508    split_di (operands+1, 1, operands+1, operands+4);
6509    split_di (operands+2, 1, operands+2, operands+5);")
6510
6511 (define_insn "subdi3_carry_rex64"
6512   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6513           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6514             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6515                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6516    (clobber (reg:CC FLAGS_REG))]
6517   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6518   "sbb{q}\t{%2, %0|%0, %2}"
6519   [(set_attr "type" "alu")
6520    (set_attr "pent_pair" "pu")
6521    (set_attr "mode" "DI")])
6522
6523 (define_insn "*subdi_1_rex64"
6524   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6525         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6526                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6529   "sub{q}\t{%2, %0|%0, %2}"
6530   [(set_attr "type" "alu")
6531    (set_attr "mode" "DI")])
6532
6533 (define_insn "*subdi_2_rex64"
6534   [(set (reg FLAGS_REG)
6535         (compare
6536           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6537                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6538           (const_int 0)))
6539    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6540         (minus:DI (match_dup 1) (match_dup 2)))]
6541   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6542    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6543   "sub{q}\t{%2, %0|%0, %2}"
6544   [(set_attr "type" "alu")
6545    (set_attr "mode" "DI")])
6546
6547 (define_insn "*subdi_3_rex63"
6548   [(set (reg FLAGS_REG)
6549         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6550                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6551    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6552         (minus:DI (match_dup 1) (match_dup 2)))]
6553   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555   "sub{q}\t{%2, %0|%0, %2}"
6556   [(set_attr "type" "alu")
6557    (set_attr "mode" "DI")])
6558
6559 (define_insn "subqi3_carry"
6560   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6561           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6562             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6563                (match_operand:QI 2 "general_operand" "qi,qm"))))
6564    (clobber (reg:CC FLAGS_REG))]
6565   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6566   "sbb{b}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "pent_pair" "pu")
6569    (set_attr "mode" "QI")])
6570
6571 (define_insn "subhi3_carry"
6572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6573           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6574             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6575                (match_operand:HI 2 "general_operand" "ri,rm"))))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6578   "sbb{w}\t{%2, %0|%0, %2}"
6579   [(set_attr "type" "alu")
6580    (set_attr "pent_pair" "pu")
6581    (set_attr "mode" "HI")])
6582
6583 (define_insn "subsi3_carry"
6584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6585           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6586             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6587                (match_operand:SI 2 "general_operand" "ri,rm"))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6590   "sbb{l}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "pent_pair" "pu")
6593    (set_attr "mode" "SI")])
6594
6595 (define_insn "subsi3_carry_zext"
6596   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6597           (zero_extend:DI
6598             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6599               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6600                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6601    (clobber (reg:CC FLAGS_REG))]
6602   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6603   "sbb{l}\t{%2, %k0|%k0, %2}"
6604   [(set_attr "type" "alu")
6605    (set_attr "pent_pair" "pu")
6606    (set_attr "mode" "SI")])
6607
6608 (define_expand "subsi3"
6609   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6610                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6611                              (match_operand:SI 2 "general_operand" "")))
6612               (clobber (reg:CC FLAGS_REG))])]
6613   ""
6614   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6615
6616 (define_insn "*subsi_1"
6617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6618         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6619                   (match_operand:SI 2 "general_operand" "ri,rm")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622   "sub{l}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "mode" "SI")])
6625
6626 (define_insn "*subsi_1_zext"
6627   [(set (match_operand:DI 0 "register_operand" "=r")
6628         (zero_extend:DI
6629           (minus:SI (match_operand:SI 1 "register_operand" "0")
6630                     (match_operand:SI 2 "general_operand" "rim"))))
6631    (clobber (reg:CC FLAGS_REG))]
6632   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6633   "sub{l}\t{%2, %k0|%k0, %2}"
6634   [(set_attr "type" "alu")
6635    (set_attr "mode" "SI")])
6636
6637 (define_insn "*subsi_2"
6638   [(set (reg FLAGS_REG)
6639         (compare
6640           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6641                     (match_operand:SI 2 "general_operand" "ri,rm"))
6642           (const_int 0)))
6643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6644         (minus:SI (match_dup 1) (match_dup 2)))]
6645   "ix86_match_ccmode (insn, CCGOCmode)
6646    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647   "sub{l}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "SI")])
6650
6651 (define_insn "*subsi_2_zext"
6652   [(set (reg FLAGS_REG)
6653         (compare
6654           (minus:SI (match_operand:SI 1 "register_operand" "0")
6655                     (match_operand:SI 2 "general_operand" "rim"))
6656           (const_int 0)))
6657    (set (match_operand:DI 0 "register_operand" "=r")
6658         (zero_extend:DI
6659           (minus:SI (match_dup 1)
6660                     (match_dup 2))))]
6661   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6662    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663   "sub{l}\t{%2, %k0|%k0, %2}"
6664   [(set_attr "type" "alu")
6665    (set_attr "mode" "SI")])
6666
6667 (define_insn "*subsi_3"
6668   [(set (reg FLAGS_REG)
6669         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670                  (match_operand:SI 2 "general_operand" "ri,rm")))
6671    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672         (minus:SI (match_dup 1) (match_dup 2)))]
6673   "ix86_match_ccmode (insn, CCmode)
6674    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675   "sub{l}\t{%2, %0|%0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "mode" "SI")])
6678
6679 (define_insn "*subsi_3_zext"
6680   [(set (reg FLAGS_REG)
6681         (compare (match_operand:SI 1 "register_operand" "0")
6682                  (match_operand:SI 2 "general_operand" "rim")))
6683    (set (match_operand:DI 0 "register_operand" "=r")
6684         (zero_extend:DI
6685           (minus:SI (match_dup 1)
6686                     (match_dup 2))))]
6687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6688    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689   "sub{q}\t{%2, %0|%0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "mode" "DI")])
6692
6693 (define_expand "subhi3"
6694   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6695                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6696                              (match_operand:HI 2 "general_operand" "")))
6697               (clobber (reg:CC FLAGS_REG))])]
6698   "TARGET_HIMODE_MATH"
6699   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6700
6701 (define_insn "*subhi_1"
6702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704                   (match_operand:HI 2 "general_operand" "ri,rm")))
6705    (clobber (reg:CC FLAGS_REG))]
6706   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6707   "sub{w}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "HI")])
6710
6711 (define_insn "*subhi_2"
6712   [(set (reg FLAGS_REG)
6713         (compare
6714           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6715                     (match_operand:HI 2 "general_operand" "ri,rm"))
6716           (const_int 0)))
6717    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6718         (minus:HI (match_dup 1) (match_dup 2)))]
6719   "ix86_match_ccmode (insn, CCGOCmode)
6720    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6721   "sub{w}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "HI")])
6724
6725 (define_insn "*subhi_3"
6726   [(set (reg FLAGS_REG)
6727         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6728                  (match_operand:HI 2 "general_operand" "ri,rm")))
6729    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6730         (minus:HI (match_dup 1) (match_dup 2)))]
6731   "ix86_match_ccmode (insn, CCmode)
6732    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6733   "sub{w}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "mode" "HI")])
6736
6737 (define_expand "subqi3"
6738   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6739                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6740                              (match_operand:QI 2 "general_operand" "")))
6741               (clobber (reg:CC FLAGS_REG))])]
6742   "TARGET_QIMODE_MATH"
6743   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6744
6745 (define_insn "*subqi_1"
6746   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6747         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6748                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6749    (clobber (reg:CC FLAGS_REG))]
6750   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6751   "sub{b}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "QI")])
6754
6755 (define_insn "*subqi_1_slp"
6756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6757         (minus:QI (match_dup 0)
6758                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6761    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6762   "sub{b}\t{%1, %0|%0, %1}"
6763   [(set_attr "type" "alu1")
6764    (set_attr "mode" "QI")])
6765
6766 (define_insn "*subqi_2"
6767   [(set (reg FLAGS_REG)
6768         (compare
6769           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6770                     (match_operand:QI 2 "general_operand" "qi,qm"))
6771           (const_int 0)))
6772    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6773         (minus:HI (match_dup 1) (match_dup 2)))]
6774   "ix86_match_ccmode (insn, CCGOCmode)
6775    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6776   "sub{b}\t{%2, %0|%0, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "QI")])
6779
6780 (define_insn "*subqi_3"
6781   [(set (reg FLAGS_REG)
6782         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6783                  (match_operand:QI 2 "general_operand" "qi,qm")))
6784    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6785         (minus:HI (match_dup 1) (match_dup 2)))]
6786   "ix86_match_ccmode (insn, CCmode)
6787    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6788   "sub{b}\t{%2, %0|%0, %2}"
6789   [(set_attr "type" "alu")
6790    (set_attr "mode" "QI")])
6791
6792 ;; The patterns that match these are at the end of this file.
6793
6794 (define_expand "subxf3"
6795   [(set (match_operand:XF 0 "register_operand" "")
6796         (minus:XF (match_operand:XF 1 "register_operand" "")
6797                   (match_operand:XF 2 "register_operand" "")))]
6798   "TARGET_80387"
6799   "")
6800
6801 (define_expand "subdf3"
6802   [(set (match_operand:DF 0 "register_operand" "")
6803         (minus:DF (match_operand:DF 1 "register_operand" "")
6804                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6805   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6806   "")
6807
6808 (define_expand "subsf3"
6809   [(set (match_operand:SF 0 "register_operand" "")
6810         (minus:SF (match_operand:SF 1 "register_operand" "")
6811                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6812   "TARGET_80387 || TARGET_SSE_MATH"
6813   "")
6814 \f
6815 ;; Multiply instructions
6816
6817 (define_expand "muldi3"
6818   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6819                    (mult:DI (match_operand:DI 1 "register_operand" "")
6820                             (match_operand:DI 2 "x86_64_general_operand" "")))
6821               (clobber (reg:CC FLAGS_REG))])]
6822   "TARGET_64BIT"
6823   "")
6824
6825 (define_insn "*muldi3_1_rex64"
6826   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6827         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6828                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6829    (clobber (reg:CC FLAGS_REG))]
6830   "TARGET_64BIT
6831    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6832   "@
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %1, %0|%0, %1, %2}
6835    imul{q}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "imul")
6837    (set_attr "prefix_0f" "0,0,1")
6838    (set (attr "athlon_decode")
6839         (cond [(eq_attr "cpu" "athlon")
6840                   (const_string "vector")
6841                (eq_attr "alternative" "1")
6842                   (const_string "vector")
6843                (and (eq_attr "alternative" "2")
6844                     (match_operand 1 "memory_operand" ""))
6845                   (const_string "vector")]
6846               (const_string "direct")))
6847    (set_attr "mode" "DI")])
6848
6849 (define_expand "mulsi3"
6850   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6851                    (mult:SI (match_operand:SI 1 "register_operand" "")
6852                             (match_operand:SI 2 "general_operand" "")))
6853               (clobber (reg:CC FLAGS_REG))])]
6854   ""
6855   "")
6856
6857 (define_insn "*mulsi3_1"
6858   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6859         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6860                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6863   "@
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\t{%2, %1, %0|%0, %1, %2}
6866    imul{l}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "imul")
6868    (set_attr "prefix_0f" "0,0,1")
6869    (set (attr "athlon_decode")
6870         (cond [(eq_attr "cpu" "athlon")
6871                   (const_string "vector")
6872                (eq_attr "alternative" "1")
6873                   (const_string "vector")
6874                (and (eq_attr "alternative" "2")
6875                     (match_operand 1 "memory_operand" ""))
6876                   (const_string "vector")]
6877               (const_string "direct")))
6878    (set_attr "mode" "SI")])
6879
6880 (define_insn "*mulsi3_1_zext"
6881   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6882         (zero_extend:DI
6883           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6884                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6885    (clobber (reg:CC FLAGS_REG))]
6886   "TARGET_64BIT
6887    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888   "@
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891    imul{l}\t{%2, %k0|%k0, %2}"
6892   [(set_attr "type" "imul")
6893    (set_attr "prefix_0f" "0,0,1")
6894    (set (attr "athlon_decode")
6895         (cond [(eq_attr "cpu" "athlon")
6896                   (const_string "vector")
6897                (eq_attr "alternative" "1")
6898                   (const_string "vector")
6899                (and (eq_attr "alternative" "2")
6900                     (match_operand 1 "memory_operand" ""))
6901                   (const_string "vector")]
6902               (const_string "direct")))
6903    (set_attr "mode" "SI")])
6904
6905 (define_expand "mulhi3"
6906   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6907                    (mult:HI (match_operand:HI 1 "register_operand" "")
6908                             (match_operand:HI 2 "general_operand" "")))
6909               (clobber (reg:CC FLAGS_REG))])]
6910   "TARGET_HIMODE_MATH"
6911   "")
6912
6913 (define_insn "*mulhi3_1"
6914   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6915         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6916                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6919   "@
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %1, %0|%0, %1, %2}
6922    imul{w}\t{%2, %0|%0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1,2")
6929                   (const_string "vector")]
6930               (const_string "direct")))
6931    (set_attr "mode" "HI")])
6932
6933 (define_expand "mulqi3"
6934   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6935                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6936                             (match_operand:QI 2 "register_operand" "")))
6937               (clobber (reg:CC FLAGS_REG))])]
6938   "TARGET_QIMODE_MATH"
6939   "")
6940
6941 (define_insn "*mulqi3_1"
6942   [(set (match_operand:QI 0 "register_operand" "=a")
6943         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6944                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6945    (clobber (reg:CC FLAGS_REG))]
6946   "TARGET_QIMODE_MATH
6947    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948   "mul{b}\t%2"
6949   [(set_attr "type" "imul")
6950    (set_attr "length_immediate" "0")
6951    (set (attr "athlon_decode")
6952      (if_then_else (eq_attr "cpu" "athlon")
6953         (const_string "vector")
6954         (const_string "direct")))
6955    (set_attr "mode" "QI")])
6956
6957 (define_expand "umulqihi3"
6958   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6959                    (mult:HI (zero_extend:HI
6960                               (match_operand:QI 1 "nonimmediate_operand" ""))
6961                             (zero_extend:HI
6962                               (match_operand:QI 2 "register_operand" ""))))
6963               (clobber (reg:CC FLAGS_REG))])]
6964   "TARGET_QIMODE_MATH"
6965   "")
6966
6967 (define_insn "*umulqihi3_1"
6968   [(set (match_operand:HI 0 "register_operand" "=a")
6969         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6970                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "TARGET_QIMODE_MATH
6973    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974   "mul{b}\t%2"
6975   [(set_attr "type" "imul")
6976    (set_attr "length_immediate" "0")
6977    (set (attr "athlon_decode")
6978      (if_then_else (eq_attr "cpu" "athlon")
6979         (const_string "vector")
6980         (const_string "direct")))
6981    (set_attr "mode" "QI")])
6982
6983 (define_expand "mulqihi3"
6984   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6985                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6986                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6987               (clobber (reg:CC FLAGS_REG))])]
6988   "TARGET_QIMODE_MATH"
6989   "")
6990
6991 (define_insn "*mulqihi3_insn"
6992   [(set (match_operand:HI 0 "register_operand" "=a")
6993         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6994                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_QIMODE_MATH
6997    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6998   "imul{b}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "direct")))
7005    (set_attr "mode" "QI")])
7006
7007 (define_expand "umulditi3"
7008   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7009                    (mult:TI (zero_extend:TI
7010                               (match_operand:DI 1 "nonimmediate_operand" ""))
7011                             (zero_extend:TI
7012                               (match_operand:DI 2 "register_operand" ""))))
7013               (clobber (reg:CC FLAGS_REG))])]
7014   "TARGET_64BIT"
7015   "")
7016
7017 (define_insn "*umulditi3_insn"
7018   [(set (match_operand:TI 0 "register_operand" "=A")
7019         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7020                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7021    (clobber (reg:CC FLAGS_REG))]
7022   "TARGET_64BIT
7023    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7024   "mul{q}\t%2"
7025   [(set_attr "type" "imul")
7026    (set_attr "length_immediate" "0")
7027    (set (attr "athlon_decode")
7028      (if_then_else (eq_attr "cpu" "athlon")
7029         (const_string "vector")
7030         (const_string "double")))
7031    (set_attr "mode" "DI")])
7032
7033 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7034 (define_expand "umulsidi3"
7035   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7036                    (mult:DI (zero_extend:DI
7037                               (match_operand:SI 1 "nonimmediate_operand" ""))
7038                             (zero_extend:DI
7039                               (match_operand:SI 2 "register_operand" ""))))
7040               (clobber (reg:CC FLAGS_REG))])]
7041   "!TARGET_64BIT"
7042   "")
7043
7044 (define_insn "*umulsidi3_insn"
7045   [(set (match_operand:DI 0 "register_operand" "=A")
7046         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7047                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7048    (clobber (reg:CC FLAGS_REG))]
7049   "!TARGET_64BIT
7050    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051   "mul{l}\t%2"
7052   [(set_attr "type" "imul")
7053    (set_attr "length_immediate" "0")
7054    (set (attr "athlon_decode")
7055      (if_then_else (eq_attr "cpu" "athlon")
7056         (const_string "vector")
7057         (const_string "double")))
7058    (set_attr "mode" "SI")])
7059
7060 (define_expand "mulditi3"
7061   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7062                    (mult:TI (sign_extend:TI
7063                               (match_operand:DI 1 "nonimmediate_operand" ""))
7064                             (sign_extend:TI
7065                               (match_operand:DI 2 "register_operand" ""))))
7066               (clobber (reg:CC FLAGS_REG))])]
7067   "TARGET_64BIT"
7068   "")
7069
7070 (define_insn "*mulditi3_insn"
7071   [(set (match_operand:TI 0 "register_operand" "=A")
7072         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7073                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7074    (clobber (reg:CC FLAGS_REG))]
7075   "TARGET_64BIT
7076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077   "imul{q}\t%2"
7078   [(set_attr "type" "imul")
7079    (set_attr "length_immediate" "0")
7080    (set (attr "athlon_decode")
7081      (if_then_else (eq_attr "cpu" "athlon")
7082         (const_string "vector")
7083         (const_string "double")))
7084    (set_attr "mode" "DI")])
7085
7086 (define_expand "mulsidi3"
7087   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7088                    (mult:DI (sign_extend:DI
7089                               (match_operand:SI 1 "nonimmediate_operand" ""))
7090                             (sign_extend:DI
7091                               (match_operand:SI 2 "register_operand" ""))))
7092               (clobber (reg:CC FLAGS_REG))])]
7093   "!TARGET_64BIT"
7094   "")
7095
7096 (define_insn "*mulsidi3_insn"
7097   [(set (match_operand:DI 0 "register_operand" "=A")
7098         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7099                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "!TARGET_64BIT
7102    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103   "imul{l}\t%2"
7104   [(set_attr "type" "imul")
7105    (set_attr "length_immediate" "0")
7106    (set (attr "athlon_decode")
7107      (if_then_else (eq_attr "cpu" "athlon")
7108         (const_string "vector")
7109         (const_string "double")))
7110    (set_attr "mode" "SI")])
7111
7112 (define_expand "umuldi3_highpart"
7113   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7114                    (truncate:DI
7115                      (lshiftrt:TI
7116                        (mult:TI (zero_extend:TI
7117                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7118                                 (zero_extend:TI
7119                                   (match_operand:DI 2 "register_operand" "")))
7120                        (const_int 64))))
7121               (clobber (match_scratch:DI 3 ""))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_64BIT"
7124   "")
7125
7126 (define_insn "*umuldi3_highpart_rex64"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (truncate:DI
7129           (lshiftrt:TI
7130             (mult:TI (zero_extend:TI
7131                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7132                      (zero_extend:TI
7133                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7134             (const_int 64))))
7135    (clobber (match_scratch:DI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139   "mul{q}\t%2"
7140   [(set_attr "type" "imul")
7141    (set_attr "length_immediate" "0")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "mode" "DI")])
7147
7148 (define_expand "umulsi3_highpart"
7149   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7150                    (truncate:SI
7151                      (lshiftrt:DI
7152                        (mult:DI (zero_extend:DI
7153                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7154                                 (zero_extend:DI
7155                                   (match_operand:SI 2 "register_operand" "")))
7156                        (const_int 32))))
7157               (clobber (match_scratch:SI 3 ""))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   ""
7160   "")
7161
7162 (define_insn "*umulsi3_highpart_insn"
7163   [(set (match_operand:SI 0 "register_operand" "=d")
7164         (truncate:SI
7165           (lshiftrt:DI
7166             (mult:DI (zero_extend:DI
7167                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168                      (zero_extend:DI
7169                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170             (const_int 32))))
7171    (clobber (match_scratch:SI 3 "=1"))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174   "mul{l}\t%2"
7175   [(set_attr "type" "imul")
7176    (set_attr "length_immediate" "0")
7177    (set (attr "athlon_decode")
7178      (if_then_else (eq_attr "cpu" "athlon")
7179         (const_string "vector")
7180         (const_string "double")))
7181    (set_attr "mode" "SI")])
7182
7183 (define_insn "*umulsi3_highpart_zext"
7184   [(set (match_operand:DI 0 "register_operand" "=d")
7185         (zero_extend:DI (truncate:SI
7186           (lshiftrt:DI
7187             (mult:DI (zero_extend:DI
7188                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7189                      (zero_extend:DI
7190                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7191             (const_int 32)))))
7192    (clobber (match_scratch:SI 3 "=1"))
7193    (clobber (reg:CC FLAGS_REG))]
7194   "TARGET_64BIT
7195    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7196   "mul{l}\t%2"
7197   [(set_attr "type" "imul")
7198    (set_attr "length_immediate" "0")
7199    (set (attr "athlon_decode")
7200      (if_then_else (eq_attr "cpu" "athlon")
7201         (const_string "vector")
7202         (const_string "double")))
7203    (set_attr "mode" "SI")])
7204
7205 (define_expand "smuldi3_highpart"
7206   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7207                    (truncate:DI
7208                      (lshiftrt:TI
7209                        (mult:TI (sign_extend:TI
7210                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7211                                 (sign_extend:TI
7212                                   (match_operand:DI 2 "register_operand" "")))
7213                        (const_int 64))))
7214               (clobber (match_scratch:DI 3 ""))
7215               (clobber (reg:CC FLAGS_REG))])]
7216   "TARGET_64BIT"
7217   "")
7218
7219 (define_insn "*smuldi3_highpart_rex64"
7220   [(set (match_operand:DI 0 "register_operand" "=d")
7221         (truncate:DI
7222           (lshiftrt:TI
7223             (mult:TI (sign_extend:TI
7224                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7225                      (sign_extend:TI
7226                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7227             (const_int 64))))
7228    (clobber (match_scratch:DI 3 "=1"))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_64BIT
7231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7232   "imul{q}\t%2"
7233   [(set_attr "type" "imul")
7234    (set (attr "athlon_decode")
7235      (if_then_else (eq_attr "cpu" "athlon")
7236         (const_string "vector")
7237         (const_string "double")))
7238    (set_attr "mode" "DI")])
7239
7240 (define_expand "smulsi3_highpart"
7241   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7242                    (truncate:SI
7243                      (lshiftrt:DI
7244                        (mult:DI (sign_extend:DI
7245                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7246                                 (sign_extend:DI
7247                                   (match_operand:SI 2 "register_operand" "")))
7248                        (const_int 32))))
7249               (clobber (match_scratch:SI 3 ""))
7250               (clobber (reg:CC FLAGS_REG))])]
7251   ""
7252   "")
7253
7254 (define_insn "*smulsi3_highpart_insn"
7255   [(set (match_operand:SI 0 "register_operand" "=d")
7256         (truncate:SI
7257           (lshiftrt:DI
7258             (mult:DI (sign_extend:DI
7259                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7260                      (sign_extend:DI
7261                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7262             (const_int 32))))
7263    (clobber (match_scratch:SI 3 "=1"))
7264    (clobber (reg:CC FLAGS_REG))]
7265   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7266   "imul{l}\t%2"
7267   [(set_attr "type" "imul")
7268    (set (attr "athlon_decode")
7269      (if_then_else (eq_attr "cpu" "athlon")
7270         (const_string "vector")
7271         (const_string "double")))
7272    (set_attr "mode" "SI")])
7273
7274 (define_insn "*smulsi3_highpart_zext"
7275   [(set (match_operand:DI 0 "register_operand" "=d")
7276         (zero_extend:DI (truncate:SI
7277           (lshiftrt:DI
7278             (mult:DI (sign_extend:DI
7279                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7280                      (sign_extend:DI
7281                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7282             (const_int 32)))))
7283    (clobber (match_scratch:SI 3 "=1"))
7284    (clobber (reg:CC FLAGS_REG))]
7285   "TARGET_64BIT
7286    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287   "imul{l}\t%2"
7288   [(set_attr "type" "imul")
7289    (set (attr "athlon_decode")
7290      (if_then_else (eq_attr "cpu" "athlon")
7291         (const_string "vector")
7292         (const_string "double")))
7293    (set_attr "mode" "SI")])
7294
7295 ;; The patterns that match these are at the end of this file.
7296
7297 (define_expand "mulxf3"
7298   [(set (match_operand:XF 0 "register_operand" "")
7299         (mult:XF (match_operand:XF 1 "register_operand" "")
7300                  (match_operand:XF 2 "register_operand" "")))]
7301   "TARGET_80387"
7302   "")
7303
7304 (define_expand "muldf3"
7305   [(set (match_operand:DF 0 "register_operand" "")
7306         (mult:DF (match_operand:DF 1 "register_operand" "")
7307                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7308   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7309   "")
7310
7311 (define_expand "mulsf3"
7312   [(set (match_operand:SF 0 "register_operand" "")
7313         (mult:SF (match_operand:SF 1 "register_operand" "")
7314                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7315   "TARGET_80387 || TARGET_SSE_MATH"
7316   "")
7317 \f
7318 ;; Divide instructions
7319
7320 (define_insn "divqi3"
7321   [(set (match_operand:QI 0 "register_operand" "=a")
7322         (div:QI (match_operand:HI 1 "register_operand" "0")
7323                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_QIMODE_MATH"
7326   "idiv{b}\t%2"
7327   [(set_attr "type" "idiv")
7328    (set_attr "mode" "QI")])
7329
7330 (define_insn "udivqi3"
7331   [(set (match_operand:QI 0 "register_operand" "=a")
7332         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7333                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7334    (clobber (reg:CC FLAGS_REG))]
7335   "TARGET_QIMODE_MATH"
7336   "div{b}\t%2"
7337   [(set_attr "type" "idiv")
7338    (set_attr "mode" "QI")])
7339
7340 ;; The patterns that match these are at the end of this file.
7341
7342 (define_expand "divxf3"
7343   [(set (match_operand:XF 0 "register_operand" "")
7344         (div:XF (match_operand:XF 1 "register_operand" "")
7345                 (match_operand:XF 2 "register_operand" "")))]
7346   "TARGET_80387"
7347   "")
7348
7349 (define_expand "divdf3"
7350   [(set (match_operand:DF 0 "register_operand" "")
7351         (div:DF (match_operand:DF 1 "register_operand" "")
7352                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7353    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7354    "")
7355  
7356 (define_expand "divsf3"
7357   [(set (match_operand:SF 0 "register_operand" "")
7358         (div:SF (match_operand:SF 1 "register_operand" "")
7359                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7360   "TARGET_80387 || TARGET_SSE_MATH"
7361   "")
7362 \f
7363 ;; Remainder instructions.
7364
7365 (define_expand "divmoddi4"
7366   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7367                    (div:DI (match_operand:DI 1 "register_operand" "")
7368                            (match_operand:DI 2 "nonimmediate_operand" "")))
7369               (set (match_operand:DI 3 "register_operand" "")
7370                    (mod:DI (match_dup 1) (match_dup 2)))
7371               (clobber (reg:CC FLAGS_REG))])]
7372   "TARGET_64BIT"
7373   "")
7374
7375 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7376 ;; Penalize eax case slightly because it results in worse scheduling
7377 ;; of code.
7378 (define_insn "*divmoddi4_nocltd_rex64"
7379   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7380         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7381                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7382    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7383         (mod:DI (match_dup 2) (match_dup 3)))
7384    (clobber (reg:CC FLAGS_REG))]
7385   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7386   "#"
7387   [(set_attr "type" "multi")])
7388
7389 (define_insn "*divmoddi4_cltd_rex64"
7390   [(set (match_operand:DI 0 "register_operand" "=a")
7391         (div:DI (match_operand:DI 2 "register_operand" "a")
7392                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7393    (set (match_operand:DI 1 "register_operand" "=&d")
7394         (mod:DI (match_dup 2) (match_dup 3)))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7397   "#"
7398   [(set_attr "type" "multi")])
7399
7400 (define_insn "*divmoddi_noext_rex64"
7401   [(set (match_operand:DI 0 "register_operand" "=a")
7402         (div:DI (match_operand:DI 1 "register_operand" "0")
7403                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7404    (set (match_operand:DI 3 "register_operand" "=d")
7405         (mod:DI (match_dup 1) (match_dup 2)))
7406    (use (match_operand:DI 4 "register_operand" "3"))
7407    (clobber (reg:CC FLAGS_REG))]
7408   "TARGET_64BIT"
7409   "idiv{q}\t%2"
7410   [(set_attr "type" "idiv")
7411    (set_attr "mode" "DI")])
7412
7413 (define_split
7414   [(set (match_operand:DI 0 "register_operand" "")
7415         (div:DI (match_operand:DI 1 "register_operand" "")
7416                 (match_operand:DI 2 "nonimmediate_operand" "")))
7417    (set (match_operand:DI 3 "register_operand" "")
7418         (mod:DI (match_dup 1) (match_dup 2)))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_64BIT && reload_completed"
7421   [(parallel [(set (match_dup 3)
7422                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7423               (clobber (reg:CC FLAGS_REG))])
7424    (parallel [(set (match_dup 0)
7425                    (div:DI (reg:DI 0) (match_dup 2)))
7426               (set (match_dup 3)
7427                    (mod:DI (reg:DI 0) (match_dup 2)))
7428               (use (match_dup 3))
7429               (clobber (reg:CC FLAGS_REG))])]
7430 {
7431   /* Avoid use of cltd in favor of a mov+shift.  */
7432   if (!TARGET_USE_CLTD && !optimize_size)
7433     {
7434       if (true_regnum (operands[1]))
7435         emit_move_insn (operands[0], operands[1]);
7436       else
7437         emit_move_insn (operands[3], operands[1]);
7438       operands[4] = operands[3];
7439     }
7440   else
7441     {
7442       gcc_assert (!true_regnum (operands[1]));
7443       operands[4] = operands[1];
7444     }
7445 })
7446
7447
7448 (define_expand "divmodsi4"
7449   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7450                    (div:SI (match_operand:SI 1 "register_operand" "")
7451                            (match_operand:SI 2 "nonimmediate_operand" "")))
7452               (set (match_operand:SI 3 "register_operand" "")
7453                    (mod:SI (match_dup 1) (match_dup 2)))
7454               (clobber (reg:CC FLAGS_REG))])]
7455   ""
7456   "")
7457
7458 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7459 ;; Penalize eax case slightly because it results in worse scheduling
7460 ;; of code.
7461 (define_insn "*divmodsi4_nocltd"
7462   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7463         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7464                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7465    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7466         (mod:SI (match_dup 2) (match_dup 3)))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "!optimize_size && !TARGET_USE_CLTD"
7469   "#"
7470   [(set_attr "type" "multi")])
7471
7472 (define_insn "*divmodsi4_cltd"
7473   [(set (match_operand:SI 0 "register_operand" "=a")
7474         (div:SI (match_operand:SI 2 "register_operand" "a")
7475                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7476    (set (match_operand:SI 1 "register_operand" "=&d")
7477         (mod:SI (match_dup 2) (match_dup 3)))
7478    (clobber (reg:CC FLAGS_REG))]
7479   "optimize_size || TARGET_USE_CLTD"
7480   "#"
7481   [(set_attr "type" "multi")])
7482
7483 (define_insn "*divmodsi_noext"
7484   [(set (match_operand:SI 0 "register_operand" "=a")
7485         (div:SI (match_operand:SI 1 "register_operand" "0")
7486                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7487    (set (match_operand:SI 3 "register_operand" "=d")
7488         (mod:SI (match_dup 1) (match_dup 2)))
7489    (use (match_operand:SI 4 "register_operand" "3"))
7490    (clobber (reg:CC FLAGS_REG))]
7491   ""
7492   "idiv{l}\t%2"
7493   [(set_attr "type" "idiv")
7494    (set_attr "mode" "SI")])
7495
7496 (define_split
7497   [(set (match_operand:SI 0 "register_operand" "")
7498         (div:SI (match_operand:SI 1 "register_operand" "")
7499                 (match_operand:SI 2 "nonimmediate_operand" "")))
7500    (set (match_operand:SI 3 "register_operand" "")
7501         (mod:SI (match_dup 1) (match_dup 2)))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "reload_completed"
7504   [(parallel [(set (match_dup 3)
7505                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7506               (clobber (reg:CC FLAGS_REG))])
7507    (parallel [(set (match_dup 0)
7508                    (div:SI (reg:SI 0) (match_dup 2)))
7509               (set (match_dup 3)
7510                    (mod:SI (reg:SI 0) (match_dup 2)))
7511               (use (match_dup 3))
7512               (clobber (reg:CC FLAGS_REG))])]
7513 {
7514   /* Avoid use of cltd in favor of a mov+shift.  */
7515   if (!TARGET_USE_CLTD && !optimize_size)
7516     {
7517       if (true_regnum (operands[1]))
7518         emit_move_insn (operands[0], operands[1]);
7519       else
7520         emit_move_insn (operands[3], operands[1]);
7521       operands[4] = operands[3];
7522     }
7523   else
7524     {
7525       gcc_assert (!true_regnum (operands[1]));
7526       operands[4] = operands[1];
7527     }
7528 })
7529 ;; %%% Split me.
7530 (define_insn "divmodhi4"
7531   [(set (match_operand:HI 0 "register_operand" "=a")
7532         (div:HI (match_operand:HI 1 "register_operand" "0")
7533                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:HI 3 "register_operand" "=&d")
7535         (mod:HI (match_dup 1) (match_dup 2)))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_HIMODE_MATH"
7538   "cwtd\;idiv{w}\t%2"
7539   [(set_attr "type" "multi")
7540    (set_attr "length_immediate" "0")
7541    (set_attr "mode" "SI")])
7542
7543 (define_insn "udivmoddi4"
7544   [(set (match_operand:DI 0 "register_operand" "=a")
7545         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7546                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7547    (set (match_operand:DI 3 "register_operand" "=&d")
7548         (umod:DI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "TARGET_64BIT"
7551   "xor{q}\t%3, %3\;div{q}\t%2"
7552   [(set_attr "type" "multi")
7553    (set_attr "length_immediate" "0")
7554    (set_attr "mode" "DI")])
7555
7556 (define_insn "*udivmoddi4_noext"
7557   [(set (match_operand:DI 0 "register_operand" "=a")
7558         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7559                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7560    (set (match_operand:DI 3 "register_operand" "=d")
7561         (umod:DI (match_dup 1) (match_dup 2)))
7562    (use (match_dup 3))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "TARGET_64BIT"
7565   "div{q}\t%2"
7566   [(set_attr "type" "idiv")
7567    (set_attr "mode" "DI")])
7568
7569 (define_split
7570   [(set (match_operand:DI 0 "register_operand" "")
7571         (udiv:DI (match_operand:DI 1 "register_operand" "")
7572                  (match_operand:DI 2 "nonimmediate_operand" "")))
7573    (set (match_operand:DI 3 "register_operand" "")
7574         (umod:DI (match_dup 1) (match_dup 2)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "TARGET_64BIT && reload_completed"
7577   [(set (match_dup 3) (const_int 0))
7578    (parallel [(set (match_dup 0)
7579                    (udiv:DI (match_dup 1) (match_dup 2)))
7580               (set (match_dup 3)
7581                    (umod:DI (match_dup 1) (match_dup 2)))
7582               (use (match_dup 3))
7583               (clobber (reg:CC FLAGS_REG))])]
7584   "")
7585
7586 (define_insn "udivmodsi4"
7587   [(set (match_operand:SI 0 "register_operand" "=a")
7588         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7589                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7590    (set (match_operand:SI 3 "register_operand" "=&d")
7591         (umod:SI (match_dup 1) (match_dup 2)))
7592    (clobber (reg:CC FLAGS_REG))]
7593   ""
7594   "xor{l}\t%3, %3\;div{l}\t%2"
7595   [(set_attr "type" "multi")
7596    (set_attr "length_immediate" "0")
7597    (set_attr "mode" "SI")])
7598
7599 (define_insn "*udivmodsi4_noext"
7600   [(set (match_operand:SI 0 "register_operand" "=a")
7601         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7602                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7603    (set (match_operand:SI 3 "register_operand" "=d")
7604         (umod:SI (match_dup 1) (match_dup 2)))
7605    (use (match_dup 3))
7606    (clobber (reg:CC FLAGS_REG))]
7607   ""
7608   "div{l}\t%2"
7609   [(set_attr "type" "idiv")
7610    (set_attr "mode" "SI")])
7611
7612 (define_split
7613   [(set (match_operand:SI 0 "register_operand" "")
7614         (udiv:SI (match_operand:SI 1 "register_operand" "")
7615                  (match_operand:SI 2 "nonimmediate_operand" "")))
7616    (set (match_operand:SI 3 "register_operand" "")
7617         (umod:SI (match_dup 1) (match_dup 2)))
7618    (clobber (reg:CC FLAGS_REG))]
7619   "reload_completed"
7620   [(set (match_dup 3) (const_int 0))
7621    (parallel [(set (match_dup 0)
7622                    (udiv:SI (match_dup 1) (match_dup 2)))
7623               (set (match_dup 3)
7624                    (umod:SI (match_dup 1) (match_dup 2)))
7625               (use (match_dup 3))
7626               (clobber (reg:CC FLAGS_REG))])]
7627   "")
7628
7629 (define_expand "udivmodhi4"
7630   [(set (match_dup 4) (const_int 0))
7631    (parallel [(set (match_operand:HI 0 "register_operand" "")
7632                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7633                             (match_operand:HI 2 "nonimmediate_operand" "")))
7634               (set (match_operand:HI 3 "register_operand" "")
7635                    (umod:HI (match_dup 1) (match_dup 2)))
7636               (use (match_dup 4))
7637               (clobber (reg:CC FLAGS_REG))])]
7638   "TARGET_HIMODE_MATH"
7639   "operands[4] = gen_reg_rtx (HImode);")
7640
7641 (define_insn "*udivmodhi_noext"
7642   [(set (match_operand:HI 0 "register_operand" "=a")
7643         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7644                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7645    (set (match_operand:HI 3 "register_operand" "=d")
7646         (umod:HI (match_dup 1) (match_dup 2)))
7647    (use (match_operand:HI 4 "register_operand" "3"))
7648    (clobber (reg:CC FLAGS_REG))]
7649   ""
7650   "div{w}\t%2"
7651   [(set_attr "type" "idiv")
7652    (set_attr "mode" "HI")])
7653
7654 ;; We cannot use div/idiv for double division, because it causes
7655 ;; "division by zero" on the overflow and that's not what we expect
7656 ;; from truncate.  Because true (non truncating) double division is
7657 ;; never generated, we can't create this insn anyway.
7658 ;
7659 ;(define_insn ""
7660 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7661 ;       (truncate:SI
7662 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7663 ;                  (zero_extend:DI
7664 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7665 ;   (set (match_operand:SI 3 "register_operand" "=d")
7666 ;       (truncate:SI
7667 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7668 ;   (clobber (reg:CC FLAGS_REG))]
7669 ;  ""
7670 ;  "div{l}\t{%2, %0|%0, %2}"
7671 ;  [(set_attr "type" "idiv")])
7672 \f
7673 ;;- Logical AND instructions
7674
7675 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7676 ;; Note that this excludes ah.
7677
7678 (define_insn "*testdi_1_rex64"
7679   [(set (reg FLAGS_REG)
7680         (compare
7681           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7682                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7683           (const_int 0)))]
7684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7686   "@
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{l}\t{%k1, %k0|%k0, %k1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}
7691    test{q}\t{%1, %0|%0, %1}"
7692   [(set_attr "type" "test")
7693    (set_attr "modrm" "0,1,0,1,1")
7694    (set_attr "mode" "SI,SI,DI,DI,DI")
7695    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7696
7697 (define_insn "testsi_1"
7698   [(set (reg FLAGS_REG)
7699         (compare
7700           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7701                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7702           (const_int 0)))]
7703   "ix86_match_ccmode (insn, CCNOmode)
7704    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7705   "test{l}\t{%1, %0|%0, %1}"
7706   [(set_attr "type" "test")
7707    (set_attr "modrm" "0,1,1")
7708    (set_attr "mode" "SI")
7709    (set_attr "pent_pair" "uv,np,uv")])
7710
7711 (define_expand "testsi_ccno_1"
7712   [(set (reg:CCNO FLAGS_REG)
7713         (compare:CCNO
7714           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7715                   (match_operand:SI 1 "nonmemory_operand" ""))
7716           (const_int 0)))]
7717   ""
7718   "")
7719
7720 (define_insn "*testhi_1"
7721   [(set (reg FLAGS_REG)
7722         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7723                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7724                  (const_int 0)))]
7725   "ix86_match_ccmode (insn, CCNOmode)
7726    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7727   "test{w}\t{%1, %0|%0, %1}"
7728   [(set_attr "type" "test")
7729    (set_attr "modrm" "0,1,1")
7730    (set_attr "mode" "HI")
7731    (set_attr "pent_pair" "uv,np,uv")])
7732
7733 (define_expand "testqi_ccz_1"
7734   [(set (reg:CCZ FLAGS_REG)
7735         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7736                              (match_operand:QI 1 "nonmemory_operand" ""))
7737                  (const_int 0)))]
7738   ""
7739   "")
7740
7741 (define_insn "*testqi_1_maybe_si"
7742   [(set (reg FLAGS_REG)
7743         (compare
7744           (and:QI
7745             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7746             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7747           (const_int 0)))]
7748    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7749     && ix86_match_ccmode (insn,
7750                          GET_CODE (operands[1]) == CONST_INT
7751                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7752 {
7753   if (which_alternative == 3)
7754     {
7755       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7756         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7757       return "test{l}\t{%1, %k0|%k0, %1}";
7758     }
7759   return "test{b}\t{%1, %0|%0, %1}";
7760 }
7761   [(set_attr "type" "test")
7762    (set_attr "modrm" "0,1,1,1")
7763    (set_attr "mode" "QI,QI,QI,SI")
7764    (set_attr "pent_pair" "uv,np,uv,np")])
7765
7766 (define_insn "*testqi_1"
7767   [(set (reg FLAGS_REG)
7768         (compare
7769           (and:QI
7770             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7771             (match_operand:QI 1 "general_operand" "n,n,qn"))
7772           (const_int 0)))]
7773   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7774    && ix86_match_ccmode (insn, CCNOmode)"
7775   "test{b}\t{%1, %0|%0, %1}"
7776   [(set_attr "type" "test")
7777    (set_attr "modrm" "0,1,1")
7778    (set_attr "mode" "QI")
7779    (set_attr "pent_pair" "uv,np,uv")])
7780
7781 (define_expand "testqi_ext_ccno_0"
7782   [(set (reg:CCNO FLAGS_REG)
7783         (compare:CCNO
7784           (and:SI
7785             (zero_extract:SI
7786               (match_operand 0 "ext_register_operand" "")
7787               (const_int 8)
7788               (const_int 8))
7789             (match_operand 1 "const_int_operand" ""))
7790           (const_int 0)))]
7791   ""
7792   "")
7793
7794 (define_insn "*testqi_ext_0"
7795   [(set (reg FLAGS_REG)
7796         (compare
7797           (and:SI
7798             (zero_extract:SI
7799               (match_operand 0 "ext_register_operand" "Q")
7800               (const_int 8)
7801               (const_int 8))
7802             (match_operand 1 "const_int_operand" "n"))
7803           (const_int 0)))]
7804   "ix86_match_ccmode (insn, CCNOmode)"
7805   "test{b}\t{%1, %h0|%h0, %1}"
7806   [(set_attr "type" "test")
7807    (set_attr "mode" "QI")
7808    (set_attr "length_immediate" "1")
7809    (set_attr "pent_pair" "np")])
7810
7811 (define_insn "*testqi_ext_1"
7812   [(set (reg FLAGS_REG)
7813         (compare
7814           (and:SI
7815             (zero_extract:SI
7816               (match_operand 0 "ext_register_operand" "Q")
7817               (const_int 8)
7818               (const_int 8))
7819             (zero_extend:SI
7820               (match_operand:QI 1 "general_operand" "Qm")))
7821           (const_int 0)))]
7822   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824   "test{b}\t{%1, %h0|%h0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "mode" "QI")])
7827
7828 (define_insn "*testqi_ext_1_rex64"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:SI
7832             (zero_extract:SI
7833               (match_operand 0 "ext_register_operand" "Q")
7834               (const_int 8)
7835               (const_int 8))
7836             (zero_extend:SI
7837               (match_operand:QI 1 "register_operand" "Q")))
7838           (const_int 0)))]
7839   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7840   "test{b}\t{%1, %h0|%h0, %1}"
7841   [(set_attr "type" "test")
7842    (set_attr "mode" "QI")])
7843
7844 (define_insn "*testqi_ext_2"
7845   [(set (reg FLAGS_REG)
7846         (compare
7847           (and:SI
7848             (zero_extract:SI
7849               (match_operand 0 "ext_register_operand" "Q")
7850               (const_int 8)
7851               (const_int 8))
7852             (zero_extract:SI
7853               (match_operand 1 "ext_register_operand" "Q")
7854               (const_int 8)
7855               (const_int 8)))
7856           (const_int 0)))]
7857   "ix86_match_ccmode (insn, CCNOmode)"
7858   "test{b}\t{%h1, %h0|%h0, %h1}"
7859   [(set_attr "type" "test")
7860    (set_attr "mode" "QI")])
7861
7862 ;; Combine likes to form bit extractions for some tests.  Humor it.
7863 (define_insn "*testqi_ext_3"
7864   [(set (reg FLAGS_REG)
7865         (compare (zero_extract:SI
7866                    (match_operand 0 "nonimmediate_operand" "rm")
7867                    (match_operand:SI 1 "const_int_operand" "")
7868                    (match_operand:SI 2 "const_int_operand" ""))
7869                  (const_int 0)))]
7870   "ix86_match_ccmode (insn, CCNOmode)
7871    && INTVAL (operands[1]) > 0
7872    && INTVAL (operands[2]) >= 0
7873    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7874    && (GET_MODE (operands[0]) == SImode
7875        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876        || GET_MODE (operands[0]) == HImode
7877        || GET_MODE (operands[0]) == QImode)"
7878   "#")
7879
7880 (define_insn "*testqi_ext_3_rex64"
7881   [(set (reg FLAGS_REG)
7882         (compare (zero_extract:DI
7883                    (match_operand 0 "nonimmediate_operand" "rm")
7884                    (match_operand:DI 1 "const_int_operand" "")
7885                    (match_operand:DI 2 "const_int_operand" ""))
7886                  (const_int 0)))]
7887   "TARGET_64BIT
7888    && ix86_match_ccmode (insn, CCNOmode)
7889    && INTVAL (operands[1]) > 0
7890    && INTVAL (operands[2]) >= 0
7891    /* Ensure that resulting mask is zero or sign extended operand.  */
7892    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894            && INTVAL (operands[1]) > 32))
7895    && (GET_MODE (operands[0]) == SImode
7896        || GET_MODE (operands[0]) == DImode
7897        || GET_MODE (operands[0]) == HImode
7898        || GET_MODE (operands[0]) == QImode)"
7899   "#")
7900
7901 (define_split
7902   [(set (match_operand 0 "flags_reg_operand" "")
7903         (match_operator 1 "compare_operator"
7904           [(zero_extract
7905              (match_operand 2 "nonimmediate_operand" "")
7906              (match_operand 3 "const_int_operand" "")
7907              (match_operand 4 "const_int_operand" ""))
7908            (const_int 0)]))]
7909   "ix86_match_ccmode (insn, CCNOmode)"
7910   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911 {
7912   rtx val = operands[2];
7913   HOST_WIDE_INT len = INTVAL (operands[3]);
7914   HOST_WIDE_INT pos = INTVAL (operands[4]);
7915   HOST_WIDE_INT mask;
7916   enum machine_mode mode, submode;
7917
7918   mode = GET_MODE (val);
7919   if (GET_CODE (val) == MEM)
7920     {
7921       /* ??? Combine likes to put non-volatile mem extractions in QImode
7922          no matter the size of the test.  So find a mode that works.  */
7923       if (! MEM_VOLATILE_P (val))
7924         {
7925           mode = smallest_mode_for_size (pos + len, MODE_INT);
7926           val = adjust_address (val, mode, 0);
7927         }
7928     }
7929   else if (GET_CODE (val) == SUBREG
7930            && (submode = GET_MODE (SUBREG_REG (val)),
7931                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932            && pos + len <= GET_MODE_BITSIZE (submode))
7933     {
7934       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7935       mode = submode;
7936       val = SUBREG_REG (val);
7937     }
7938   else if (mode == HImode && pos + len <= 8)
7939     {
7940       /* Small HImode tests can be converted to QImode.  */
7941       mode = QImode;
7942       val = gen_lowpart (QImode, val);
7943     }
7944
7945   if (len == HOST_BITS_PER_WIDE_INT)
7946     mask = -1;
7947   else
7948     mask = ((HOST_WIDE_INT)1 << len) - 1;
7949   mask <<= pos;
7950
7951   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7952 })
7953
7954 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7955 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7956 ;; this is relatively important trick.
7957 ;; Do the conversion only post-reload to avoid limiting of the register class
7958 ;; to QI regs.
7959 (define_split
7960   [(set (match_operand 0 "flags_reg_operand" "")
7961         (match_operator 1 "compare_operator"
7962           [(and (match_operand 2 "register_operand" "")
7963                 (match_operand 3 "const_int_operand" ""))
7964            (const_int 0)]))]
7965    "reload_completed
7966     && QI_REG_P (operands[2])
7967     && GET_MODE (operands[2]) != QImode
7968     && ((ix86_match_ccmode (insn, CCZmode)
7969          && !(INTVAL (operands[3]) & ~(255 << 8)))
7970         || (ix86_match_ccmode (insn, CCNOmode)
7971             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7972   [(set (match_dup 0)
7973         (match_op_dup 1
7974           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7975                    (match_dup 3))
7976            (const_int 0)]))]
7977   "operands[2] = gen_lowpart (SImode, operands[2]);
7978    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7979
7980 (define_split
7981   [(set (match_operand 0 "flags_reg_operand" "")
7982         (match_operator 1 "compare_operator"
7983           [(and (match_operand 2 "nonimmediate_operand" "")
7984                 (match_operand 3 "const_int_operand" ""))
7985            (const_int 0)]))]
7986    "reload_completed
7987     && GET_MODE (operands[2]) != QImode
7988     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7989     && ((ix86_match_ccmode (insn, CCZmode)
7990          && !(INTVAL (operands[3]) & ~255))
7991         || (ix86_match_ccmode (insn, CCNOmode)
7992             && !(INTVAL (operands[3]) & ~127)))"
7993   [(set (match_dup 0)
7994         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7995                          (const_int 0)]))]
7996   "operands[2] = gen_lowpart (QImode, operands[2]);
7997    operands[3] = gen_lowpart (QImode, operands[3]);")
7998
7999
8000 ;; %%% This used to optimize known byte-wide and operations to memory,
8001 ;; and sometimes to QImode registers.  If this is considered useful,
8002 ;; it should be done with splitters.
8003
8004 (define_expand "anddi3"
8005   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8006         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8007                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "TARGET_64BIT"
8010   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8011
8012 (define_insn "*anddi_1_rex64"
8013   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8014         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8015                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8018 {
8019   switch (get_attr_type (insn))
8020     {
8021     case TYPE_IMOVX:
8022       {
8023         enum machine_mode mode;
8024
8025         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8026         if (INTVAL (operands[2]) == 0xff)
8027           mode = QImode;
8028         else
8029           {
8030             gcc_assert (INTVAL (operands[2]) == 0xffff);
8031             mode = HImode;
8032           }
8033         
8034         operands[1] = gen_lowpart (mode, operands[1]);
8035         if (mode == QImode)
8036           return "movz{bq|x}\t{%1,%0|%0, %1}";
8037         else
8038           return "movz{wq|x}\t{%1,%0|%0, %1}";
8039       }
8040
8041     default:
8042       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8043       if (get_attr_mode (insn) == MODE_SI)
8044         return "and{l}\t{%k2, %k0|%k0, %k2}";
8045       else
8046         return "and{q}\t{%2, %0|%0, %2}";
8047     }
8048 }
8049   [(set_attr "type" "alu,alu,alu,imovx")
8050    (set_attr "length_immediate" "*,*,*,0")
8051    (set_attr "mode" "SI,DI,DI,DI")])
8052
8053 (define_insn "*anddi_2"
8054   [(set (reg FLAGS_REG)
8055         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8056                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8057                  (const_int 0)))
8058    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8059         (and:DI (match_dup 1) (match_dup 2)))]
8060   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8061    && ix86_binary_operator_ok (AND, DImode, operands)"
8062   "@
8063    and{l}\t{%k2, %k0|%k0, %k2}
8064    and{q}\t{%2, %0|%0, %2}
8065    and{q}\t{%2, %0|%0, %2}"
8066   [(set_attr "type" "alu")
8067    (set_attr "mode" "SI,DI,DI")])
8068
8069 (define_expand "andsi3"
8070   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8071         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8072                 (match_operand:SI 2 "general_operand" "")))
8073    (clobber (reg:CC FLAGS_REG))]
8074   ""
8075   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8076
8077 (define_insn "*andsi_1"
8078   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8079         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8080                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "ix86_binary_operator_ok (AND, SImode, operands)"
8083 {
8084   switch (get_attr_type (insn))
8085     {
8086     case TYPE_IMOVX:
8087       {
8088         enum machine_mode mode;
8089
8090         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8091         if (INTVAL (operands[2]) == 0xff)
8092           mode = QImode;
8093         else
8094           {
8095             gcc_assert (INTVAL (operands[2]) == 0xffff);
8096             mode = HImode;
8097           }
8098         
8099         operands[1] = gen_lowpart (mode, operands[1]);
8100         if (mode == QImode)
8101           return "movz{bl|x}\t{%1,%0|%0, %1}";
8102         else
8103           return "movz{wl|x}\t{%1,%0|%0, %1}";
8104       }
8105
8106     default:
8107       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8108       return "and{l}\t{%2, %0|%0, %2}";
8109     }
8110 }
8111   [(set_attr "type" "alu,alu,imovx")
8112    (set_attr "length_immediate" "*,*,0")
8113    (set_attr "mode" "SI")])
8114
8115 (define_split
8116   [(set (match_operand 0 "register_operand" "")
8117         (and (match_dup 0)
8118              (const_int -65536)))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8121   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8122   "operands[1] = gen_lowpart (HImode, operands[0]);")
8123
8124 (define_split
8125   [(set (match_operand 0 "ext_register_operand" "")
8126         (and (match_dup 0)
8127              (const_int -256)))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8130   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8131   "operands[1] = gen_lowpart (QImode, operands[0]);")
8132
8133 (define_split
8134   [(set (match_operand 0 "ext_register_operand" "")
8135         (and (match_dup 0)
8136              (const_int -65281)))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8139   [(parallel [(set (zero_extract:SI (match_dup 0)
8140                                     (const_int 8)
8141                                     (const_int 8))
8142                    (xor:SI 
8143                      (zero_extract:SI (match_dup 0)
8144                                       (const_int 8)
8145                                       (const_int 8))
8146                      (zero_extract:SI (match_dup 0)
8147                                       (const_int 8)
8148                                       (const_int 8))))
8149               (clobber (reg:CC FLAGS_REG))])]
8150   "operands[0] = gen_lowpart (SImode, operands[0]);")
8151
8152 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8153 (define_insn "*andsi_1_zext"
8154   [(set (match_operand:DI 0 "register_operand" "=r")
8155         (zero_extend:DI
8156           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8157                   (match_operand:SI 2 "general_operand" "rim"))))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8160   "and{l}\t{%2, %k0|%k0, %2}"
8161   [(set_attr "type" "alu")
8162    (set_attr "mode" "SI")])
8163
8164 (define_insn "*andsi_2"
8165   [(set (reg FLAGS_REG)
8166         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8167                          (match_operand:SI 2 "general_operand" "rim,ri"))
8168                  (const_int 0)))
8169    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8170         (and:SI (match_dup 1) (match_dup 2)))]
8171   "ix86_match_ccmode (insn, CCNOmode)
8172    && ix86_binary_operator_ok (AND, SImode, operands)"
8173   "and{l}\t{%2, %0|%0, %2}"
8174   [(set_attr "type" "alu")
8175    (set_attr "mode" "SI")])
8176
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 (define_insn "*andsi_2_zext"
8179   [(set (reg FLAGS_REG)
8180         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8181                          (match_operand:SI 2 "general_operand" "rim"))
8182                  (const_int 0)))
8183    (set (match_operand:DI 0 "register_operand" "=r")
8184         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8185   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8186    && ix86_binary_operator_ok (AND, SImode, operands)"
8187   "and{l}\t{%2, %k0|%k0, %2}"
8188   [(set_attr "type" "alu")
8189    (set_attr "mode" "SI")])
8190
8191 (define_expand "andhi3"
8192   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8193         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8194                 (match_operand:HI 2 "general_operand" "")))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "TARGET_HIMODE_MATH"
8197   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8198
8199 (define_insn "*andhi_1"
8200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8201         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8202                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8203    (clobber (reg:CC FLAGS_REG))]
8204   "ix86_binary_operator_ok (AND, HImode, operands)"
8205 {
8206   switch (get_attr_type (insn))
8207     {
8208     case TYPE_IMOVX:
8209       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8210       gcc_assert (INTVAL (operands[2]) == 0xff);
8211       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8212
8213     default:
8214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8215
8216       return "and{w}\t{%2, %0|%0, %2}";
8217     }
8218 }
8219   [(set_attr "type" "alu,alu,imovx")
8220    (set_attr "length_immediate" "*,*,0")
8221    (set_attr "mode" "HI,HI,SI")])
8222
8223 (define_insn "*andhi_2"
8224   [(set (reg FLAGS_REG)
8225         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8226                          (match_operand:HI 2 "general_operand" "rim,ri"))
8227                  (const_int 0)))
8228    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8229         (and:HI (match_dup 1) (match_dup 2)))]
8230   "ix86_match_ccmode (insn, CCNOmode)
8231    && ix86_binary_operator_ok (AND, HImode, operands)"
8232   "and{w}\t{%2, %0|%0, %2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "mode" "HI")])
8235
8236 (define_expand "andqi3"
8237   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8238         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8239                 (match_operand:QI 2 "general_operand" "")))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "TARGET_QIMODE_MATH"
8242   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8243
8244 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8245 (define_insn "*andqi_1"
8246   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8247         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8248                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8249    (clobber (reg:CC FLAGS_REG))]
8250   "ix86_binary_operator_ok (AND, QImode, operands)"
8251   "@
8252    and{b}\t{%2, %0|%0, %2}
8253    and{b}\t{%2, %0|%0, %2}
8254    and{l}\t{%k2, %k0|%k0, %k2}"
8255   [(set_attr "type" "alu")
8256    (set_attr "mode" "QI,QI,SI")])
8257
8258 (define_insn "*andqi_1_slp"
8259   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8260         (and:QI (match_dup 0)
8261                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8265   "and{b}\t{%1, %0|%0, %1}"
8266   [(set_attr "type" "alu1")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*andqi_2_maybe_si"
8270   [(set (reg FLAGS_REG)
8271         (compare (and:QI
8272                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8273                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8274                  (const_int 0)))
8275    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8276         (and:QI (match_dup 1) (match_dup 2)))]
8277   "ix86_binary_operator_ok (AND, QImode, operands)
8278    && ix86_match_ccmode (insn,
8279                          GET_CODE (operands[2]) == CONST_INT
8280                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8281 {
8282   if (which_alternative == 2)
8283     {
8284       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8285         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8286       return "and{l}\t{%2, %k0|%k0, %2}";
8287     }
8288   return "and{b}\t{%2, %0|%0, %2}";
8289 }
8290   [(set_attr "type" "alu")
8291    (set_attr "mode" "QI,QI,SI")])
8292
8293 (define_insn "*andqi_2"
8294   [(set (reg FLAGS_REG)
8295         (compare (and:QI
8296                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8297                    (match_operand:QI 2 "general_operand" "qim,qi"))
8298                  (const_int 0)))
8299    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8300         (and:QI (match_dup 1) (match_dup 2)))]
8301   "ix86_match_ccmode (insn, CCNOmode)
8302    && ix86_binary_operator_ok (AND, QImode, operands)"
8303   "and{b}\t{%2, %0|%0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "mode" "QI")])
8306
8307 (define_insn "*andqi_2_slp"
8308   [(set (reg FLAGS_REG)
8309         (compare (and:QI
8310                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8311                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8312                  (const_int 0)))
8313    (set (strict_low_part (match_dup 0))
8314         (and:QI (match_dup 0) (match_dup 1)))]
8315   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8316    && ix86_match_ccmode (insn, CCNOmode)
8317    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8318   "and{b}\t{%1, %0|%0, %1}"
8319   [(set_attr "type" "alu1")
8320    (set_attr "mode" "QI")])
8321
8322 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8323 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8324 ;; for a QImode operand, which of course failed.
8325
8326 (define_insn "andqi_ext_0"
8327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328                          (const_int 8)
8329                          (const_int 8))
8330         (and:SI 
8331           (zero_extract:SI
8332             (match_operand 1 "ext_register_operand" "0")
8333             (const_int 8)
8334             (const_int 8))
8335           (match_operand 2 "const_int_operand" "n")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   ""
8338   "and{b}\t{%2, %h0|%h0, %2}"
8339   [(set_attr "type" "alu")
8340    (set_attr "length_immediate" "1")
8341    (set_attr "mode" "QI")])
8342
8343 ;; Generated by peephole translating test to and.  This shows up
8344 ;; often in fp comparisons.
8345
8346 (define_insn "*andqi_ext_0_cc"
8347   [(set (reg FLAGS_REG)
8348         (compare
8349           (and:SI
8350             (zero_extract:SI
8351               (match_operand 1 "ext_register_operand" "0")
8352               (const_int 8)
8353               (const_int 8))
8354             (match_operand 2 "const_int_operand" "n"))
8355           (const_int 0)))
8356    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8357                          (const_int 8)
8358                          (const_int 8))
8359         (and:SI 
8360           (zero_extract:SI
8361             (match_dup 1)
8362             (const_int 8)
8363             (const_int 8))
8364           (match_dup 2)))]
8365   "ix86_match_ccmode (insn, CCNOmode)"
8366   "and{b}\t{%2, %h0|%h0, %2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "length_immediate" "1")
8369    (set_attr "mode" "QI")])
8370
8371 (define_insn "*andqi_ext_1"
8372   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8373                          (const_int 8)
8374                          (const_int 8))
8375         (and:SI 
8376           (zero_extract:SI
8377             (match_operand 1 "ext_register_operand" "0")
8378             (const_int 8)
8379             (const_int 8))
8380           (zero_extend:SI
8381             (match_operand:QI 2 "general_operand" "Qm"))))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "!TARGET_64BIT"
8384   "and{b}\t{%2, %h0|%h0, %2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "length_immediate" "0")
8387    (set_attr "mode" "QI")])
8388
8389 (define_insn "*andqi_ext_1_rex64"
8390   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391                          (const_int 8)
8392                          (const_int 8))
8393         (and:SI 
8394           (zero_extract:SI
8395             (match_operand 1 "ext_register_operand" "0")
8396             (const_int 8)
8397             (const_int 8))
8398           (zero_extend:SI
8399             (match_operand 2 "ext_register_operand" "Q"))))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "TARGET_64BIT"
8402   "and{b}\t{%2, %h0|%h0, %2}"
8403   [(set_attr "type" "alu")
8404    (set_attr "length_immediate" "0")
8405    (set_attr "mode" "QI")])
8406
8407 (define_insn "*andqi_ext_2"
8408   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409                          (const_int 8)
8410                          (const_int 8))
8411         (and:SI
8412           (zero_extract:SI
8413             (match_operand 1 "ext_register_operand" "%0")
8414             (const_int 8)
8415             (const_int 8))
8416           (zero_extract:SI
8417             (match_operand 2 "ext_register_operand" "Q")
8418             (const_int 8)
8419             (const_int 8))))
8420    (clobber (reg:CC FLAGS_REG))]
8421   ""
8422   "and{b}\t{%h2, %h0|%h0, %h2}"
8423   [(set_attr "type" "alu")
8424    (set_attr "length_immediate" "0")
8425    (set_attr "mode" "QI")])
8426
8427 ;; Convert wide AND instructions with immediate operand to shorter QImode
8428 ;; equivalents when possible.
8429 ;; Don't do the splitting with memory operands, since it introduces risk
8430 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8431 ;; for size, but that can (should?) be handled by generic code instead.
8432 (define_split
8433   [(set (match_operand 0 "register_operand" "")
8434         (and (match_operand 1 "register_operand" "")
8435              (match_operand 2 "const_int_operand" "")))
8436    (clobber (reg:CC FLAGS_REG))]
8437    "reload_completed
8438     && QI_REG_P (operands[0])
8439     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8440     && !(~INTVAL (operands[2]) & ~(255 << 8))
8441     && GET_MODE (operands[0]) != QImode"
8442   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8443                    (and:SI (zero_extract:SI (match_dup 1)
8444                                             (const_int 8) (const_int 8))
8445                            (match_dup 2)))
8446               (clobber (reg:CC FLAGS_REG))])]
8447   "operands[0] = gen_lowpart (SImode, operands[0]);
8448    operands[1] = gen_lowpart (SImode, operands[1]);
8449    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8450
8451 ;; Since AND can be encoded with sign extended immediate, this is only
8452 ;; profitable when 7th bit is not set.
8453 (define_split
8454   [(set (match_operand 0 "register_operand" "")
8455         (and (match_operand 1 "general_operand" "")
8456              (match_operand 2 "const_int_operand" "")))
8457    (clobber (reg:CC FLAGS_REG))]
8458    "reload_completed
8459     && ANY_QI_REG_P (operands[0])
8460     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8461     && !(~INTVAL (operands[2]) & ~255)
8462     && !(INTVAL (operands[2]) & 128)
8463     && GET_MODE (operands[0]) != QImode"
8464   [(parallel [(set (strict_low_part (match_dup 0))
8465                    (and:QI (match_dup 1)
8466                            (match_dup 2)))
8467               (clobber (reg:CC FLAGS_REG))])]
8468   "operands[0] = gen_lowpart (QImode, operands[0]);
8469    operands[1] = gen_lowpart (QImode, operands[1]);
8470    operands[2] = gen_lowpart (QImode, operands[2]);")
8471 \f
8472 ;; Logical inclusive OR instructions
8473
8474 ;; %%% This used to optimize known byte-wide and operations to memory.
8475 ;; If this is considered useful, it should be done with splitters.
8476
8477 (define_expand "iordi3"
8478   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8479         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8480                 (match_operand:DI 2 "x86_64_general_operand" "")))
8481    (clobber (reg:CC FLAGS_REG))]
8482   "TARGET_64BIT"
8483   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8484
8485 (define_insn "*iordi_1_rex64"
8486   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8487         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8488                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8489    (clobber (reg:CC FLAGS_REG))]
8490   "TARGET_64BIT
8491    && ix86_binary_operator_ok (IOR, DImode, operands)"
8492   "or{q}\t{%2, %0|%0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "mode" "DI")])
8495
8496 (define_insn "*iordi_2_rex64"
8497   [(set (reg FLAGS_REG)
8498         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8499                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8500                  (const_int 0)))
8501    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8502         (ior:DI (match_dup 1) (match_dup 2)))]
8503   "TARGET_64BIT
8504    && ix86_match_ccmode (insn, CCNOmode)
8505    && ix86_binary_operator_ok (IOR, DImode, operands)"
8506   "or{q}\t{%2, %0|%0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "mode" "DI")])
8509
8510 (define_insn "*iordi_3_rex64"
8511   [(set (reg FLAGS_REG)
8512         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8513                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8514                  (const_int 0)))
8515    (clobber (match_scratch:DI 0 "=r"))]
8516   "TARGET_64BIT
8517    && ix86_match_ccmode (insn, CCNOmode)
8518    && ix86_binary_operator_ok (IOR, DImode, operands)"
8519   "or{q}\t{%2, %0|%0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "mode" "DI")])
8522
8523
8524 (define_expand "iorsi3"
8525   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8526         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8527                 (match_operand:SI 2 "general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   ""
8530   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8531
8532 (define_insn "*iorsi_1"
8533   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8534         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "ix86_binary_operator_ok (IOR, SImode, operands)"
8538   "or{l}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "SI")])
8541
8542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8543 (define_insn "*iorsi_1_zext"
8544   [(set (match_operand:DI 0 "register_operand" "=rm")
8545         (zero_extend:DI
8546           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8547                   (match_operand:SI 2 "general_operand" "rim"))))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8550   "or{l}\t{%2, %k0|%k0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8553
8554 (define_insn "*iorsi_1_zext_imm"
8555   [(set (match_operand:DI 0 "register_operand" "=rm")
8556         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8557                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "TARGET_64BIT"
8560   "or{l}\t{%2, %k0|%k0, %2}"
8561   [(set_attr "type" "alu")
8562    (set_attr "mode" "SI")])
8563
8564 (define_insn "*iorsi_2"
8565   [(set (reg FLAGS_REG)
8566         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567                          (match_operand:SI 2 "general_operand" "rim,ri"))
8568                  (const_int 0)))
8569    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8570         (ior:SI (match_dup 1) (match_dup 2)))]
8571   "ix86_match_ccmode (insn, CCNOmode)
8572    && ix86_binary_operator_ok (IOR, SImode, operands)"
8573   "or{l}\t{%2, %0|%0, %2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "SI")])
8576
8577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8578 ;; ??? Special case for immediate operand is missing - it is tricky.
8579 (define_insn "*iorsi_2_zext"
8580   [(set (reg FLAGS_REG)
8581         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8582                          (match_operand:SI 2 "general_operand" "rim"))
8583                  (const_int 0)))
8584    (set (match_operand:DI 0 "register_operand" "=r")
8585         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8586   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8587    && ix86_binary_operator_ok (IOR, SImode, operands)"
8588   "or{l}\t{%2, %k0|%k0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "SI")])
8591
8592 (define_insn "*iorsi_2_zext_imm"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8595                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8596                  (const_int 0)))
8597    (set (match_operand:DI 0 "register_operand" "=r")
8598         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8599   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, SImode, operands)"
8601   "or{l}\t{%2, %k0|%k0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "SI")])
8604
8605 (define_insn "*iorsi_3"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8608                          (match_operand:SI 2 "general_operand" "rim"))
8609                  (const_int 0)))
8610    (clobber (match_scratch:SI 0 "=r"))]
8611   "ix86_match_ccmode (insn, CCNOmode)
8612    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8613   "or{l}\t{%2, %0|%0, %2}"
8614   [(set_attr "type" "alu")
8615    (set_attr "mode" "SI")])
8616
8617 (define_expand "iorhi3"
8618   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8619         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8620                 (match_operand:HI 2 "general_operand" "")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "TARGET_HIMODE_MATH"
8623   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8624
8625 (define_insn "*iorhi_1"
8626   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8627         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8628                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "ix86_binary_operator_ok (IOR, HImode, operands)"
8631   "or{w}\t{%2, %0|%0, %2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "HI")])
8634
8635 (define_insn "*iorhi_2"
8636   [(set (reg FLAGS_REG)
8637         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8638                          (match_operand:HI 2 "general_operand" "rim,ri"))
8639                  (const_int 0)))
8640    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8641         (ior:HI (match_dup 1) (match_dup 2)))]
8642   "ix86_match_ccmode (insn, CCNOmode)
8643    && ix86_binary_operator_ok (IOR, HImode, operands)"
8644   "or{w}\t{%2, %0|%0, %2}"
8645   [(set_attr "type" "alu")
8646    (set_attr "mode" "HI")])
8647
8648 (define_insn "*iorhi_3"
8649   [(set (reg FLAGS_REG)
8650         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8651                          (match_operand:HI 2 "general_operand" "rim"))
8652                  (const_int 0)))
8653    (clobber (match_scratch:HI 0 "=r"))]
8654   "ix86_match_ccmode (insn, CCNOmode)
8655    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8656   "or{w}\t{%2, %0|%0, %2}"
8657   [(set_attr "type" "alu")
8658    (set_attr "mode" "HI")])
8659
8660 (define_expand "iorqi3"
8661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8662         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8663                 (match_operand:QI 2 "general_operand" "")))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "TARGET_QIMODE_MATH"
8666   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8667
8668 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8669 (define_insn "*iorqi_1"
8670   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8671         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8672                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "ix86_binary_operator_ok (IOR, QImode, operands)"
8675   "@
8676    or{b}\t{%2, %0|%0, %2}
8677    or{b}\t{%2, %0|%0, %2}
8678    or{l}\t{%k2, %k0|%k0, %k2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "QI,QI,SI")])
8681
8682 (define_insn "*iorqi_1_slp"
8683   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8684         (ior:QI (match_dup 0)
8685                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8689   "or{b}\t{%1, %0|%0, %1}"
8690   [(set_attr "type" "alu1")
8691    (set_attr "mode" "QI")])
8692
8693 (define_insn "*iorqi_2"
8694   [(set (reg FLAGS_REG)
8695         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8696                          (match_operand:QI 2 "general_operand" "qim,qi"))
8697                  (const_int 0)))
8698    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8699         (ior:QI (match_dup 1) (match_dup 2)))]
8700   "ix86_match_ccmode (insn, CCNOmode)
8701    && ix86_binary_operator_ok (IOR, QImode, operands)"
8702   "or{b}\t{%2, %0|%0, %2}"
8703   [(set_attr "type" "alu")
8704    (set_attr "mode" "QI")])
8705
8706 (define_insn "*iorqi_2_slp"
8707   [(set (reg FLAGS_REG)
8708         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8709                          (match_operand:QI 1 "general_operand" "qim,qi"))
8710                  (const_int 0)))
8711    (set (strict_low_part (match_dup 0))
8712         (ior:QI (match_dup 0) (match_dup 1)))]
8713   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8714    && ix86_match_ccmode (insn, CCNOmode)
8715    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8716   "or{b}\t{%1, %0|%0, %1}"
8717   [(set_attr "type" "alu1")
8718    (set_attr "mode" "QI")])
8719
8720 (define_insn "*iorqi_3"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8723                          (match_operand:QI 2 "general_operand" "qim"))
8724                  (const_int 0)))
8725    (clobber (match_scratch:QI 0 "=q"))]
8726   "ix86_match_ccmode (insn, CCNOmode)
8727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8728   "or{b}\t{%2, %0|%0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "mode" "QI")])
8731
8732 (define_insn "iorqi_ext_0"
8733   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734                          (const_int 8)
8735                          (const_int 8))
8736         (ior:SI 
8737           (zero_extract:SI
8738             (match_operand 1 "ext_register_operand" "0")
8739             (const_int 8)
8740             (const_int 8))
8741           (match_operand 2 "const_int_operand" "n")))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744   "or{b}\t{%2, %h0|%h0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "1")
8747    (set_attr "mode" "QI")])
8748
8749 (define_insn "*iorqi_ext_1"
8750   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751                          (const_int 8)
8752                          (const_int 8))
8753         (ior:SI 
8754           (zero_extract:SI
8755             (match_operand 1 "ext_register_operand" "0")
8756             (const_int 8)
8757             (const_int 8))
8758           (zero_extend:SI
8759             (match_operand:QI 2 "general_operand" "Qm"))))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "!TARGET_64BIT
8762    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8763   "or{b}\t{%2, %h0|%h0, %2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "length_immediate" "0")
8766    (set_attr "mode" "QI")])
8767
8768 (define_insn "*iorqi_ext_1_rex64"
8769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770                          (const_int 8)
8771                          (const_int 8))
8772         (ior:SI 
8773           (zero_extract:SI
8774             (match_operand 1 "ext_register_operand" "0")
8775             (const_int 8)
8776             (const_int 8))
8777           (zero_extend:SI
8778             (match_operand 2 "ext_register_operand" "Q"))))
8779    (clobber (reg:CC FLAGS_REG))]
8780   "TARGET_64BIT
8781    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782   "or{b}\t{%2, %h0|%h0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "length_immediate" "0")
8785    (set_attr "mode" "QI")])
8786
8787 (define_insn "*iorqi_ext_2"
8788   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789                          (const_int 8)
8790                          (const_int 8))
8791         (ior:SI 
8792           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8793                            (const_int 8)
8794                            (const_int 8))
8795           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8796                            (const_int 8)
8797                            (const_int 8))))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8800   "ior{b}\t{%h2, %h0|%h0, %h2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "length_immediate" "0")
8803    (set_attr "mode" "QI")])
8804
8805 (define_split
8806   [(set (match_operand 0 "register_operand" "")
8807         (ior (match_operand 1 "register_operand" "")
8808              (match_operand 2 "const_int_operand" "")))
8809    (clobber (reg:CC FLAGS_REG))]
8810    "reload_completed
8811     && QI_REG_P (operands[0])
8812     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8813     && !(INTVAL (operands[2]) & ~(255 << 8))
8814     && GET_MODE (operands[0]) != QImode"
8815   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8816                    (ior:SI (zero_extract:SI (match_dup 1)
8817                                             (const_int 8) (const_int 8))
8818                            (match_dup 2)))
8819               (clobber (reg:CC FLAGS_REG))])]
8820   "operands[0] = gen_lowpart (SImode, operands[0]);
8821    operands[1] = gen_lowpart (SImode, operands[1]);
8822    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8823
8824 ;; Since OR can be encoded with sign extended immediate, this is only
8825 ;; profitable when 7th bit is set.
8826 (define_split
8827   [(set (match_operand 0 "register_operand" "")
8828         (ior (match_operand 1 "general_operand" "")
8829              (match_operand 2 "const_int_operand" "")))
8830    (clobber (reg:CC FLAGS_REG))]
8831    "reload_completed
8832     && ANY_QI_REG_P (operands[0])
8833     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834     && !(INTVAL (operands[2]) & ~255)
8835     && (INTVAL (operands[2]) & 128)
8836     && GET_MODE (operands[0]) != QImode"
8837   [(parallel [(set (strict_low_part (match_dup 0))
8838                    (ior:QI (match_dup 1)
8839                            (match_dup 2)))
8840               (clobber (reg:CC FLAGS_REG))])]
8841   "operands[0] = gen_lowpart (QImode, operands[0]);
8842    operands[1] = gen_lowpart (QImode, operands[1]);
8843    operands[2] = gen_lowpart (QImode, operands[2]);")
8844 \f
8845 ;; Logical XOR instructions
8846
8847 ;; %%% This used to optimize known byte-wide and operations to memory.
8848 ;; If this is considered useful, it should be done with splitters.
8849
8850 (define_expand "xordi3"
8851   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8852         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8853                 (match_operand:DI 2 "x86_64_general_operand" "")))
8854    (clobber (reg:CC FLAGS_REG))]
8855   "TARGET_64BIT"
8856   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8857
8858 (define_insn "*xordi_1_rex64"
8859   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8860         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8861                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8862    (clobber (reg:CC FLAGS_REG))]
8863   "TARGET_64BIT
8864    && ix86_binary_operator_ok (XOR, DImode, operands)"
8865   "@
8866    xor{q}\t{%2, %0|%0, %2}
8867    xor{q}\t{%2, %0|%0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "mode" "DI,DI")])
8870
8871 (define_insn "*xordi_2_rex64"
8872   [(set (reg FLAGS_REG)
8873         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8874                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8875                  (const_int 0)))
8876    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8877         (xor:DI (match_dup 1) (match_dup 2)))]
8878   "TARGET_64BIT
8879    && ix86_match_ccmode (insn, CCNOmode)
8880    && ix86_binary_operator_ok (XOR, DImode, operands)"
8881   "@
8882    xor{q}\t{%2, %0|%0, %2}
8883    xor{q}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "DI,DI")])
8886
8887 (define_insn "*xordi_3_rex64"
8888   [(set (reg FLAGS_REG)
8889         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891                  (const_int 0)))
8892    (clobber (match_scratch:DI 0 "=r"))]
8893   "TARGET_64BIT
8894    && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (XOR, DImode, operands)"
8896   "xor{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900 (define_expand "xorsi3"
8901   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8902         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8903                 (match_operand:SI 2 "general_operand" "")))
8904    (clobber (reg:CC FLAGS_REG))]
8905   ""
8906   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8907
8908 (define_insn "*xorsi_1"
8909   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8910         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8911                 (match_operand:SI 2 "general_operand" "ri,rm")))
8912    (clobber (reg:CC FLAGS_REG))]
8913   "ix86_binary_operator_ok (XOR, SImode, operands)"
8914   "xor{l}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "SI")])
8917
8918 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8919 ;; Add speccase for immediates
8920 (define_insn "*xorsi_1_zext"
8921   [(set (match_operand:DI 0 "register_operand" "=r")
8922         (zero_extend:DI
8923           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924                   (match_operand:SI 2 "general_operand" "rim"))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8927   "xor{l}\t{%2, %k0|%k0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "SI")])
8930
8931 (define_insn "*xorsi_1_zext_imm"
8932   [(set (match_operand:DI 0 "register_operand" "=r")
8933         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8937   "xor{l}\t{%2, %k0|%k0, %2}"
8938   [(set_attr "type" "alu")
8939    (set_attr "mode" "SI")])
8940
8941 (define_insn "*xorsi_2"
8942   [(set (reg FLAGS_REG)
8943         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944                          (match_operand:SI 2 "general_operand" "rim,ri"))
8945                  (const_int 0)))
8946    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947         (xor:SI (match_dup 1) (match_dup 2)))]
8948   "ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (XOR, SImode, operands)"
8950   "xor{l}\t{%2, %0|%0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8953
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*xorsi_2_zext"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959                          (match_operand:SI 2 "general_operand" "rim"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "register_operand" "=r")
8962         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (XOR, SImode, operands)"
8965   "xor{l}\t{%2, %k0|%k0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "SI")])
8968
8969 (define_insn "*xorsi_2_zext_imm"
8970   [(set (reg FLAGS_REG)
8971         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "register_operand" "=r")
8975         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977    && ix86_binary_operator_ok (XOR, SImode, operands)"
8978   "xor{l}\t{%2, %k0|%k0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "SI")])
8981
8982 (define_insn "*xorsi_3"
8983   [(set (reg FLAGS_REG)
8984         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:SI 2 "general_operand" "rim"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:SI 0 "=r"))]
8988   "ix86_match_ccmode (insn, CCNOmode)
8989    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8990   "xor{l}\t{%2, %0|%0, %2}"
8991   [(set_attr "type" "alu")
8992    (set_attr "mode" "SI")])
8993
8994 (define_expand "xorhi3"
8995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997                 (match_operand:HI 2 "general_operand" "")))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "TARGET_HIMODE_MATH"
9000   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9001
9002 (define_insn "*xorhi_1"
9003   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "ix86_binary_operator_ok (XOR, HImode, operands)"
9008   "xor{w}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "HI")])
9011
9012 (define_insn "*xorhi_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015                          (match_operand:HI 2 "general_operand" "rim,ri"))
9016                  (const_int 0)))
9017    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018         (xor:HI (match_dup 1) (match_dup 2)))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && ix86_binary_operator_ok (XOR, HImode, operands)"
9021   "xor{w}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "HI")])
9024
9025 (define_insn "*xorhi_3"
9026   [(set (reg FLAGS_REG)
9027         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028                          (match_operand:HI 2 "general_operand" "rim"))
9029                  (const_int 0)))
9030    (clobber (match_scratch:HI 0 "=r"))]
9031   "ix86_match_ccmode (insn, CCNOmode)
9032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9033   "xor{w}\t{%2, %0|%0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "HI")])
9036
9037 (define_expand "xorqi3"
9038   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040                 (match_operand:QI 2 "general_operand" "")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "TARGET_QIMODE_MATH"
9043   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9044
9045 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9046 (define_insn "*xorqi_1"
9047   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050    (clobber (reg:CC FLAGS_REG))]
9051   "ix86_binary_operator_ok (XOR, QImode, operands)"
9052   "@
9053    xor{b}\t{%2, %0|%0, %2}
9054    xor{b}\t{%2, %0|%0, %2}
9055    xor{l}\t{%k2, %k0|%k0, %k2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "QI,QI,SI")])
9058
9059 (define_insn "*xorqi_1_slp"
9060   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9061         (xor:QI (match_dup 0)
9062                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066   "xor{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9069
9070 (define_insn "xorqi_ext_0"
9071   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9072                          (const_int 8)
9073                          (const_int 8))
9074         (xor:SI 
9075           (zero_extract:SI
9076             (match_operand 1 "ext_register_operand" "0")
9077             (const_int 8)
9078             (const_int 8))
9079           (match_operand 2 "const_int_operand" "n")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082   "xor{b}\t{%2, %h0|%h0, %2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "1")
9085    (set_attr "mode" "QI")])
9086
9087 (define_insn "*xorqi_ext_1"
9088   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089                          (const_int 8)
9090                          (const_int 8))
9091         (xor:SI 
9092           (zero_extract:SI
9093             (match_operand 1 "ext_register_operand" "0")
9094             (const_int 8)
9095             (const_int 8))
9096           (zero_extend:SI
9097             (match_operand:QI 2 "general_operand" "Qm"))))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "!TARGET_64BIT
9100    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9101   "xor{b}\t{%2, %h0|%h0, %2}"
9102   [(set_attr "type" "alu")
9103    (set_attr "length_immediate" "0")
9104    (set_attr "mode" "QI")])
9105
9106 (define_insn "*xorqi_ext_1_rex64"
9107   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108                          (const_int 8)
9109                          (const_int 8))
9110         (xor:SI 
9111           (zero_extract:SI
9112             (match_operand 1 "ext_register_operand" "0")
9113             (const_int 8)
9114             (const_int 8))
9115           (zero_extend:SI
9116             (match_operand 2 "ext_register_operand" "Q"))))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "TARGET_64BIT
9119    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120   "xor{b}\t{%2, %h0|%h0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "length_immediate" "0")
9123    (set_attr "mode" "QI")])
9124
9125 (define_insn "*xorqi_ext_2"
9126   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127                          (const_int 8)
9128                          (const_int 8))
9129         (xor:SI 
9130           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9131                            (const_int 8)
9132                            (const_int 8))
9133           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9134                            (const_int 8)
9135                            (const_int 8))))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138   "xor{b}\t{%h2, %h0|%h0, %h2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "length_immediate" "0")
9141    (set_attr "mode" "QI")])
9142
9143 (define_insn "*xorqi_cc_1"
9144   [(set (reg FLAGS_REG)
9145         (compare
9146           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9147                   (match_operand:QI 2 "general_operand" "qim,qi"))
9148           (const_int 0)))
9149    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9150         (xor:QI (match_dup 1) (match_dup 2)))]
9151   "ix86_match_ccmode (insn, CCNOmode)
9152    && ix86_binary_operator_ok (XOR, QImode, operands)"
9153   "xor{b}\t{%2, %0|%0, %2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "QI")])
9156
9157 (define_insn "*xorqi_2_slp"
9158   [(set (reg FLAGS_REG)
9159         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9160                          (match_operand:QI 1 "general_operand" "qim,qi"))
9161                  (const_int 0)))
9162    (set (strict_low_part (match_dup 0))
9163         (xor:QI (match_dup 0) (match_dup 1)))]
9164   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9165    && ix86_match_ccmode (insn, CCNOmode)
9166    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9167   "xor{b}\t{%1, %0|%0, %1}"
9168   [(set_attr "type" "alu1")
9169    (set_attr "mode" "QI")])
9170
9171 (define_insn "*xorqi_cc_2"
9172   [(set (reg FLAGS_REG)
9173         (compare
9174           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9175                   (match_operand:QI 2 "general_operand" "qim"))
9176           (const_int 0)))
9177    (clobber (match_scratch:QI 0 "=q"))]
9178   "ix86_match_ccmode (insn, CCNOmode)
9179    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180   "xor{b}\t{%2, %0|%0, %2}"
9181   [(set_attr "type" "alu")
9182    (set_attr "mode" "QI")])
9183
9184 (define_insn "*xorqi_cc_ext_1"
9185   [(set (reg FLAGS_REG)
9186         (compare
9187           (xor:SI
9188             (zero_extract:SI
9189               (match_operand 1 "ext_register_operand" "0")
9190               (const_int 8)
9191               (const_int 8))
9192             (match_operand:QI 2 "general_operand" "qmn"))
9193           (const_int 0)))
9194    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI 
9198           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9199           (match_dup 2)))]
9200   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9201   "xor{b}\t{%2, %h0|%h0, %2}"
9202   [(set_attr "type" "alu")
9203    (set_attr "mode" "QI")])
9204
9205 (define_insn "*xorqi_cc_ext_1_rex64"
9206   [(set (reg FLAGS_REG)
9207         (compare
9208           (xor:SI
9209             (zero_extract:SI
9210               (match_operand 1 "ext_register_operand" "0")
9211               (const_int 8)
9212               (const_int 8))
9213             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9214           (const_int 0)))
9215    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216                          (const_int 8)
9217                          (const_int 8))
9218         (xor:SI 
9219           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9220           (match_dup 2)))]
9221   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9222   "xor{b}\t{%2, %h0|%h0, %2}"
9223   [(set_attr "type" "alu")
9224    (set_attr "mode" "QI")])
9225
9226 (define_expand "xorqi_cc_ext_1"
9227   [(parallel [
9228      (set (reg:CCNO FLAGS_REG)
9229           (compare:CCNO
9230             (xor:SI
9231               (zero_extract:SI
9232                 (match_operand 1 "ext_register_operand" "")
9233                 (const_int 8)
9234                 (const_int 8))
9235               (match_operand:QI 2 "general_operand" ""))
9236             (const_int 0)))
9237      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9238                            (const_int 8)
9239                            (const_int 8))
9240           (xor:SI 
9241             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9242             (match_dup 2)))])]
9243   ""
9244   "")
9245
9246 (define_split
9247   [(set (match_operand 0 "register_operand" "")
9248         (xor (match_operand 1 "register_operand" "")
9249              (match_operand 2 "const_int_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251    "reload_completed
9252     && QI_REG_P (operands[0])
9253     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9254     && !(INTVAL (operands[2]) & ~(255 << 8))
9255     && GET_MODE (operands[0]) != QImode"
9256   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9257                    (xor:SI (zero_extract:SI (match_dup 1)
9258                                             (const_int 8) (const_int 8))
9259                            (match_dup 2)))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   "operands[0] = gen_lowpart (SImode, operands[0]);
9262    operands[1] = gen_lowpart (SImode, operands[1]);
9263    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9264
9265 ;; Since XOR can be encoded with sign extended immediate, this is only
9266 ;; profitable when 7th bit is set.
9267 (define_split
9268   [(set (match_operand 0 "register_operand" "")
9269         (xor (match_operand 1 "general_operand" "")
9270              (match_operand 2 "const_int_operand" "")))
9271    (clobber (reg:CC FLAGS_REG))]
9272    "reload_completed
9273     && ANY_QI_REG_P (operands[0])
9274     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9275     && !(INTVAL (operands[2]) & ~255)
9276     && (INTVAL (operands[2]) & 128)
9277     && GET_MODE (operands[0]) != QImode"
9278   [(parallel [(set (strict_low_part (match_dup 0))
9279                    (xor:QI (match_dup 1)
9280                            (match_dup 2)))
9281               (clobber (reg:CC FLAGS_REG))])]
9282   "operands[0] = gen_lowpart (QImode, operands[0]);
9283    operands[1] = gen_lowpart (QImode, operands[1]);
9284    operands[2] = gen_lowpart (QImode, operands[2]);")
9285 \f
9286 ;; Negation instructions
9287
9288 (define_expand "negti2"
9289   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9290                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9291               (clobber (reg:CC FLAGS_REG))])]
9292   "TARGET_64BIT"
9293   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9294
9295 (define_insn "*negti2_1"
9296   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9297         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9298    (clobber (reg:CC FLAGS_REG))]
9299   "TARGET_64BIT
9300    && ix86_unary_operator_ok (NEG, TImode, operands)"
9301   "#")
9302
9303 (define_split
9304   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9305         (neg:TI (match_operand:TI 1 "general_operand" "")))
9306    (clobber (reg:CC FLAGS_REG))]
9307   "TARGET_64BIT && reload_completed"
9308   [(parallel
9309     [(set (reg:CCZ FLAGS_REG)
9310           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9311      (set (match_dup 0) (neg:DI (match_dup 2)))])
9312    (parallel
9313     [(set (match_dup 1)
9314           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9315                             (match_dup 3))
9316                    (const_int 0)))
9317      (clobber (reg:CC FLAGS_REG))])
9318    (parallel
9319     [(set (match_dup 1)
9320           (neg:DI (match_dup 1)))
9321      (clobber (reg:CC FLAGS_REG))])]
9322   "split_ti (operands+1, 1, operands+2, operands+3);
9323    split_ti (operands+0, 1, operands+0, operands+1);")
9324
9325 (define_expand "negdi2"
9326   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9327                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9328               (clobber (reg:CC FLAGS_REG))])]
9329   ""
9330   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9331
9332 (define_insn "*negdi2_1"
9333   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9334         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "!TARGET_64BIT
9337    && ix86_unary_operator_ok (NEG, DImode, operands)"
9338   "#")
9339
9340 (define_split
9341   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9342         (neg:DI (match_operand:DI 1 "general_operand" "")))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "!TARGET_64BIT && reload_completed"
9345   [(parallel
9346     [(set (reg:CCZ FLAGS_REG)
9347           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9348      (set (match_dup 0) (neg:SI (match_dup 2)))])
9349    (parallel
9350     [(set (match_dup 1)
9351           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9352                             (match_dup 3))
9353                    (const_int 0)))
9354      (clobber (reg:CC FLAGS_REG))])
9355    (parallel
9356     [(set (match_dup 1)
9357           (neg:SI (match_dup 1)))
9358      (clobber (reg:CC FLAGS_REG))])]
9359   "split_di (operands+1, 1, operands+2, operands+3);
9360    split_di (operands+0, 1, operands+0, operands+1);")
9361
9362 (define_insn "*negdi2_1_rex64"
9363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9364         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9365    (clobber (reg:CC FLAGS_REG))]
9366   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9367   "neg{q}\t%0"
9368   [(set_attr "type" "negnot")
9369    (set_attr "mode" "DI")])
9370
9371 ;; The problem with neg is that it does not perform (compare x 0),
9372 ;; it really performs (compare 0 x), which leaves us with the zero
9373 ;; flag being the only useful item.
9374
9375 (define_insn "*negdi2_cmpz_rex64"
9376   [(set (reg:CCZ FLAGS_REG)
9377         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9378                      (const_int 0)))
9379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9380         (neg:DI (match_dup 1)))]
9381   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9382   "neg{q}\t%0"
9383   [(set_attr "type" "negnot")
9384    (set_attr "mode" "DI")])
9385
9386
9387 (define_expand "negsi2"
9388   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9389                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9390               (clobber (reg:CC FLAGS_REG))])]
9391   ""
9392   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9393
9394 (define_insn "*negsi2_1"
9395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9396         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "ix86_unary_operator_ok (NEG, SImode, operands)"
9399   "neg{l}\t%0"
9400   [(set_attr "type" "negnot")
9401    (set_attr "mode" "SI")])
9402
9403 ;; Combine is quite creative about this pattern.
9404 (define_insn "*negsi2_1_zext"
9405   [(set (match_operand:DI 0 "register_operand" "=r")
9406         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9407                                         (const_int 32)))
9408                      (const_int 32)))
9409    (clobber (reg:CC FLAGS_REG))]
9410   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9411   "neg{l}\t%k0"
9412   [(set_attr "type" "negnot")
9413    (set_attr "mode" "SI")])
9414
9415 ;; The problem with neg is that it does not perform (compare x 0),
9416 ;; it really performs (compare 0 x), which leaves us with the zero
9417 ;; flag being the only useful item.
9418
9419 (define_insn "*negsi2_cmpz"
9420   [(set (reg:CCZ FLAGS_REG)
9421         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9422                      (const_int 0)))
9423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9424         (neg:SI (match_dup 1)))]
9425   "ix86_unary_operator_ok (NEG, SImode, operands)"
9426   "neg{l}\t%0"
9427   [(set_attr "type" "negnot")
9428    (set_attr "mode" "SI")])
9429
9430 (define_insn "*negsi2_cmpz_zext"
9431   [(set (reg:CCZ FLAGS_REG)
9432         (compare:CCZ (lshiftrt:DI
9433                        (neg:DI (ashift:DI
9434                                  (match_operand:DI 1 "register_operand" "0")
9435                                  (const_int 32)))
9436                        (const_int 32))
9437                      (const_int 0)))
9438    (set (match_operand:DI 0 "register_operand" "=r")
9439         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9440                                         (const_int 32)))
9441                      (const_int 32)))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443   "neg{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9446
9447 (define_expand "neghi2"
9448   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9449                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9450               (clobber (reg:CC FLAGS_REG))])]
9451   "TARGET_HIMODE_MATH"
9452   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9453
9454 (define_insn "*neghi2_1"
9455   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9456         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "ix86_unary_operator_ok (NEG, HImode, operands)"
9459   "neg{w}\t%0"
9460   [(set_attr "type" "negnot")
9461    (set_attr "mode" "HI")])
9462
9463 (define_insn "*neghi2_cmpz"
9464   [(set (reg:CCZ FLAGS_REG)
9465         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9466                      (const_int 0)))
9467    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9468         (neg:HI (match_dup 1)))]
9469   "ix86_unary_operator_ok (NEG, HImode, operands)"
9470   "neg{w}\t%0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "HI")])
9473
9474 (define_expand "negqi2"
9475   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9476                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9477               (clobber (reg:CC FLAGS_REG))])]
9478   "TARGET_QIMODE_MATH"
9479   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9480
9481 (define_insn "*negqi2_1"
9482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9483         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "ix86_unary_operator_ok (NEG, QImode, operands)"
9486   "neg{b}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "QI")])
9489
9490 (define_insn "*negqi2_cmpz"
9491   [(set (reg:CCZ FLAGS_REG)
9492         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9493                      (const_int 0)))
9494    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9495         (neg:QI (match_dup 1)))]
9496   "ix86_unary_operator_ok (NEG, QImode, operands)"
9497   "neg{b}\t%0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "QI")])
9500
9501 ;; Changing of sign for FP values is doable using integer unit too.
9502
9503 (define_expand "negsf2"
9504   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9505         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9506   "TARGET_80387 || TARGET_SSE_MATH"
9507   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9508
9509 (define_expand "abssf2"
9510   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9511         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9512   "TARGET_80387 || TARGET_SSE_MATH"
9513   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9514
9515 (define_insn "*absnegsf2_mixed"
9516   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9517         (match_operator:SF 3 "absneg_operator"
9518           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9519    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9520    (clobber (reg:CC FLAGS_REG))]
9521   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9522    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9523   "#")
9524
9525 (define_insn "*absnegsf2_sse"
9526   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9527         (match_operator:SF 3 "absneg_operator"
9528           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9529    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9530    (clobber (reg:CC FLAGS_REG))]
9531   "TARGET_SSE_MATH
9532    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9533   "#")
9534
9535 (define_insn "*absnegsf2_i387"
9536   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9537         (match_operator:SF 3 "absneg_operator"
9538           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9539    (use (match_operand 2 "" ""))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "TARGET_80387 && !TARGET_SSE_MATH
9542    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9543   "#")
9544
9545 (define_expand "copysignsf3"
9546   [(match_operand:SF 0 "register_operand" "")
9547    (match_operand:SF 1 "nonmemory_operand" "")
9548    (match_operand:SF 2 "register_operand" "")]
9549   "TARGET_SSE_MATH"
9550 {
9551   ix86_expand_copysign (operands);
9552   DONE;
9553 })
9554
9555 (define_insn_and_split "copysignsf3_const"
9556   [(set (match_operand:SF 0 "register_operand"          "=x")
9557         (unspec:SF
9558           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9559            (match_operand:SF 2 "register_operand"       "0")
9560            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9561           UNSPEC_COPYSIGN))]
9562   "TARGET_SSE_MATH"
9563   "#"
9564   "&& reload_completed"
9565   [(const_int 0)]
9566 {
9567   ix86_split_copysign_const (operands);
9568   DONE;
9569 })
9570
9571 (define_insn "copysignsf3_var"
9572   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9573         (unspec:SF
9574           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9575            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9576            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9577            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9578           UNSPEC_COPYSIGN))
9579    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9580   "TARGET_SSE_MATH"
9581   "#")
9582
9583 (define_split
9584   [(set (match_operand:SF 0 "register_operand" "")
9585         (unspec:SF
9586           [(match_operand:SF 2 "register_operand" "")
9587            (match_operand:SF 3 "register_operand" "")
9588            (match_operand:V4SF 4 "" "")
9589            (match_operand:V4SF 5 "" "")]
9590           UNSPEC_COPYSIGN))
9591    (clobber (match_scratch:V4SF 1 ""))]
9592   "TARGET_SSE_MATH && reload_completed"
9593   [(const_int 0)]
9594 {
9595   ix86_split_copysign_var (operands);
9596   DONE;
9597 })
9598
9599 (define_expand "negdf2"
9600   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9601         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9602   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9603   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9604
9605 (define_expand "absdf2"
9606   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9607         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9608   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9609   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9610
9611 (define_insn "*absnegdf2_mixed"
9612   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9613         (match_operator:DF 3 "absneg_operator"
9614           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9615    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9618    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9619   "#")
9620
9621 (define_insn "*absnegdf2_sse"
9622   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9623         (match_operator:DF 3 "absneg_operator"
9624           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9625    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_SSE2 && TARGET_SSE_MATH
9628    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9629   "#")
9630
9631 (define_insn "*absnegdf2_i387"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9633         (match_operator:DF 3 "absneg_operator"
9634           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9635    (use (match_operand 2 "" ""))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9638    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9639   "#")
9640
9641 (define_expand "copysigndf3"
9642   [(match_operand:DF 0 "register_operand" "")
9643    (match_operand:DF 1 "nonmemory_operand" "")
9644    (match_operand:DF 2 "register_operand" "")]
9645   "TARGET_SSE2 && TARGET_SSE_MATH"
9646 {
9647   ix86_expand_copysign (operands);
9648   DONE;
9649 })
9650
9651 (define_insn_and_split "copysigndf3_const"
9652   [(set (match_operand:DF 0 "register_operand"          "=x")
9653         (unspec:DF
9654           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9655            (match_operand:DF 2 "register_operand"       "0")
9656            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9657           UNSPEC_COPYSIGN))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH"
9659   "#"
9660   "&& reload_completed"
9661   [(const_int 0)]
9662 {
9663   ix86_split_copysign_const (operands);
9664   DONE;
9665 })
9666
9667 (define_insn "copysigndf3_var"
9668   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9669         (unspec:DF
9670           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9671            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9672            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9673            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9674           UNSPEC_COPYSIGN))
9675    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9676   "TARGET_SSE2 && TARGET_SSE_MATH"
9677   "#")
9678
9679 (define_split
9680   [(set (match_operand:DF 0 "register_operand" "")
9681         (unspec:DF
9682           [(match_operand:DF 2 "register_operand" "")
9683            (match_operand:DF 3 "register_operand" "")
9684            (match_operand:V2DF 4 "" "")
9685            (match_operand:V2DF 5 "" "")]
9686           UNSPEC_COPYSIGN))
9687    (clobber (match_scratch:V2DF 1 ""))]
9688   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9689   [(const_int 0)]
9690 {
9691   ix86_split_copysign_var (operands);
9692   DONE;
9693 })
9694
9695 (define_expand "negxf2"
9696   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9697         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9698   "TARGET_80387"
9699   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9700
9701 (define_expand "absxf2"
9702   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9703         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9704   "TARGET_80387"
9705   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9706
9707 (define_insn "*absnegxf2_i387"
9708   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9709         (match_operator:XF 3 "absneg_operator"
9710           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9711    (use (match_operand 2 "" ""))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "TARGET_80387
9714    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9715   "#")
9716
9717 ;; Splitters for fp abs and neg.
9718
9719 (define_split
9720   [(set (match_operand 0 "fp_register_operand" "")
9721         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed"
9725   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9726
9727 (define_split
9728   [(set (match_operand 0 "register_operand" "")
9729         (match_operator 3 "absneg_operator"
9730           [(match_operand 1 "register_operand" "")]))
9731    (use (match_operand 2 "nonimmediate_operand" ""))
9732    (clobber (reg:CC FLAGS_REG))]
9733   "reload_completed && SSE_REG_P (operands[0])"
9734   [(set (match_dup 0) (match_dup 3))]
9735 {
9736   enum machine_mode mode = GET_MODE (operands[0]);
9737   enum machine_mode vmode = GET_MODE (operands[2]);
9738   rtx tmp;
9739   
9740   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9741   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9742   if (operands_match_p (operands[0], operands[2]))
9743     {
9744       tmp = operands[1];
9745       operands[1] = operands[2];
9746       operands[2] = tmp;
9747     }
9748   if (GET_CODE (operands[3]) == ABS)
9749     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9750   else
9751     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9752   operands[3] = tmp;
9753 })
9754
9755 (define_split
9756   [(set (match_operand:SF 0 "register_operand" "")
9757         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9758    (use (match_operand:V4SF 2 "" ""))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "reload_completed"
9761   [(parallel [(set (match_dup 0) (match_dup 1))
9762               (clobber (reg:CC FLAGS_REG))])]
9763
9764   rtx tmp;
9765   operands[0] = gen_lowpart (SImode, operands[0]);
9766   if (GET_CODE (operands[1]) == ABS)
9767     {
9768       tmp = gen_int_mode (0x7fffffff, SImode);
9769       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770     }
9771   else
9772     {
9773       tmp = gen_int_mode (0x80000000, SImode);
9774       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9775     }
9776   operands[1] = tmp;
9777 })
9778
9779 (define_split
9780   [(set (match_operand:DF 0 "register_operand" "")
9781         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9782    (use (match_operand 2 "" ""))
9783    (clobber (reg:CC FLAGS_REG))]
9784   "reload_completed"
9785   [(parallel [(set (match_dup 0) (match_dup 1))
9786               (clobber (reg:CC FLAGS_REG))])]
9787 {
9788   rtx tmp;
9789   if (TARGET_64BIT)
9790     {
9791       tmp = gen_lowpart (DImode, operands[0]);
9792       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9793       operands[0] = tmp;
9794
9795       if (GET_CODE (operands[1]) == ABS)
9796         tmp = const0_rtx;
9797       else
9798         tmp = gen_rtx_NOT (DImode, tmp);
9799     }
9800   else
9801     {
9802       operands[0] = gen_highpart (SImode, operands[0]);
9803       if (GET_CODE (operands[1]) == ABS)
9804         {
9805           tmp = gen_int_mode (0x7fffffff, SImode);
9806           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9807         }
9808       else
9809         {
9810           tmp = gen_int_mode (0x80000000, SImode);
9811           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9812         }
9813     }
9814   operands[1] = tmp;
9815 })
9816
9817 (define_split
9818   [(set (match_operand:XF 0 "register_operand" "")
9819         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9820    (use (match_operand 2 "" ""))
9821    (clobber (reg:CC FLAGS_REG))]
9822   "reload_completed"
9823   [(parallel [(set (match_dup 0) (match_dup 1))
9824               (clobber (reg:CC FLAGS_REG))])]
9825 {
9826   rtx tmp;
9827   operands[0] = gen_rtx_REG (SImode,
9828                              true_regnum (operands[0])
9829                              + (TARGET_64BIT ? 1 : 2));
9830   if (GET_CODE (operands[1]) == ABS)
9831     {
9832       tmp = GEN_INT (0x7fff);
9833       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834     }
9835   else
9836     {
9837       tmp = GEN_INT (0x8000);
9838       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9839     }
9840   operands[1] = tmp;
9841 })
9842
9843 (define_split
9844   [(set (match_operand 0 "memory_operand" "")
9845         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9846    (use (match_operand 2 "" ""))
9847    (clobber (reg:CC FLAGS_REG))]
9848   "reload_completed"
9849   [(parallel [(set (match_dup 0) (match_dup 1))
9850               (clobber (reg:CC FLAGS_REG))])]
9851 {
9852   enum machine_mode mode = GET_MODE (operands[0]);
9853   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9854   rtx tmp;
9855
9856   operands[0] = adjust_address (operands[0], QImode, size - 1);
9857   if (GET_CODE (operands[1]) == ABS)
9858     {
9859       tmp = gen_int_mode (0x7f, QImode);
9860       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9861     }
9862   else
9863     {
9864       tmp = gen_int_mode (0x80, QImode);
9865       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9866     }
9867   operands[1] = tmp;
9868 })
9869
9870 ;; Conditionalize these after reload. If they match before reload, we 
9871 ;; lose the clobber and ability to use integer instructions.
9872
9873 (define_insn "*negsf2_1"
9874   [(set (match_operand:SF 0 "register_operand" "=f")
9875         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9876   "TARGET_80387 && reload_completed"
9877   "fchs"
9878   [(set_attr "type" "fsgn")
9879    (set_attr "mode" "SF")])
9880
9881 (define_insn "*negdf2_1"
9882   [(set (match_operand:DF 0 "register_operand" "=f")
9883         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9884   "TARGET_80387 && reload_completed"
9885   "fchs"
9886   [(set_attr "type" "fsgn")
9887    (set_attr "mode" "DF")])
9888
9889 (define_insn "*negxf2_1"
9890   [(set (match_operand:XF 0 "register_operand" "=f")
9891         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9892   "TARGET_80387 && reload_completed"
9893   "fchs"
9894   [(set_attr "type" "fsgn")
9895    (set_attr "mode" "XF")])
9896
9897 (define_insn "*abssf2_1"
9898   [(set (match_operand:SF 0 "register_operand" "=f")
9899         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9900   "TARGET_80387 && reload_completed"
9901   "fabs"
9902   [(set_attr "type" "fsgn")
9903    (set_attr "mode" "SF")])
9904
9905 (define_insn "*absdf2_1"
9906   [(set (match_operand:DF 0 "register_operand" "=f")
9907         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9908   "TARGET_80387 && reload_completed"
9909   "fabs"
9910   [(set_attr "type" "fsgn")
9911    (set_attr "mode" "DF")])
9912
9913 (define_insn "*absxf2_1"
9914   [(set (match_operand:XF 0 "register_operand" "=f")
9915         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9916   "TARGET_80387 && reload_completed"
9917   "fabs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "DF")])
9920
9921 (define_insn "*negextendsfdf2"
9922   [(set (match_operand:DF 0 "register_operand" "=f")
9923         (neg:DF (float_extend:DF
9924                   (match_operand:SF 1 "register_operand" "0"))))]
9925   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9926   "fchs"
9927   [(set_attr "type" "fsgn")
9928    (set_attr "mode" "DF")])
9929
9930 (define_insn "*negextenddfxf2"
9931   [(set (match_operand:XF 0 "register_operand" "=f")
9932         (neg:XF (float_extend:XF
9933                   (match_operand:DF 1 "register_operand" "0"))))]
9934   "TARGET_80387"
9935   "fchs"
9936   [(set_attr "type" "fsgn")
9937    (set_attr "mode" "XF")])
9938
9939 (define_insn "*negextendsfxf2"
9940   [(set (match_operand:XF 0 "register_operand" "=f")
9941         (neg:XF (float_extend:XF
9942                   (match_operand:SF 1 "register_operand" "0"))))]
9943   "TARGET_80387"
9944   "fchs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "XF")])
9947
9948 (define_insn "*absextendsfdf2"
9949   [(set (match_operand:DF 0 "register_operand" "=f")
9950         (abs:DF (float_extend:DF
9951                   (match_operand:SF 1 "register_operand" "0"))))]
9952   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9953   "fabs"
9954   [(set_attr "type" "fsgn")
9955    (set_attr "mode" "DF")])
9956
9957 (define_insn "*absextenddfxf2"
9958   [(set (match_operand:XF 0 "register_operand" "=f")
9959         (abs:XF (float_extend:XF
9960           (match_operand:DF 1 "register_operand" "0"))))]
9961   "TARGET_80387"
9962   "fabs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")])
9965
9966 (define_insn "*absextendsfxf2"
9967   [(set (match_operand:XF 0 "register_operand" "=f")
9968         (abs:XF (float_extend:XF
9969           (match_operand:SF 1 "register_operand" "0"))))]
9970   "TARGET_80387"
9971   "fabs"
9972   [(set_attr "type" "fsgn")
9973    (set_attr "mode" "XF")])
9974 \f
9975 ;; One complement instructions
9976
9977 (define_expand "one_cmpldi2"
9978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9979         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9980   "TARGET_64BIT"
9981   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9982
9983 (define_insn "*one_cmpldi2_1_rex64"
9984   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9985         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9986   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9987   "not{q}\t%0"
9988   [(set_attr "type" "negnot")
9989    (set_attr "mode" "DI")])
9990
9991 (define_insn "*one_cmpldi2_2_rex64"
9992   [(set (reg FLAGS_REG)
9993         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9994                  (const_int 0)))
9995    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9996         (not:DI (match_dup 1)))]
9997   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9998    && ix86_unary_operator_ok (NOT, DImode, operands)"
9999   "#"
10000   [(set_attr "type" "alu1")
10001    (set_attr "mode" "DI")])
10002
10003 (define_split
10004   [(set (match_operand 0 "flags_reg_operand" "")
10005         (match_operator 2 "compare_operator"
10006           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10007            (const_int 0)]))
10008    (set (match_operand:DI 1 "nonimmediate_operand" "")
10009         (not:DI (match_dup 3)))]
10010   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10011   [(parallel [(set (match_dup 0)
10012                    (match_op_dup 2
10013                      [(xor:DI (match_dup 3) (const_int -1))
10014                       (const_int 0)]))
10015               (set (match_dup 1)
10016                    (xor:DI (match_dup 3) (const_int -1)))])]
10017   "")
10018
10019 (define_expand "one_cmplsi2"
10020   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10021         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10022   ""
10023   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10024
10025 (define_insn "*one_cmplsi2_1"
10026   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10027         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10028   "ix86_unary_operator_ok (NOT, SImode, operands)"
10029   "not{l}\t%0"
10030   [(set_attr "type" "negnot")
10031    (set_attr "mode" "SI")])
10032
10033 ;; ??? Currently never generated - xor is used instead.
10034 (define_insn "*one_cmplsi2_1_zext"
10035   [(set (match_operand:DI 0 "register_operand" "=r")
10036         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10037   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10038   "not{l}\t%k0"
10039   [(set_attr "type" "negnot")
10040    (set_attr "mode" "SI")])
10041
10042 (define_insn "*one_cmplsi2_2"
10043   [(set (reg FLAGS_REG)
10044         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10045                  (const_int 0)))
10046    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10047         (not:SI (match_dup 1)))]
10048   "ix86_match_ccmode (insn, CCNOmode)
10049    && ix86_unary_operator_ok (NOT, SImode, operands)"
10050   "#"
10051   [(set_attr "type" "alu1")
10052    (set_attr "mode" "SI")])
10053
10054 (define_split
10055   [(set (match_operand 0 "flags_reg_operand" "")
10056         (match_operator 2 "compare_operator"
10057           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10058            (const_int 0)]))
10059    (set (match_operand:SI 1 "nonimmediate_operand" "")
10060         (not:SI (match_dup 3)))]
10061   "ix86_match_ccmode (insn, CCNOmode)"
10062   [(parallel [(set (match_dup 0)
10063                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10064                                     (const_int 0)]))
10065               (set (match_dup 1)
10066                    (xor:SI (match_dup 3) (const_int -1)))])]
10067   "")
10068
10069 ;; ??? Currently never generated - xor is used instead.
10070 (define_insn "*one_cmplsi2_2_zext"
10071   [(set (reg FLAGS_REG)
10072         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10073                  (const_int 0)))
10074    (set (match_operand:DI 0 "register_operand" "=r")
10075         (zero_extend:DI (not:SI (match_dup 1))))]
10076   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10077    && ix86_unary_operator_ok (NOT, SImode, operands)"
10078   "#"
10079   [(set_attr "type" "alu1")
10080    (set_attr "mode" "SI")])
10081
10082 (define_split
10083   [(set (match_operand 0 "flags_reg_operand" "")
10084         (match_operator 2 "compare_operator"
10085           [(not:SI (match_operand:SI 3 "register_operand" ""))
10086            (const_int 0)]))
10087    (set (match_operand:DI 1 "register_operand" "")
10088         (zero_extend:DI (not:SI (match_dup 3))))]
10089   "ix86_match_ccmode (insn, CCNOmode)"
10090   [(parallel [(set (match_dup 0)
10091                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10092                                     (const_int 0)]))
10093               (set (match_dup 1)
10094                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10095   "")
10096
10097 (define_expand "one_cmplhi2"
10098   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10099         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10100   "TARGET_HIMODE_MATH"
10101   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10102
10103 (define_insn "*one_cmplhi2_1"
10104   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10105         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10106   "ix86_unary_operator_ok (NOT, HImode, operands)"
10107   "not{w}\t%0"
10108   [(set_attr "type" "negnot")
10109    (set_attr "mode" "HI")])
10110
10111 (define_insn "*one_cmplhi2_2"
10112   [(set (reg FLAGS_REG)
10113         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10114                  (const_int 0)))
10115    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10116         (not:HI (match_dup 1)))]
10117   "ix86_match_ccmode (insn, CCNOmode)
10118    && ix86_unary_operator_ok (NEG, HImode, operands)"
10119   "#"
10120   [(set_attr "type" "alu1")
10121    (set_attr "mode" "HI")])
10122
10123 (define_split
10124   [(set (match_operand 0 "flags_reg_operand" "")
10125         (match_operator 2 "compare_operator"
10126           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10127            (const_int 0)]))
10128    (set (match_operand:HI 1 "nonimmediate_operand" "")
10129         (not:HI (match_dup 3)))]
10130   "ix86_match_ccmode (insn, CCNOmode)"
10131   [(parallel [(set (match_dup 0)
10132                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10133                                     (const_int 0)]))
10134               (set (match_dup 1)
10135                    (xor:HI (match_dup 3) (const_int -1)))])]
10136   "")
10137
10138 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10139 (define_expand "one_cmplqi2"
10140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10141         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10142   "TARGET_QIMODE_MATH"
10143   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10144
10145 (define_insn "*one_cmplqi2_1"
10146   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10147         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10148   "ix86_unary_operator_ok (NOT, QImode, operands)"
10149   "@
10150    not{b}\t%0
10151    not{l}\t%k0"
10152   [(set_attr "type" "negnot")
10153    (set_attr "mode" "QI,SI")])
10154
10155 (define_insn "*one_cmplqi2_2"
10156   [(set (reg FLAGS_REG)
10157         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10158                  (const_int 0)))
10159    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10160         (not:QI (match_dup 1)))]
10161   "ix86_match_ccmode (insn, CCNOmode)
10162    && ix86_unary_operator_ok (NOT, QImode, operands)"
10163   "#"
10164   [(set_attr "type" "alu1")
10165    (set_attr "mode" "QI")])
10166
10167 (define_split
10168   [(set (match_operand 0 "flags_reg_operand" "")
10169         (match_operator 2 "compare_operator"
10170           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10171            (const_int 0)]))
10172    (set (match_operand:QI 1 "nonimmediate_operand" "")
10173         (not:QI (match_dup 3)))]
10174   "ix86_match_ccmode (insn, CCNOmode)"
10175   [(parallel [(set (match_dup 0)
10176                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10177                                     (const_int 0)]))
10178               (set (match_dup 1)
10179                    (xor:QI (match_dup 3) (const_int -1)))])]
10180   "")
10181 \f
10182 ;; Arithmetic shift instructions
10183
10184 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10185 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10186 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10187 ;; from the assembler input.
10188 ;;
10189 ;; This instruction shifts the target reg/mem as usual, but instead of
10190 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10191 ;; is a left shift double, bits are taken from the high order bits of
10192 ;; reg, else if the insn is a shift right double, bits are taken from the
10193 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10194 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10195 ;;
10196 ;; Since sh[lr]d does not change the `reg' operand, that is done
10197 ;; separately, making all shifts emit pairs of shift double and normal
10198 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10199 ;; support a 63 bit shift, each shift where the count is in a reg expands
10200 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10201 ;;
10202 ;; If the shift count is a constant, we need never emit more than one
10203 ;; shift pair, instead using moves and sign extension for counts greater
10204 ;; than 31.
10205
10206 (define_expand "ashlti3"
10207   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10208                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10209                               (match_operand:QI 2 "nonmemory_operand" "")))
10210               (clobber (reg:CC FLAGS_REG))])]
10211   "TARGET_64BIT"
10212 {
10213   if (! immediate_operand (operands[2], QImode))
10214     {
10215       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10216       DONE;
10217     }
10218   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10219   DONE;
10220 })
10221
10222 (define_insn "ashlti3_1"
10223   [(set (match_operand:TI 0 "register_operand" "=r")
10224         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10225                    (match_operand:QI 2 "register_operand" "c")))
10226    (clobber (match_scratch:DI 3 "=&r"))
10227    (clobber (reg:CC FLAGS_REG))]
10228   "TARGET_64BIT"
10229   "#"
10230   [(set_attr "type" "multi")])
10231
10232 (define_insn "*ashlti3_2"
10233   [(set (match_operand:TI 0 "register_operand" "=r")
10234         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10235                    (match_operand:QI 2 "immediate_operand" "O")))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "TARGET_64BIT"
10238   "#"
10239   [(set_attr "type" "multi")])
10240
10241 (define_split
10242   [(set (match_operand:TI 0 "register_operand" "")
10243         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10244                    (match_operand:QI 2 "register_operand" "")))
10245    (clobber (match_scratch:DI 3 ""))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "TARGET_64BIT && reload_completed"
10248   [(const_int 0)]
10249   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10250
10251 (define_split
10252   [(set (match_operand:TI 0 "register_operand" "")
10253         (ashift:TI (match_operand:TI 1 "register_operand" "")
10254                    (match_operand:QI 2 "immediate_operand" "")))
10255    (clobber (reg:CC FLAGS_REG))]
10256   "TARGET_64BIT && reload_completed"
10257   [(const_int 0)]
10258   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10259
10260 (define_insn "x86_64_shld"
10261   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10262         (ior:DI (ashift:DI (match_dup 0)
10263                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10264                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10265                   (minus:QI (const_int 64) (match_dup 2)))))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "@
10269    shld{q}\t{%2, %1, %0|%0, %1, %2}
10270    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10271   [(set_attr "type" "ishift")
10272    (set_attr "prefix_0f" "1")
10273    (set_attr "mode" "DI")
10274    (set_attr "athlon_decode" "vector")])
10275
10276 (define_expand "x86_64_shift_adj"
10277   [(set (reg:CCZ FLAGS_REG)
10278         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10279                              (const_int 64))
10280                      (const_int 0)))
10281    (set (match_operand:DI 0 "register_operand" "")
10282         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10283                          (match_operand:DI 1 "register_operand" "")
10284                          (match_dup 0)))
10285    (set (match_dup 1)
10286         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10287                          (match_operand:DI 3 "register_operand" "r")
10288                          (match_dup 1)))]
10289   "TARGET_64BIT"
10290   "")
10291
10292 (define_expand "ashldi3"
10293   [(set (match_operand:DI 0 "shiftdi_operand" "")
10294         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10295                    (match_operand:QI 2 "nonmemory_operand" "")))]
10296   ""
10297   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10298
10299 (define_insn "*ashldi3_1_rex64"
10300   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10301         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10302                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10305 {
10306   switch (get_attr_type (insn))
10307     {
10308     case TYPE_ALU:
10309       gcc_assert (operands[2] == const1_rtx);
10310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10311       return "add{q}\t{%0, %0|%0, %0}";
10312
10313     case TYPE_LEA:
10314       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10315       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10316       operands[1] = gen_rtx_MULT (DImode, operands[1],
10317                                   GEN_INT (1 << INTVAL (operands[2])));
10318       return "lea{q}\t{%a1, %0|%0, %a1}";
10319
10320     default:
10321       if (REG_P (operands[2]))
10322         return "sal{q}\t{%b2, %0|%0, %b2}";
10323       else if (operands[2] == const1_rtx
10324                && (TARGET_SHIFT1 || optimize_size))
10325         return "sal{q}\t%0";
10326       else
10327         return "sal{q}\t{%2, %0|%0, %2}";
10328     }
10329 }
10330   [(set (attr "type")
10331      (cond [(eq_attr "alternative" "1")
10332               (const_string "lea")
10333             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10334                           (const_int 0))
10335                       (match_operand 0 "register_operand" ""))
10336                  (match_operand 2 "const1_operand" ""))
10337               (const_string "alu")
10338            ]
10339            (const_string "ishift")))
10340    (set_attr "mode" "DI")])
10341
10342 ;; Convert lea to the lea pattern to avoid flags dependency.
10343 (define_split
10344   [(set (match_operand:DI 0 "register_operand" "")
10345         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10346                    (match_operand:QI 2 "immediate_operand" "")))
10347    (clobber (reg:CC FLAGS_REG))]
10348   "TARGET_64BIT && reload_completed
10349    && true_regnum (operands[0]) != true_regnum (operands[1])"
10350   [(set (match_dup 0)
10351         (mult:DI (match_dup 1)
10352                  (match_dup 2)))]
10353   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10354
10355 ;; This pattern can't accept a variable shift count, since shifts by
10356 ;; zero don't affect the flags.  We assume that shifts by constant
10357 ;; zero are optimized away.
10358 (define_insn "*ashldi3_cmp_rex64"
10359   [(set (reg FLAGS_REG)
10360         (compare
10361           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10362                      (match_operand:QI 2 "immediate_operand" "e"))
10363           (const_int 0)))
10364    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10365         (ashift:DI (match_dup 1) (match_dup 2)))]
10366   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10367    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10368 {
10369   switch (get_attr_type (insn))
10370     {
10371     case TYPE_ALU:
10372       gcc_assert (operands[2] == const1_rtx);
10373       return "add{q}\t{%0, %0|%0, %0}";
10374
10375     default:
10376       if (REG_P (operands[2]))
10377         return "sal{q}\t{%b2, %0|%0, %b2}";
10378       else if (operands[2] == const1_rtx
10379                && (TARGET_SHIFT1 || optimize_size))
10380         return "sal{q}\t%0";
10381       else
10382         return "sal{q}\t{%2, %0|%0, %2}";
10383     }
10384 }
10385   [(set (attr "type")
10386      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387                           (const_int 0))
10388                       (match_operand 0 "register_operand" ""))
10389                  (match_operand 2 "const1_operand" ""))
10390               (const_string "alu")
10391            ]
10392            (const_string "ishift")))
10393    (set_attr "mode" "DI")])
10394
10395 (define_insn "*ashldi3_1"
10396   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10397         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10398                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "!TARGET_64BIT"
10401   "#"
10402   [(set_attr "type" "multi")])
10403
10404 ;; By default we don't ask for a scratch register, because when DImode
10405 ;; values are manipulated, registers are already at a premium.  But if
10406 ;; we have one handy, we won't turn it away.
10407 (define_peephole2
10408   [(match_scratch:SI 3 "r")
10409    (parallel [(set (match_operand:DI 0 "register_operand" "")
10410                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10411                               (match_operand:QI 2 "nonmemory_operand" "")))
10412               (clobber (reg:CC FLAGS_REG))])
10413    (match_dup 3)]
10414   "!TARGET_64BIT && TARGET_CMOVE"
10415   [(const_int 0)]
10416   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10417
10418 (define_split
10419   [(set (match_operand:DI 0 "register_operand" "")
10420         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10421                    (match_operand:QI 2 "nonmemory_operand" "")))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10424                      ? flow2_completed : reload_completed)"
10425   [(const_int 0)]
10426   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10427
10428 (define_insn "x86_shld_1"
10429   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10430         (ior:SI (ashift:SI (match_dup 0)
10431                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10432                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10433                   (minus:QI (const_int 32) (match_dup 2)))))
10434    (clobber (reg:CC FLAGS_REG))]
10435   ""
10436   "@
10437    shld{l}\t{%2, %1, %0|%0, %1, %2}
10438    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10439   [(set_attr "type" "ishift")
10440    (set_attr "prefix_0f" "1")
10441    (set_attr "mode" "SI")
10442    (set_attr "pent_pair" "np")
10443    (set_attr "athlon_decode" "vector")])
10444
10445 (define_expand "x86_shift_adj_1"
10446   [(set (reg:CCZ FLAGS_REG)
10447         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10448                              (const_int 32))
10449                      (const_int 0)))
10450    (set (match_operand:SI 0 "register_operand" "")
10451         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10452                          (match_operand:SI 1 "register_operand" "")
10453                          (match_dup 0)))
10454    (set (match_dup 1)
10455         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10456                          (match_operand:SI 3 "register_operand" "r")
10457                          (match_dup 1)))]
10458   "TARGET_CMOVE"
10459   "")
10460
10461 (define_expand "x86_shift_adj_2"
10462   [(use (match_operand:SI 0 "register_operand" ""))
10463    (use (match_operand:SI 1 "register_operand" ""))
10464    (use (match_operand:QI 2 "register_operand" ""))]
10465   ""
10466 {
10467   rtx label = gen_label_rtx ();
10468   rtx tmp;
10469
10470   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10471
10472   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10473   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10474   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10475                               gen_rtx_LABEL_REF (VOIDmode, label),
10476                               pc_rtx);
10477   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10478   JUMP_LABEL (tmp) = label;
10479
10480   emit_move_insn (operands[0], operands[1]);
10481   ix86_expand_clear (operands[1]);
10482
10483   emit_label (label);
10484   LABEL_NUSES (label) = 1;
10485
10486   DONE;
10487 })
10488
10489 (define_expand "ashlsi3"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10491         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10492                    (match_operand:QI 2 "nonmemory_operand" "")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   ""
10495   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10496
10497 (define_insn "*ashlsi3_1"
10498   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10499         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10500                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10501    (clobber (reg:CC FLAGS_REG))]
10502   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10503 {
10504   switch (get_attr_type (insn))
10505     {
10506     case TYPE_ALU:
10507       gcc_assert (operands[2] == const1_rtx);
10508       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10509       return "add{l}\t{%0, %0|%0, %0}";
10510
10511     case TYPE_LEA:
10512       return "#";
10513
10514     default:
10515       if (REG_P (operands[2]))
10516         return "sal{l}\t{%b2, %0|%0, %b2}";
10517       else if (operands[2] == const1_rtx
10518                && (TARGET_SHIFT1 || optimize_size))
10519         return "sal{l}\t%0";
10520       else
10521         return "sal{l}\t{%2, %0|%0, %2}";
10522     }
10523 }
10524   [(set (attr "type")
10525      (cond [(eq_attr "alternative" "1")
10526               (const_string "lea")
10527             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10528                           (const_int 0))
10529                       (match_operand 0 "register_operand" ""))
10530                  (match_operand 2 "const1_operand" ""))
10531               (const_string "alu")
10532            ]
10533            (const_string "ishift")))
10534    (set_attr "mode" "SI")])
10535
10536 ;; Convert lea to the lea pattern to avoid flags dependency.
10537 (define_split
10538   [(set (match_operand 0 "register_operand" "")
10539         (ashift (match_operand 1 "index_register_operand" "")
10540                 (match_operand:QI 2 "const_int_operand" "")))
10541    (clobber (reg:CC FLAGS_REG))]
10542   "reload_completed
10543    && true_regnum (operands[0]) != true_regnum (operands[1])
10544    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10545   [(const_int 0)]
10546 {
10547   rtx pat;
10548   enum machine_mode mode = GET_MODE (operands[0]);
10549
10550   if (GET_MODE_SIZE (mode) < 4)
10551     operands[0] = gen_lowpart (SImode, operands[0]);
10552   if (mode != Pmode)
10553     operands[1] = gen_lowpart (Pmode, operands[1]);
10554   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10555
10556   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10557   if (Pmode != SImode)
10558     pat = gen_rtx_SUBREG (SImode, pat, 0);
10559   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10560   DONE;
10561 })
10562
10563 ;; Rare case of shifting RSP is handled by generating move and shift
10564 (define_split
10565   [(set (match_operand 0 "register_operand" "")
10566         (ashift (match_operand 1 "register_operand" "")
10567                 (match_operand:QI 2 "const_int_operand" "")))
10568    (clobber (reg:CC FLAGS_REG))]
10569   "reload_completed
10570    && true_regnum (operands[0]) != true_regnum (operands[1])"
10571   [(const_int 0)]
10572 {
10573   rtx pat, clob;
10574   emit_move_insn (operands[1], operands[0]);
10575   pat = gen_rtx_SET (VOIDmode, operands[0],
10576                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10577                                      operands[0], operands[2]));
10578   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10579   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10580   DONE;
10581 })
10582
10583 (define_insn "*ashlsi3_1_zext"
10584   [(set (match_operand:DI 0 "register_operand" "=r,r")
10585         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10586                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10587    (clobber (reg:CC FLAGS_REG))]
10588   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10589 {
10590   switch (get_attr_type (insn))
10591     {
10592     case TYPE_ALU:
10593       gcc_assert (operands[2] == const1_rtx);
10594       return "add{l}\t{%k0, %k0|%k0, %k0}";
10595
10596     case TYPE_LEA:
10597       return "#";
10598
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{l}\t%k0";
10605       else
10606         return "sal{l}\t{%2, %k0|%k0, %2}";
10607     }
10608 }
10609   [(set (attr "type")
10610      (cond [(eq_attr "alternative" "1")
10611               (const_string "lea")
10612             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                      (const_int 0))
10614                  (match_operand 2 "const1_operand" ""))
10615               (const_string "alu")
10616            ]
10617            (const_string "ishift")))
10618    (set_attr "mode" "SI")])
10619
10620 ;; Convert lea to the lea pattern to avoid flags dependency.
10621 (define_split
10622   [(set (match_operand:DI 0 "register_operand" "")
10623         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10624                                 (match_operand:QI 2 "const_int_operand" ""))))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_64BIT && reload_completed
10627    && true_regnum (operands[0]) != true_regnum (operands[1])"
10628   [(set (match_dup 0) (zero_extend:DI
10629                         (subreg:SI (mult:SI (match_dup 1)
10630                                             (match_dup 2)) 0)))]
10631 {
10632   operands[1] = gen_lowpart (Pmode, operands[1]);
10633   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10634 })
10635
10636 ;; This pattern can't accept a variable shift count, since shifts by
10637 ;; zero don't affect the flags.  We assume that shifts by constant
10638 ;; zero are optimized away.
10639 (define_insn "*ashlsi3_cmp"
10640   [(set (reg FLAGS_REG)
10641         (compare
10642           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10643                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10644           (const_int 0)))
10645    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10646         (ashift:SI (match_dup 1) (match_dup 2)))]
10647   "ix86_match_ccmode (insn, CCGOCmode)
10648    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10649 {
10650   switch (get_attr_type (insn))
10651     {
10652     case TYPE_ALU:
10653       gcc_assert (operands[2] == const1_rtx);
10654       return "add{l}\t{%0, %0|%0, %0}";
10655
10656     default:
10657       if (REG_P (operands[2]))
10658         return "sal{l}\t{%b2, %0|%0, %b2}";
10659       else if (operands[2] == const1_rtx
10660                && (TARGET_SHIFT1 || optimize_size))
10661         return "sal{l}\t%0";
10662       else
10663         return "sal{l}\t{%2, %0|%0, %2}";
10664     }
10665 }
10666   [(set (attr "type")
10667      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668                           (const_int 0))
10669                       (match_operand 0 "register_operand" ""))
10670                  (match_operand 2 "const1_operand" ""))
10671               (const_string "alu")
10672            ]
10673            (const_string "ishift")))
10674    (set_attr "mode" "SI")])
10675
10676 (define_insn "*ashlsi3_cmp_zext"
10677   [(set (reg FLAGS_REG)
10678         (compare
10679           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10680                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10681           (const_int 0)))
10682    (set (match_operand:DI 0 "register_operand" "=r")
10683         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10684   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10685    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10686 {
10687   switch (get_attr_type (insn))
10688     {
10689     case TYPE_ALU:
10690       gcc_assert (operands[2] == const1_rtx);
10691       return "add{l}\t{%k0, %k0|%k0, %k0}";
10692
10693     default:
10694       if (REG_P (operands[2]))
10695         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10696       else if (operands[2] == const1_rtx
10697                && (TARGET_SHIFT1 || optimize_size))
10698         return "sal{l}\t%k0";
10699       else
10700         return "sal{l}\t{%2, %k0|%k0, %2}";
10701     }
10702 }
10703   [(set (attr "type")
10704      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10705                      (const_int 0))
10706                  (match_operand 2 "const1_operand" ""))
10707               (const_string "alu")
10708            ]
10709            (const_string "ishift")))
10710    (set_attr "mode" "SI")])
10711
10712 (define_expand "ashlhi3"
10713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10714         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10715                    (match_operand:QI 2 "nonmemory_operand" "")))
10716    (clobber (reg:CC FLAGS_REG))]
10717   "TARGET_HIMODE_MATH"
10718   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10719
10720 (define_insn "*ashlhi3_1_lea"
10721   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10722         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10723                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10724    (clobber (reg:CC FLAGS_REG))]
10725   "!TARGET_PARTIAL_REG_STALL
10726    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10727 {
10728   switch (get_attr_type (insn))
10729     {
10730     case TYPE_LEA:
10731       return "#";
10732     case TYPE_ALU:
10733       gcc_assert (operands[2] == const1_rtx);
10734       return "add{w}\t{%0, %0|%0, %0}";
10735
10736     default:
10737       if (REG_P (operands[2]))
10738         return "sal{w}\t{%b2, %0|%0, %b2}";
10739       else if (operands[2] == const1_rtx
10740                && (TARGET_SHIFT1 || optimize_size))
10741         return "sal{w}\t%0";
10742       else
10743         return "sal{w}\t{%2, %0|%0, %2}";
10744     }
10745 }
10746   [(set (attr "type")
10747      (cond [(eq_attr "alternative" "1")
10748               (const_string "lea")
10749             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10750                           (const_int 0))
10751                       (match_operand 0 "register_operand" ""))
10752                  (match_operand 2 "const1_operand" ""))
10753               (const_string "alu")
10754            ]
10755            (const_string "ishift")))
10756    (set_attr "mode" "HI,SI")])
10757
10758 (define_insn "*ashlhi3_1"
10759   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10760         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10761                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10762    (clobber (reg:CC FLAGS_REG))]
10763   "TARGET_PARTIAL_REG_STALL
10764    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10765 {
10766   switch (get_attr_type (insn))
10767     {
10768     case TYPE_ALU:
10769       gcc_assert (operands[2] == const1_rtx);
10770       return "add{w}\t{%0, %0|%0, %0}";
10771
10772     default:
10773       if (REG_P (operands[2]))
10774         return "sal{w}\t{%b2, %0|%0, %b2}";
10775       else if (operands[2] == const1_rtx
10776                && (TARGET_SHIFT1 || optimize_size))
10777         return "sal{w}\t%0";
10778       else
10779         return "sal{w}\t{%2, %0|%0, %2}";
10780     }
10781 }
10782   [(set (attr "type")
10783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784                           (const_int 0))
10785                       (match_operand 0 "register_operand" ""))
10786                  (match_operand 2 "const1_operand" ""))
10787               (const_string "alu")
10788            ]
10789            (const_string "ishift")))
10790    (set_attr "mode" "HI")])
10791
10792 ;; This pattern can't accept a variable shift count, since shifts by
10793 ;; zero don't affect the flags.  We assume that shifts by constant
10794 ;; zero are optimized away.
10795 (define_insn "*ashlhi3_cmp"
10796   [(set (reg FLAGS_REG)
10797         (compare
10798           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10799                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10800           (const_int 0)))
10801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10802         (ashift:HI (match_dup 1) (match_dup 2)))]
10803   "ix86_match_ccmode (insn, CCGOCmode)
10804    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10805 {
10806   switch (get_attr_type (insn))
10807     {
10808     case TYPE_ALU:
10809       gcc_assert (operands[2] == const1_rtx);
10810       return "add{w}\t{%0, %0|%0, %0}";
10811
10812     default:
10813       if (REG_P (operands[2]))
10814         return "sal{w}\t{%b2, %0|%0, %b2}";
10815       else if (operands[2] == const1_rtx
10816                && (TARGET_SHIFT1 || optimize_size))
10817         return "sal{w}\t%0";
10818       else
10819         return "sal{w}\t{%2, %0|%0, %2}";
10820     }
10821 }
10822   [(set (attr "type")
10823      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10824                           (const_int 0))
10825                       (match_operand 0 "register_operand" ""))
10826                  (match_operand 2 "const1_operand" ""))
10827               (const_string "alu")
10828            ]
10829            (const_string "ishift")))
10830    (set_attr "mode" "HI")])
10831
10832 (define_expand "ashlqi3"
10833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10834         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10835                    (match_operand:QI 2 "nonmemory_operand" "")))
10836    (clobber (reg:CC FLAGS_REG))]
10837   "TARGET_QIMODE_MATH"
10838   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10839
10840 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10841
10842 (define_insn "*ashlqi3_1_lea"
10843   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10844         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10845                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10846    (clobber (reg:CC FLAGS_REG))]
10847   "!TARGET_PARTIAL_REG_STALL
10848    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10849 {
10850   switch (get_attr_type (insn))
10851     {
10852     case TYPE_LEA:
10853       return "#";
10854     case TYPE_ALU:
10855       gcc_assert (operands[2] == const1_rtx);
10856       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10857         return "add{l}\t{%k0, %k0|%k0, %k0}";
10858       else
10859         return "add{b}\t{%0, %0|%0, %0}";
10860
10861     default:
10862       if (REG_P (operands[2]))
10863         {
10864           if (get_attr_mode (insn) == MODE_SI)
10865             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10866           else
10867             return "sal{b}\t{%b2, %0|%0, %b2}";
10868         }
10869       else if (operands[2] == const1_rtx
10870                && (TARGET_SHIFT1 || optimize_size))
10871         {
10872           if (get_attr_mode (insn) == MODE_SI)
10873             return "sal{l}\t%0";
10874           else
10875             return "sal{b}\t%0";
10876         }
10877       else
10878         {
10879           if (get_attr_mode (insn) == MODE_SI)
10880             return "sal{l}\t{%2, %k0|%k0, %2}";
10881           else
10882             return "sal{b}\t{%2, %0|%0, %2}";
10883         }
10884     }
10885 }
10886   [(set (attr "type")
10887      (cond [(eq_attr "alternative" "2")
10888               (const_string "lea")
10889             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890                           (const_int 0))
10891                       (match_operand 0 "register_operand" ""))
10892                  (match_operand 2 "const1_operand" ""))
10893               (const_string "alu")
10894            ]
10895            (const_string "ishift")))
10896    (set_attr "mode" "QI,SI,SI")])
10897
10898 (define_insn "*ashlqi3_1"
10899   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10900         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10901                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "TARGET_PARTIAL_REG_STALL
10904    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10905 {
10906   switch (get_attr_type (insn))
10907     {
10908     case TYPE_ALU:
10909       gcc_assert (operands[2] == const1_rtx);
10910       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10911         return "add{l}\t{%k0, %k0|%k0, %k0}";
10912       else
10913         return "add{b}\t{%0, %0|%0, %0}";
10914
10915     default:
10916       if (REG_P (operands[2]))
10917         {
10918           if (get_attr_mode (insn) == MODE_SI)
10919             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10920           else
10921             return "sal{b}\t{%b2, %0|%0, %b2}";
10922         }
10923       else if (operands[2] == const1_rtx
10924                && (TARGET_SHIFT1 || optimize_size))
10925         {
10926           if (get_attr_mode (insn) == MODE_SI)
10927             return "sal{l}\t%0";
10928           else
10929             return "sal{b}\t%0";
10930         }
10931       else
10932         {
10933           if (get_attr_mode (insn) == MODE_SI)
10934             return "sal{l}\t{%2, %k0|%k0, %2}";
10935           else
10936             return "sal{b}\t{%2, %0|%0, %2}";
10937         }
10938     }
10939 }
10940   [(set (attr "type")
10941      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10942                           (const_int 0))
10943                       (match_operand 0 "register_operand" ""))
10944                  (match_operand 2 "const1_operand" ""))
10945               (const_string "alu")
10946            ]
10947            (const_string "ishift")))
10948    (set_attr "mode" "QI,SI")])
10949
10950 ;; This pattern can't accept a variable shift count, since shifts by
10951 ;; zero don't affect the flags.  We assume that shifts by constant
10952 ;; zero are optimized away.
10953 (define_insn "*ashlqi3_cmp"
10954   [(set (reg FLAGS_REG)
10955         (compare
10956           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10957                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10958           (const_int 0)))
10959    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10960         (ashift:QI (match_dup 1) (match_dup 2)))]
10961   "ix86_match_ccmode (insn, CCGOCmode)
10962    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10963 {
10964   switch (get_attr_type (insn))
10965     {
10966     case TYPE_ALU:
10967       gcc_assert (operands[2] == const1_rtx);
10968       return "add{b}\t{%0, %0|%0, %0}";
10969
10970     default:
10971       if (REG_P (operands[2]))
10972         return "sal{b}\t{%b2, %0|%0, %b2}";
10973       else if (operands[2] == const1_rtx
10974                && (TARGET_SHIFT1 || optimize_size))
10975         return "sal{b}\t%0";
10976       else
10977         return "sal{b}\t{%2, %0|%0, %2}";
10978     }
10979 }
10980   [(set (attr "type")
10981      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10982                           (const_int 0))
10983                       (match_operand 0 "register_operand" ""))
10984                  (match_operand 2 "const1_operand" ""))
10985               (const_string "alu")
10986            ]
10987            (const_string "ishift")))
10988    (set_attr "mode" "QI")])
10989
10990 ;; See comment above `ashldi3' about how this works.
10991
10992 (define_expand "ashrti3"
10993   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10994                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10995                                 (match_operand:QI 2 "nonmemory_operand" "")))
10996               (clobber (reg:CC FLAGS_REG))])]
10997   "TARGET_64BIT"
10998 {
10999   if (! immediate_operand (operands[2], QImode))
11000     {
11001       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11002       DONE;
11003     }
11004   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11005   DONE;
11006 })
11007
11008 (define_insn "ashrti3_1"
11009   [(set (match_operand:TI 0 "register_operand" "=r")
11010         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11011                      (match_operand:QI 2 "register_operand" "c")))
11012    (clobber (match_scratch:DI 3 "=&r"))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "TARGET_64BIT"
11015   "#"
11016   [(set_attr "type" "multi")])
11017
11018 (define_insn "*ashrti3_2"
11019   [(set (match_operand:TI 0 "register_operand" "=r")
11020         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11021                      (match_operand:QI 2 "immediate_operand" "O")))
11022    (clobber (reg:CC FLAGS_REG))]
11023   "TARGET_64BIT"
11024   "#"
11025   [(set_attr "type" "multi")])
11026
11027 (define_split
11028   [(set (match_operand:TI 0 "register_operand" "")
11029         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11030                      (match_operand:QI 2 "register_operand" "")))
11031    (clobber (match_scratch:DI 3 ""))
11032    (clobber (reg:CC FLAGS_REG))]
11033   "TARGET_64BIT && reload_completed"
11034   [(const_int 0)]
11035   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11036
11037 (define_split
11038   [(set (match_operand:TI 0 "register_operand" "")
11039         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11040                      (match_operand:QI 2 "immediate_operand" "")))
11041    (clobber (reg:CC FLAGS_REG))]
11042   "TARGET_64BIT && reload_completed"
11043   [(const_int 0)]
11044   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11045
11046 (define_insn "x86_64_shrd"
11047   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11048         (ior:DI (ashiftrt:DI (match_dup 0)
11049                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11050                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11051                   (minus:QI (const_int 64) (match_dup 2)))))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "TARGET_64BIT"
11054   "@
11055    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11056    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11057   [(set_attr "type" "ishift")
11058    (set_attr "prefix_0f" "1")
11059    (set_attr "mode" "DI")
11060    (set_attr "athlon_decode" "vector")])
11061
11062 (define_expand "ashrdi3"
11063   [(set (match_operand:DI 0 "shiftdi_operand" "")
11064         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11065                      (match_operand:QI 2 "nonmemory_operand" "")))]
11066   ""
11067   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11068
11069 (define_insn "*ashrdi3_63_rex64"
11070   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11071         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11072                      (match_operand:DI 2 "const_int_operand" "i,i")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "TARGET_64BIT && INTVAL (operands[2]) == 63
11075    && (TARGET_USE_CLTD || optimize_size)
11076    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11077   "@
11078    {cqto|cqo}
11079    sar{q}\t{%2, %0|%0, %2}"
11080   [(set_attr "type" "imovx,ishift")
11081    (set_attr "prefix_0f" "0,*")
11082    (set_attr "length_immediate" "0,*")
11083    (set_attr "modrm" "0,1")
11084    (set_attr "mode" "DI")])
11085
11086 (define_insn "*ashrdi3_1_one_bit_rex64"
11087   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11088         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11089                      (match_operand:QI 2 "const1_operand" "")))
11090    (clobber (reg:CC FLAGS_REG))]
11091   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11092    && (TARGET_SHIFT1 || optimize_size)"
11093   "sar{q}\t%0"
11094   [(set_attr "type" "ishift")
11095    (set (attr "length") 
11096      (if_then_else (match_operand:DI 0 "register_operand" "") 
11097         (const_string "2")
11098         (const_string "*")))])
11099
11100 (define_insn "*ashrdi3_1_rex64"
11101   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11102         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11103                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11106   "@
11107    sar{q}\t{%2, %0|%0, %2}
11108    sar{q}\t{%b2, %0|%0, %b2}"
11109   [(set_attr "type" "ishift")
11110    (set_attr "mode" "DI")])
11111
11112 ;; This pattern can't accept a variable shift count, since shifts by
11113 ;; zero don't affect the flags.  We assume that shifts by constant
11114 ;; zero are optimized away.
11115 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11116   [(set (reg FLAGS_REG)
11117         (compare
11118           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11119                        (match_operand:QI 2 "const1_operand" ""))
11120           (const_int 0)))
11121    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11122         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11123   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11124    && (TARGET_SHIFT1 || optimize_size)
11125    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11126   "sar{q}\t%0"
11127   [(set_attr "type" "ishift")
11128    (set (attr "length") 
11129      (if_then_else (match_operand:DI 0 "register_operand" "") 
11130         (const_string "2")
11131         (const_string "*")))])
11132
11133 ;; This pattern can't accept a variable shift count, since shifts by
11134 ;; zero don't affect the flags.  We assume that shifts by constant
11135 ;; zero are optimized away.
11136 (define_insn "*ashrdi3_cmp_rex64"
11137   [(set (reg FLAGS_REG)
11138         (compare
11139           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11140                        (match_operand:QI 2 "const_int_operand" "n"))
11141           (const_int 0)))
11142    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11143         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11144   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11145    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11146   "sar{q}\t{%2, %0|%0, %2}"
11147   [(set_attr "type" "ishift")
11148    (set_attr "mode" "DI")])
11149
11150 (define_insn "*ashrdi3_1"
11151   [(set (match_operand:DI 0 "register_operand" "=r")
11152         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11153                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11154    (clobber (reg:CC FLAGS_REG))]
11155   "!TARGET_64BIT"
11156   "#"
11157   [(set_attr "type" "multi")])
11158
11159 ;; By default we don't ask for a scratch register, because when DImode
11160 ;; values are manipulated, registers are already at a premium.  But if
11161 ;; we have one handy, we won't turn it away.
11162 (define_peephole2
11163   [(match_scratch:SI 3 "r")
11164    (parallel [(set (match_operand:DI 0 "register_operand" "")
11165                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11166                                 (match_operand:QI 2 "nonmemory_operand" "")))
11167               (clobber (reg:CC FLAGS_REG))])
11168    (match_dup 3)]
11169   "!TARGET_64BIT && TARGET_CMOVE"
11170   [(const_int 0)]
11171   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11172
11173 (define_split
11174   [(set (match_operand:DI 0 "register_operand" "")
11175         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11176                      (match_operand:QI 2 "nonmemory_operand" "")))
11177    (clobber (reg:CC FLAGS_REG))]
11178   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11179                      ? flow2_completed : reload_completed)"
11180   [(const_int 0)]
11181   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11182
11183 (define_insn "x86_shrd_1"
11184   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11185         (ior:SI (ashiftrt:SI (match_dup 0)
11186                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11187                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11188                   (minus:QI (const_int 32) (match_dup 2)))))
11189    (clobber (reg:CC FLAGS_REG))]
11190   ""
11191   "@
11192    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11193    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11194   [(set_attr "type" "ishift")
11195    (set_attr "prefix_0f" "1")
11196    (set_attr "pent_pair" "np")
11197    (set_attr "mode" "SI")])
11198
11199 (define_expand "x86_shift_adj_3"
11200   [(use (match_operand:SI 0 "register_operand" ""))
11201    (use (match_operand:SI 1 "register_operand" ""))
11202    (use (match_operand:QI 2 "register_operand" ""))]
11203   ""
11204 {
11205   rtx label = gen_label_rtx ();
11206   rtx tmp;
11207
11208   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11209
11210   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11211   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11212   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11213                               gen_rtx_LABEL_REF (VOIDmode, label),
11214                               pc_rtx);
11215   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11216   JUMP_LABEL (tmp) = label;
11217
11218   emit_move_insn (operands[0], operands[1]);
11219   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11220
11221   emit_label (label);
11222   LABEL_NUSES (label) = 1;
11223
11224   DONE;
11225 })
11226
11227 (define_insn "ashrsi3_31"
11228   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11229         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11230                      (match_operand:SI 2 "const_int_operand" "i,i")))
11231    (clobber (reg:CC FLAGS_REG))]
11232   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11233    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11234   "@
11235    {cltd|cdq}
11236    sar{l}\t{%2, %0|%0, %2}"
11237   [(set_attr "type" "imovx,ishift")
11238    (set_attr "prefix_0f" "0,*")
11239    (set_attr "length_immediate" "0,*")
11240    (set_attr "modrm" "0,1")
11241    (set_attr "mode" "SI")])
11242
11243 (define_insn "*ashrsi3_31_zext"
11244   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11245         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11246                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11247    (clobber (reg:CC FLAGS_REG))]
11248   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11249    && INTVAL (operands[2]) == 31
11250    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11251   "@
11252    {cltd|cdq}
11253    sar{l}\t{%2, %k0|%k0, %2}"
11254   [(set_attr "type" "imovx,ishift")
11255    (set_attr "prefix_0f" "0,*")
11256    (set_attr "length_immediate" "0,*")
11257    (set_attr "modrm" "0,1")
11258    (set_attr "mode" "SI")])
11259
11260 (define_expand "ashrsi3"
11261   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11262         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11263                      (match_operand:QI 2 "nonmemory_operand" "")))
11264    (clobber (reg:CC FLAGS_REG))]
11265   ""
11266   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11267
11268 (define_insn "*ashrsi3_1_one_bit"
11269   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11270         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11271                      (match_operand:QI 2 "const1_operand" "")))
11272    (clobber (reg:CC FLAGS_REG))]
11273   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11274    && (TARGET_SHIFT1 || optimize_size)"
11275   "sar{l}\t%0"
11276   [(set_attr "type" "ishift")
11277    (set (attr "length") 
11278      (if_then_else (match_operand:SI 0 "register_operand" "") 
11279         (const_string "2")
11280         (const_string "*")))])
11281
11282 (define_insn "*ashrsi3_1_one_bit_zext"
11283   [(set (match_operand:DI 0 "register_operand" "=r")
11284         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11285                                      (match_operand:QI 2 "const1_operand" ""))))
11286    (clobber (reg:CC FLAGS_REG))]
11287   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11288    && (TARGET_SHIFT1 || optimize_size)"
11289   "sar{l}\t%k0"
11290   [(set_attr "type" "ishift")
11291    (set_attr "length" "2")])
11292
11293 (define_insn "*ashrsi3_1"
11294   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11295         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11296                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11299   "@
11300    sar{l}\t{%2, %0|%0, %2}
11301    sar{l}\t{%b2, %0|%0, %b2}"
11302   [(set_attr "type" "ishift")
11303    (set_attr "mode" "SI")])
11304
11305 (define_insn "*ashrsi3_1_zext"
11306   [(set (match_operand:DI 0 "register_operand" "=r,r")
11307         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11308                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11311   "@
11312    sar{l}\t{%2, %k0|%k0, %2}
11313    sar{l}\t{%b2, %k0|%k0, %b2}"
11314   [(set_attr "type" "ishift")
11315    (set_attr "mode" "SI")])
11316
11317 ;; This pattern can't accept a variable shift count, since shifts by
11318 ;; zero don't affect the flags.  We assume that shifts by constant
11319 ;; zero are optimized away.
11320 (define_insn "*ashrsi3_one_bit_cmp"
11321   [(set (reg FLAGS_REG)
11322         (compare
11323           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11324                        (match_operand:QI 2 "const1_operand" ""))
11325           (const_int 0)))
11326    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11327         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11328   "ix86_match_ccmode (insn, CCGOCmode)
11329    && (TARGET_SHIFT1 || optimize_size)
11330    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331   "sar{l}\t%0"
11332   [(set_attr "type" "ishift")
11333    (set (attr "length") 
11334      (if_then_else (match_operand:SI 0 "register_operand" "") 
11335         (const_string "2")
11336         (const_string "*")))])
11337
11338 (define_insn "*ashrsi3_one_bit_cmp_zext"
11339   [(set (reg FLAGS_REG)
11340         (compare
11341           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11342                        (match_operand:QI 2 "const1_operand" ""))
11343           (const_int 0)))
11344    (set (match_operand:DI 0 "register_operand" "=r")
11345         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11346   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11347    && (TARGET_SHIFT1 || optimize_size)
11348    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11349   "sar{l}\t%k0"
11350   [(set_attr "type" "ishift")
11351    (set_attr "length" "2")])
11352
11353 ;; This pattern can't accept a variable shift count, since shifts by
11354 ;; zero don't affect the flags.  We assume that shifts by constant
11355 ;; zero are optimized away.
11356 (define_insn "*ashrsi3_cmp"
11357   [(set (reg FLAGS_REG)
11358         (compare
11359           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11360                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11361           (const_int 0)))
11362    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11363         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11364   "ix86_match_ccmode (insn, CCGOCmode)
11365    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11366   "sar{l}\t{%2, %0|%0, %2}"
11367   [(set_attr "type" "ishift")
11368    (set_attr "mode" "SI")])
11369
11370 (define_insn "*ashrsi3_cmp_zext"
11371   [(set (reg FLAGS_REG)
11372         (compare
11373           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11375           (const_int 0)))
11376    (set (match_operand:DI 0 "register_operand" "=r")
11377         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11379    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11380   "sar{l}\t{%2, %k0|%k0, %2}"
11381   [(set_attr "type" "ishift")
11382    (set_attr "mode" "SI")])
11383
11384 (define_expand "ashrhi3"
11385   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11386         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11387                      (match_operand:QI 2 "nonmemory_operand" "")))
11388    (clobber (reg:CC FLAGS_REG))]
11389   "TARGET_HIMODE_MATH"
11390   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11391
11392 (define_insn "*ashrhi3_1_one_bit"
11393   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11394         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11395                      (match_operand:QI 2 "const1_operand" "")))
11396    (clobber (reg:CC FLAGS_REG))]
11397   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11398    && (TARGET_SHIFT1 || optimize_size)"
11399   "sar{w}\t%0"
11400   [(set_attr "type" "ishift")
11401    (set (attr "length") 
11402      (if_then_else (match_operand 0 "register_operand" "") 
11403         (const_string "2")
11404         (const_string "*")))])
11405
11406 (define_insn "*ashrhi3_1"
11407   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11408         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11409                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11410    (clobber (reg:CC FLAGS_REG))]
11411   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11412   "@
11413    sar{w}\t{%2, %0|%0, %2}
11414    sar{w}\t{%b2, %0|%0, %b2}"
11415   [(set_attr "type" "ishift")
11416    (set_attr "mode" "HI")])
11417
11418 ;; This pattern can't accept a variable shift count, since shifts by
11419 ;; zero don't affect the flags.  We assume that shifts by constant
11420 ;; zero are optimized away.
11421 (define_insn "*ashrhi3_one_bit_cmp"
11422   [(set (reg FLAGS_REG)
11423         (compare
11424           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11425                        (match_operand:QI 2 "const1_operand" ""))
11426           (const_int 0)))
11427    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11428         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11429   "ix86_match_ccmode (insn, CCGOCmode)
11430    && (TARGET_SHIFT1 || optimize_size)
11431    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11432   "sar{w}\t%0"
11433   [(set_attr "type" "ishift")
11434    (set (attr "length") 
11435      (if_then_else (match_operand 0 "register_operand" "") 
11436         (const_string "2")
11437         (const_string "*")))])
11438
11439 ;; This pattern can't accept a variable shift count, since shifts by
11440 ;; zero don't affect the flags.  We assume that shifts by constant
11441 ;; zero are optimized away.
11442 (define_insn "*ashrhi3_cmp"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11446                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11447           (const_int 0)))
11448    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11449         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11450   "ix86_match_ccmode (insn, CCGOCmode)
11451    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11452   "sar{w}\t{%2, %0|%0, %2}"
11453   [(set_attr "type" "ishift")
11454    (set_attr "mode" "HI")])
11455
11456 (define_expand "ashrqi3"
11457   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11458         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11459                      (match_operand:QI 2 "nonmemory_operand" "")))
11460    (clobber (reg:CC FLAGS_REG))]
11461   "TARGET_QIMODE_MATH"
11462   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11463
11464 (define_insn "*ashrqi3_1_one_bit"
11465   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11466         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11467                      (match_operand:QI 2 "const1_operand" "")))
11468    (clobber (reg:CC FLAGS_REG))]
11469   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11470    && (TARGET_SHIFT1 || optimize_size)"
11471   "sar{b}\t%0"
11472   [(set_attr "type" "ishift")
11473    (set (attr "length") 
11474      (if_then_else (match_operand 0 "register_operand" "") 
11475         (const_string "2")
11476         (const_string "*")))])
11477
11478 (define_insn "*ashrqi3_1_one_bit_slp"
11479   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11480         (ashiftrt:QI (match_dup 0)
11481                      (match_operand:QI 1 "const1_operand" "")))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11484    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11485    && (TARGET_SHIFT1 || optimize_size)"
11486   "sar{b}\t%0"
11487   [(set_attr "type" "ishift1")
11488    (set (attr "length") 
11489      (if_then_else (match_operand 0 "register_operand" "") 
11490         (const_string "2")
11491         (const_string "*")))])
11492
11493 (define_insn "*ashrqi3_1"
11494   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11495         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11496                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11497    (clobber (reg:CC FLAGS_REG))]
11498   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11499   "@
11500    sar{b}\t{%2, %0|%0, %2}
11501    sar{b}\t{%b2, %0|%0, %b2}"
11502   [(set_attr "type" "ishift")
11503    (set_attr "mode" "QI")])
11504
11505 (define_insn "*ashrqi3_1_slp"
11506   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11507         (ashiftrt:QI (match_dup 0)
11508                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11511    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11512   "@
11513    sar{b}\t{%1, %0|%0, %1}
11514    sar{b}\t{%b1, %0|%0, %b1}"
11515   [(set_attr "type" "ishift1")
11516    (set_attr "mode" "QI")])
11517
11518 ;; This pattern can't accept a variable shift count, since shifts by
11519 ;; zero don't affect the flags.  We assume that shifts by constant
11520 ;; zero are optimized away.
11521 (define_insn "*ashrqi3_one_bit_cmp"
11522   [(set (reg FLAGS_REG)
11523         (compare
11524           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11525                        (match_operand:QI 2 "const1_operand" "I"))
11526           (const_int 0)))
11527    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11528         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11529   "ix86_match_ccmode (insn, CCGOCmode)
11530    && (TARGET_SHIFT1 || optimize_size)
11531    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11532   "sar{b}\t%0"
11533   [(set_attr "type" "ishift")
11534    (set (attr "length") 
11535      (if_then_else (match_operand 0 "register_operand" "") 
11536         (const_string "2")
11537         (const_string "*")))])
11538
11539 ;; This pattern can't accept a variable shift count, since shifts by
11540 ;; zero don't affect the flags.  We assume that shifts by constant
11541 ;; zero are optimized away.
11542 (define_insn "*ashrqi3_cmp"
11543   [(set (reg FLAGS_REG)
11544         (compare
11545           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11546                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11547           (const_int 0)))
11548    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11549         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11550   "ix86_match_ccmode (insn, CCGOCmode)
11551    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11552   "sar{b}\t{%2, %0|%0, %2}"
11553   [(set_attr "type" "ishift")
11554    (set_attr "mode" "QI")])
11555 \f
11556 ;; Logical shift instructions
11557
11558 ;; See comment above `ashldi3' about how this works.
11559
11560 (define_expand "lshrti3"
11561   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11563                                 (match_operand:QI 2 "nonmemory_operand" "")))
11564               (clobber (reg:CC FLAGS_REG))])]
11565   "TARGET_64BIT"
11566 {
11567   if (! immediate_operand (operands[2], QImode))
11568     {
11569       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11570       DONE;
11571     }
11572   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11573   DONE;
11574 })
11575
11576 (define_insn "lshrti3_1"
11577   [(set (match_operand:TI 0 "register_operand" "=r")
11578         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579                      (match_operand:QI 2 "register_operand" "c")))
11580    (clobber (match_scratch:DI 3 "=&r"))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_insn "*lshrti3_2"
11587   [(set (match_operand:TI 0 "register_operand" "=r")
11588         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589                      (match_operand:QI 2 "immediate_operand" "O")))
11590    (clobber (reg:CC FLAGS_REG))]
11591   "TARGET_64BIT"
11592   "#"
11593   [(set_attr "type" "multi")])
11594
11595 (define_split 
11596   [(set (match_operand:TI 0 "register_operand" "")
11597         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11598                      (match_operand:QI 2 "register_operand" "")))
11599    (clobber (match_scratch:DI 3 ""))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11604
11605 (define_split 
11606   [(set (match_operand:TI 0 "register_operand" "")
11607         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11608                      (match_operand:QI 2 "immediate_operand" "")))
11609    (clobber (reg:CC FLAGS_REG))]
11610   "TARGET_64BIT && reload_completed"
11611   [(const_int 0)]
11612   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11613
11614 (define_expand "lshrdi3"
11615   [(set (match_operand:DI 0 "shiftdi_operand" "")
11616         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11617                      (match_operand:QI 2 "nonmemory_operand" "")))]
11618   ""
11619   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11620
11621 (define_insn "*lshrdi3_1_one_bit_rex64"
11622   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11623         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11624                      (match_operand:QI 2 "const1_operand" "")))
11625    (clobber (reg:CC FLAGS_REG))]
11626   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11627    && (TARGET_SHIFT1 || optimize_size)"
11628   "shr{q}\t%0"
11629   [(set_attr "type" "ishift")
11630    (set (attr "length") 
11631      (if_then_else (match_operand:DI 0 "register_operand" "") 
11632         (const_string "2")
11633         (const_string "*")))])
11634
11635 (define_insn "*lshrdi3_1_rex64"
11636   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11637         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11638                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11639    (clobber (reg:CC FLAGS_REG))]
11640   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11641   "@
11642    shr{q}\t{%2, %0|%0, %2}
11643    shr{q}\t{%b2, %0|%0, %b2}"
11644   [(set_attr "type" "ishift")
11645    (set_attr "mode" "DI")])
11646
11647 ;; This pattern can't accept a variable shift count, since shifts by
11648 ;; zero don't affect the flags.  We assume that shifts by constant
11649 ;; zero are optimized away.
11650 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11651   [(set (reg FLAGS_REG)
11652         (compare
11653           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11654                        (match_operand:QI 2 "const1_operand" ""))
11655           (const_int 0)))
11656    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11658   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11659    && (TARGET_SHIFT1 || optimize_size)
11660    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11661   "shr{q}\t%0"
11662   [(set_attr "type" "ishift")
11663    (set (attr "length") 
11664      (if_then_else (match_operand:DI 0 "register_operand" "") 
11665         (const_string "2")
11666         (const_string "*")))])
11667
11668 ;; This pattern can't accept a variable shift count, since shifts by
11669 ;; zero don't affect the flags.  We assume that shifts by constant
11670 ;; zero are optimized away.
11671 (define_insn "*lshrdi3_cmp_rex64"
11672   [(set (reg FLAGS_REG)
11673         (compare
11674           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11675                        (match_operand:QI 2 "const_int_operand" "e"))
11676           (const_int 0)))
11677    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11678         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11679   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11680    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11681   "shr{q}\t{%2, %0|%0, %2}"
11682   [(set_attr "type" "ishift")
11683    (set_attr "mode" "DI")])
11684
11685 (define_insn "*lshrdi3_1"
11686   [(set (match_operand:DI 0 "register_operand" "=r")
11687         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11688                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11689    (clobber (reg:CC FLAGS_REG))]
11690   "!TARGET_64BIT"
11691   "#"
11692   [(set_attr "type" "multi")])
11693
11694 ;; By default we don't ask for a scratch register, because when DImode
11695 ;; values are manipulated, registers are already at a premium.  But if
11696 ;; we have one handy, we won't turn it away.
11697 (define_peephole2
11698   [(match_scratch:SI 3 "r")
11699    (parallel [(set (match_operand:DI 0 "register_operand" "")
11700                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11701                                 (match_operand:QI 2 "nonmemory_operand" "")))
11702               (clobber (reg:CC FLAGS_REG))])
11703    (match_dup 3)]
11704   "!TARGET_64BIT && TARGET_CMOVE"
11705   [(const_int 0)]
11706   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11707
11708 (define_split 
11709   [(set (match_operand:DI 0 "register_operand" "")
11710         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11711                      (match_operand:QI 2 "nonmemory_operand" "")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11714                      ? flow2_completed : reload_completed)"
11715   [(const_int 0)]
11716   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11717
11718 (define_expand "lshrsi3"
11719   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11720         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11721                      (match_operand:QI 2 "nonmemory_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   ""
11724   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11725
11726 (define_insn "*lshrsi3_1_one_bit"
11727   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11728         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11729                      (match_operand:QI 2 "const1_operand" "")))
11730    (clobber (reg:CC FLAGS_REG))]
11731   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11732    && (TARGET_SHIFT1 || optimize_size)"
11733   "shr{l}\t%0"
11734   [(set_attr "type" "ishift")
11735    (set (attr "length") 
11736      (if_then_else (match_operand:SI 0 "register_operand" "") 
11737         (const_string "2")
11738         (const_string "*")))])
11739
11740 (define_insn "*lshrsi3_1_one_bit_zext"
11741   [(set (match_operand:DI 0 "register_operand" "=r")
11742         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11743                      (match_operand:QI 2 "const1_operand" "")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11746    && (TARGET_SHIFT1 || optimize_size)"
11747   "shr{l}\t%k0"
11748   [(set_attr "type" "ishift")
11749    (set_attr "length" "2")])
11750
11751 (define_insn "*lshrsi3_1"
11752   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11753         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11754                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11757   "@
11758    shr{l}\t{%2, %0|%0, %2}
11759    shr{l}\t{%b2, %0|%0, %b2}"
11760   [(set_attr "type" "ishift")
11761    (set_attr "mode" "SI")])
11762
11763 (define_insn "*lshrsi3_1_zext"
11764   [(set (match_operand:DI 0 "register_operand" "=r,r")
11765         (zero_extend:DI
11766           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11767                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11768    (clobber (reg:CC FLAGS_REG))]
11769   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11770   "@
11771    shr{l}\t{%2, %k0|%k0, %2}
11772    shr{l}\t{%b2, %k0|%k0, %b2}"
11773   [(set_attr "type" "ishift")
11774    (set_attr "mode" "SI")])
11775
11776 ;; This pattern can't accept a variable shift count, since shifts by
11777 ;; zero don't affect the flags.  We assume that shifts by constant
11778 ;; zero are optimized away.
11779 (define_insn "*lshrsi3_one_bit_cmp"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const1_operand" ""))
11784           (const_int 0)))
11785    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11786         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11787   "ix86_match_ccmode (insn, CCGOCmode)
11788    && (TARGET_SHIFT1 || optimize_size)
11789    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11790   "shr{l}\t%0"
11791   [(set_attr "type" "ishift")
11792    (set (attr "length") 
11793      (if_then_else (match_operand:SI 0 "register_operand" "") 
11794         (const_string "2")
11795         (const_string "*")))])
11796
11797 (define_insn "*lshrsi3_cmp_one_bit_zext"
11798   [(set (reg FLAGS_REG)
11799         (compare
11800           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11801                        (match_operand:QI 2 "const1_operand" ""))
11802           (const_int 0)))
11803    (set (match_operand:DI 0 "register_operand" "=r")
11804         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11805   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11806    && (TARGET_SHIFT1 || optimize_size)
11807    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11808   "shr{l}\t%k0"
11809   [(set_attr "type" "ishift")
11810    (set_attr "length" "2")])
11811
11812 ;; This pattern can't accept a variable shift count, since shifts by
11813 ;; zero don't affect the flags.  We assume that shifts by constant
11814 ;; zero are optimized away.
11815 (define_insn "*lshrsi3_cmp"
11816   [(set (reg FLAGS_REG)
11817         (compare
11818           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11819                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11820           (const_int 0)))
11821    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11822         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11823   "ix86_match_ccmode (insn, CCGOCmode)
11824    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11825   "shr{l}\t{%2, %0|%0, %2}"
11826   [(set_attr "type" "ishift")
11827    (set_attr "mode" "SI")])
11828
11829 (define_insn "*lshrsi3_cmp_zext"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11834           (const_int 0)))
11835    (set (match_operand:DI 0 "register_operand" "=r")
11836         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11839   "shr{l}\t{%2, %k0|%k0, %2}"
11840   [(set_attr "type" "ishift")
11841    (set_attr "mode" "SI")])
11842
11843 (define_expand "lshrhi3"
11844   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11845         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11846                      (match_operand:QI 2 "nonmemory_operand" "")))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_HIMODE_MATH"
11849   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11850
11851 (define_insn "*lshrhi3_1_one_bit"
11852   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11853         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11854                      (match_operand:QI 2 "const1_operand" "")))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11857    && (TARGET_SHIFT1 || optimize_size)"
11858   "shr{w}\t%0"
11859   [(set_attr "type" "ishift")
11860    (set (attr "length") 
11861      (if_then_else (match_operand 0 "register_operand" "") 
11862         (const_string "2")
11863         (const_string "*")))])
11864
11865 (define_insn "*lshrhi3_1"
11866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11867         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11868                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "@
11872    shr{w}\t{%2, %0|%0, %2}
11873    shr{w}\t{%b2, %0|%0, %b2}"
11874   [(set_attr "type" "ishift")
11875    (set_attr "mode" "HI")])
11876
11877 ;; This pattern can't accept a variable shift count, since shifts by
11878 ;; zero don't affect the flags.  We assume that shifts by constant
11879 ;; zero are optimized away.
11880 (define_insn "*lshrhi3_one_bit_cmp"
11881   [(set (reg FLAGS_REG)
11882         (compare
11883           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11884                        (match_operand:QI 2 "const1_operand" ""))
11885           (const_int 0)))
11886    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11887         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11888   "ix86_match_ccmode (insn, CCGOCmode)
11889    && (TARGET_SHIFT1 || optimize_size)
11890    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11891   "shr{w}\t%0"
11892   [(set_attr "type" "ishift")
11893    (set (attr "length") 
11894      (if_then_else (match_operand:SI 0 "register_operand" "") 
11895         (const_string "2")
11896         (const_string "*")))])
11897
11898 ;; This pattern can't accept a variable shift count, since shifts by
11899 ;; zero don't affect the flags.  We assume that shifts by constant
11900 ;; zero are optimized away.
11901 (define_insn "*lshrhi3_cmp"
11902   [(set (reg FLAGS_REG)
11903         (compare
11904           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11905                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11906           (const_int 0)))
11907    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11908         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11909   "ix86_match_ccmode (insn, CCGOCmode)
11910    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11911   "shr{w}\t{%2, %0|%0, %2}"
11912   [(set_attr "type" "ishift")
11913    (set_attr "mode" "HI")])
11914
11915 (define_expand "lshrqi3"
11916   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11917         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11918                      (match_operand:QI 2 "nonmemory_operand" "")))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_QIMODE_MATH"
11921   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11922
11923 (define_insn "*lshrqi3_1_one_bit"
11924   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11925         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11926                      (match_operand:QI 2 "const1_operand" "")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11929    && (TARGET_SHIFT1 || optimize_size)"
11930   "shr{b}\t%0"
11931   [(set_attr "type" "ishift")
11932    (set (attr "length") 
11933      (if_then_else (match_operand 0 "register_operand" "") 
11934         (const_string "2")
11935         (const_string "*")))])
11936
11937 (define_insn "*lshrqi3_1_one_bit_slp"
11938   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11939         (lshiftrt:QI (match_dup 0)
11940                      (match_operand:QI 1 "const1_operand" "")))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11943    && (TARGET_SHIFT1 || optimize_size)"
11944   "shr{b}\t%0"
11945   [(set_attr "type" "ishift1")
11946    (set (attr "length") 
11947      (if_then_else (match_operand 0 "register_operand" "") 
11948         (const_string "2")
11949         (const_string "*")))])
11950
11951 (define_insn "*lshrqi3_1"
11952   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11953         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11954                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11957   "@
11958    shr{b}\t{%2, %0|%0, %2}
11959    shr{b}\t{%b2, %0|%0, %b2}"
11960   [(set_attr "type" "ishift")
11961    (set_attr "mode" "QI")])
11962
11963 (define_insn "*lshrqi3_1_slp"
11964   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11965         (lshiftrt:QI (match_dup 0)
11966                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11967    (clobber (reg:CC FLAGS_REG))]
11968   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11969    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11970   "@
11971    shr{b}\t{%1, %0|%0, %1}
11972    shr{b}\t{%b1, %0|%0, %b1}"
11973   [(set_attr "type" "ishift1")
11974    (set_attr "mode" "QI")])
11975
11976 ;; This pattern can't accept a variable shift count, since shifts by
11977 ;; zero don't affect the flags.  We assume that shifts by constant
11978 ;; zero are optimized away.
11979 (define_insn "*lshrqi2_one_bit_cmp"
11980   [(set (reg FLAGS_REG)
11981         (compare
11982           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11983                        (match_operand:QI 2 "const1_operand" ""))
11984           (const_int 0)))
11985    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11986         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11987   "ix86_match_ccmode (insn, CCGOCmode)
11988    && (TARGET_SHIFT1 || optimize_size)
11989    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11990   "shr{b}\t%0"
11991   [(set_attr "type" "ishift")
11992    (set (attr "length") 
11993      (if_then_else (match_operand:SI 0 "register_operand" "") 
11994         (const_string "2")
11995         (const_string "*")))])
11996
11997 ;; This pattern can't accept a variable shift count, since shifts by
11998 ;; zero don't affect the flags.  We assume that shifts by constant
11999 ;; zero are optimized away.
12000 (define_insn "*lshrqi2_cmp"
12001   [(set (reg FLAGS_REG)
12002         (compare
12003           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12004                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12005           (const_int 0)))
12006    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12007         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12008   "ix86_match_ccmode (insn, CCGOCmode)
12009    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12010   "shr{b}\t{%2, %0|%0, %2}"
12011   [(set_attr "type" "ishift")
12012    (set_attr "mode" "QI")])
12013 \f
12014 ;; Rotate instructions
12015
12016 (define_expand "rotldi3"
12017   [(set (match_operand:DI 0 "shiftdi_operand" "")
12018         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12019                    (match_operand:QI 2 "nonmemory_operand" "")))
12020    (clobber (reg:CC FLAGS_REG))]
12021  ""
12022 {
12023   if (TARGET_64BIT)
12024     {
12025       ix86_expand_binary_operator (ROTATE, DImode, operands);
12026       DONE;
12027     }
12028   if (!const_1_to_31_operand (operands[2], VOIDmode))
12029     FAIL;
12030   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12031   DONE;
12032 })
12033
12034 ;; Implement rotation using two double-precision shift instructions
12035 ;; and a scratch register.   
12036 (define_insn_and_split "ix86_rotldi3"
12037  [(set (match_operand:DI 0 "register_operand" "=r")
12038        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12039                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12040   (clobber (reg:CC FLAGS_REG))
12041   (clobber (match_scratch:SI 3 "=&r"))]
12042  "!TARGET_64BIT"
12043  "" 
12044  "&& reload_completed"
12045  [(set (match_dup 3) (match_dup 4))
12046   (parallel
12047    [(set (match_dup 4)
12048          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12049                  (lshiftrt:SI (match_dup 5)
12050                               (minus:QI (const_int 32) (match_dup 2)))))
12051     (clobber (reg:CC FLAGS_REG))])
12052   (parallel
12053    [(set (match_dup 5)
12054          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12055                  (lshiftrt:SI (match_dup 3)
12056                               (minus:QI (const_int 32) (match_dup 2)))))
12057     (clobber (reg:CC FLAGS_REG))])]
12058  "split_di (operands, 1, operands + 4, operands + 5);")
12059  
12060 (define_insn "*rotlsi3_1_one_bit_rex64"
12061   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12062         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12063                    (match_operand:QI 2 "const1_operand" "")))
12064    (clobber (reg:CC FLAGS_REG))]
12065   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12066    && (TARGET_SHIFT1 || optimize_size)"
12067   "rol{q}\t%0"
12068   [(set_attr "type" "rotate")
12069    (set (attr "length") 
12070      (if_then_else (match_operand:DI 0 "register_operand" "") 
12071         (const_string "2")
12072         (const_string "*")))])
12073
12074 (define_insn "*rotldi3_1_rex64"
12075   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12076         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12077                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12080   "@
12081    rol{q}\t{%2, %0|%0, %2}
12082    rol{q}\t{%b2, %0|%0, %b2}"
12083   [(set_attr "type" "rotate")
12084    (set_attr "mode" "DI")])
12085
12086 (define_expand "rotlsi3"
12087   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12088         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12089                    (match_operand:QI 2 "nonmemory_operand" "")))
12090    (clobber (reg:CC FLAGS_REG))]
12091   ""
12092   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12093
12094 (define_insn "*rotlsi3_1_one_bit"
12095   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12096         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12097                    (match_operand:QI 2 "const1_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12100    && (TARGET_SHIFT1 || optimize_size)"
12101   "rol{l}\t%0"
12102   [(set_attr "type" "rotate")
12103    (set (attr "length") 
12104      (if_then_else (match_operand:SI 0 "register_operand" "") 
12105         (const_string "2")
12106         (const_string "*")))])
12107
12108 (define_insn "*rotlsi3_1_one_bit_zext"
12109   [(set (match_operand:DI 0 "register_operand" "=r")
12110         (zero_extend:DI
12111           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12112                      (match_operand:QI 2 "const1_operand" ""))))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12115    && (TARGET_SHIFT1 || optimize_size)"
12116   "rol{l}\t%k0"
12117   [(set_attr "type" "rotate")
12118    (set_attr "length" "2")])
12119
12120 (define_insn "*rotlsi3_1"
12121   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12122         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12123                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12126   "@
12127    rol{l}\t{%2, %0|%0, %2}
12128    rol{l}\t{%b2, %0|%0, %b2}"
12129   [(set_attr "type" "rotate")
12130    (set_attr "mode" "SI")])
12131
12132 (define_insn "*rotlsi3_1_zext"
12133   [(set (match_operand:DI 0 "register_operand" "=r,r")
12134         (zero_extend:DI
12135           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12136                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12139   "@
12140    rol{l}\t{%2, %k0|%k0, %2}
12141    rol{l}\t{%b2, %k0|%k0, %b2}"
12142   [(set_attr "type" "rotate")
12143    (set_attr "mode" "SI")])
12144
12145 (define_expand "rotlhi3"
12146   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12147         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12148                    (match_operand:QI 2 "nonmemory_operand" "")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "TARGET_HIMODE_MATH"
12151   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12152
12153 (define_insn "*rotlhi3_1_one_bit"
12154   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12155         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12156                    (match_operand:QI 2 "const1_operand" "")))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12159    && (TARGET_SHIFT1 || optimize_size)"
12160   "rol{w}\t%0"
12161   [(set_attr "type" "rotate")
12162    (set (attr "length") 
12163      (if_then_else (match_operand 0 "register_operand" "") 
12164         (const_string "2")
12165         (const_string "*")))])
12166
12167 (define_insn "*rotlhi3_1"
12168   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12169         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12170                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12171    (clobber (reg:CC FLAGS_REG))]
12172   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12173   "@
12174    rol{w}\t{%2, %0|%0, %2}
12175    rol{w}\t{%b2, %0|%0, %b2}"
12176   [(set_attr "type" "rotate")
12177    (set_attr "mode" "HI")])
12178
12179 (define_expand "rotlqi3"
12180   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12181         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12182                    (match_operand:QI 2 "nonmemory_operand" "")))
12183    (clobber (reg:CC FLAGS_REG))]
12184   "TARGET_QIMODE_MATH"
12185   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12186
12187 (define_insn "*rotlqi3_1_one_bit_slp"
12188   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12189         (rotate:QI (match_dup 0)
12190                    (match_operand:QI 1 "const1_operand" "")))
12191    (clobber (reg:CC FLAGS_REG))]
12192   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12193    && (TARGET_SHIFT1 || optimize_size)"
12194   "rol{b}\t%0"
12195   [(set_attr "type" "rotate1")
12196    (set (attr "length") 
12197      (if_then_else (match_operand 0 "register_operand" "") 
12198         (const_string "2")
12199         (const_string "*")))])
12200
12201 (define_insn "*rotlqi3_1_one_bit"
12202   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12203         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12204                    (match_operand:QI 2 "const1_operand" "")))
12205    (clobber (reg:CC FLAGS_REG))]
12206   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12207    && (TARGET_SHIFT1 || optimize_size)"
12208   "rol{b}\t%0"
12209   [(set_attr "type" "rotate")
12210    (set (attr "length") 
12211      (if_then_else (match_operand 0 "register_operand" "") 
12212         (const_string "2")
12213         (const_string "*")))])
12214
12215 (define_insn "*rotlqi3_1_slp"
12216   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12217         (rotate:QI (match_dup 0)
12218                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12221    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12222   "@
12223    rol{b}\t{%1, %0|%0, %1}
12224    rol{b}\t{%b1, %0|%0, %b1}"
12225   [(set_attr "type" "rotate1")
12226    (set_attr "mode" "QI")])
12227
12228 (define_insn "*rotlqi3_1"
12229   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12230         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12231                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12232    (clobber (reg:CC FLAGS_REG))]
12233   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12234   "@
12235    rol{b}\t{%2, %0|%0, %2}
12236    rol{b}\t{%b2, %0|%0, %b2}"
12237   [(set_attr "type" "rotate")
12238    (set_attr "mode" "QI")])
12239
12240 (define_expand "rotrdi3"
12241   [(set (match_operand:DI 0 "shiftdi_operand" "")
12242         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12243                    (match_operand:QI 2 "nonmemory_operand" "")))
12244    (clobber (reg:CC FLAGS_REG))]
12245  ""
12246 {
12247   if (TARGET_64BIT)
12248     {
12249       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12250       DONE;
12251     }
12252   if (!const_1_to_31_operand (operands[2], VOIDmode))
12253     FAIL;
12254   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12255   DONE;
12256 })
12257   
12258 ;; Implement rotation using two double-precision shift instructions
12259 ;; and a scratch register.   
12260 (define_insn_and_split "ix86_rotrdi3"
12261  [(set (match_operand:DI 0 "register_operand" "=r")
12262        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12263                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12264   (clobber (reg:CC FLAGS_REG))
12265   (clobber (match_scratch:SI 3 "=&r"))]
12266  "!TARGET_64BIT"
12267  ""
12268  "&& reload_completed"
12269  [(set (match_dup 3) (match_dup 4))
12270   (parallel
12271    [(set (match_dup 4)
12272          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12273                  (ashift:SI (match_dup 5)
12274                             (minus:QI (const_int 32) (match_dup 2)))))
12275     (clobber (reg:CC FLAGS_REG))])
12276   (parallel
12277    [(set (match_dup 5)
12278          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12279                  (ashift:SI (match_dup 3)
12280                             (minus:QI (const_int 32) (match_dup 2)))))
12281     (clobber (reg:CC FLAGS_REG))])]
12282  "split_di (operands, 1, operands + 4, operands + 5);")
12283
12284 (define_insn "*rotrdi3_1_one_bit_rex64"
12285   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12286         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12287                      (match_operand:QI 2 "const1_operand" "")))
12288    (clobber (reg:CC FLAGS_REG))]
12289   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12290    && (TARGET_SHIFT1 || optimize_size)"
12291   "ror{q}\t%0"
12292   [(set_attr "type" "rotate")
12293    (set (attr "length") 
12294      (if_then_else (match_operand:DI 0 "register_operand" "") 
12295         (const_string "2")
12296         (const_string "*")))])
12297
12298 (define_insn "*rotrdi3_1_rex64"
12299   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12300         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12301                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12304   "@
12305    ror{q}\t{%2, %0|%0, %2}
12306    ror{q}\t{%b2, %0|%0, %b2}"
12307   [(set_attr "type" "rotate")
12308    (set_attr "mode" "DI")])
12309
12310 (define_expand "rotrsi3"
12311   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12312         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   ""
12316   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12317
12318 (define_insn "*rotrsi3_1_one_bit"
12319   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12320         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12321                      (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "ror{l}\t%0"
12326   [(set_attr "type" "rotate")
12327    (set (attr "length") 
12328      (if_then_else (match_operand:SI 0 "register_operand" "") 
12329         (const_string "2")
12330         (const_string "*")))])
12331
12332 (define_insn "*rotrsi3_1_one_bit_zext"
12333   [(set (match_operand:DI 0 "register_operand" "=r")
12334         (zero_extend:DI
12335           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12336                        (match_operand:QI 2 "const1_operand" ""))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12339    && (TARGET_SHIFT1 || optimize_size)"
12340   "ror{l}\t%k0"
12341   [(set_attr "type" "rotate")
12342    (set (attr "length") 
12343      (if_then_else (match_operand:SI 0 "register_operand" "") 
12344         (const_string "2")
12345         (const_string "*")))])
12346
12347 (define_insn "*rotrsi3_1"
12348   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12349         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12350                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12351    (clobber (reg:CC FLAGS_REG))]
12352   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12353   "@
12354    ror{l}\t{%2, %0|%0, %2}
12355    ror{l}\t{%b2, %0|%0, %b2}"
12356   [(set_attr "type" "rotate")
12357    (set_attr "mode" "SI")])
12358
12359 (define_insn "*rotrsi3_1_zext"
12360   [(set (match_operand:DI 0 "register_operand" "=r,r")
12361         (zero_extend:DI
12362           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12363                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12366   "@
12367    ror{l}\t{%2, %k0|%k0, %2}
12368    ror{l}\t{%b2, %k0|%k0, %b2}"
12369   [(set_attr "type" "rotate")
12370    (set_attr "mode" "SI")])
12371
12372 (define_expand "rotrhi3"
12373   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12374         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12375                      (match_operand:QI 2 "nonmemory_operand" "")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "TARGET_HIMODE_MATH"
12378   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12379
12380 (define_insn "*rotrhi3_one_bit"
12381   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12382         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12383                      (match_operand:QI 2 "const1_operand" "")))
12384    (clobber (reg:CC FLAGS_REG))]
12385   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12386    && (TARGET_SHIFT1 || optimize_size)"
12387   "ror{w}\t%0"
12388   [(set_attr "type" "rotate")
12389    (set (attr "length") 
12390      (if_then_else (match_operand 0 "register_operand" "") 
12391         (const_string "2")
12392         (const_string "*")))])
12393
12394 (define_insn "*rotrhi3"
12395   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12396         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12397                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12400   "@
12401    ror{w}\t{%2, %0|%0, %2}
12402    ror{w}\t{%b2, %0|%0, %b2}"
12403   [(set_attr "type" "rotate")
12404    (set_attr "mode" "HI")])
12405
12406 (define_expand "rotrqi3"
12407   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12408         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12409                      (match_operand:QI 2 "nonmemory_operand" "")))
12410    (clobber (reg:CC FLAGS_REG))]
12411   "TARGET_QIMODE_MATH"
12412   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12413
12414 (define_insn "*rotrqi3_1_one_bit"
12415   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12416         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12417                      (match_operand:QI 2 "const1_operand" "")))
12418    (clobber (reg:CC FLAGS_REG))]
12419   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12420    && (TARGET_SHIFT1 || optimize_size)"
12421   "ror{b}\t%0"
12422   [(set_attr "type" "rotate")
12423    (set (attr "length") 
12424      (if_then_else (match_operand 0 "register_operand" "") 
12425         (const_string "2")
12426         (const_string "*")))])
12427
12428 (define_insn "*rotrqi3_1_one_bit_slp"
12429   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12430         (rotatert:QI (match_dup 0)
12431                      (match_operand:QI 1 "const1_operand" "")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12434    && (TARGET_SHIFT1 || optimize_size)"
12435   "ror{b}\t%0"
12436   [(set_attr "type" "rotate1")
12437    (set (attr "length") 
12438      (if_then_else (match_operand 0 "register_operand" "") 
12439         (const_string "2")
12440         (const_string "*")))])
12441
12442 (define_insn "*rotrqi3_1"
12443   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12444         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12445                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12448   "@
12449    ror{b}\t{%2, %0|%0, %2}
12450    ror{b}\t{%b2, %0|%0, %b2}"
12451   [(set_attr "type" "rotate")
12452    (set_attr "mode" "QI")])
12453
12454 (define_insn "*rotrqi3_1_slp"
12455   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12456         (rotatert:QI (match_dup 0)
12457                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12458    (clobber (reg:CC FLAGS_REG))]
12459   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12460    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12461   "@
12462    ror{b}\t{%1, %0|%0, %1}
12463    ror{b}\t{%b1, %0|%0, %b1}"
12464   [(set_attr "type" "rotate1")
12465    (set_attr "mode" "QI")])
12466 \f
12467 ;; Bit set / bit test instructions
12468
12469 (define_expand "extv"
12470   [(set (match_operand:SI 0 "register_operand" "")
12471         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12472                          (match_operand:SI 2 "const8_operand" "")
12473                          (match_operand:SI 3 "const8_operand" "")))]
12474   ""
12475 {
12476   /* Handle extractions from %ah et al.  */
12477   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12478     FAIL;
12479
12480   /* From mips.md: extract_bit_field doesn't verify that our source
12481      matches the predicate, so check it again here.  */
12482   if (! ext_register_operand (operands[1], VOIDmode))
12483     FAIL;
12484 })
12485
12486 (define_expand "extzv"
12487   [(set (match_operand:SI 0 "register_operand" "")
12488         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12489                          (match_operand:SI 2 "const8_operand" "")
12490                          (match_operand:SI 3 "const8_operand" "")))]
12491   ""
12492 {
12493   /* Handle extractions from %ah et al.  */
12494   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12495     FAIL;
12496
12497   /* From mips.md: extract_bit_field doesn't verify that our source
12498      matches the predicate, so check it again here.  */
12499   if (! ext_register_operand (operands[1], VOIDmode))
12500     FAIL;
12501 })
12502
12503 (define_expand "insv"
12504   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12505                       (match_operand 1 "const8_operand" "")
12506                       (match_operand 2 "const8_operand" ""))
12507         (match_operand 3 "register_operand" ""))]
12508   ""
12509 {
12510   /* Handle insertions to %ah et al.  */
12511   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12512     FAIL;
12513
12514   /* From mips.md: insert_bit_field doesn't verify that our source
12515      matches the predicate, so check it again here.  */
12516   if (! ext_register_operand (operands[0], VOIDmode))
12517     FAIL;
12518
12519   if (TARGET_64BIT)
12520     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12521   else
12522     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12523
12524   DONE;
12525 })
12526
12527 ;; %%% bts, btr, btc, bt.
12528 ;; In general these instructions are *slow* when applied to memory,
12529 ;; since they enforce atomic operation.  When applied to registers,
12530 ;; it depends on the cpu implementation.  They're never faster than
12531 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12532 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12533 ;; within the instruction itself, so operating on bits in the high
12534 ;; 32-bits of a register becomes easier.
12535 ;;
12536 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12537 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12538 ;; negdf respectively, so they can never be disabled entirely.
12539
12540 (define_insn "*btsq"
12541   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12542                          (const_int 1)
12543                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12544         (const_int 1))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12547   "bts{q} %1,%0"
12548   [(set_attr "type" "alu1")])
12549
12550 (define_insn "*btrq"
12551   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12552                          (const_int 1)
12553                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12554         (const_int 0))
12555    (clobber (reg:CC FLAGS_REG))]
12556   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12557   "btr{q} %1,%0"
12558   [(set_attr "type" "alu1")])
12559
12560 (define_insn "*btcq"
12561   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12562                          (const_int 1)
12563                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12564         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12565    (clobber (reg:CC FLAGS_REG))]
12566   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12567   "btc{q} %1,%0"
12568   [(set_attr "type" "alu1")])
12569
12570 ;; Allow Nocona to avoid these instructions if a register is available.
12571
12572 (define_peephole2
12573   [(match_scratch:DI 2 "r")
12574    (parallel [(set (zero_extract:DI
12575                      (match_operand:DI 0 "register_operand" "")
12576                      (const_int 1)
12577                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12578                    (const_int 1))
12579               (clobber (reg:CC FLAGS_REG))])]
12580   "TARGET_64BIT && !TARGET_USE_BT"
12581   [(const_int 0)]
12582 {
12583   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12584   rtx op1;
12585
12586   if (HOST_BITS_PER_WIDE_INT >= 64)
12587     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12588   else if (i < HOST_BITS_PER_WIDE_INT)
12589     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12590   else
12591     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12592
12593   op1 = immed_double_const (lo, hi, DImode);
12594   if (i >= 31)
12595     {
12596       emit_move_insn (operands[2], op1);
12597       op1 = operands[2];
12598     }
12599
12600   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12601   DONE;
12602 })
12603
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 0))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12614 {
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12617
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624
12625   op1 = immed_double_const (~lo, ~hi, DImode);
12626   if (i >= 32)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12631
12632   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12633   DONE;
12634 })
12635
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642               (not:DI (zero_extract:DI
12643                         (match_dup 0) (const_int 1) (match_dup 1))))
12644               (clobber (reg:CC FLAGS_REG))])]
12645   "TARGET_64BIT && !TARGET_USE_BT"
12646   [(const_int 0)]
12647 {
12648   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12649   rtx op1;
12650
12651   if (HOST_BITS_PER_WIDE_INT >= 64)
12652     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653   else if (i < HOST_BITS_PER_WIDE_INT)
12654     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12655   else
12656     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657
12658   op1 = immed_double_const (lo, hi, DImode);
12659   if (i >= 31)
12660     {
12661       emit_move_insn (operands[2], op1);
12662       op1 = operands[2];
12663     }
12664
12665   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12666   DONE;
12667 })
12668 \f
12669 ;; Store-flag instructions.
12670
12671 ;; For all sCOND expanders, also expand the compare or test insn that
12672 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12673
12674 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12675 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12676 ;; way, which can later delete the movzx if only QImode is needed.
12677
12678 (define_expand "seq"
12679   [(set (match_operand:QI 0 "register_operand" "")
12680         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12681   ""
12682   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12683
12684 (define_expand "sne"
12685   [(set (match_operand:QI 0 "register_operand" "")
12686         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12687   ""
12688   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12689
12690 (define_expand "sgt"
12691   [(set (match_operand:QI 0 "register_operand" "")
12692         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12693   ""
12694   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12695
12696 (define_expand "sgtu"
12697   [(set (match_operand:QI 0 "register_operand" "")
12698         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12699   ""
12700   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12701
12702 (define_expand "slt"
12703   [(set (match_operand:QI 0 "register_operand" "")
12704         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12705   ""
12706   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12707
12708 (define_expand "sltu"
12709   [(set (match_operand:QI 0 "register_operand" "")
12710         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12711   ""
12712   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12713
12714 (define_expand "sge"
12715   [(set (match_operand:QI 0 "register_operand" "")
12716         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12717   ""
12718   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12719
12720 (define_expand "sgeu"
12721   [(set (match_operand:QI 0 "register_operand" "")
12722         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12723   ""
12724   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12725
12726 (define_expand "sle"
12727   [(set (match_operand:QI 0 "register_operand" "")
12728         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729   ""
12730   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12731
12732 (define_expand "sleu"
12733   [(set (match_operand:QI 0 "register_operand" "")
12734         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735   ""
12736   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12737
12738 (define_expand "sunordered"
12739   [(set (match_operand:QI 0 "register_operand" "")
12740         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12741   "TARGET_80387 || TARGET_SSE"
12742   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12743
12744 (define_expand "sordered"
12745   [(set (match_operand:QI 0 "register_operand" "")
12746         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747   "TARGET_80387"
12748   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12749
12750 (define_expand "suneq"
12751   [(set (match_operand:QI 0 "register_operand" "")
12752         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12753   "TARGET_80387 || TARGET_SSE"
12754   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12755
12756 (define_expand "sunge"
12757   [(set (match_operand:QI 0 "register_operand" "")
12758         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12759   "TARGET_80387 || TARGET_SSE"
12760   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12761
12762 (define_expand "sungt"
12763   [(set (match_operand:QI 0 "register_operand" "")
12764         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12765   "TARGET_80387 || TARGET_SSE"
12766   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12767
12768 (define_expand "sunle"
12769   [(set (match_operand:QI 0 "register_operand" "")
12770         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12771   "TARGET_80387 || TARGET_SSE"
12772   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12773
12774 (define_expand "sunlt"
12775   [(set (match_operand:QI 0 "register_operand" "")
12776         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12777   "TARGET_80387 || TARGET_SSE"
12778   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12779
12780 (define_expand "sltgt"
12781   [(set (match_operand:QI 0 "register_operand" "")
12782         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12783   "TARGET_80387 || TARGET_SSE"
12784   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12785
12786 (define_insn "*setcc_1"
12787   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12788         (match_operator:QI 1 "ix86_comparison_operator"
12789           [(reg FLAGS_REG) (const_int 0)]))]
12790   ""
12791   "set%C1\t%0"
12792   [(set_attr "type" "setcc")
12793    (set_attr "mode" "QI")])
12794
12795 (define_insn "*setcc_2"
12796   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12797         (match_operator:QI 1 "ix86_comparison_operator"
12798           [(reg FLAGS_REG) (const_int 0)]))]
12799   ""
12800   "set%C1\t%0"
12801   [(set_attr "type" "setcc")
12802    (set_attr "mode" "QI")])
12803
12804 ;; In general it is not safe to assume too much about CCmode registers,
12805 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12806 ;; conditions this is safe on x86, so help combine not create
12807 ;;
12808 ;;      seta    %al
12809 ;;      testb   %al, %al
12810 ;;      sete    %al
12811
12812 (define_split 
12813   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12814         (ne:QI (match_operator 1 "ix86_comparison_operator"
12815                  [(reg FLAGS_REG) (const_int 0)])
12816             (const_int 0)))]
12817   ""
12818   [(set (match_dup 0) (match_dup 1))]
12819 {
12820   PUT_MODE (operands[1], QImode);
12821 })
12822
12823 (define_split 
12824   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12825         (ne:QI (match_operator 1 "ix86_comparison_operator"
12826                  [(reg FLAGS_REG) (const_int 0)])
12827             (const_int 0)))]
12828   ""
12829   [(set (match_dup 0) (match_dup 1))]
12830 {
12831   PUT_MODE (operands[1], QImode);
12832 })
12833
12834 (define_split 
12835   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12836         (eq:QI (match_operator 1 "ix86_comparison_operator"
12837                  [(reg FLAGS_REG) (const_int 0)])
12838             (const_int 0)))]
12839   ""
12840   [(set (match_dup 0) (match_dup 1))]
12841 {
12842   rtx new_op1 = copy_rtx (operands[1]);
12843   operands[1] = new_op1;
12844   PUT_MODE (new_op1, QImode);
12845   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12846                                              GET_MODE (XEXP (new_op1, 0))));
12847
12848   /* Make sure that (a) the CCmode we have for the flags is strong
12849      enough for the reversed compare or (b) we have a valid FP compare.  */
12850   if (! ix86_comparison_operator (new_op1, VOIDmode))
12851     FAIL;
12852 })
12853
12854 (define_split 
12855   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12856         (eq:QI (match_operator 1 "ix86_comparison_operator"
12857                  [(reg FLAGS_REG) (const_int 0)])
12858             (const_int 0)))]
12859   ""
12860   [(set (match_dup 0) (match_dup 1))]
12861 {
12862   rtx new_op1 = copy_rtx (operands[1]);
12863   operands[1] = new_op1;
12864   PUT_MODE (new_op1, QImode);
12865   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12866                                              GET_MODE (XEXP (new_op1, 0))));
12867
12868   /* Make sure that (a) the CCmode we have for the flags is strong
12869      enough for the reversed compare or (b) we have a valid FP compare.  */
12870   if (! ix86_comparison_operator (new_op1, VOIDmode))
12871     FAIL;
12872 })
12873
12874 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12875 ;; subsequent logical operations are used to imitate conditional moves.
12876 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12877 ;; it directly.
12878
12879 (define_insn "*sse_setccsf"
12880   [(set (match_operand:SF 0 "register_operand" "=x")
12881         (match_operator:SF 1 "sse_comparison_operator"
12882           [(match_operand:SF 2 "register_operand" "0")
12883            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12884   "TARGET_SSE"
12885   "cmp%D1ss\t{%3, %0|%0, %3}"
12886   [(set_attr "type" "ssecmp")
12887    (set_attr "mode" "SF")])
12888
12889 (define_insn "*sse_setccdf"
12890   [(set (match_operand:DF 0 "register_operand" "=Y")
12891         (match_operator:DF 1 "sse_comparison_operator"
12892           [(match_operand:DF 2 "register_operand" "0")
12893            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12894   "TARGET_SSE2"
12895   "cmp%D1sd\t{%3, %0|%0, %3}"
12896   [(set_attr "type" "ssecmp")
12897    (set_attr "mode" "DF")])
12898 \f
12899 ;; Basic conditional jump instructions.
12900 ;; We ignore the overflow flag for signed branch instructions.
12901
12902 ;; For all bCOND expanders, also expand the compare or test insn that
12903 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12904
12905 (define_expand "beq"
12906   [(set (pc)
12907         (if_then_else (match_dup 1)
12908                       (label_ref (match_operand 0 "" ""))
12909                       (pc)))]
12910   ""
12911   "ix86_expand_branch (EQ, operands[0]); DONE;")
12912
12913 (define_expand "bne"
12914   [(set (pc)
12915         (if_then_else (match_dup 1)
12916                       (label_ref (match_operand 0 "" ""))
12917                       (pc)))]
12918   ""
12919   "ix86_expand_branch (NE, operands[0]); DONE;")
12920
12921 (define_expand "bgt"
12922   [(set (pc)
12923         (if_then_else (match_dup 1)
12924                       (label_ref (match_operand 0 "" ""))
12925                       (pc)))]
12926   ""
12927   "ix86_expand_branch (GT, operands[0]); DONE;")
12928
12929 (define_expand "bgtu"
12930   [(set (pc)
12931         (if_then_else (match_dup 1)
12932                       (label_ref (match_operand 0 "" ""))
12933                       (pc)))]
12934   ""
12935   "ix86_expand_branch (GTU, operands[0]); DONE;")
12936
12937 (define_expand "blt"
12938   [(set (pc)
12939         (if_then_else (match_dup 1)
12940                       (label_ref (match_operand 0 "" ""))
12941                       (pc)))]
12942   ""
12943   "ix86_expand_branch (LT, operands[0]); DONE;")
12944
12945 (define_expand "bltu"
12946   [(set (pc)
12947         (if_then_else (match_dup 1)
12948                       (label_ref (match_operand 0 "" ""))
12949                       (pc)))]
12950   ""
12951   "ix86_expand_branch (LTU, operands[0]); DONE;")
12952
12953 (define_expand "bge"
12954   [(set (pc)
12955         (if_then_else (match_dup 1)
12956                       (label_ref (match_operand 0 "" ""))
12957                       (pc)))]
12958   ""
12959   "ix86_expand_branch (GE, operands[0]); DONE;")
12960
12961 (define_expand "bgeu"
12962   [(set (pc)
12963         (if_then_else (match_dup 1)
12964                       (label_ref (match_operand 0 "" ""))
12965                       (pc)))]
12966   ""
12967   "ix86_expand_branch (GEU, operands[0]); DONE;")
12968
12969 (define_expand "ble"
12970   [(set (pc)
12971         (if_then_else (match_dup 1)
12972                       (label_ref (match_operand 0 "" ""))
12973                       (pc)))]
12974   ""
12975   "ix86_expand_branch (LE, operands[0]); DONE;")
12976
12977 (define_expand "bleu"
12978   [(set (pc)
12979         (if_then_else (match_dup 1)
12980                       (label_ref (match_operand 0 "" ""))
12981                       (pc)))]
12982   ""
12983   "ix86_expand_branch (LEU, operands[0]); DONE;")
12984
12985 (define_expand "bunordered"
12986   [(set (pc)
12987         (if_then_else (match_dup 1)
12988                       (label_ref (match_operand 0 "" ""))
12989                       (pc)))]
12990   "TARGET_80387 || TARGET_SSE_MATH"
12991   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12992
12993 (define_expand "bordered"
12994   [(set (pc)
12995         (if_then_else (match_dup 1)
12996                       (label_ref (match_operand 0 "" ""))
12997                       (pc)))]
12998   "TARGET_80387 || TARGET_SSE_MATH"
12999   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13000
13001 (define_expand "buneq"
13002   [(set (pc)
13003         (if_then_else (match_dup 1)
13004                       (label_ref (match_operand 0 "" ""))
13005                       (pc)))]
13006   "TARGET_80387 || TARGET_SSE_MATH"
13007   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13008
13009 (define_expand "bunge"
13010   [(set (pc)
13011         (if_then_else (match_dup 1)
13012                       (label_ref (match_operand 0 "" ""))
13013                       (pc)))]
13014   "TARGET_80387 || TARGET_SSE_MATH"
13015   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13016
13017 (define_expand "bungt"
13018   [(set (pc)
13019         (if_then_else (match_dup 1)
13020                       (label_ref (match_operand 0 "" ""))
13021                       (pc)))]
13022   "TARGET_80387 || TARGET_SSE_MATH"
13023   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13024
13025 (define_expand "bunle"
13026   [(set (pc)
13027         (if_then_else (match_dup 1)
13028                       (label_ref (match_operand 0 "" ""))
13029                       (pc)))]
13030   "TARGET_80387 || TARGET_SSE_MATH"
13031   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13032
13033 (define_expand "bunlt"
13034   [(set (pc)
13035         (if_then_else (match_dup 1)
13036                       (label_ref (match_operand 0 "" ""))
13037                       (pc)))]
13038   "TARGET_80387 || TARGET_SSE_MATH"
13039   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13040
13041 (define_expand "bltgt"
13042   [(set (pc)
13043         (if_then_else (match_dup 1)
13044                       (label_ref (match_operand 0 "" ""))
13045                       (pc)))]
13046   "TARGET_80387 || TARGET_SSE_MATH"
13047   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13048
13049 (define_insn "*jcc_1"
13050   [(set (pc)
13051         (if_then_else (match_operator 1 "ix86_comparison_operator"
13052                                       [(reg FLAGS_REG) (const_int 0)])
13053                       (label_ref (match_operand 0 "" ""))
13054                       (pc)))]
13055   ""
13056   "%+j%C1\t%l0"
13057   [(set_attr "type" "ibr")
13058    (set_attr "modrm" "0")
13059    (set (attr "length")
13060            (if_then_else (and (ge (minus (match_dup 0) (pc))
13061                                   (const_int -126))
13062                               (lt (minus (match_dup 0) (pc))
13063                                   (const_int 128)))
13064              (const_int 2)
13065              (const_int 6)))])
13066
13067 (define_insn "*jcc_2"
13068   [(set (pc)
13069         (if_then_else (match_operator 1 "ix86_comparison_operator"
13070                                       [(reg FLAGS_REG) (const_int 0)])
13071                       (pc)
13072                       (label_ref (match_operand 0 "" ""))))]
13073   ""
13074   "%+j%c1\t%l0"
13075   [(set_attr "type" "ibr")
13076    (set_attr "modrm" "0")
13077    (set (attr "length")
13078            (if_then_else (and (ge (minus (match_dup 0) (pc))
13079                                   (const_int -126))
13080                               (lt (minus (match_dup 0) (pc))
13081                                   (const_int 128)))
13082              (const_int 2)
13083              (const_int 6)))])
13084
13085 ;; In general it is not safe to assume too much about CCmode registers,
13086 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13087 ;; conditions this is safe on x86, so help combine not create
13088 ;;
13089 ;;      seta    %al
13090 ;;      testb   %al, %al
13091 ;;      je      Lfoo
13092
13093 (define_split 
13094   [(set (pc)
13095         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13096                                       [(reg FLAGS_REG) (const_int 0)])
13097                           (const_int 0))
13098                       (label_ref (match_operand 1 "" ""))
13099                       (pc)))]
13100   ""
13101   [(set (pc)
13102         (if_then_else (match_dup 0)
13103                       (label_ref (match_dup 1))
13104                       (pc)))]
13105 {
13106   PUT_MODE (operands[0], VOIDmode);
13107 })
13108   
13109 (define_split 
13110   [(set (pc)
13111         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13112                                       [(reg FLAGS_REG) (const_int 0)])
13113                           (const_int 0))
13114                       (label_ref (match_operand 1 "" ""))
13115                       (pc)))]
13116   ""
13117   [(set (pc)
13118         (if_then_else (match_dup 0)
13119                       (label_ref (match_dup 1))
13120                       (pc)))]
13121 {
13122   rtx new_op0 = copy_rtx (operands[0]);
13123   operands[0] = new_op0;
13124   PUT_MODE (new_op0, VOIDmode);
13125   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13126                                              GET_MODE (XEXP (new_op0, 0))));
13127
13128   /* Make sure that (a) the CCmode we have for the flags is strong
13129      enough for the reversed compare or (b) we have a valid FP compare.  */
13130   if (! ix86_comparison_operator (new_op0, VOIDmode))
13131     FAIL;
13132 })
13133
13134 ;; Define combination compare-and-branch fp compare instructions to use
13135 ;; during early optimization.  Splitting the operation apart early makes
13136 ;; for bad code when we want to reverse the operation.
13137
13138 (define_insn "*fp_jcc_1_mixed"
13139   [(set (pc)
13140         (if_then_else (match_operator 0 "comparison_operator"
13141                         [(match_operand 1 "register_operand" "f#x,x#f")
13142                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13143           (label_ref (match_operand 3 "" ""))
13144           (pc)))
13145    (clobber (reg:CCFP FPSR_REG))
13146    (clobber (reg:CCFP FLAGS_REG))]
13147   "TARGET_MIX_SSE_I387
13148    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13149    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13150    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13151   "#")
13152
13153 (define_insn "*fp_jcc_1_sse"
13154   [(set (pc)
13155         (if_then_else (match_operator 0 "comparison_operator"
13156                         [(match_operand 1 "register_operand" "x")
13157                          (match_operand 2 "nonimmediate_operand" "xm")])
13158           (label_ref (match_operand 3 "" ""))
13159           (pc)))
13160    (clobber (reg:CCFP FPSR_REG))
13161    (clobber (reg:CCFP FLAGS_REG))]
13162   "TARGET_SSE_MATH
13163    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13164    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13165    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13166   "#")
13167
13168 (define_insn "*fp_jcc_1_387"
13169   [(set (pc)
13170         (if_then_else (match_operator 0 "comparison_operator"
13171                         [(match_operand 1 "register_operand" "f")
13172                          (match_operand 2 "register_operand" "f")])
13173           (label_ref (match_operand 3 "" ""))
13174           (pc)))
13175    (clobber (reg:CCFP FPSR_REG))
13176    (clobber (reg:CCFP FLAGS_REG))]
13177   "TARGET_CMOVE && TARGET_80387
13178    && FLOAT_MODE_P (GET_MODE (operands[1]))
13179    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13180    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13181   "#")
13182
13183 (define_insn "*fp_jcc_2_mixed"
13184   [(set (pc)
13185         (if_then_else (match_operator 0 "comparison_operator"
13186                         [(match_operand 1 "register_operand" "f#x,x#f")
13187                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13188           (pc)
13189           (label_ref (match_operand 3 "" ""))))
13190    (clobber (reg:CCFP FPSR_REG))
13191    (clobber (reg:CCFP FLAGS_REG))]
13192   "TARGET_MIX_SSE_I387
13193    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13194    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13195    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13196   "#")
13197
13198 (define_insn "*fp_jcc_2_sse"
13199   [(set (pc)
13200         (if_then_else (match_operator 0 "comparison_operator"
13201                         [(match_operand 1 "register_operand" "x")
13202                          (match_operand 2 "nonimmediate_operand" "xm")])
13203           (pc)
13204           (label_ref (match_operand 3 "" ""))))
13205    (clobber (reg:CCFP FPSR_REG))
13206    (clobber (reg:CCFP FLAGS_REG))]
13207   "TARGET_SSE_MATH
13208    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13209    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13210    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13211   "#")
13212
13213 (define_insn "*fp_jcc_2_387"
13214   [(set (pc)
13215         (if_then_else (match_operator 0 "comparison_operator"
13216                         [(match_operand 1 "register_operand" "f")
13217                          (match_operand 2 "register_operand" "f")])
13218           (pc)
13219           (label_ref (match_operand 3 "" ""))))
13220    (clobber (reg:CCFP FPSR_REG))
13221    (clobber (reg:CCFP FLAGS_REG))]
13222   "TARGET_CMOVE && TARGET_80387
13223    && FLOAT_MODE_P (GET_MODE (operands[1]))
13224    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13225    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13226   "#")
13227
13228 (define_insn "*fp_jcc_3_387"
13229   [(set (pc)
13230         (if_then_else (match_operator 0 "comparison_operator"
13231                         [(match_operand 1 "register_operand" "f")
13232                          (match_operand 2 "nonimmediate_operand" "fm")])
13233           (label_ref (match_operand 3 "" ""))
13234           (pc)))
13235    (clobber (reg:CCFP FPSR_REG))
13236    (clobber (reg:CCFP FLAGS_REG))
13237    (clobber (match_scratch:HI 4 "=a"))]
13238   "TARGET_80387
13239    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13240    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13241    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13242    && SELECT_CC_MODE (GET_CODE (operands[0]),
13243                       operands[1], operands[2]) == CCFPmode
13244    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13245   "#")
13246
13247 (define_insn "*fp_jcc_4_387"
13248   [(set (pc)
13249         (if_then_else (match_operator 0 "comparison_operator"
13250                         [(match_operand 1 "register_operand" "f")
13251                          (match_operand 2 "nonimmediate_operand" "fm")])
13252           (pc)
13253           (label_ref (match_operand 3 "" ""))))
13254    (clobber (reg:CCFP FPSR_REG))
13255    (clobber (reg:CCFP FLAGS_REG))
13256    (clobber (match_scratch:HI 4 "=a"))]
13257   "TARGET_80387
13258    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13259    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13260    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13261    && SELECT_CC_MODE (GET_CODE (operands[0]),
13262                       operands[1], operands[2]) == CCFPmode
13263    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13264   "#")
13265
13266 (define_insn "*fp_jcc_5_387"
13267   [(set (pc)
13268         (if_then_else (match_operator 0 "comparison_operator"
13269                         [(match_operand 1 "register_operand" "f")
13270                          (match_operand 2 "register_operand" "f")])
13271           (label_ref (match_operand 3 "" ""))
13272           (pc)))
13273    (clobber (reg:CCFP FPSR_REG))
13274    (clobber (reg:CCFP FLAGS_REG))
13275    (clobber (match_scratch:HI 4 "=a"))]
13276   "TARGET_80387
13277    && FLOAT_MODE_P (GET_MODE (operands[1]))
13278    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13279    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13280   "#")
13281
13282 (define_insn "*fp_jcc_6_387"
13283   [(set (pc)
13284         (if_then_else (match_operator 0 "comparison_operator"
13285                         [(match_operand 1 "register_operand" "f")
13286                          (match_operand 2 "register_operand" "f")])
13287           (pc)
13288           (label_ref (match_operand 3 "" ""))))
13289    (clobber (reg:CCFP FPSR_REG))
13290    (clobber (reg:CCFP FLAGS_REG))
13291    (clobber (match_scratch:HI 4 "=a"))]
13292   "TARGET_80387
13293    && FLOAT_MODE_P (GET_MODE (operands[1]))
13294    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13297
13298 (define_insn "*fp_jcc_7_387"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "const0_operand" "X")])
13303           (label_ref (match_operand 3 "" ""))
13304           (pc)))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && FLOAT_MODE_P (GET_MODE (operands[1]))
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13312    && SELECT_CC_MODE (GET_CODE (operands[0]),
13313                       operands[1], operands[2]) == CCFPmode
13314    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13315   "#")
13316
13317 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13318 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13319 ;; with a precedence over other operators and is always put in the first
13320 ;; place. Swap condition and operands to match ficom instruction.
13321
13322 (define_insn "*fp_jcc_8<mode>_387"
13323   [(set (pc)
13324         (if_then_else (match_operator 0 "comparison_operator"
13325                         [(match_operator 1 "float_operator"
13326                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13327                            (match_operand 3 "register_operand" "f,f")])
13328           (label_ref (match_operand 4 "" ""))
13329           (pc)))
13330    (clobber (reg:CCFP FPSR_REG))
13331    (clobber (reg:CCFP FLAGS_REG))
13332    (clobber (match_scratch:HI 5 "=a,a"))]
13333   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13334    && FLOAT_MODE_P (GET_MODE (operands[3]))
13335    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13336    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13337    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13338    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13339   "#")
13340
13341 (define_split
13342   [(set (pc)
13343         (if_then_else (match_operator 0 "comparison_operator"
13344                         [(match_operand 1 "register_operand" "")
13345                          (match_operand 2 "nonimmediate_operand" "")])
13346           (match_operand 3 "" "")
13347           (match_operand 4 "" "")))
13348    (clobber (reg:CCFP FPSR_REG))
13349    (clobber (reg:CCFP FLAGS_REG))]
13350   "reload_completed"
13351   [(const_int 0)]
13352 {
13353   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13354                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13355   DONE;
13356 })
13357
13358 (define_split
13359   [(set (pc)
13360         (if_then_else (match_operator 0 "comparison_operator"
13361                         [(match_operand 1 "register_operand" "")
13362                          (match_operand 2 "general_operand" "")])
13363           (match_operand 3 "" "")
13364           (match_operand 4 "" "")))
13365    (clobber (reg:CCFP FPSR_REG))
13366    (clobber (reg:CCFP FLAGS_REG))
13367    (clobber (match_scratch:HI 5 "=a"))]
13368   "reload_completed"
13369   [(const_int 0)]
13370 {
13371   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13372                         operands[3], operands[4], operands[5], NULL_RTX);
13373   DONE;
13374 })
13375
13376 (define_split
13377   [(set (pc)
13378         (if_then_else (match_operator 0 "comparison_operator"
13379                         [(match_operator 1 "float_operator"
13380                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13381                            (match_operand 3 "register_operand" "")])
13382           (match_operand 4 "" "")
13383           (match_operand 5 "" "")))
13384    (clobber (reg:CCFP FPSR_REG))
13385    (clobber (reg:CCFP FLAGS_REG))
13386    (clobber (match_scratch:HI 6 "=a"))]
13387   "reload_completed"
13388   [(const_int 0)]
13389 {
13390   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13391   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13392                         operands[3], operands[7],
13393                         operands[4], operands[5], operands[6], NULL_RTX);
13394   DONE;
13395 })
13396
13397 ;; %%% Kill this when reload knows how to do it.
13398 (define_split
13399   [(set (pc)
13400         (if_then_else (match_operator 0 "comparison_operator"
13401                         [(match_operator 1 "float_operator"
13402                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13403                            (match_operand 3 "register_operand" "")])
13404           (match_operand 4 "" "")
13405           (match_operand 5 "" "")))
13406    (clobber (reg:CCFP FPSR_REG))
13407    (clobber (reg:CCFP FLAGS_REG))
13408    (clobber (match_scratch:HI 6 "=a"))]
13409   "reload_completed"
13410   [(const_int 0)]
13411 {
13412   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13413   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13414   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13415                         operands[3], operands[7],
13416                         operands[4], operands[5], operands[6], operands[2]);
13417   DONE;
13418 })
13419 \f
13420 ;; Unconditional and other jump instructions
13421
13422 (define_insn "jump"
13423   [(set (pc)
13424         (label_ref (match_operand 0 "" "")))]
13425   ""
13426   "jmp\t%l0"
13427   [(set_attr "type" "ibr")
13428    (set (attr "length")
13429            (if_then_else (and (ge (minus (match_dup 0) (pc))
13430                                   (const_int -126))
13431                               (lt (minus (match_dup 0) (pc))
13432                                   (const_int 128)))
13433              (const_int 2)
13434              (const_int 5)))
13435    (set_attr "modrm" "0")])
13436
13437 (define_expand "indirect_jump"
13438   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13439   ""
13440   "")
13441
13442 (define_insn "*indirect_jump"
13443   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13444   "!TARGET_64BIT"
13445   "jmp\t%A0"
13446   [(set_attr "type" "ibr")
13447    (set_attr "length_immediate" "0")])
13448
13449 (define_insn "*indirect_jump_rtx64"
13450   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13451   "TARGET_64BIT"
13452   "jmp\t%A0"
13453   [(set_attr "type" "ibr")
13454    (set_attr "length_immediate" "0")])
13455
13456 (define_expand "tablejump"
13457   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13458               (use (label_ref (match_operand 1 "" "")))])]
13459   ""
13460 {
13461   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13462      relative.  Convert the relative address to an absolute address.  */
13463   if (flag_pic)
13464     {
13465       rtx op0, op1;
13466       enum rtx_code code;
13467
13468       if (TARGET_64BIT)
13469         {
13470           code = PLUS;
13471           op0 = operands[0];
13472           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13473         }
13474       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13475         {
13476           code = PLUS;
13477           op0 = operands[0];
13478           op1 = pic_offset_table_rtx;
13479         }
13480       else
13481         {
13482           code = MINUS;
13483           op0 = pic_offset_table_rtx;
13484           op1 = operands[0];
13485         }
13486
13487       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13488                                          OPTAB_DIRECT);
13489     }
13490 })
13491
13492 (define_insn "*tablejump_1"
13493   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13494    (use (label_ref (match_operand 1 "" "")))]
13495   "!TARGET_64BIT"
13496   "jmp\t%A0"
13497   [(set_attr "type" "ibr")
13498    (set_attr "length_immediate" "0")])
13499
13500 (define_insn "*tablejump_1_rtx64"
13501   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13502    (use (label_ref (match_operand 1 "" "")))]
13503   "TARGET_64BIT"
13504   "jmp\t%A0"
13505   [(set_attr "type" "ibr")
13506    (set_attr "length_immediate" "0")])
13507 \f
13508 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13509
13510 (define_peephole2
13511   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13512    (set (match_operand:QI 1 "register_operand" "")
13513         (match_operator:QI 2 "ix86_comparison_operator"
13514           [(reg FLAGS_REG) (const_int 0)]))
13515    (set (match_operand 3 "q_regs_operand" "")
13516         (zero_extend (match_dup 1)))]
13517   "(peep2_reg_dead_p (3, operands[1])
13518     || operands_match_p (operands[1], operands[3]))
13519    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13520   [(set (match_dup 4) (match_dup 0))
13521    (set (strict_low_part (match_dup 5))
13522         (match_dup 2))]
13523 {
13524   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13525   operands[5] = gen_lowpart (QImode, operands[3]);
13526   ix86_expand_clear (operands[3]);
13527 })
13528
13529 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13530
13531 (define_peephole2
13532   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13533    (set (match_operand:QI 1 "register_operand" "")
13534         (match_operator:QI 2 "ix86_comparison_operator"
13535           [(reg FLAGS_REG) (const_int 0)]))
13536    (parallel [(set (match_operand 3 "q_regs_operand" "")
13537                    (zero_extend (match_dup 1)))
13538               (clobber (reg:CC FLAGS_REG))])]
13539   "(peep2_reg_dead_p (3, operands[1])
13540     || operands_match_p (operands[1], operands[3]))
13541    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13542   [(set (match_dup 4) (match_dup 0))
13543    (set (strict_low_part (match_dup 5))
13544         (match_dup 2))]
13545 {
13546   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13547   operands[5] = gen_lowpart (QImode, operands[3]);
13548   ix86_expand_clear (operands[3]);
13549 })
13550 \f
13551 ;; Call instructions.
13552
13553 ;; The predicates normally associated with named expanders are not properly
13554 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13555 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13556
13557 ;; Call subroutine returning no value.
13558
13559 (define_expand "call_pop"
13560   [(parallel [(call (match_operand:QI 0 "" "")
13561                     (match_operand:SI 1 "" ""))
13562               (set (reg:SI SP_REG)
13563                    (plus:SI (reg:SI SP_REG)
13564                             (match_operand:SI 3 "" "")))])]
13565   "!TARGET_64BIT"
13566 {
13567   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13568   DONE;
13569 })
13570
13571 (define_insn "*call_pop_0"
13572   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13573          (match_operand:SI 1 "" ""))
13574    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13575                             (match_operand:SI 2 "immediate_operand" "")))]
13576   "!TARGET_64BIT"
13577 {
13578   if (SIBLING_CALL_P (insn))
13579     return "jmp\t%P0";
13580   else
13581     return "call\t%P0";
13582 }
13583   [(set_attr "type" "call")])
13584   
13585 (define_insn "*call_pop_1"
13586   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13587          (match_operand:SI 1 "" ""))
13588    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13589                             (match_operand:SI 2 "immediate_operand" "i")))]
13590   "!TARGET_64BIT"
13591 {
13592   if (constant_call_address_operand (operands[0], Pmode))
13593     {
13594       if (SIBLING_CALL_P (insn))
13595         return "jmp\t%P0";
13596       else
13597         return "call\t%P0";
13598     }
13599   if (SIBLING_CALL_P (insn))
13600     return "jmp\t%A0";
13601   else
13602     return "call\t%A0";
13603 }
13604   [(set_attr "type" "call")])
13605
13606 (define_expand "call"
13607   [(call (match_operand:QI 0 "" "")
13608          (match_operand 1 "" ""))
13609    (use (match_operand 2 "" ""))]
13610   ""
13611 {
13612   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13613   DONE;
13614 })
13615
13616 (define_expand "sibcall"
13617   [(call (match_operand:QI 0 "" "")
13618          (match_operand 1 "" ""))
13619    (use (match_operand 2 "" ""))]
13620   ""
13621 {
13622   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13623   DONE;
13624 })
13625
13626 (define_insn "*call_0"
13627   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13628          (match_operand 1 "" ""))]
13629   ""
13630 {
13631   if (SIBLING_CALL_P (insn))
13632     return "jmp\t%P0";
13633   else
13634     return "call\t%P0";
13635 }
13636   [(set_attr "type" "call")])
13637
13638 (define_insn "*call_1"
13639   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13640          (match_operand 1 "" ""))]
13641   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13642 {
13643   if (constant_call_address_operand (operands[0], Pmode))
13644     return "call\t%P0";
13645   return "call\t%A0";
13646 }
13647   [(set_attr "type" "call")])
13648
13649 (define_insn "*sibcall_1"
13650   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13651          (match_operand 1 "" ""))]
13652   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13653 {
13654   if (constant_call_address_operand (operands[0], Pmode))
13655     return "jmp\t%P0";
13656   return "jmp\t%A0";
13657 }
13658   [(set_attr "type" "call")])
13659
13660 (define_insn "*call_1_rex64"
13661   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13662          (match_operand 1 "" ""))]
13663   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13664 {
13665   if (constant_call_address_operand (operands[0], Pmode))
13666     return "call\t%P0";
13667   return "call\t%A0";
13668 }
13669   [(set_attr "type" "call")])
13670
13671 (define_insn "*sibcall_1_rex64"
13672   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13673          (match_operand 1 "" ""))]
13674   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13675   "jmp\t%P0"
13676   [(set_attr "type" "call")])
13677
13678 (define_insn "*sibcall_1_rex64_v"
13679   [(call (mem:QI (reg:DI 40))
13680          (match_operand 0 "" ""))]
13681   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13682   "jmp\t*%%r11"
13683   [(set_attr "type" "call")])
13684
13685
13686 ;; Call subroutine, returning value in operand 0
13687
13688 (define_expand "call_value_pop"
13689   [(parallel [(set (match_operand 0 "" "")
13690                    (call (match_operand:QI 1 "" "")
13691                          (match_operand:SI 2 "" "")))
13692               (set (reg:SI SP_REG)
13693                    (plus:SI (reg:SI SP_REG)
13694                             (match_operand:SI 4 "" "")))])]
13695   "!TARGET_64BIT"
13696 {
13697   ix86_expand_call (operands[0], operands[1], operands[2],
13698                     operands[3], operands[4], 0);
13699   DONE;
13700 })
13701
13702 (define_expand "call_value"
13703   [(set (match_operand 0 "" "")
13704         (call (match_operand:QI 1 "" "")
13705               (match_operand:SI 2 "" "")))
13706    (use (match_operand:SI 3 "" ""))]
13707   ;; Operand 2 not used on the i386.
13708   ""
13709 {
13710   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13711   DONE;
13712 })
13713
13714 (define_expand "sibcall_value"
13715   [(set (match_operand 0 "" "")
13716         (call (match_operand:QI 1 "" "")
13717               (match_operand:SI 2 "" "")))
13718    (use (match_operand:SI 3 "" ""))]
13719   ;; Operand 2 not used on the i386.
13720   ""
13721 {
13722   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13723   DONE;
13724 })
13725
13726 ;; Call subroutine returning any type.
13727
13728 (define_expand "untyped_call"
13729   [(parallel [(call (match_operand 0 "" "")
13730                     (const_int 0))
13731               (match_operand 1 "" "")
13732               (match_operand 2 "" "")])]
13733   ""
13734 {
13735   int i;
13736
13737   /* In order to give reg-stack an easier job in validating two
13738      coprocessor registers as containing a possible return value,
13739      simply pretend the untyped call returns a complex long double
13740      value.  */
13741
13742   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13743                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13744                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13745                     NULL, 0);
13746
13747   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13748     {
13749       rtx set = XVECEXP (operands[2], 0, i);
13750       emit_move_insn (SET_DEST (set), SET_SRC (set));
13751     }
13752
13753   /* The optimizer does not know that the call sets the function value
13754      registers we stored in the result block.  We avoid problems by
13755      claiming that all hard registers are used and clobbered at this
13756      point.  */
13757   emit_insn (gen_blockage (const0_rtx));
13758
13759   DONE;
13760 })
13761 \f
13762 ;; Prologue and epilogue instructions
13763
13764 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13765 ;; all of memory.  This blocks insns from being moved across this point.
13766
13767 (define_insn "blockage"
13768   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13769   ""
13770   ""
13771   [(set_attr "length" "0")])
13772
13773 ;; Insn emitted into the body of a function to return from a function.
13774 ;; This is only done if the function's epilogue is known to be simple.
13775 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13776
13777 (define_expand "return"
13778   [(return)]
13779   "ix86_can_use_return_insn_p ()"
13780 {
13781   if (current_function_pops_args)
13782     {
13783       rtx popc = GEN_INT (current_function_pops_args);
13784       emit_jump_insn (gen_return_pop_internal (popc));
13785       DONE;
13786     }
13787 })
13788
13789 (define_insn "return_internal"
13790   [(return)]
13791   "reload_completed"
13792   "ret"
13793   [(set_attr "length" "1")
13794    (set_attr "length_immediate" "0")
13795    (set_attr "modrm" "0")])
13796
13797 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13798 ;; instruction Athlon and K8 have.
13799
13800 (define_insn "return_internal_long"
13801   [(return)
13802    (unspec [(const_int 0)] UNSPEC_REP)]
13803   "reload_completed"
13804   "rep {;} ret"
13805   [(set_attr "length" "1")
13806    (set_attr "length_immediate" "0")
13807    (set_attr "prefix_rep" "1")
13808    (set_attr "modrm" "0")])
13809
13810 (define_insn "return_pop_internal"
13811   [(return)
13812    (use (match_operand:SI 0 "const_int_operand" ""))]
13813   "reload_completed"
13814   "ret\t%0"
13815   [(set_attr "length" "3")
13816    (set_attr "length_immediate" "2")
13817    (set_attr "modrm" "0")])
13818
13819 (define_insn "return_indirect_internal"
13820   [(return)
13821    (use (match_operand:SI 0 "register_operand" "r"))]
13822   "reload_completed"
13823   "jmp\t%A0"
13824   [(set_attr "type" "ibr")
13825    (set_attr "length_immediate" "0")])
13826
13827 (define_insn "nop"
13828   [(const_int 0)]
13829   ""
13830   "nop"
13831   [(set_attr "length" "1")
13832    (set_attr "length_immediate" "0")
13833    (set_attr "modrm" "0")])
13834
13835 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13836 ;; branch prediction penalty for the third jump in a 16-byte
13837 ;; block on K8.
13838
13839 (define_insn "align"
13840   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13841   ""
13842 {
13843 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13844   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13845 #else
13846   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13847      The align insn is used to avoid 3 jump instructions in the row to improve
13848      branch prediction and the benefits hardly outweight the cost of extra 8
13849      nops on the average inserted by full alignment pseudo operation.  */
13850 #endif
13851   return "";
13852 }
13853   [(set_attr "length" "16")])
13854
13855 (define_expand "prologue"
13856   [(const_int 1)]
13857   ""
13858   "ix86_expand_prologue (); DONE;")
13859
13860 (define_insn "set_got"
13861   [(set (match_operand:SI 0 "register_operand" "=r")
13862         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13863    (clobber (reg:CC FLAGS_REG))]
13864   "!TARGET_64BIT"
13865   { return output_set_got (operands[0]); }
13866   [(set_attr "type" "multi")
13867    (set_attr "length" "12")])
13868
13869 (define_insn "set_got_rex64"
13870   [(set (match_operand:DI 0 "register_operand" "=r")
13871         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13872   "TARGET_64BIT"
13873   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13874   [(set_attr "type" "lea")
13875    (set_attr "length" "6")])
13876
13877 (define_expand "epilogue"
13878   [(const_int 1)]
13879   ""
13880   "ix86_expand_epilogue (1); DONE;")
13881
13882 (define_expand "sibcall_epilogue"
13883   [(const_int 1)]
13884   ""
13885   "ix86_expand_epilogue (0); DONE;")
13886
13887 (define_expand "eh_return"
13888   [(use (match_operand 0 "register_operand" ""))]
13889   ""
13890 {
13891   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13892
13893   /* Tricky bit: we write the address of the handler to which we will
13894      be returning into someone else's stack frame, one word below the
13895      stack address we wish to restore.  */
13896   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13897   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13898   tmp = gen_rtx_MEM (Pmode, tmp);
13899   emit_move_insn (tmp, ra);
13900
13901   if (Pmode == SImode)
13902     emit_jump_insn (gen_eh_return_si (sa));
13903   else
13904     emit_jump_insn (gen_eh_return_di (sa));
13905   emit_barrier ();
13906   DONE;
13907 })
13908
13909 (define_insn_and_split "eh_return_si"
13910   [(set (pc) 
13911         (unspec [(match_operand:SI 0 "register_operand" "c")]
13912                  UNSPEC_EH_RETURN))]
13913   "!TARGET_64BIT"
13914   "#"
13915   "reload_completed"
13916   [(const_int 1)]
13917   "ix86_expand_epilogue (2); DONE;")
13918
13919 (define_insn_and_split "eh_return_di"
13920   [(set (pc) 
13921         (unspec [(match_operand:DI 0 "register_operand" "c")]
13922                  UNSPEC_EH_RETURN))]
13923   "TARGET_64BIT"
13924   "#"
13925   "reload_completed"
13926   [(const_int 1)]
13927   "ix86_expand_epilogue (2); DONE;")
13928
13929 (define_insn "leave"
13930   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13931    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13932    (clobber (mem:BLK (scratch)))]
13933   "!TARGET_64BIT"
13934   "leave"
13935   [(set_attr "type" "leave")])
13936
13937 (define_insn "leave_rex64"
13938   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13939    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13940    (clobber (mem:BLK (scratch)))]
13941   "TARGET_64BIT"
13942   "leave"
13943   [(set_attr "type" "leave")])
13944 \f
13945 (define_expand "ffssi2"
13946   [(parallel
13947      [(set (match_operand:SI 0 "register_operand" "") 
13948            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13949       (clobber (match_scratch:SI 2 ""))
13950       (clobber (reg:CC FLAGS_REG))])]
13951   ""
13952   "")
13953
13954 (define_insn_and_split "*ffs_cmove"
13955   [(set (match_operand:SI 0 "register_operand" "=r") 
13956         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13957    (clobber (match_scratch:SI 2 "=&r"))
13958    (clobber (reg:CC FLAGS_REG))]
13959   "TARGET_CMOVE"
13960   "#"
13961   "&& reload_completed"
13962   [(set (match_dup 2) (const_int -1))
13963    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13964               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13965    (set (match_dup 0) (if_then_else:SI
13966                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13967                         (match_dup 2)
13968                         (match_dup 0)))
13969    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13970               (clobber (reg:CC FLAGS_REG))])]
13971   "")
13972
13973 (define_insn_and_split "*ffs_no_cmove"
13974   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13975         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13976    (clobber (match_scratch:SI 2 "=&q"))
13977    (clobber (reg:CC FLAGS_REG))]
13978   ""
13979   "#"
13980   "reload_completed"
13981   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13982               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13983    (set (strict_low_part (match_dup 3))
13984         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13985    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13986               (clobber (reg:CC FLAGS_REG))])
13987    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13988               (clobber (reg:CC FLAGS_REG))])
13989    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13990               (clobber (reg:CC FLAGS_REG))])]
13991 {
13992   operands[3] = gen_lowpart (QImode, operands[2]);
13993   ix86_expand_clear (operands[2]);
13994 })
13995
13996 (define_insn "*ffssi_1"
13997   [(set (reg:CCZ FLAGS_REG)
13998         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13999                      (const_int 0)))
14000    (set (match_operand:SI 0 "register_operand" "=r")
14001         (ctz:SI (match_dup 1)))]
14002   ""
14003   "bsf{l}\t{%1, %0|%0, %1}"
14004   [(set_attr "prefix_0f" "1")])
14005
14006 (define_expand "ffsdi2"
14007   [(parallel
14008      [(set (match_operand:DI 0 "register_operand" "") 
14009            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14010       (clobber (match_scratch:DI 2 ""))
14011       (clobber (reg:CC FLAGS_REG))])]
14012   "TARGET_64BIT && TARGET_CMOVE"
14013   "")
14014
14015 (define_insn_and_split "*ffs_rex64"
14016   [(set (match_operand:DI 0 "register_operand" "=r") 
14017         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:DI 2 "=&r"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   "TARGET_64BIT && TARGET_CMOVE"
14021   "#"
14022   "&& reload_completed"
14023   [(set (match_dup 2) (const_int -1))
14024    (parallel [(set (reg:CCZ FLAGS_REG)
14025                    (compare:CCZ (match_dup 1) (const_int 0)))
14026               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14027    (set (match_dup 0) (if_then_else:DI
14028                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14029                         (match_dup 2)
14030                         (match_dup 0)))
14031    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033   "")
14034
14035 (define_insn "*ffsdi_1"
14036   [(set (reg:CCZ FLAGS_REG)
14037         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14038                      (const_int 0)))
14039    (set (match_operand:DI 0 "register_operand" "=r")
14040         (ctz:DI (match_dup 1)))]
14041   "TARGET_64BIT"
14042   "bsf{q}\t{%1, %0|%0, %1}"
14043   [(set_attr "prefix_0f" "1")])
14044
14045 (define_insn "ctzsi2"
14046   [(set (match_operand:SI 0 "register_operand" "=r")
14047         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14048    (clobber (reg:CC FLAGS_REG))]
14049   ""
14050   "bsf{l}\t{%1, %0|%0, %1}"
14051   [(set_attr "prefix_0f" "1")])
14052
14053 (define_insn "ctzdi2"
14054   [(set (match_operand:DI 0 "register_operand" "=r")
14055         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14056    (clobber (reg:CC FLAGS_REG))]
14057   "TARGET_64BIT"
14058   "bsf{q}\t{%1, %0|%0, %1}"
14059   [(set_attr "prefix_0f" "1")])
14060
14061 (define_expand "clzsi2"
14062   [(parallel
14063      [(set (match_operand:SI 0 "register_operand" "")
14064            (minus:SI (const_int 31)
14065                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14066       (clobber (reg:CC FLAGS_REG))])
14067    (parallel
14068      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14069       (clobber (reg:CC FLAGS_REG))])]
14070   ""
14071   "")
14072
14073 (define_insn "*bsr"
14074   [(set (match_operand:SI 0 "register_operand" "=r")
14075         (minus:SI (const_int 31)
14076                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14077    (clobber (reg:CC FLAGS_REG))]
14078   ""
14079   "bsr{l}\t{%1, %0|%0, %1}"
14080   [(set_attr "prefix_0f" "1")])
14081
14082 (define_expand "clzdi2"
14083   [(parallel
14084      [(set (match_operand:DI 0 "register_operand" "")
14085            (minus:DI (const_int 63)
14086                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14087       (clobber (reg:CC FLAGS_REG))])
14088    (parallel
14089      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14090       (clobber (reg:CC FLAGS_REG))])]
14091   "TARGET_64BIT"
14092   "")
14093
14094 (define_insn "*bsr_rex64"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (minus:DI (const_int 63)
14097                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14098    (clobber (reg:CC FLAGS_REG))]
14099   "TARGET_64BIT"
14100   "bsr{q}\t{%1, %0|%0, %1}"
14101   [(set_attr "prefix_0f" "1")])
14102 \f
14103 ;; Thread-local storage patterns for ELF.
14104 ;;
14105 ;; Note that these code sequences must appear exactly as shown
14106 ;; in order to allow linker relaxation.
14107
14108 (define_insn "*tls_global_dynamic_32_gnu"
14109   [(set (match_operand:SI 0 "register_operand" "=a")
14110         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14111                     (match_operand:SI 2 "tls_symbolic_operand" "")
14112                     (match_operand:SI 3 "call_insn_operand" "")]
14113                     UNSPEC_TLS_GD))
14114    (clobber (match_scratch:SI 4 "=d"))
14115    (clobber (match_scratch:SI 5 "=c"))
14116    (clobber (reg:CC FLAGS_REG))]
14117   "!TARGET_64BIT && TARGET_GNU_TLS"
14118   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14119   [(set_attr "type" "multi")
14120    (set_attr "length" "12")])
14121
14122 (define_insn "*tls_global_dynamic_32_sun"
14123   [(set (match_operand:SI 0 "register_operand" "=a")
14124         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14125                     (match_operand:SI 2 "tls_symbolic_operand" "")
14126                     (match_operand:SI 3 "call_insn_operand" "")]
14127                     UNSPEC_TLS_GD))
14128    (clobber (match_scratch:SI 4 "=d"))
14129    (clobber (match_scratch:SI 5 "=c"))
14130    (clobber (reg:CC FLAGS_REG))]
14131   "!TARGET_64BIT && TARGET_SUN_TLS"
14132   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14133         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14134   [(set_attr "type" "multi")
14135    (set_attr "length" "14")])
14136
14137 (define_expand "tls_global_dynamic_32"
14138   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14139                    (unspec:SI
14140                     [(match_dup 2)
14141                      (match_operand:SI 1 "tls_symbolic_operand" "")
14142                      (match_dup 3)]
14143                     UNSPEC_TLS_GD))
14144               (clobber (match_scratch:SI 4 ""))
14145               (clobber (match_scratch:SI 5 ""))
14146               (clobber (reg:CC FLAGS_REG))])]
14147   ""
14148 {
14149   if (flag_pic)
14150     operands[2] = pic_offset_table_rtx;
14151   else
14152     {
14153       operands[2] = gen_reg_rtx (Pmode);
14154       emit_insn (gen_set_got (operands[2]));
14155     }
14156   operands[3] = ix86_tls_get_addr ();
14157 })
14158
14159 (define_insn "*tls_global_dynamic_64"
14160   [(set (match_operand:DI 0 "register_operand" "=a")
14161         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14162                  (match_operand:DI 3 "" "")))
14163    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14164               UNSPEC_TLS_GD)]
14165   "TARGET_64BIT"
14166   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14167   [(set_attr "type" "multi")
14168    (set_attr "length" "16")])
14169
14170 (define_expand "tls_global_dynamic_64"
14171   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14172                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14173               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14174                          UNSPEC_TLS_GD)])]
14175   ""
14176 {
14177   operands[2] = ix86_tls_get_addr ();
14178 })
14179
14180 (define_insn "*tls_local_dynamic_base_32_gnu"
14181   [(set (match_operand:SI 0 "register_operand" "=a")
14182         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14183                     (match_operand:SI 2 "call_insn_operand" "")]
14184                    UNSPEC_TLS_LD_BASE))
14185    (clobber (match_scratch:SI 3 "=d"))
14186    (clobber (match_scratch:SI 4 "=c"))
14187    (clobber (reg:CC FLAGS_REG))]
14188   "!TARGET_64BIT && TARGET_GNU_TLS"
14189   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14190   [(set_attr "type" "multi")
14191    (set_attr "length" "11")])
14192
14193 (define_insn "*tls_local_dynamic_base_32_sun"
14194   [(set (match_operand:SI 0 "register_operand" "=a")
14195         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14196                     (match_operand:SI 2 "call_insn_operand" "")]
14197                    UNSPEC_TLS_LD_BASE))
14198    (clobber (match_scratch:SI 3 "=d"))
14199    (clobber (match_scratch:SI 4 "=c"))
14200    (clobber (reg:CC FLAGS_REG))]
14201   "!TARGET_64BIT && TARGET_SUN_TLS"
14202   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14203         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14204   [(set_attr "type" "multi")
14205    (set_attr "length" "13")])
14206
14207 (define_expand "tls_local_dynamic_base_32"
14208   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14209                    (unspec:SI [(match_dup 1) (match_dup 2)]
14210                               UNSPEC_TLS_LD_BASE))
14211               (clobber (match_scratch:SI 3 ""))
14212               (clobber (match_scratch:SI 4 ""))
14213               (clobber (reg:CC FLAGS_REG))])]
14214   ""
14215 {
14216   if (flag_pic)
14217     operands[1] = pic_offset_table_rtx;
14218   else
14219     {
14220       operands[1] = gen_reg_rtx (Pmode);
14221       emit_insn (gen_set_got (operands[1]));
14222     }
14223   operands[2] = ix86_tls_get_addr ();
14224 })
14225
14226 (define_insn "*tls_local_dynamic_base_64"
14227   [(set (match_operand:DI 0 "register_operand" "=a")
14228         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14229                  (match_operand:DI 2 "" "")))
14230    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14231   "TARGET_64BIT"
14232   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14233   [(set_attr "type" "multi")
14234    (set_attr "length" "12")])
14235
14236 (define_expand "tls_local_dynamic_base_64"
14237   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14238                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14239               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14240   ""
14241 {
14242   operands[1] = ix86_tls_get_addr ();
14243 })
14244
14245 ;; Local dynamic of a single variable is a lose.  Show combine how
14246 ;; to convert that back to global dynamic.
14247
14248 (define_insn_and_split "*tls_local_dynamic_32_once"
14249   [(set (match_operand:SI 0 "register_operand" "=a")
14250         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14251                              (match_operand:SI 2 "call_insn_operand" "")]
14252                             UNSPEC_TLS_LD_BASE)
14253                  (const:SI (unspec:SI
14254                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14255                             UNSPEC_DTPOFF))))
14256    (clobber (match_scratch:SI 4 "=d"))
14257    (clobber (match_scratch:SI 5 "=c"))
14258    (clobber (reg:CC FLAGS_REG))]
14259   ""
14260   "#"
14261   ""
14262   [(parallel [(set (match_dup 0)
14263                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14264                               UNSPEC_TLS_GD))
14265               (clobber (match_dup 4))
14266               (clobber (match_dup 5))
14267               (clobber (reg:CC FLAGS_REG))])]
14268   "")
14269
14270 ;; Load and add the thread base pointer from %gs:0.
14271
14272 (define_insn "*load_tp_si"
14273   [(set (match_operand:SI 0 "register_operand" "=r")
14274         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14275   "!TARGET_64BIT"
14276   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14277   [(set_attr "type" "imov")
14278    (set_attr "modrm" "0")
14279    (set_attr "length" "7")
14280    (set_attr "memory" "load")
14281    (set_attr "imm_disp" "false")])
14282
14283 (define_insn "*add_tp_si"
14284   [(set (match_operand:SI 0 "register_operand" "=r")
14285         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14286                  (match_operand:SI 1 "register_operand" "0")))
14287    (clobber (reg:CC FLAGS_REG))]
14288   "!TARGET_64BIT"
14289   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14290   [(set_attr "type" "alu")
14291    (set_attr "modrm" "0")
14292    (set_attr "length" "7")
14293    (set_attr "memory" "load")
14294    (set_attr "imm_disp" "false")])
14295
14296 (define_insn "*load_tp_di"
14297   [(set (match_operand:DI 0 "register_operand" "=r")
14298         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14299   "TARGET_64BIT"
14300   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14301   [(set_attr "type" "imov")
14302    (set_attr "modrm" "0")
14303    (set_attr "length" "7")
14304    (set_attr "memory" "load")
14305    (set_attr "imm_disp" "false")])
14306
14307 (define_insn "*add_tp_di"
14308   [(set (match_operand:DI 0 "register_operand" "=r")
14309         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14310                  (match_operand:DI 1 "register_operand" "0")))
14311    (clobber (reg:CC FLAGS_REG))]
14312   "TARGET_64BIT"
14313   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14314   [(set_attr "type" "alu")
14315    (set_attr "modrm" "0")
14316    (set_attr "length" "7")
14317    (set_attr "memory" "load")
14318    (set_attr "imm_disp" "false")])
14319 \f
14320 ;; These patterns match the binary 387 instructions for addM3, subM3,
14321 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14322 ;; SFmode.  The first is the normal insn, the second the same insn but
14323 ;; with one operand a conversion, and the third the same insn but with
14324 ;; the other operand a conversion.  The conversion may be SFmode or
14325 ;; SImode if the target mode DFmode, but only SImode if the target mode
14326 ;; is SFmode.
14327
14328 ;; Gcc is slightly more smart about handling normal two address instructions
14329 ;; so use special patterns for add and mull.
14330
14331 (define_insn "*fop_sf_comm_mixed"
14332   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14333         (match_operator:SF 3 "binary_fp_operator"
14334                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14335                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14336   "TARGET_MIX_SSE_I387
14337    && COMMUTATIVE_ARITH_P (operands[3])
14338    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14339   "* return output_387_binary_op (insn, operands);"
14340   [(set (attr "type") 
14341         (if_then_else (eq_attr "alternative" "1")
14342            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14343               (const_string "ssemul")
14344               (const_string "sseadd"))
14345            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14346               (const_string "fmul")
14347               (const_string "fop"))))
14348    (set_attr "mode" "SF")])
14349
14350 (define_insn "*fop_sf_comm_sse"
14351   [(set (match_operand:SF 0 "register_operand" "=x")
14352         (match_operator:SF 3 "binary_fp_operator"
14353                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14354                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14355   "TARGET_SSE_MATH
14356    && COMMUTATIVE_ARITH_P (operands[3])
14357    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14358   "* return output_387_binary_op (insn, operands);"
14359   [(set (attr "type") 
14360         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14361            (const_string "ssemul")
14362            (const_string "sseadd")))
14363    (set_attr "mode" "SF")])
14364
14365 (define_insn "*fop_sf_comm_i387"
14366   [(set (match_operand:SF 0 "register_operand" "=f")
14367         (match_operator:SF 3 "binary_fp_operator"
14368                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14369                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14370   "TARGET_80387
14371    && COMMUTATIVE_ARITH_P (operands[3])
14372    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14373   "* return output_387_binary_op (insn, operands);"
14374   [(set (attr "type") 
14375         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14376            (const_string "fmul")
14377            (const_string "fop")))
14378    (set_attr "mode" "SF")])
14379
14380 (define_insn "*fop_sf_1_mixed"
14381   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14382         (match_operator:SF 3 "binary_fp_operator"
14383                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14384                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14385   "TARGET_MIX_SSE_I387
14386    && !COMMUTATIVE_ARITH_P (operands[3])
14387    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14388   "* return output_387_binary_op (insn, operands);"
14389   [(set (attr "type") 
14390         (cond [(and (eq_attr "alternative" "2")
14391                     (match_operand:SF 3 "mult_operator" ""))
14392                  (const_string "ssemul")
14393                (and (eq_attr "alternative" "2")
14394                     (match_operand:SF 3 "div_operator" ""))
14395                  (const_string "ssediv")
14396                (eq_attr "alternative" "2")
14397                  (const_string "sseadd")
14398                (match_operand:SF 3 "mult_operator" "") 
14399                  (const_string "fmul")
14400                (match_operand:SF 3 "div_operator" "") 
14401                  (const_string "fdiv")
14402               ]
14403               (const_string "fop")))
14404    (set_attr "mode" "SF")])
14405
14406 (define_insn "*fop_sf_1_sse"
14407   [(set (match_operand:SF 0 "register_operand" "=x")
14408         (match_operator:SF 3 "binary_fp_operator"
14409                         [(match_operand:SF 1 "register_operand" "0")
14410                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14411   "TARGET_SSE_MATH
14412    && !COMMUTATIVE_ARITH_P (operands[3])"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (cond [(match_operand:SF 3 "mult_operator" "")
14416                  (const_string "ssemul")
14417                (match_operand:SF 3 "div_operator" "")
14418                  (const_string "ssediv")
14419               ]
14420               (const_string "sseadd")))
14421    (set_attr "mode" "SF")])
14422
14423 ;; This pattern is not fully shadowed by the pattern above.
14424 (define_insn "*fop_sf_1_i387"
14425   [(set (match_operand:SF 0 "register_operand" "=f,f")
14426         (match_operator:SF 3 "binary_fp_operator"
14427                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14428                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14429   "TARGET_80387 && !TARGET_SSE_MATH
14430    && !COMMUTATIVE_ARITH_P (operands[3])
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (cond [(match_operand:SF 3 "mult_operator" "") 
14435                  (const_string "fmul")
14436                (match_operand:SF 3 "div_operator" "") 
14437                  (const_string "fdiv")
14438               ]
14439               (const_string "fop")))
14440    (set_attr "mode" "SF")])
14441
14442 ;; ??? Add SSE splitters for these!
14443 (define_insn "*fop_sf_2<mode>_i387"
14444   [(set (match_operand:SF 0 "register_operand" "=f,f")
14445         (match_operator:SF 3 "binary_fp_operator"
14446           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14447            (match_operand:SF 2 "register_operand" "0,0")]))]
14448   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14449   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14450   [(set (attr "type") 
14451         (cond [(match_operand:SF 3 "mult_operator" "") 
14452                  (const_string "fmul")
14453                (match_operand:SF 3 "div_operator" "") 
14454                  (const_string "fdiv")
14455               ]
14456               (const_string "fop")))
14457    (set_attr "fp_int_src" "true")
14458    (set_attr "mode" "<MODE>")])
14459
14460 (define_insn "*fop_sf_3<mode>_i387"
14461   [(set (match_operand:SF 0 "register_operand" "=f,f")
14462         (match_operator:SF 3 "binary_fp_operator"
14463           [(match_operand:SF 1 "register_operand" "0,0")
14464            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14465   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14466   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14467   [(set (attr "type") 
14468         (cond [(match_operand:SF 3 "mult_operator" "") 
14469                  (const_string "fmul")
14470                (match_operand:SF 3 "div_operator" "") 
14471                  (const_string "fdiv")
14472               ]
14473               (const_string "fop")))
14474    (set_attr "fp_int_src" "true")
14475    (set_attr "mode" "<MODE>")])
14476
14477 (define_insn "*fop_df_comm_mixed"
14478   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14479         (match_operator:DF 3 "binary_fp_operator"
14480                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14481                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14482   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14483    && COMMUTATIVE_ARITH_P (operands[3])
14484    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14485   "* return output_387_binary_op (insn, operands);"
14486   [(set (attr "type") 
14487         (if_then_else (eq_attr "alternative" "1")
14488            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14489               (const_string "ssemul")
14490               (const_string "sseadd"))
14491            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14492               (const_string "fmul")
14493               (const_string "fop"))))
14494    (set_attr "mode" "DF")])
14495
14496 (define_insn "*fop_df_comm_sse"
14497   [(set (match_operand:DF 0 "register_operand" "=Y")
14498         (match_operator:DF 3 "binary_fp_operator"
14499                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14500                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14501   "TARGET_SSE2 && TARGET_SSE_MATH
14502    && COMMUTATIVE_ARITH_P (operands[3])
14503    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14507            (const_string "ssemul")
14508            (const_string "sseadd")))
14509    (set_attr "mode" "DF")])
14510
14511 (define_insn "*fop_df_comm_i387"
14512   [(set (match_operand:DF 0 "register_operand" "=f")
14513         (match_operator:DF 3 "binary_fp_operator"
14514                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14515                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14516   "TARGET_80387
14517    && COMMUTATIVE_ARITH_P (operands[3])
14518    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14519   "* return output_387_binary_op (insn, operands);"
14520   [(set (attr "type") 
14521         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14522            (const_string "fmul")
14523            (const_string "fop")))
14524    (set_attr "mode" "DF")])
14525
14526 (define_insn "*fop_df_1_mixed"
14527   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14528         (match_operator:DF 3 "binary_fp_operator"
14529                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14530                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14531   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14532    && !COMMUTATIVE_ARITH_P (operands[3])
14533    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14534   "* return output_387_binary_op (insn, operands);"
14535   [(set (attr "type") 
14536         (cond [(and (eq_attr "alternative" "2")
14537                     (match_operand:SF 3 "mult_operator" ""))
14538                  (const_string "ssemul")
14539                (and (eq_attr "alternative" "2")
14540                     (match_operand:SF 3 "div_operator" ""))
14541                  (const_string "ssediv")
14542                (eq_attr "alternative" "2")
14543                  (const_string "sseadd")
14544                (match_operand:DF 3 "mult_operator" "") 
14545                  (const_string "fmul")
14546                (match_operand:DF 3 "div_operator" "") 
14547                  (const_string "fdiv")
14548               ]
14549               (const_string "fop")))
14550    (set_attr "mode" "DF")])
14551
14552 (define_insn "*fop_df_1_sse"
14553   [(set (match_operand:DF 0 "register_operand" "=Y")
14554         (match_operator:DF 3 "binary_fp_operator"
14555                         [(match_operand:DF 1 "register_operand" "0")
14556                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14557   "TARGET_SSE2 && TARGET_SSE_MATH
14558    && !COMMUTATIVE_ARITH_P (operands[3])"
14559   "* return output_387_binary_op (insn, operands);"
14560   [(set_attr "mode" "DF")
14561    (set (attr "type") 
14562         (cond [(match_operand:SF 3 "mult_operator" "")
14563                  (const_string "ssemul")
14564                (match_operand:SF 3 "div_operator" "")
14565                  (const_string "ssediv")
14566               ]
14567               (const_string "sseadd")))])
14568
14569 ;; This pattern is not fully shadowed by the pattern above.
14570 (define_insn "*fop_df_1_i387"
14571   [(set (match_operand:DF 0 "register_operand" "=f,f")
14572         (match_operator:DF 3 "binary_fp_operator"
14573                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14574                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14575   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14576    && !COMMUTATIVE_ARITH_P (operands[3])
14577    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14578   "* return output_387_binary_op (insn, operands);"
14579   [(set (attr "type") 
14580         (cond [(match_operand:DF 3 "mult_operator" "") 
14581                  (const_string "fmul")
14582                (match_operand:DF 3 "div_operator" "")
14583                  (const_string "fdiv")
14584               ]
14585               (const_string "fop")))
14586    (set_attr "mode" "DF")])
14587
14588 ;; ??? Add SSE splitters for these!
14589 (define_insn "*fop_df_2<mode>_i387"
14590   [(set (match_operand:DF 0 "register_operand" "=f,f")
14591         (match_operator:DF 3 "binary_fp_operator"
14592            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14593             (match_operand:DF 2 "register_operand" "0,0")]))]
14594   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14595    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14596   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14597   [(set (attr "type") 
14598         (cond [(match_operand:DF 3 "mult_operator" "") 
14599                  (const_string "fmul")
14600                (match_operand:DF 3 "div_operator" "") 
14601                  (const_string "fdiv")
14602               ]
14603               (const_string "fop")))
14604    (set_attr "fp_int_src" "true")
14605    (set_attr "mode" "<MODE>")])
14606
14607 (define_insn "*fop_df_3<mode>_i387"
14608   [(set (match_operand:DF 0 "register_operand" "=f,f")
14609         (match_operator:DF 3 "binary_fp_operator"
14610            [(match_operand:DF 1 "register_operand" "0,0")
14611             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14612   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14613    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14614   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14615   [(set (attr "type") 
14616         (cond [(match_operand:DF 3 "mult_operator" "") 
14617                  (const_string "fmul")
14618                (match_operand:DF 3 "div_operator" "") 
14619                  (const_string "fdiv")
14620               ]
14621               (const_string "fop")))
14622    (set_attr "fp_int_src" "true")
14623    (set_attr "mode" "<MODE>")])
14624
14625 (define_insn "*fop_df_4_i387"
14626   [(set (match_operand:DF 0 "register_operand" "=f,f")
14627         (match_operator:DF 3 "binary_fp_operator"
14628            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14629             (match_operand:DF 2 "register_operand" "0,f")]))]
14630   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14631    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14632   "* return output_387_binary_op (insn, operands);"
14633   [(set (attr "type") 
14634         (cond [(match_operand:DF 3 "mult_operator" "") 
14635                  (const_string "fmul")
14636                (match_operand:DF 3 "div_operator" "") 
14637                  (const_string "fdiv")
14638               ]
14639               (const_string "fop")))
14640    (set_attr "mode" "SF")])
14641
14642 (define_insn "*fop_df_5_i387"
14643   [(set (match_operand:DF 0 "register_operand" "=f,f")
14644         (match_operator:DF 3 "binary_fp_operator"
14645           [(match_operand:DF 1 "register_operand" "0,f")
14646            (float_extend:DF
14647             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14648   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14649   "* return output_387_binary_op (insn, operands);"
14650   [(set (attr "type") 
14651         (cond [(match_operand:DF 3 "mult_operator" "") 
14652                  (const_string "fmul")
14653                (match_operand:DF 3 "div_operator" "") 
14654                  (const_string "fdiv")
14655               ]
14656               (const_string "fop")))
14657    (set_attr "mode" "SF")])
14658
14659 (define_insn "*fop_df_6_i387"
14660   [(set (match_operand:DF 0 "register_operand" "=f,f")
14661         (match_operator:DF 3 "binary_fp_operator"
14662           [(float_extend:DF
14663             (match_operand:SF 1 "register_operand" "0,f"))
14664            (float_extend:DF
14665             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14666   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14667   "* return output_387_binary_op (insn, operands);"
14668   [(set (attr "type") 
14669         (cond [(match_operand:DF 3 "mult_operator" "") 
14670                  (const_string "fmul")
14671                (match_operand:DF 3 "div_operator" "") 
14672                  (const_string "fdiv")
14673               ]
14674               (const_string "fop")))
14675    (set_attr "mode" "SF")])
14676
14677 (define_insn "*fop_xf_comm_i387"
14678   [(set (match_operand:XF 0 "register_operand" "=f")
14679         (match_operator:XF 3 "binary_fp_operator"
14680                         [(match_operand:XF 1 "register_operand" "%0")
14681                          (match_operand:XF 2 "register_operand" "f")]))]
14682   "TARGET_80387
14683    && COMMUTATIVE_ARITH_P (operands[3])"
14684   "* return output_387_binary_op (insn, operands);"
14685   [(set (attr "type") 
14686         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14687            (const_string "fmul")
14688            (const_string "fop")))
14689    (set_attr "mode" "XF")])
14690
14691 (define_insn "*fop_xf_1_i387"
14692   [(set (match_operand:XF 0 "register_operand" "=f,f")
14693         (match_operator:XF 3 "binary_fp_operator"
14694                         [(match_operand:XF 1 "register_operand" "0,f")
14695                          (match_operand:XF 2 "register_operand" "f,0")]))]
14696   "TARGET_80387
14697    && !COMMUTATIVE_ARITH_P (operands[3])"
14698   "* return output_387_binary_op (insn, operands);"
14699   [(set (attr "type") 
14700         (cond [(match_operand:XF 3 "mult_operator" "") 
14701                  (const_string "fmul")
14702                (match_operand:XF 3 "div_operator" "") 
14703                  (const_string "fdiv")
14704               ]
14705               (const_string "fop")))
14706    (set_attr "mode" "XF")])
14707
14708 (define_insn "*fop_xf_2<mode>_i387"
14709   [(set (match_operand:XF 0 "register_operand" "=f,f")
14710         (match_operator:XF 3 "binary_fp_operator"
14711            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14712             (match_operand:XF 2 "register_operand" "0,0")]))]
14713   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14714   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14715   [(set (attr "type") 
14716         (cond [(match_operand:XF 3 "mult_operator" "") 
14717                  (const_string "fmul")
14718                (match_operand:XF 3 "div_operator" "") 
14719                  (const_string "fdiv")
14720               ]
14721               (const_string "fop")))
14722    (set_attr "fp_int_src" "true")
14723    (set_attr "mode" "<MODE>")])
14724
14725 (define_insn "*fop_xf_3<mode>_i387"
14726   [(set (match_operand:XF 0 "register_operand" "=f,f")
14727         (match_operator:XF 3 "binary_fp_operator"
14728           [(match_operand:XF 1 "register_operand" "0,0")
14729            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14730   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14731   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14732   [(set (attr "type") 
14733         (cond [(match_operand:XF 3 "mult_operator" "") 
14734                  (const_string "fmul")
14735                (match_operand:XF 3 "div_operator" "") 
14736                  (const_string "fdiv")
14737               ]
14738               (const_string "fop")))
14739    (set_attr "fp_int_src" "true")
14740    (set_attr "mode" "<MODE>")])
14741
14742 (define_insn "*fop_xf_4_i387"
14743   [(set (match_operand:XF 0 "register_operand" "=f,f")
14744         (match_operator:XF 3 "binary_fp_operator"
14745            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14746             (match_operand:XF 2 "register_operand" "0,f")]))]
14747   "TARGET_80387"
14748   "* return output_387_binary_op (insn, operands);"
14749   [(set (attr "type") 
14750         (cond [(match_operand:XF 3 "mult_operator" "") 
14751                  (const_string "fmul")
14752                (match_operand:XF 3 "div_operator" "") 
14753                  (const_string "fdiv")
14754               ]
14755               (const_string "fop")))
14756    (set_attr "mode" "SF")])
14757
14758 (define_insn "*fop_xf_5_i387"
14759   [(set (match_operand:XF 0 "register_operand" "=f,f")
14760         (match_operator:XF 3 "binary_fp_operator"
14761           [(match_operand:XF 1 "register_operand" "0,f")
14762            (float_extend:XF
14763             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14764   "TARGET_80387"
14765   "* return output_387_binary_op (insn, operands);"
14766   [(set (attr "type") 
14767         (cond [(match_operand:XF 3 "mult_operator" "") 
14768                  (const_string "fmul")
14769                (match_operand:XF 3 "div_operator" "") 
14770                  (const_string "fdiv")
14771               ]
14772               (const_string "fop")))
14773    (set_attr "mode" "SF")])
14774
14775 (define_insn "*fop_xf_6_i387"
14776   [(set (match_operand:XF 0 "register_operand" "=f,f")
14777         (match_operator:XF 3 "binary_fp_operator"
14778           [(float_extend:XF
14779             (match_operand 1 "register_operand" "0,f"))
14780            (float_extend:XF
14781             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14782   "TARGET_80387"
14783   "* return output_387_binary_op (insn, operands);"
14784   [(set (attr "type") 
14785         (cond [(match_operand:XF 3 "mult_operator" "") 
14786                  (const_string "fmul")
14787                (match_operand:XF 3 "div_operator" "") 
14788                  (const_string "fdiv")
14789               ]
14790               (const_string "fop")))
14791    (set_attr "mode" "SF")])
14792
14793 (define_split
14794   [(set (match_operand 0 "register_operand" "")
14795         (match_operator 3 "binary_fp_operator"
14796            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14797             (match_operand 2 "register_operand" "")]))]
14798   "TARGET_80387 && reload_completed
14799    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14800   [(const_int 0)]
14801
14802   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14803   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14804   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14805                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14806                                           GET_MODE (operands[3]),
14807                                           operands[4],
14808                                           operands[2])));
14809   ix86_free_from_memory (GET_MODE (operands[1]));
14810   DONE;
14811 })
14812
14813 (define_split
14814   [(set (match_operand 0 "register_operand" "")
14815         (match_operator 3 "binary_fp_operator"
14816            [(match_operand 1 "register_operand" "")
14817             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14818   "TARGET_80387 && reload_completed
14819    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14820   [(const_int 0)]
14821 {
14822   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14823   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14824   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14825                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14826                                           GET_MODE (operands[3]),
14827                                           operands[1],
14828                                           operands[4])));
14829   ix86_free_from_memory (GET_MODE (operands[2]));
14830   DONE;
14831 })
14832 \f
14833 ;; FPU special functions.
14834
14835 (define_expand "sqrtsf2"
14836   [(set (match_operand:SF 0 "register_operand" "")
14837         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14838   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14839 {
14840   if (!TARGET_SSE_MATH)
14841     operands[1] = force_reg (SFmode, operands[1]);
14842 })
14843
14844 (define_insn "*sqrtsf2_mixed"
14845   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14846         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14847   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14848   "@
14849    fsqrt
14850    sqrtss\t{%1, %0|%0, %1}"
14851   [(set_attr "type" "fpspc,sse")
14852    (set_attr "mode" "SF,SF")
14853    (set_attr "athlon_decode" "direct,*")])
14854
14855 (define_insn "*sqrtsf2_sse"
14856   [(set (match_operand:SF 0 "register_operand" "=x")
14857         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14858   "TARGET_SSE_MATH"
14859   "sqrtss\t{%1, %0|%0, %1}"
14860   [(set_attr "type" "sse")
14861    (set_attr "mode" "SF")
14862    (set_attr "athlon_decode" "*")])
14863
14864 (define_insn "*sqrtsf2_i387"
14865   [(set (match_operand:SF 0 "register_operand" "=f")
14866         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14867   "TARGET_USE_FANCY_MATH_387"
14868   "fsqrt"
14869   [(set_attr "type" "fpspc")
14870    (set_attr "mode" "SF")
14871    (set_attr "athlon_decode" "direct")])
14872
14873 (define_expand "sqrtdf2"
14874   [(set (match_operand:DF 0 "register_operand" "")
14875         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14876   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14877 {
14878   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14879     operands[1] = force_reg (DFmode, operands[1]);
14880 })
14881
14882 (define_insn "*sqrtdf2_mixed"
14883   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14884         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14885   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14886   "@
14887    fsqrt
14888    sqrtsd\t{%1, %0|%0, %1}"
14889   [(set_attr "type" "fpspc,sse")
14890    (set_attr "mode" "DF,DF")
14891    (set_attr "athlon_decode" "direct,*")])
14892
14893 (define_insn "*sqrtdf2_sse"
14894   [(set (match_operand:DF 0 "register_operand" "=Y")
14895         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14896   "TARGET_SSE2 && TARGET_SSE_MATH"
14897   "sqrtsd\t{%1, %0|%0, %1}"
14898   [(set_attr "type" "sse")
14899    (set_attr "mode" "DF")
14900    (set_attr "athlon_decode" "*")])
14901
14902 (define_insn "*sqrtdf2_i387"
14903   [(set (match_operand:DF 0 "register_operand" "=f")
14904         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14905   "TARGET_USE_FANCY_MATH_387"
14906   "fsqrt"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "mode" "DF")
14909    (set_attr "athlon_decode" "direct")])
14910
14911 (define_insn "*sqrtextendsfdf2_i387"
14912   [(set (match_operand:DF 0 "register_operand" "=f")
14913         (sqrt:DF (float_extend:DF
14914                   (match_operand:SF 1 "register_operand" "0"))))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14917   "fsqrt"
14918   [(set_attr "type" "fpspc")
14919    (set_attr "mode" "DF")
14920    (set_attr "athlon_decode" "direct")])
14921
14922 (define_insn "sqrtxf2"
14923   [(set (match_operand:XF 0 "register_operand" "=f")
14924         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14925   "TARGET_USE_FANCY_MATH_387 
14926    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14927   "fsqrt"
14928   [(set_attr "type" "fpspc")
14929    (set_attr "mode" "XF")
14930    (set_attr "athlon_decode" "direct")])
14931
14932 (define_insn "*sqrtextendsfxf2_i387"
14933   [(set (match_operand:XF 0 "register_operand" "=f")
14934         (sqrt:XF (float_extend:XF
14935                   (match_operand:SF 1 "register_operand" "0"))))]
14936   "TARGET_USE_FANCY_MATH_387"
14937   "fsqrt"
14938   [(set_attr "type" "fpspc")
14939    (set_attr "mode" "XF")
14940    (set_attr "athlon_decode" "direct")])
14941
14942 (define_insn "*sqrtextenddfxf2_i387"
14943   [(set (match_operand:XF 0 "register_operand" "=f")
14944         (sqrt:XF (float_extend:XF
14945                   (match_operand:DF 1 "register_operand" "0"))))]
14946   "TARGET_USE_FANCY_MATH_387"
14947   "fsqrt"
14948   [(set_attr "type" "fpspc")
14949    (set_attr "mode" "XF")
14950    (set_attr "athlon_decode" "direct")])
14951
14952 (define_insn "fpremxf4"
14953   [(set (match_operand:XF 0 "register_operand" "=f")
14954         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14955                     (match_operand:XF 3 "register_operand" "1")]
14956                    UNSPEC_FPREM_F))
14957    (set (match_operand:XF 1 "register_operand" "=u")
14958         (unspec:XF [(match_dup 2) (match_dup 3)]
14959                    UNSPEC_FPREM_U))
14960    (set (reg:CCFP FPSR_REG)
14961         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14964   "fprem"
14965   [(set_attr "type" "fpspc")
14966    (set_attr "mode" "XF")])
14967
14968 (define_expand "fmodsf3"
14969   [(use (match_operand:SF 0 "register_operand" ""))
14970    (use (match_operand:SF 1 "register_operand" ""))
14971    (use (match_operand:SF 2 "register_operand" ""))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14974    && flag_unsafe_math_optimizations"
14975 {
14976   rtx label = gen_label_rtx ();
14977
14978   rtx op1 = gen_reg_rtx (XFmode);
14979   rtx op2 = gen_reg_rtx (XFmode);
14980
14981   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14982   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14983
14984   emit_label (label);
14985
14986   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14987   ix86_emit_fp_unordered_jump (label);
14988
14989   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14990   DONE;
14991 })
14992
14993 (define_expand "fmoddf3"
14994   [(use (match_operand:DF 0 "register_operand" ""))
14995    (use (match_operand:DF 1 "register_operand" ""))
14996    (use (match_operand:DF 2 "register_operand" ""))]
14997   "TARGET_USE_FANCY_MATH_387
14998    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14999    && flag_unsafe_math_optimizations"
15000 {
15001   rtx label = gen_label_rtx ();
15002
15003   rtx op1 = gen_reg_rtx (XFmode);
15004   rtx op2 = gen_reg_rtx (XFmode);
15005
15006   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15007   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15008
15009   emit_label (label);
15010
15011   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15012   ix86_emit_fp_unordered_jump (label);
15013
15014   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15015   DONE;
15016 })
15017
15018 (define_expand "fmodxf3"
15019   [(use (match_operand:XF 0 "register_operand" ""))
15020    (use (match_operand:XF 1 "register_operand" ""))
15021    (use (match_operand:XF 2 "register_operand" ""))]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15024 {
15025   rtx label = gen_label_rtx ();
15026
15027   emit_label (label);
15028
15029   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15030                            operands[1], operands[2]));
15031   ix86_emit_fp_unordered_jump (label);
15032
15033   emit_move_insn (operands[0], operands[1]);
15034   DONE;
15035 })
15036
15037 (define_insn "fprem1xf4"
15038   [(set (match_operand:XF 0 "register_operand" "=f")
15039         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15040                     (match_operand:XF 3 "register_operand" "1")]
15041                    UNSPEC_FPREM1_F))
15042    (set (match_operand:XF 1 "register_operand" "=u")
15043         (unspec:XF [(match_dup 2) (match_dup 3)]
15044                    UNSPEC_FPREM1_U))
15045    (set (reg:CCFP FPSR_REG)
15046         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations"
15049   "fprem1"
15050   [(set_attr "type" "fpspc")
15051    (set_attr "mode" "XF")])
15052
15053 (define_expand "dremsf3"
15054   [(use (match_operand:SF 0 "register_operand" ""))
15055    (use (match_operand:SF 1 "register_operand" ""))
15056    (use (match_operand:SF 2 "register_operand" ""))]
15057   "TARGET_USE_FANCY_MATH_387
15058    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15059    && flag_unsafe_math_optimizations"
15060 {
15061   rtx label = gen_label_rtx ();
15062
15063   rtx op1 = gen_reg_rtx (XFmode);
15064   rtx op2 = gen_reg_rtx (XFmode);
15065
15066   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15067   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15068
15069   emit_label (label);
15070
15071   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15072   ix86_emit_fp_unordered_jump (label);
15073
15074   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15075   DONE;
15076 })
15077
15078 (define_expand "dremdf3"
15079   [(use (match_operand:DF 0 "register_operand" ""))
15080    (use (match_operand:DF 1 "register_operand" ""))
15081    (use (match_operand:DF 2 "register_operand" ""))]
15082   "TARGET_USE_FANCY_MATH_387
15083    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15084    && flag_unsafe_math_optimizations"
15085 {
15086   rtx label = gen_label_rtx ();
15087
15088   rtx op1 = gen_reg_rtx (XFmode);
15089   rtx op2 = gen_reg_rtx (XFmode);
15090
15091   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15092   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15093
15094   emit_label (label);
15095
15096   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15097   ix86_emit_fp_unordered_jump (label);
15098
15099   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15100   DONE;
15101 })
15102
15103 (define_expand "dremxf3"
15104   [(use (match_operand:XF 0 "register_operand" ""))
15105    (use (match_operand:XF 1 "register_operand" ""))
15106    (use (match_operand:XF 2 "register_operand" ""))]
15107   "TARGET_USE_FANCY_MATH_387
15108    && flag_unsafe_math_optimizations"
15109 {
15110   rtx label = gen_label_rtx ();
15111
15112   emit_label (label);
15113
15114   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15115                             operands[1], operands[2]));
15116   ix86_emit_fp_unordered_jump (label);
15117
15118   emit_move_insn (operands[0], operands[1]);
15119   DONE;
15120 })
15121
15122 (define_insn "*sindf2"
15123   [(set (match_operand:DF 0 "register_operand" "=f")
15124         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15125   "TARGET_USE_FANCY_MATH_387
15126    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15127    && flag_unsafe_math_optimizations"
15128   "fsin"
15129   [(set_attr "type" "fpspc")
15130    (set_attr "mode" "DF")])
15131
15132 (define_insn "*sinsf2"
15133   [(set (match_operand:SF 0 "register_operand" "=f")
15134         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15135   "TARGET_USE_FANCY_MATH_387
15136    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15137    && flag_unsafe_math_optimizations"
15138   "fsin"
15139   [(set_attr "type" "fpspc")
15140    (set_attr "mode" "SF")])
15141
15142 (define_insn "*sinextendsfdf2"
15143   [(set (match_operand:DF 0 "register_operand" "=f")
15144         (unspec:DF [(float_extend:DF
15145                      (match_operand:SF 1 "register_operand" "0"))]
15146                    UNSPEC_SIN))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15149    && flag_unsafe_math_optimizations"
15150   "fsin"
15151   [(set_attr "type" "fpspc")
15152    (set_attr "mode" "DF")])
15153
15154 (define_insn "*sinxf2"
15155   [(set (match_operand:XF 0 "register_operand" "=f")
15156         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15157   "TARGET_USE_FANCY_MATH_387
15158    && flag_unsafe_math_optimizations"
15159   "fsin"
15160   [(set_attr "type" "fpspc")
15161    (set_attr "mode" "XF")])
15162
15163 (define_insn "*cosdf2"
15164   [(set (match_operand:DF 0 "register_operand" "=f")
15165         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15168    && flag_unsafe_math_optimizations"
15169   "fcos"
15170   [(set_attr "type" "fpspc")
15171    (set_attr "mode" "DF")])
15172
15173 (define_insn "*cossf2"
15174   [(set (match_operand:SF 0 "register_operand" "=f")
15175         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15178    && flag_unsafe_math_optimizations"
15179   "fcos"
15180   [(set_attr "type" "fpspc")
15181    (set_attr "mode" "SF")])
15182
15183 (define_insn "*cosextendsfdf2"
15184   [(set (match_operand:DF 0 "register_operand" "=f")
15185         (unspec:DF [(float_extend:DF
15186                      (match_operand:SF 1 "register_operand" "0"))]
15187                    UNSPEC_COS))]
15188   "TARGET_USE_FANCY_MATH_387
15189    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15190    && flag_unsafe_math_optimizations"
15191   "fcos"
15192   [(set_attr "type" "fpspc")
15193    (set_attr "mode" "DF")])
15194
15195 (define_insn "*cosxf2"
15196   [(set (match_operand:XF 0 "register_operand" "=f")
15197         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15198   "TARGET_USE_FANCY_MATH_387
15199    && flag_unsafe_math_optimizations"
15200   "fcos"
15201   [(set_attr "type" "fpspc")
15202    (set_attr "mode" "XF")])
15203
15204 ;; With sincos pattern defined, sin and cos builtin function will be
15205 ;; expanded to sincos pattern with one of its outputs left unused. 
15206 ;; Cse pass  will detected, if two sincos patterns can be combined,
15207 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15208 ;; depending on the unused output.
15209
15210 (define_insn "sincosdf3"
15211   [(set (match_operand:DF 0 "register_operand" "=f")
15212         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15213                    UNSPEC_SINCOS_COS))
15214    (set (match_operand:DF 1 "register_operand" "=u")
15215         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15216   "TARGET_USE_FANCY_MATH_387
15217    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15218    && flag_unsafe_math_optimizations"
15219   "fsincos"
15220   [(set_attr "type" "fpspc")
15221    (set_attr "mode" "DF")])
15222
15223 (define_split
15224   [(set (match_operand:DF 0 "register_operand" "")
15225         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15226                    UNSPEC_SINCOS_COS))
15227    (set (match_operand:DF 1 "register_operand" "")
15228         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15229   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15230    && !reload_completed && !reload_in_progress"
15231   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15232   "")
15233
15234 (define_split
15235   [(set (match_operand:DF 0 "register_operand" "")
15236         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15237                    UNSPEC_SINCOS_COS))
15238    (set (match_operand:DF 1 "register_operand" "")
15239         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15240   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15241    && !reload_completed && !reload_in_progress"
15242   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15243   "")
15244
15245 (define_insn "sincossf3"
15246   [(set (match_operand:SF 0 "register_operand" "=f")
15247         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15248                    UNSPEC_SINCOS_COS))
15249    (set (match_operand:SF 1 "register_operand" "=u")
15250         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15251   "TARGET_USE_FANCY_MATH_387
15252    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15253    && flag_unsafe_math_optimizations"
15254   "fsincos"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "SF")])
15257
15258 (define_split
15259   [(set (match_operand:SF 0 "register_operand" "")
15260         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15261                    UNSPEC_SINCOS_COS))
15262    (set (match_operand:SF 1 "register_operand" "")
15263         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267   "")
15268
15269 (define_split
15270   [(set (match_operand:SF 0 "register_operand" "")
15271         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15272                    UNSPEC_SINCOS_COS))
15273    (set (match_operand:SF 1 "register_operand" "")
15274         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15275   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15276    && !reload_completed && !reload_in_progress"
15277   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15278   "")
15279
15280 (define_insn "*sincosextendsfdf3"
15281   [(set (match_operand:DF 0 "register_operand" "=f")
15282         (unspec:DF [(float_extend:DF
15283                      (match_operand:SF 2 "register_operand" "0"))]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(float_extend:DF
15287                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15290    && flag_unsafe_math_optimizations"
15291   "fsincos"
15292   [(set_attr "type" "fpspc")
15293    (set_attr "mode" "DF")])
15294
15295 (define_split
15296   [(set (match_operand:DF 0 "register_operand" "")
15297         (unspec:DF [(float_extend:DF
15298                      (match_operand:SF 2 "register_operand" ""))]
15299                    UNSPEC_SINCOS_COS))
15300    (set (match_operand:DF 1 "register_operand" "")
15301         (unspec:DF [(float_extend:DF
15302                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15303   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15304    && !reload_completed && !reload_in_progress"
15305   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15306                                    (match_dup 2))] UNSPEC_SIN))]
15307   "")
15308
15309 (define_split
15310   [(set (match_operand:DF 0 "register_operand" "")
15311         (unspec:DF [(float_extend:DF
15312                      (match_operand:SF 2 "register_operand" ""))]
15313                    UNSPEC_SINCOS_COS))
15314    (set (match_operand:DF 1 "register_operand" "")
15315         (unspec:DF [(float_extend:DF
15316                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15317   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15318    && !reload_completed && !reload_in_progress"
15319   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15320                                    (match_dup 2))] UNSPEC_COS))]
15321   "")
15322
15323 (define_insn "sincosxf3"
15324   [(set (match_operand:XF 0 "register_operand" "=f")
15325         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15326                    UNSPEC_SINCOS_COS))
15327    (set (match_operand:XF 1 "register_operand" "=u")
15328         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && flag_unsafe_math_optimizations"
15331   "fsincos"
15332   [(set_attr "type" "fpspc")
15333    (set_attr "mode" "XF")])
15334
15335 (define_split
15336   [(set (match_operand:XF 0 "register_operand" "")
15337         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15338                    UNSPEC_SINCOS_COS))
15339    (set (match_operand:XF 1 "register_operand" "")
15340         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15341   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15342    && !reload_completed && !reload_in_progress"
15343   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15344   "")
15345
15346 (define_split
15347   [(set (match_operand:XF 0 "register_operand" "")
15348         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15349                    UNSPEC_SINCOS_COS))
15350    (set (match_operand:XF 1 "register_operand" "")
15351         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15352   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15353    && !reload_completed && !reload_in_progress"
15354   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15355   "")
15356
15357 (define_insn "*tandf3_1"
15358   [(set (match_operand:DF 0 "register_operand" "=f")
15359         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15360                    UNSPEC_TAN_ONE))
15361    (set (match_operand:DF 1 "register_operand" "=u")
15362         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15365    && flag_unsafe_math_optimizations"
15366   "fptan"
15367   [(set_attr "type" "fpspc")
15368    (set_attr "mode" "DF")])
15369
15370 ;; optimize sequence: fptan
15371 ;;                    fstp    %st(0)
15372 ;;                    fld1
15373 ;; into fptan insn.
15374
15375 (define_peephole2
15376   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15377                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15378                              UNSPEC_TAN_ONE))
15379              (set (match_operand:DF 1 "register_operand" "")
15380                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15381    (set (match_dup 0)
15382         (match_operand:DF 3 "immediate_operand" ""))]
15383   "standard_80387_constant_p (operands[3]) == 2"
15384   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15385              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15386   "")
15387
15388 (define_expand "tandf2"
15389   [(parallel [(set (match_dup 2)
15390                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15391                               UNSPEC_TAN_ONE))
15392               (set (match_operand:DF 0 "register_operand" "")
15393                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15394   "TARGET_USE_FANCY_MATH_387
15395    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15396    && flag_unsafe_math_optimizations"
15397 {
15398   operands[2] = gen_reg_rtx (DFmode);
15399 })
15400
15401 (define_insn "*tansf3_1"
15402   [(set (match_operand:SF 0 "register_operand" "=f")
15403         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15404                    UNSPEC_TAN_ONE))
15405    (set (match_operand:SF 1 "register_operand" "=u")
15406         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15407   "TARGET_USE_FANCY_MATH_387
15408    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15409    && flag_unsafe_math_optimizations"
15410   "fptan"
15411   [(set_attr "type" "fpspc")
15412    (set_attr "mode" "SF")])
15413
15414 ;; optimize sequence: fptan
15415 ;;                    fstp    %st(0)
15416 ;;                    fld1
15417 ;; into fptan insn.
15418
15419 (define_peephole2
15420   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15421                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15422                              UNSPEC_TAN_ONE))
15423              (set (match_operand:SF 1 "register_operand" "")
15424                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15425    (set (match_dup 0)
15426         (match_operand:SF 3 "immediate_operand" ""))]
15427   "standard_80387_constant_p (operands[3]) == 2"
15428   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15429              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15430   "")
15431
15432 (define_expand "tansf2"
15433   [(parallel [(set (match_dup 2)
15434                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15435                               UNSPEC_TAN_ONE))
15436               (set (match_operand:SF 0 "register_operand" "")
15437                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15440    && flag_unsafe_math_optimizations"
15441 {
15442   operands[2] = gen_reg_rtx (SFmode);
15443 })
15444
15445 (define_insn "*tanxf3_1"
15446   [(set (match_operand:XF 0 "register_operand" "=f")
15447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15448                    UNSPEC_TAN_ONE))
15449    (set (match_operand:XF 1 "register_operand" "=u")
15450         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15451   "TARGET_USE_FANCY_MATH_387
15452    && flag_unsafe_math_optimizations"
15453   "fptan"
15454   [(set_attr "type" "fpspc")
15455    (set_attr "mode" "XF")])
15456
15457 ;; optimize sequence: fptan
15458 ;;                    fstp    %st(0)
15459 ;;                    fld1
15460 ;; into fptan insn.
15461
15462 (define_peephole2
15463   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15464                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15465                              UNSPEC_TAN_ONE))
15466              (set (match_operand:XF 1 "register_operand" "")
15467                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15468    (set (match_dup 0)
15469         (match_operand:XF 3 "immediate_operand" ""))]
15470   "standard_80387_constant_p (operands[3]) == 2"
15471   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15472              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15473   "")
15474
15475 (define_expand "tanxf2"
15476   [(parallel [(set (match_dup 2)
15477                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15478                               UNSPEC_TAN_ONE))
15479               (set (match_operand:XF 0 "register_operand" "")
15480                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15481   "TARGET_USE_FANCY_MATH_387
15482    && flag_unsafe_math_optimizations"
15483 {
15484   operands[2] = gen_reg_rtx (XFmode);
15485 })
15486
15487 (define_insn "atan2df3_1"
15488   [(set (match_operand:DF 0 "register_operand" "=f")
15489         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15490                     (match_operand:DF 1 "register_operand" "u")]
15491                    UNSPEC_FPATAN))
15492    (clobber (match_scratch:DF 3 "=1"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15495    && flag_unsafe_math_optimizations"
15496   "fpatan"
15497   [(set_attr "type" "fpspc")
15498    (set_attr "mode" "DF")])
15499
15500 (define_expand "atan2df3"
15501   [(use (match_operand:DF 0 "register_operand" ""))
15502    (use (match_operand:DF 2 "register_operand" ""))
15503    (use (match_operand:DF 1 "register_operand" ""))]
15504   "TARGET_USE_FANCY_MATH_387
15505    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15506    && flag_unsafe_math_optimizations"
15507 {
15508   rtx copy = gen_reg_rtx (DFmode);
15509   emit_move_insn (copy, operands[1]);
15510   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15511   DONE;
15512 })
15513
15514 (define_expand "atandf2"
15515   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15516                    (unspec:DF [(match_dup 2)
15517                                (match_operand:DF 1 "register_operand" "")]
15518                     UNSPEC_FPATAN))
15519               (clobber (match_scratch:DF 3 ""))])]
15520   "TARGET_USE_FANCY_MATH_387
15521    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15522    && flag_unsafe_math_optimizations"
15523 {
15524   operands[2] = gen_reg_rtx (DFmode);
15525   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15526 })
15527
15528 (define_insn "atan2sf3_1"
15529   [(set (match_operand:SF 0 "register_operand" "=f")
15530         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15531                     (match_operand:SF 1 "register_operand" "u")]
15532                    UNSPEC_FPATAN))
15533    (clobber (match_scratch:SF 3 "=1"))]
15534   "TARGET_USE_FANCY_MATH_387
15535    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15536    && flag_unsafe_math_optimizations"
15537   "fpatan"
15538   [(set_attr "type" "fpspc")
15539    (set_attr "mode" "SF")])
15540
15541 (define_expand "atan2sf3"
15542   [(use (match_operand:SF 0 "register_operand" ""))
15543    (use (match_operand:SF 2 "register_operand" ""))
15544    (use (match_operand:SF 1 "register_operand" ""))]
15545   "TARGET_USE_FANCY_MATH_387
15546    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15547    && flag_unsafe_math_optimizations"
15548 {
15549   rtx copy = gen_reg_rtx (SFmode);
15550   emit_move_insn (copy, operands[1]);
15551   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15552   DONE;
15553 })
15554
15555 (define_expand "atansf2"
15556   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15557                    (unspec:SF [(match_dup 2)
15558                                (match_operand:SF 1 "register_operand" "")]
15559                     UNSPEC_FPATAN))
15560               (clobber (match_scratch:SF 3 ""))])]
15561   "TARGET_USE_FANCY_MATH_387
15562    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15563    && flag_unsafe_math_optimizations"
15564 {
15565   operands[2] = gen_reg_rtx (SFmode);
15566   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15567 })
15568
15569 (define_insn "atan2xf3_1"
15570   [(set (match_operand:XF 0 "register_operand" "=f")
15571         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15572                     (match_operand:XF 1 "register_operand" "u")]
15573                    UNSPEC_FPATAN))
15574    (clobber (match_scratch:XF 3 "=1"))]
15575   "TARGET_USE_FANCY_MATH_387
15576    && flag_unsafe_math_optimizations"
15577   "fpatan"
15578   [(set_attr "type" "fpspc")
15579    (set_attr "mode" "XF")])
15580
15581 (define_expand "atan2xf3"
15582   [(use (match_operand:XF 0 "register_operand" ""))
15583    (use (match_operand:XF 2 "register_operand" ""))
15584    (use (match_operand:XF 1 "register_operand" ""))]
15585   "TARGET_USE_FANCY_MATH_387
15586    && flag_unsafe_math_optimizations"
15587 {
15588   rtx copy = gen_reg_rtx (XFmode);
15589   emit_move_insn (copy, operands[1]);
15590   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15591   DONE;
15592 })
15593
15594 (define_expand "atanxf2"
15595   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15596                    (unspec:XF [(match_dup 2)
15597                                (match_operand:XF 1 "register_operand" "")]
15598                     UNSPEC_FPATAN))
15599               (clobber (match_scratch:XF 3 ""))])]
15600   "TARGET_USE_FANCY_MATH_387
15601    && flag_unsafe_math_optimizations"
15602 {
15603   operands[2] = gen_reg_rtx (XFmode);
15604   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15605 })
15606
15607 (define_expand "asindf2"
15608   [(set (match_dup 2)
15609         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15610    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15611    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15612    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15613    (parallel [(set (match_dup 7)
15614                    (unspec:XF [(match_dup 6) (match_dup 2)]
15615                               UNSPEC_FPATAN))
15616               (clobber (match_scratch:XF 8 ""))])
15617    (set (match_operand:DF 0 "register_operand" "")
15618         (float_truncate:DF (match_dup 7)))]
15619   "TARGET_USE_FANCY_MATH_387
15620    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15621    && flag_unsafe_math_optimizations"
15622 {
15623   int i;
15624
15625   for (i=2; i<8; i++)
15626     operands[i] = gen_reg_rtx (XFmode);
15627
15628   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15629 })
15630
15631 (define_expand "asinsf2"
15632   [(set (match_dup 2)
15633         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15634    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15635    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15636    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15637    (parallel [(set (match_dup 7)
15638                    (unspec:XF [(match_dup 6) (match_dup 2)]
15639                               UNSPEC_FPATAN))
15640               (clobber (match_scratch:XF 8 ""))])
15641    (set (match_operand:SF 0 "register_operand" "")
15642         (float_truncate:SF (match_dup 7)))]
15643   "TARGET_USE_FANCY_MATH_387
15644    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15645    && flag_unsafe_math_optimizations"
15646 {
15647   int i;
15648
15649   for (i=2; i<8; i++)
15650     operands[i] = gen_reg_rtx (XFmode);
15651
15652   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15653 })
15654
15655 (define_expand "asinxf2"
15656   [(set (match_dup 2)
15657         (mult:XF (match_operand:XF 1 "register_operand" "")
15658                  (match_dup 1)))
15659    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15660    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15661    (parallel [(set (match_operand:XF 0 "register_operand" "")
15662                    (unspec:XF [(match_dup 5) (match_dup 1)]
15663                               UNSPEC_FPATAN))
15664               (clobber (match_scratch:XF 6 ""))])]
15665   "TARGET_USE_FANCY_MATH_387
15666    && flag_unsafe_math_optimizations"
15667 {
15668   int i;
15669
15670   for (i=2; i<6; i++)
15671     operands[i] = gen_reg_rtx (XFmode);
15672
15673   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15674 })
15675
15676 (define_expand "acosdf2"
15677   [(set (match_dup 2)
15678         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15679    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15680    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15681    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15682    (parallel [(set (match_dup 7)
15683                    (unspec:XF [(match_dup 2) (match_dup 6)]
15684                               UNSPEC_FPATAN))
15685               (clobber (match_scratch:XF 8 ""))])
15686    (set (match_operand:DF 0 "register_operand" "")
15687         (float_truncate:DF (match_dup 7)))]
15688   "TARGET_USE_FANCY_MATH_387
15689    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15690    && flag_unsafe_math_optimizations"
15691 {
15692   int i;
15693
15694   for (i=2; i<8; i++)
15695     operands[i] = gen_reg_rtx (XFmode);
15696
15697   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15698 })
15699
15700 (define_expand "acossf2"
15701   [(set (match_dup 2)
15702         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15703    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15704    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15705    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15706    (parallel [(set (match_dup 7)
15707                    (unspec:XF [(match_dup 2) (match_dup 6)]
15708                               UNSPEC_FPATAN))
15709               (clobber (match_scratch:XF 8 ""))])
15710    (set (match_operand:SF 0 "register_operand" "")
15711         (float_truncate:SF (match_dup 7)))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15714    && flag_unsafe_math_optimizations"
15715 {
15716   int i;
15717
15718   for (i=2; i<8; i++)
15719     operands[i] = gen_reg_rtx (XFmode);
15720
15721   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15722 })
15723
15724 (define_expand "acosxf2"
15725   [(set (match_dup 2)
15726         (mult:XF (match_operand:XF 1 "register_operand" "")
15727                  (match_dup 1)))
15728    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15729    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15730    (parallel [(set (match_operand:XF 0 "register_operand" "")
15731                    (unspec:XF [(match_dup 1) (match_dup 5)]
15732                               UNSPEC_FPATAN))
15733               (clobber (match_scratch:XF 6 ""))])]
15734   "TARGET_USE_FANCY_MATH_387
15735    && flag_unsafe_math_optimizations"
15736 {
15737   int i;
15738
15739   for (i=2; i<6; i++)
15740     operands[i] = gen_reg_rtx (XFmode);
15741
15742   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15743 })
15744
15745 (define_insn "fyl2x_xf3"
15746   [(set (match_operand:XF 0 "register_operand" "=f")
15747         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15748                     (match_operand:XF 1 "register_operand" "u")]
15749                    UNSPEC_FYL2X))
15750    (clobber (match_scratch:XF 3 "=1"))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && flag_unsafe_math_optimizations"
15753   "fyl2x"
15754   [(set_attr "type" "fpspc")
15755    (set_attr "mode" "XF")])
15756
15757 (define_expand "logsf2"
15758   [(set (match_dup 2)
15759         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15760    (parallel [(set (match_dup 4)
15761                    (unspec:XF [(match_dup 2)
15762                                (match_dup 3)] UNSPEC_FYL2X))
15763               (clobber (match_scratch:XF 5 ""))])
15764    (set (match_operand:SF 0 "register_operand" "")
15765         (float_truncate:SF (match_dup 4)))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15768    && flag_unsafe_math_optimizations"
15769 {
15770   rtx temp;
15771
15772   operands[2] = gen_reg_rtx (XFmode);
15773   operands[3] = gen_reg_rtx (XFmode);
15774   operands[4] = gen_reg_rtx (XFmode);
15775
15776   temp = standard_80387_constant_rtx (4); /* fldln2 */
15777   emit_move_insn (operands[3], temp);
15778 })
15779
15780 (define_expand "logdf2"
15781   [(set (match_dup 2)
15782         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15783    (parallel [(set (match_dup 4)
15784                    (unspec:XF [(match_dup 2)
15785                                (match_dup 3)] UNSPEC_FYL2X))
15786               (clobber (match_scratch:XF 5 ""))])
15787    (set (match_operand:DF 0 "register_operand" "")
15788         (float_truncate:DF (match_dup 4)))]
15789   "TARGET_USE_FANCY_MATH_387
15790    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15791    && flag_unsafe_math_optimizations"
15792 {
15793   rtx temp;
15794
15795   operands[2] = gen_reg_rtx (XFmode);
15796   operands[3] = gen_reg_rtx (XFmode);
15797   operands[4] = gen_reg_rtx (XFmode);
15798
15799   temp = standard_80387_constant_rtx (4); /* fldln2 */
15800   emit_move_insn (operands[3], temp);
15801 })
15802
15803 (define_expand "logxf2"
15804   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15805                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15806                                (match_dup 2)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 3 ""))])]
15808   "TARGET_USE_FANCY_MATH_387
15809    && flag_unsafe_math_optimizations"
15810 {
15811   rtx temp;
15812
15813   operands[2] = gen_reg_rtx (XFmode);
15814   temp = standard_80387_constant_rtx (4); /* fldln2 */
15815   emit_move_insn (operands[2], temp);
15816 })
15817
15818 (define_expand "log10sf2"
15819   [(set (match_dup 2)
15820         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15821    (parallel [(set (match_dup 4)
15822                    (unspec:XF [(match_dup 2)
15823                                (match_dup 3)] UNSPEC_FYL2X))
15824               (clobber (match_scratch:XF 5 ""))])
15825    (set (match_operand:SF 0 "register_operand" "")
15826         (float_truncate:SF (match_dup 4)))]
15827   "TARGET_USE_FANCY_MATH_387
15828    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15829    && flag_unsafe_math_optimizations"
15830 {
15831   rtx temp;
15832
15833   operands[2] = gen_reg_rtx (XFmode);
15834   operands[3] = gen_reg_rtx (XFmode);
15835   operands[4] = gen_reg_rtx (XFmode);
15836
15837   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15838   emit_move_insn (operands[3], temp);
15839 })
15840
15841 (define_expand "log10df2"
15842   [(set (match_dup 2)
15843         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15844    (parallel [(set (match_dup 4)
15845                    (unspec:XF [(match_dup 2)
15846                                (match_dup 3)] UNSPEC_FYL2X))
15847               (clobber (match_scratch:XF 5 ""))])
15848    (set (match_operand:DF 0 "register_operand" "")
15849         (float_truncate:DF (match_dup 4)))]
15850   "TARGET_USE_FANCY_MATH_387
15851    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15852    && flag_unsafe_math_optimizations"
15853 {
15854   rtx temp;
15855
15856   operands[2] = gen_reg_rtx (XFmode);
15857   operands[3] = gen_reg_rtx (XFmode);
15858   operands[4] = gen_reg_rtx (XFmode);
15859
15860   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15861   emit_move_insn (operands[3], temp);
15862 })
15863
15864 (define_expand "log10xf2"
15865   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15866                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15867                                (match_dup 2)] UNSPEC_FYL2X))
15868               (clobber (match_scratch:XF 3 ""))])]
15869   "TARGET_USE_FANCY_MATH_387
15870    && flag_unsafe_math_optimizations"
15871 {
15872   rtx temp;
15873
15874   operands[2] = gen_reg_rtx (XFmode);
15875   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15876   emit_move_insn (operands[2], temp);
15877 })
15878
15879 (define_expand "log2sf2"
15880   [(set (match_dup 2)
15881         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15882    (parallel [(set (match_dup 4)
15883                    (unspec:XF [(match_dup 2)
15884                                (match_dup 3)] UNSPEC_FYL2X))
15885               (clobber (match_scratch:XF 5 ""))])
15886    (set (match_operand:SF 0 "register_operand" "")
15887         (float_truncate:SF (match_dup 4)))]
15888   "TARGET_USE_FANCY_MATH_387
15889    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15890    && flag_unsafe_math_optimizations"
15891 {
15892   operands[2] = gen_reg_rtx (XFmode);
15893   operands[3] = gen_reg_rtx (XFmode);
15894   operands[4] = gen_reg_rtx (XFmode);
15895
15896   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15897 })
15898
15899 (define_expand "log2df2"
15900   [(set (match_dup 2)
15901         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15902    (parallel [(set (match_dup 4)
15903                    (unspec:XF [(match_dup 2)
15904                                (match_dup 3)] UNSPEC_FYL2X))
15905               (clobber (match_scratch:XF 5 ""))])
15906    (set (match_operand:DF 0 "register_operand" "")
15907         (float_truncate:DF (match_dup 4)))]
15908   "TARGET_USE_FANCY_MATH_387
15909    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15910    && flag_unsafe_math_optimizations"
15911 {
15912   operands[2] = gen_reg_rtx (XFmode);
15913   operands[3] = gen_reg_rtx (XFmode);
15914   operands[4] = gen_reg_rtx (XFmode);
15915
15916   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15917 })
15918
15919 (define_expand "log2xf2"
15920   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15921                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15922                                (match_dup 2)] UNSPEC_FYL2X))
15923               (clobber (match_scratch:XF 3 ""))])]
15924   "TARGET_USE_FANCY_MATH_387
15925    && flag_unsafe_math_optimizations"
15926 {
15927   operands[2] = gen_reg_rtx (XFmode);
15928   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15929 })
15930
15931 (define_insn "fyl2xp1_xf3"
15932   [(set (match_operand:XF 0 "register_operand" "=f")
15933         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15934                     (match_operand:XF 1 "register_operand" "u")]
15935                    UNSPEC_FYL2XP1))
15936    (clobber (match_scratch:XF 3 "=1"))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && flag_unsafe_math_optimizations"
15939   "fyl2xp1"
15940   [(set_attr "type" "fpspc")
15941    (set_attr "mode" "XF")])
15942
15943 (define_expand "log1psf2"
15944   [(use (match_operand:SF 0 "register_operand" ""))
15945    (use (match_operand:SF 1 "register_operand" ""))]
15946   "TARGET_USE_FANCY_MATH_387
15947    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15948    && flag_unsafe_math_optimizations"
15949 {
15950   rtx op0 = gen_reg_rtx (XFmode);
15951   rtx op1 = gen_reg_rtx (XFmode);
15952
15953   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15954   ix86_emit_i387_log1p (op0, op1);
15955   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15956   DONE;
15957 })
15958
15959 (define_expand "log1pdf2"
15960   [(use (match_operand:DF 0 "register_operand" ""))
15961    (use (match_operand:DF 1 "register_operand" ""))]
15962   "TARGET_USE_FANCY_MATH_387
15963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15964    && flag_unsafe_math_optimizations"
15965 {
15966   rtx op0 = gen_reg_rtx (XFmode);
15967   rtx op1 = gen_reg_rtx (XFmode);
15968
15969   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15970   ix86_emit_i387_log1p (op0, op1);
15971   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15972   DONE;
15973 })
15974
15975 (define_expand "log1pxf2"
15976   [(use (match_operand:XF 0 "register_operand" ""))
15977    (use (match_operand:XF 1 "register_operand" ""))]
15978   "TARGET_USE_FANCY_MATH_387
15979    && flag_unsafe_math_optimizations"
15980 {
15981   ix86_emit_i387_log1p (operands[0], operands[1]);
15982   DONE;
15983 })
15984
15985 (define_insn "*fxtractxf3"
15986   [(set (match_operand:XF 0 "register_operand" "=f")
15987         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15988                    UNSPEC_XTRACT_FRACT))
15989    (set (match_operand:XF 1 "register_operand" "=u")
15990         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15991   "TARGET_USE_FANCY_MATH_387
15992    && flag_unsafe_math_optimizations"
15993   "fxtract"
15994   [(set_attr "type" "fpspc")
15995    (set_attr "mode" "XF")])
15996
15997 (define_expand "logbsf2"
15998   [(set (match_dup 2)
15999         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16000    (parallel [(set (match_dup 3)
16001                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16002               (set (match_dup 4)
16003                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16004    (set (match_operand:SF 0 "register_operand" "")
16005         (float_truncate:SF (match_dup 4)))]
16006   "TARGET_USE_FANCY_MATH_387
16007    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16008    && flag_unsafe_math_optimizations"
16009 {
16010   operands[2] = gen_reg_rtx (XFmode);
16011   operands[3] = gen_reg_rtx (XFmode);
16012   operands[4] = gen_reg_rtx (XFmode);
16013 })
16014
16015 (define_expand "logbdf2"
16016   [(set (match_dup 2)
16017         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16018    (parallel [(set (match_dup 3)
16019                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16020               (set (match_dup 4)
16021                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16022    (set (match_operand:DF 0 "register_operand" "")
16023         (float_truncate:DF (match_dup 4)))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16026    && flag_unsafe_math_optimizations"
16027 {
16028   operands[2] = gen_reg_rtx (XFmode);
16029   operands[3] = gen_reg_rtx (XFmode);
16030   operands[4] = gen_reg_rtx (XFmode);
16031 })
16032
16033 (define_expand "logbxf2"
16034   [(parallel [(set (match_dup 2)
16035                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16036                               UNSPEC_XTRACT_FRACT))
16037               (set (match_operand:XF 0 "register_operand" "")
16038                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16039   "TARGET_USE_FANCY_MATH_387
16040    && flag_unsafe_math_optimizations"
16041 {
16042   operands[2] = gen_reg_rtx (XFmode);
16043 })
16044
16045 (define_expand "ilogbsi2"
16046   [(parallel [(set (match_dup 2)
16047                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16048                               UNSPEC_XTRACT_FRACT))
16049               (set (match_operand:XF 3 "register_operand" "")
16050                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16051    (parallel [(set (match_operand:SI 0 "register_operand" "")
16052                    (fix:SI (match_dup 3)))
16053               (clobber (reg:CC FLAGS_REG))])]
16054   "TARGET_USE_FANCY_MATH_387
16055    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16056    && flag_unsafe_math_optimizations"
16057 {
16058   operands[2] = gen_reg_rtx (XFmode);
16059   operands[3] = gen_reg_rtx (XFmode);
16060 })
16061
16062 (define_insn "*f2xm1xf2"
16063   [(set (match_operand:XF 0 "register_operand" "=f")
16064         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16065          UNSPEC_F2XM1))]
16066   "TARGET_USE_FANCY_MATH_387
16067    && flag_unsafe_math_optimizations"
16068   "f2xm1"
16069   [(set_attr "type" "fpspc")
16070    (set_attr "mode" "XF")])
16071
16072 (define_insn "*fscalexf4"
16073   [(set (match_operand:XF 0 "register_operand" "=f")
16074         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16075                     (match_operand:XF 3 "register_operand" "1")]
16076                    UNSPEC_FSCALE_FRACT))
16077    (set (match_operand:XF 1 "register_operand" "=u")
16078         (unspec:XF [(match_dup 2) (match_dup 3)]
16079                    UNSPEC_FSCALE_EXP))]
16080   "TARGET_USE_FANCY_MATH_387
16081    && flag_unsafe_math_optimizations"
16082   "fscale"
16083   [(set_attr "type" "fpspc")
16084    (set_attr "mode" "XF")])
16085
16086 (define_expand "expsf2"
16087   [(set (match_dup 2)
16088         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16089    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16090    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16091    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16092    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16093    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16094    (parallel [(set (match_dup 10)
16095                    (unspec:XF [(match_dup 9) (match_dup 5)]
16096                               UNSPEC_FSCALE_FRACT))
16097               (set (match_dup 11)
16098                    (unspec:XF [(match_dup 9) (match_dup 5)]
16099                               UNSPEC_FSCALE_EXP))])
16100    (set (match_operand:SF 0 "register_operand" "")
16101         (float_truncate:SF (match_dup 10)))]
16102   "TARGET_USE_FANCY_MATH_387
16103    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16104    && flag_unsafe_math_optimizations"
16105 {
16106   rtx temp;
16107   int i;
16108
16109   for (i=2; i<12; i++)
16110     operands[i] = gen_reg_rtx (XFmode);
16111   temp = standard_80387_constant_rtx (5); /* fldl2e */
16112   emit_move_insn (operands[3], temp);
16113   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16114 })
16115
16116 (define_expand "expdf2"
16117   [(set (match_dup 2)
16118         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16119    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16120    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16121    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16122    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16123    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16124    (parallel [(set (match_dup 10)
16125                    (unspec:XF [(match_dup 9) (match_dup 5)]
16126                               UNSPEC_FSCALE_FRACT))
16127               (set (match_dup 11)
16128                    (unspec:XF [(match_dup 9) (match_dup 5)]
16129                               UNSPEC_FSCALE_EXP))])
16130    (set (match_operand:DF 0 "register_operand" "")
16131         (float_truncate:DF (match_dup 10)))]
16132   "TARGET_USE_FANCY_MATH_387
16133    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16134    && flag_unsafe_math_optimizations"
16135 {
16136   rtx temp;
16137   int i;
16138
16139   for (i=2; i<12; i++)
16140     operands[i] = gen_reg_rtx (XFmode);
16141   temp = standard_80387_constant_rtx (5); /* fldl2e */
16142   emit_move_insn (operands[3], temp);
16143   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16144 })
16145
16146 (define_expand "expxf2"
16147   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16148                                (match_dup 2)))
16149    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16150    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16151    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16152    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16153    (parallel [(set (match_operand:XF 0 "register_operand" "")
16154                    (unspec:XF [(match_dup 8) (match_dup 4)]
16155                               UNSPEC_FSCALE_FRACT))
16156               (set (match_dup 9)
16157                    (unspec:XF [(match_dup 8) (match_dup 4)]
16158                               UNSPEC_FSCALE_EXP))])]
16159   "TARGET_USE_FANCY_MATH_387
16160    && flag_unsafe_math_optimizations"
16161 {
16162   rtx temp;
16163   int i;
16164
16165   for (i=2; i<10; i++)
16166     operands[i] = gen_reg_rtx (XFmode);
16167   temp = standard_80387_constant_rtx (5); /* fldl2e */
16168   emit_move_insn (operands[2], temp);
16169   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16170 })
16171
16172 (define_expand "exp10sf2"
16173   [(set (match_dup 2)
16174         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16175    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16176    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16177    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16178    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16179    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16180    (parallel [(set (match_dup 10)
16181                    (unspec:XF [(match_dup 9) (match_dup 5)]
16182                               UNSPEC_FSCALE_FRACT))
16183               (set (match_dup 11)
16184                    (unspec:XF [(match_dup 9) (match_dup 5)]
16185                               UNSPEC_FSCALE_EXP))])
16186    (set (match_operand:SF 0 "register_operand" "")
16187         (float_truncate:SF (match_dup 10)))]
16188   "TARGET_USE_FANCY_MATH_387
16189    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190    && flag_unsafe_math_optimizations"
16191 {
16192   rtx temp;
16193   int i;
16194
16195   for (i=2; i<12; i++)
16196     operands[i] = gen_reg_rtx (XFmode);
16197   temp = standard_80387_constant_rtx (6); /* fldl2t */
16198   emit_move_insn (operands[3], temp);
16199   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16200 })
16201
16202 (define_expand "exp10df2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16206    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16207    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16208    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16209    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16210    (parallel [(set (match_dup 10)
16211                    (unspec:XF [(match_dup 9) (match_dup 5)]
16212                               UNSPEC_FSCALE_FRACT))
16213               (set (match_dup 11)
16214                    (unspec:XF [(match_dup 9) (match_dup 5)]
16215                               UNSPEC_FSCALE_EXP))])
16216    (set (match_operand:DF 0 "register_operand" "")
16217         (float_truncate:DF (match_dup 10)))]
16218   "TARGET_USE_FANCY_MATH_387
16219    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16220    && flag_unsafe_math_optimizations"
16221 {
16222   rtx temp;
16223   int i;
16224
16225   for (i=2; i<12; i++)
16226     operands[i] = gen_reg_rtx (XFmode);
16227   temp = standard_80387_constant_rtx (6); /* fldl2t */
16228   emit_move_insn (operands[3], temp);
16229   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16230 })
16231
16232 (define_expand "exp10xf2"
16233   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16234                                (match_dup 2)))
16235    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16236    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16237    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16238    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16239    (parallel [(set (match_operand:XF 0 "register_operand" "")
16240                    (unspec:XF [(match_dup 8) (match_dup 4)]
16241                               UNSPEC_FSCALE_FRACT))
16242               (set (match_dup 9)
16243                    (unspec:XF [(match_dup 8) (match_dup 4)]
16244                               UNSPEC_FSCALE_EXP))])]
16245   "TARGET_USE_FANCY_MATH_387
16246    && flag_unsafe_math_optimizations"
16247 {
16248   rtx temp;
16249   int i;
16250
16251   for (i=2; i<10; i++)
16252     operands[i] = gen_reg_rtx (XFmode);
16253   temp = standard_80387_constant_rtx (6); /* fldl2t */
16254   emit_move_insn (operands[2], temp);
16255   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16256 })
16257
16258 (define_expand "exp2sf2"
16259   [(set (match_dup 2)
16260         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16261    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16262    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16263    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16264    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16265    (parallel [(set (match_dup 8)
16266                    (unspec:XF [(match_dup 7) (match_dup 3)]
16267                               UNSPEC_FSCALE_FRACT))
16268               (set (match_dup 9)
16269                    (unspec:XF [(match_dup 7) (match_dup 3)]
16270                               UNSPEC_FSCALE_EXP))])
16271    (set (match_operand:SF 0 "register_operand" "")
16272         (float_truncate:SF (match_dup 8)))]
16273   "TARGET_USE_FANCY_MATH_387
16274    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16275    && flag_unsafe_math_optimizations"
16276 {
16277   int i;
16278
16279   for (i=2; i<10; i++)
16280     operands[i] = gen_reg_rtx (XFmode);
16281   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16282 })
16283
16284 (define_expand "exp2df2"
16285   [(set (match_dup 2)
16286         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16287    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16288    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16289    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16290    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16291    (parallel [(set (match_dup 8)
16292                    (unspec:XF [(match_dup 7) (match_dup 3)]
16293                               UNSPEC_FSCALE_FRACT))
16294               (set (match_dup 9)
16295                    (unspec:XF [(match_dup 7) (match_dup 3)]
16296                               UNSPEC_FSCALE_EXP))])
16297    (set (match_operand:DF 0 "register_operand" "")
16298         (float_truncate:DF (match_dup 8)))]
16299   "TARGET_USE_FANCY_MATH_387
16300    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16301    && flag_unsafe_math_optimizations"
16302 {
16303   int i;
16304
16305   for (i=2; i<10; i++)
16306     operands[i] = gen_reg_rtx (XFmode);
16307   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16308 })
16309
16310 (define_expand "exp2xf2"
16311   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16312    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16313    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16314    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16315    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16316    (parallel [(set (match_operand:XF 0 "register_operand" "")
16317                    (unspec:XF [(match_dup 7) (match_dup 3)]
16318                               UNSPEC_FSCALE_FRACT))
16319               (set (match_dup 8)
16320                    (unspec:XF [(match_dup 7) (match_dup 3)]
16321                               UNSPEC_FSCALE_EXP))])]
16322   "TARGET_USE_FANCY_MATH_387
16323    && flag_unsafe_math_optimizations"
16324 {
16325   int i;
16326
16327   for (i=2; i<9; i++)
16328     operands[i] = gen_reg_rtx (XFmode);
16329   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16330 })
16331
16332 (define_expand "expm1df2"
16333   [(set (match_dup 2)
16334         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16335    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16336    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16337    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16338    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16339    (parallel [(set (match_dup 8)
16340                    (unspec:XF [(match_dup 7) (match_dup 5)]
16341                               UNSPEC_FSCALE_FRACT))
16342                    (set (match_dup 9)
16343                    (unspec:XF [(match_dup 7) (match_dup 5)]
16344                               UNSPEC_FSCALE_EXP))])
16345    (parallel [(set (match_dup 11)
16346                    (unspec:XF [(match_dup 10) (match_dup 9)]
16347                               UNSPEC_FSCALE_FRACT))
16348               (set (match_dup 12)
16349                    (unspec:XF [(match_dup 10) (match_dup 9)]
16350                               UNSPEC_FSCALE_EXP))])
16351    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16352    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16353    (set (match_operand:DF 0 "register_operand" "")
16354         (float_truncate:DF (match_dup 14)))]
16355   "TARGET_USE_FANCY_MATH_387
16356    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16357    && flag_unsafe_math_optimizations"
16358 {
16359   rtx temp;
16360   int i;
16361
16362   for (i=2; i<15; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16364   temp = standard_80387_constant_rtx (5); /* fldl2e */
16365   emit_move_insn (operands[3], temp);
16366   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16367 })
16368
16369 (define_expand "expm1sf2"
16370   [(set (match_dup 2)
16371         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16372    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16373    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16374    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16375    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16376    (parallel [(set (match_dup 8)
16377                    (unspec:XF [(match_dup 7) (match_dup 5)]
16378                               UNSPEC_FSCALE_FRACT))
16379                    (set (match_dup 9)
16380                    (unspec:XF [(match_dup 7) (match_dup 5)]
16381                               UNSPEC_FSCALE_EXP))])
16382    (parallel [(set (match_dup 11)
16383                    (unspec:XF [(match_dup 10) (match_dup 9)]
16384                               UNSPEC_FSCALE_FRACT))
16385               (set (match_dup 12)
16386                    (unspec:XF [(match_dup 10) (match_dup 9)]
16387                               UNSPEC_FSCALE_EXP))])
16388    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16389    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16390    (set (match_operand:SF 0 "register_operand" "")
16391         (float_truncate:SF (match_dup 14)))]
16392   "TARGET_USE_FANCY_MATH_387
16393    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16394    && flag_unsafe_math_optimizations"
16395 {
16396   rtx temp;
16397   int i;
16398
16399   for (i=2; i<15; i++)
16400     operands[i] = gen_reg_rtx (XFmode);
16401   temp = standard_80387_constant_rtx (5); /* fldl2e */
16402   emit_move_insn (operands[3], temp);
16403   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16404 })
16405
16406 (define_expand "expm1xf2"
16407   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16408                                (match_dup 2)))
16409    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16410    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16411    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16412    (parallel [(set (match_dup 7)
16413                    (unspec:XF [(match_dup 6) (match_dup 4)]
16414                               UNSPEC_FSCALE_FRACT))
16415                    (set (match_dup 8)
16416                    (unspec:XF [(match_dup 6) (match_dup 4)]
16417                               UNSPEC_FSCALE_EXP))])
16418    (parallel [(set (match_dup 10)
16419                    (unspec:XF [(match_dup 9) (match_dup 8)]
16420                               UNSPEC_FSCALE_FRACT))
16421               (set (match_dup 11)
16422                    (unspec:XF [(match_dup 9) (match_dup 8)]
16423                               UNSPEC_FSCALE_EXP))])
16424    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16425    (set (match_operand:XF 0 "register_operand" "")
16426         (plus:XF (match_dup 12) (match_dup 7)))]
16427   "TARGET_USE_FANCY_MATH_387
16428    && flag_unsafe_math_optimizations"
16429 {
16430   rtx temp;
16431   int i;
16432
16433   for (i=2; i<13; i++)
16434     operands[i] = gen_reg_rtx (XFmode);
16435   temp = standard_80387_constant_rtx (5); /* fldl2e */
16436   emit_move_insn (operands[2], temp);
16437   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16438 })
16439
16440 (define_expand "ldexpdf3"
16441   [(set (match_dup 3)
16442         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16443    (set (match_dup 4)
16444         (float:XF (match_operand:SI 2 "register_operand" "")))
16445    (parallel [(set (match_dup 5)
16446                    (unspec:XF [(match_dup 3) (match_dup 4)]
16447                               UNSPEC_FSCALE_FRACT))
16448               (set (match_dup 6)
16449                    (unspec:XF [(match_dup 3) (match_dup 4)]
16450                               UNSPEC_FSCALE_EXP))])
16451    (set (match_operand:DF 0 "register_operand" "")
16452         (float_truncate:DF (match_dup 5)))]
16453   "TARGET_USE_FANCY_MATH_387
16454    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16455    && flag_unsafe_math_optimizations"
16456 {
16457   int i;
16458
16459   for (i=3; i<7; i++)
16460     operands[i] = gen_reg_rtx (XFmode);
16461 })
16462
16463 (define_expand "ldexpsf3"
16464   [(set (match_dup 3)
16465         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16466    (set (match_dup 4)
16467         (float:XF (match_operand:SI 2 "register_operand" "")))
16468    (parallel [(set (match_dup 5)
16469                    (unspec:XF [(match_dup 3) (match_dup 4)]
16470                               UNSPEC_FSCALE_FRACT))
16471               (set (match_dup 6)
16472                    (unspec:XF [(match_dup 3) (match_dup 4)]
16473                               UNSPEC_FSCALE_EXP))])
16474    (set (match_operand:SF 0 "register_operand" "")
16475         (float_truncate:SF (match_dup 5)))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16478    && flag_unsafe_math_optimizations"
16479 {
16480   int i;
16481
16482   for (i=3; i<7; i++)
16483     operands[i] = gen_reg_rtx (XFmode);
16484 })
16485
16486 (define_expand "ldexpxf3"
16487   [(set (match_dup 3)
16488         (float:XF (match_operand:SI 2 "register_operand" "")))
16489    (parallel [(set (match_operand:XF 0 " register_operand" "")
16490                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16491                                (match_dup 3)]
16492                               UNSPEC_FSCALE_FRACT))
16493               (set (match_dup 4)
16494                    (unspec:XF [(match_dup 1) (match_dup 3)]
16495                               UNSPEC_FSCALE_EXP))])]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations"
16498 {
16499   int i;
16500
16501   for (i=3; i<5; i++)
16502     operands[i] = gen_reg_rtx (XFmode);
16503 })
16504 \f
16505
16506 (define_insn "frndintxf2"
16507   [(set (match_operand:XF 0 "register_operand" "=f")
16508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16509          UNSPEC_FRNDINT))]
16510   "TARGET_USE_FANCY_MATH_387
16511    && flag_unsafe_math_optimizations"
16512   "frndint"
16513   [(set_attr "type" "fpspc")
16514    (set_attr "mode" "XF")])
16515
16516 (define_expand "rintdf2"
16517   [(use (match_operand:DF 0 "register_operand" ""))
16518    (use (match_operand:DF 1 "register_operand" ""))]
16519   "TARGET_USE_FANCY_MATH_387
16520    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16521    && flag_unsafe_math_optimizations"
16522 {
16523   rtx op0 = gen_reg_rtx (XFmode);
16524   rtx op1 = gen_reg_rtx (XFmode);
16525
16526   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16527   emit_insn (gen_frndintxf2 (op0, op1));
16528
16529   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16530   DONE;
16531 })
16532
16533 (define_expand "rintsf2"
16534   [(use (match_operand:SF 0 "register_operand" ""))
16535    (use (match_operand:SF 1 "register_operand" ""))]
16536   "TARGET_USE_FANCY_MATH_387
16537    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16538    && flag_unsafe_math_optimizations"
16539 {
16540   rtx op0 = gen_reg_rtx (XFmode);
16541   rtx op1 = gen_reg_rtx (XFmode);
16542
16543   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16544   emit_insn (gen_frndintxf2 (op0, op1));
16545
16546   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16547   DONE;
16548 })
16549
16550 (define_expand "rintxf2"
16551   [(use (match_operand:XF 0 "register_operand" ""))
16552    (use (match_operand:XF 1 "register_operand" ""))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && flag_unsafe_math_optimizations"
16555 {
16556   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16557   DONE;
16558 })
16559
16560 (define_insn_and_split "*fistdi2_1"
16561   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16562         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16563          UNSPEC_FIST))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && flag_unsafe_math_optimizations
16566    && !(reload_completed || reload_in_progress)"
16567   "#"
16568   "&& 1"
16569   [(const_int 0)]
16570 {
16571   if (memory_operand (operands[0], VOIDmode))
16572     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16573   else
16574     {
16575       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16576       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16577                                          operands[2]));
16578     }
16579   DONE;
16580 }
16581   [(set_attr "type" "fpspc")
16582    (set_attr "mode" "DI")])
16583
16584 (define_insn "fistdi2"
16585   [(set (match_operand:DI 0 "memory_operand" "=m")
16586         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16587          UNSPEC_FIST))
16588    (clobber (match_scratch:XF 2 "=&1f"))]
16589   "TARGET_USE_FANCY_MATH_387
16590    && flag_unsafe_math_optimizations"
16591   "* return output_fix_trunc (insn, operands, 0);"
16592   [(set_attr "type" "fpspc")
16593    (set_attr "mode" "DI")])
16594
16595 (define_insn "fistdi2_with_temp"
16596   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16597         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16598          UNSPEC_FIST))
16599    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16600    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16601   "TARGET_USE_FANCY_MATH_387
16602    && flag_unsafe_math_optimizations"
16603   "#"
16604   [(set_attr "type" "fpspc")
16605    (set_attr "mode" "DI")])
16606
16607 (define_split 
16608   [(set (match_operand:DI 0 "register_operand" "")
16609         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16610          UNSPEC_FIST))
16611    (clobber (match_operand:DI 2 "memory_operand" ""))
16612    (clobber (match_scratch 3 ""))]
16613   "reload_completed"
16614   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16615               (clobber (match_dup 3))])
16616    (set (match_dup 0) (match_dup 2))]
16617   "")
16618
16619 (define_split 
16620   [(set (match_operand:DI 0 "memory_operand" "")
16621         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16622          UNSPEC_FIST))
16623    (clobber (match_operand:DI 2 "memory_operand" ""))
16624    (clobber (match_scratch 3 ""))]
16625   "reload_completed"
16626   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16627               (clobber (match_dup 3))])]
16628   "")
16629
16630 (define_insn_and_split "*fist<mode>2_1"
16631   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16632         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16633          UNSPEC_FIST))]
16634   "TARGET_USE_FANCY_MATH_387
16635    && flag_unsafe_math_optimizations
16636    && !(reload_completed || reload_in_progress)"
16637   "#"
16638   "&& 1"
16639   [(const_int 0)]
16640 {
16641   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16642   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16643                                         operands[2]));
16644   DONE;
16645 }
16646   [(set_attr "type" "fpspc")
16647    (set_attr "mode" "<MODE>")])
16648
16649 (define_insn "fist<mode>2"
16650   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16651         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16652          UNSPEC_FIST))]
16653   "TARGET_USE_FANCY_MATH_387
16654    && flag_unsafe_math_optimizations"
16655   "* return output_fix_trunc (insn, operands, 0);"
16656   [(set_attr "type" "fpspc")
16657    (set_attr "mode" "<MODE>")])
16658
16659 (define_insn "fist<mode>2_with_temp"
16660   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16661         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16662          UNSPEC_FIST))
16663    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16664   "TARGET_USE_FANCY_MATH_387
16665    && flag_unsafe_math_optimizations"
16666   "#"
16667   [(set_attr "type" "fpspc")
16668    (set_attr "mode" "<MODE>")])
16669
16670 (define_split 
16671   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16672         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16673          UNSPEC_FIST))
16674    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16675   "reload_completed"
16676   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16677                        UNSPEC_FIST))
16678    (set (match_dup 0) (match_dup 2))]
16679   "")
16680
16681 (define_split 
16682   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16683         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16684          UNSPEC_FIST))
16685    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16686   "reload_completed"
16687   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16688                        UNSPEC_FIST))]
16689   "")
16690
16691 (define_expand "lrint<mode>2"
16692   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16693         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16694          UNSPEC_FIST))]
16695   "TARGET_USE_FANCY_MATH_387
16696    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16697    && flag_unsafe_math_optimizations"
16698   "")
16699
16700 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16701 (define_insn_and_split "frndintxf2_floor"
16702   [(set (match_operand:XF 0 "register_operand" "=f")
16703         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16704          UNSPEC_FRNDINT_FLOOR))
16705    (clobber (reg:CC FLAGS_REG))]
16706   "TARGET_USE_FANCY_MATH_387
16707    && flag_unsafe_math_optimizations
16708    && !(reload_completed || reload_in_progress)"
16709   "#"
16710   "&& 1"
16711   [(const_int 0)]
16712 {
16713   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16714
16715   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16716   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16717
16718   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16719                                         operands[2], operands[3]));
16720   DONE;
16721 }
16722   [(set_attr "type" "frndint")
16723    (set_attr "i387_cw" "floor")
16724    (set_attr "mode" "XF")])
16725
16726 (define_insn "frndintxf2_floor_i387"
16727   [(set (match_operand:XF 0 "register_operand" "=f")
16728         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16729          UNSPEC_FRNDINT_FLOOR))
16730    (use (match_operand:HI 2 "memory_operand" "m"))
16731    (use (match_operand:HI 3 "memory_operand" "m"))]
16732   "TARGET_USE_FANCY_MATH_387
16733    && flag_unsafe_math_optimizations"
16734   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16735   [(set_attr "type" "frndint")
16736    (set_attr "i387_cw" "floor")
16737    (set_attr "mode" "XF")])
16738
16739 (define_expand "floorxf2"
16740   [(use (match_operand:XF 0 "register_operand" ""))
16741    (use (match_operand:XF 1 "register_operand" ""))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && flag_unsafe_math_optimizations"
16744 {
16745   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16746   DONE;
16747 })
16748
16749 (define_expand "floordf2"
16750   [(use (match_operand:DF 0 "register_operand" ""))
16751    (use (match_operand:DF 1 "register_operand" ""))]
16752   "TARGET_USE_FANCY_MATH_387
16753    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16754    && flag_unsafe_math_optimizations"
16755 {
16756   rtx op0 = gen_reg_rtx (XFmode);
16757   rtx op1 = gen_reg_rtx (XFmode);
16758
16759   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16760   emit_insn (gen_frndintxf2_floor (op0, op1));
16761
16762   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16763   DONE;
16764 })
16765
16766 (define_expand "floorsf2"
16767   [(use (match_operand:SF 0 "register_operand" ""))
16768    (use (match_operand:SF 1 "register_operand" ""))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16771    && flag_unsafe_math_optimizations"
16772 {
16773   rtx op0 = gen_reg_rtx (XFmode);
16774   rtx op1 = gen_reg_rtx (XFmode);
16775
16776   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16777   emit_insn (gen_frndintxf2_floor (op0, op1));
16778
16779   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16780   DONE;
16781 })
16782
16783 (define_insn_and_split "*fist<mode>2_floor_1"
16784   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16785         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16786          UNSPEC_FIST_FLOOR))
16787    (clobber (reg:CC FLAGS_REG))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && flag_unsafe_math_optimizations
16790    && !(reload_completed || reload_in_progress)"
16791   "#"
16792   "&& 1"
16793   [(const_int 0)]
16794 {
16795   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16796
16797   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16798   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16799   if (memory_operand (operands[0], VOIDmode))
16800     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16801                                       operands[2], operands[3]));
16802   else
16803     {
16804       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16805       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16806                                                   operands[2], operands[3],
16807                                                   operands[4]));
16808     }
16809   DONE;
16810 }
16811   [(set_attr "type" "fistp")
16812    (set_attr "i387_cw" "floor")
16813    (set_attr "mode" "<MODE>")])
16814
16815 (define_insn "fistdi2_floor"
16816   [(set (match_operand:DI 0 "memory_operand" "=m")
16817         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16818          UNSPEC_FIST_FLOOR))
16819    (use (match_operand:HI 2 "memory_operand" "m"))
16820    (use (match_operand:HI 3 "memory_operand" "m"))
16821    (clobber (match_scratch:XF 4 "=&1f"))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && flag_unsafe_math_optimizations"
16824   "* return output_fix_trunc (insn, operands, 0);"
16825   [(set_attr "type" "fistp")
16826    (set_attr "i387_cw" "floor")
16827    (set_attr "mode" "DI")])
16828
16829 (define_insn "fistdi2_floor_with_temp"
16830   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16831         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16832          UNSPEC_FIST_FLOOR))
16833    (use (match_operand:HI 2 "memory_operand" "m,m"))
16834    (use (match_operand:HI 3 "memory_operand" "m,m"))
16835    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16836    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16837   "TARGET_USE_FANCY_MATH_387
16838    && flag_unsafe_math_optimizations"
16839   "#"
16840   [(set_attr "type" "fistp")
16841    (set_attr "i387_cw" "floor")
16842    (set_attr "mode" "DI")])
16843
16844 (define_split 
16845   [(set (match_operand:DI 0 "register_operand" "")
16846         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16847          UNSPEC_FIST_FLOOR))
16848    (use (match_operand:HI 2 "memory_operand" ""))
16849    (use (match_operand:HI 3 "memory_operand" ""))
16850    (clobber (match_operand:DI 4 "memory_operand" ""))
16851    (clobber (match_scratch 5 ""))]
16852   "reload_completed"
16853   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16854               (use (match_dup 2))
16855               (use (match_dup 3))
16856               (clobber (match_dup 5))])
16857    (set (match_dup 0) (match_dup 4))]
16858   "")
16859
16860 (define_split 
16861   [(set (match_operand:DI 0 "memory_operand" "")
16862         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16863          UNSPEC_FIST_FLOOR))
16864    (use (match_operand:HI 2 "memory_operand" ""))
16865    (use (match_operand:HI 3 "memory_operand" ""))
16866    (clobber (match_operand:DI 4 "memory_operand" ""))
16867    (clobber (match_scratch 5 ""))]
16868   "reload_completed"
16869   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16870               (use (match_dup 2))
16871               (use (match_dup 3))
16872               (clobber (match_dup 5))])]
16873   "")
16874
16875 (define_insn "fist<mode>2_floor"
16876   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16877         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16878          UNSPEC_FIST_FLOOR))
16879    (use (match_operand:HI 2 "memory_operand" "m"))
16880    (use (match_operand:HI 3 "memory_operand" "m"))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && flag_unsafe_math_optimizations"
16883   "* return output_fix_trunc (insn, operands, 0);"
16884   [(set_attr "type" "fistp")
16885    (set_attr "i387_cw" "floor")
16886    (set_attr "mode" "<MODE>")])
16887
16888 (define_insn "fist<mode>2_floor_with_temp"
16889   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16890         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16891          UNSPEC_FIST_FLOOR))
16892    (use (match_operand:HI 2 "memory_operand" "m,m"))
16893    (use (match_operand:HI 3 "memory_operand" "m,m"))
16894    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16895   "TARGET_USE_FANCY_MATH_387
16896    && flag_unsafe_math_optimizations"
16897   "#"
16898   [(set_attr "type" "fistp")
16899    (set_attr "i387_cw" "floor")
16900    (set_attr "mode" "<MODE>")])
16901
16902 (define_split 
16903   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16904         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16905          UNSPEC_FIST_FLOOR))
16906    (use (match_operand:HI 2 "memory_operand" ""))
16907    (use (match_operand:HI 3 "memory_operand" ""))
16908    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16909   "reload_completed"
16910   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16911                                   UNSPEC_FIST_FLOOR))
16912               (use (match_dup 2))
16913               (use (match_dup 3))])
16914    (set (match_dup 0) (match_dup 4))]
16915   "")
16916
16917 (define_split 
16918   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16919         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16920          UNSPEC_FIST_FLOOR))
16921    (use (match_operand:HI 2 "memory_operand" ""))
16922    (use (match_operand:HI 3 "memory_operand" ""))
16923    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16924   "reload_completed"
16925   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16926                                   UNSPEC_FIST_FLOOR))
16927               (use (match_dup 2))
16928               (use (match_dup 3))])]
16929   "")
16930
16931 (define_expand "lfloor<mode>2"
16932   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16933                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16934                     UNSPEC_FIST_FLOOR))
16935               (clobber (reg:CC FLAGS_REG))])]
16936   "TARGET_USE_FANCY_MATH_387
16937    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16938    && flag_unsafe_math_optimizations"
16939   "")
16940
16941 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16942 (define_insn_and_split "frndintxf2_ceil"
16943   [(set (match_operand:XF 0 "register_operand" "=f")
16944         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16945          UNSPEC_FRNDINT_CEIL))
16946    (clobber (reg:CC FLAGS_REG))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && flag_unsafe_math_optimizations
16949    && !(reload_completed || reload_in_progress)"
16950   "#"
16951   "&& 1"
16952   [(const_int 0)]
16953 {
16954   ix86_optimize_mode_switching[I387_CEIL] = 1;
16955
16956   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16957   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16958
16959   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16960                                        operands[2], operands[3]));
16961   DONE;
16962 }
16963   [(set_attr "type" "frndint")
16964    (set_attr "i387_cw" "ceil")
16965    (set_attr "mode" "XF")])
16966
16967 (define_insn "frndintxf2_ceil_i387"
16968   [(set (match_operand:XF 0 "register_operand" "=f")
16969         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16970          UNSPEC_FRNDINT_CEIL))
16971    (use (match_operand:HI 2 "memory_operand" "m"))
16972    (use (match_operand:HI 3 "memory_operand" "m"))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && flag_unsafe_math_optimizations"
16975   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16976   [(set_attr "type" "frndint")
16977    (set_attr "i387_cw" "ceil")
16978    (set_attr "mode" "XF")])
16979
16980 (define_expand "ceilxf2"
16981   [(use (match_operand:XF 0 "register_operand" ""))
16982    (use (match_operand:XF 1 "register_operand" ""))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && flag_unsafe_math_optimizations"
16985 {
16986   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16987   DONE;
16988 })
16989
16990 (define_expand "ceildf2"
16991   [(use (match_operand:DF 0 "register_operand" ""))
16992    (use (match_operand:DF 1 "register_operand" ""))]
16993   "TARGET_USE_FANCY_MATH_387
16994    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16995    && flag_unsafe_math_optimizations"
16996 {
16997   rtx op0 = gen_reg_rtx (XFmode);
16998   rtx op1 = gen_reg_rtx (XFmode);
16999
17000   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17001   emit_insn (gen_frndintxf2_ceil (op0, op1));
17002
17003   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17004   DONE;
17005 })
17006
17007 (define_expand "ceilsf2"
17008   [(use (match_operand:SF 0 "register_operand" ""))
17009    (use (match_operand:SF 1 "register_operand" ""))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17012    && flag_unsafe_math_optimizations"
17013 {
17014   rtx op0 = gen_reg_rtx (XFmode);
17015   rtx op1 = gen_reg_rtx (XFmode);
17016
17017   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17018   emit_insn (gen_frndintxf2_ceil (op0, op1));
17019
17020   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17021   DONE;
17022 })
17023
17024 (define_insn_and_split "*fist<mode>2_ceil_1"
17025   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17026         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17027          UNSPEC_FIST_CEIL))
17028    (clobber (reg:CC FLAGS_REG))]
17029   "TARGET_USE_FANCY_MATH_387
17030    && flag_unsafe_math_optimizations
17031    && !(reload_completed || reload_in_progress)"
17032   "#"
17033   "&& 1"
17034   [(const_int 0)]
17035 {
17036   ix86_optimize_mode_switching[I387_CEIL] = 1;
17037
17038   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17039   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17040   if (memory_operand (operands[0], VOIDmode))
17041     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17042                                      operands[2], operands[3]));
17043   else
17044     {
17045       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17046       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17047                                                  operands[2], operands[3],
17048                                                  operands[4]));
17049     }
17050   DONE;
17051 }
17052   [(set_attr "type" "fistp")
17053    (set_attr "i387_cw" "ceil")
17054    (set_attr "mode" "<MODE>")])
17055
17056 (define_insn "fistdi2_ceil"
17057   [(set (match_operand:DI 0 "memory_operand" "=m")
17058         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17059          UNSPEC_FIST_CEIL))
17060    (use (match_operand:HI 2 "memory_operand" "m"))
17061    (use (match_operand:HI 3 "memory_operand" "m"))
17062    (clobber (match_scratch:XF 4 "=&1f"))]
17063   "TARGET_USE_FANCY_MATH_387
17064    && flag_unsafe_math_optimizations"
17065   "* return output_fix_trunc (insn, operands, 0);"
17066   [(set_attr "type" "fistp")
17067    (set_attr "i387_cw" "ceil")
17068    (set_attr "mode" "DI")])
17069
17070 (define_insn "fistdi2_ceil_with_temp"
17071   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17072         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17073          UNSPEC_FIST_CEIL))
17074    (use (match_operand:HI 2 "memory_operand" "m,m"))
17075    (use (match_operand:HI 3 "memory_operand" "m,m"))
17076    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17077    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17078   "TARGET_USE_FANCY_MATH_387
17079    && flag_unsafe_math_optimizations"
17080   "#"
17081   [(set_attr "type" "fistp")
17082    (set_attr "i387_cw" "ceil")
17083    (set_attr "mode" "DI")])
17084
17085 (define_split 
17086   [(set (match_operand:DI 0 "register_operand" "")
17087         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17088          UNSPEC_FIST_CEIL))
17089    (use (match_operand:HI 2 "memory_operand" ""))
17090    (use (match_operand:HI 3 "memory_operand" ""))
17091    (clobber (match_operand:DI 4 "memory_operand" ""))
17092    (clobber (match_scratch 5 ""))]
17093   "reload_completed"
17094   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17095               (use (match_dup 2))
17096               (use (match_dup 3))
17097               (clobber (match_dup 5))])
17098    (set (match_dup 0) (match_dup 4))]
17099   "")
17100
17101 (define_split 
17102   [(set (match_operand:DI 0 "memory_operand" "")
17103         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17104          UNSPEC_FIST_CEIL))
17105    (use (match_operand:HI 2 "memory_operand" ""))
17106    (use (match_operand:HI 3 "memory_operand" ""))
17107    (clobber (match_operand:DI 4 "memory_operand" ""))
17108    (clobber (match_scratch 5 ""))]
17109   "reload_completed"
17110   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17111               (use (match_dup 2))
17112               (use (match_dup 3))
17113               (clobber (match_dup 5))])]
17114   "")
17115
17116 (define_insn "fist<mode>2_ceil"
17117   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17118         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17119          UNSPEC_FIST_CEIL))
17120    (use (match_operand:HI 2 "memory_operand" "m"))
17121    (use (match_operand:HI 3 "memory_operand" "m"))]
17122   "TARGET_USE_FANCY_MATH_387
17123    && flag_unsafe_math_optimizations"
17124   "* return output_fix_trunc (insn, operands, 0);"
17125   [(set_attr "type" "fistp")
17126    (set_attr "i387_cw" "ceil")
17127    (set_attr "mode" "<MODE>")])
17128
17129 (define_insn "fist<mode>2_ceil_with_temp"
17130   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17131         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17132          UNSPEC_FIST_CEIL))
17133    (use (match_operand:HI 2 "memory_operand" "m,m"))
17134    (use (match_operand:HI 3 "memory_operand" "m,m"))
17135    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && flag_unsafe_math_optimizations"
17138   "#"
17139   [(set_attr "type" "fistp")
17140    (set_attr "i387_cw" "ceil")
17141    (set_attr "mode" "<MODE>")])
17142
17143 (define_split 
17144   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17145         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17146          UNSPEC_FIST_CEIL))
17147    (use (match_operand:HI 2 "memory_operand" ""))
17148    (use (match_operand:HI 3 "memory_operand" ""))
17149    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17150   "reload_completed"
17151   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17152                                   UNSPEC_FIST_CEIL))
17153               (use (match_dup 2))
17154               (use (match_dup 3))])
17155    (set (match_dup 0) (match_dup 4))]
17156   "")
17157
17158 (define_split 
17159   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17160         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17161          UNSPEC_FIST_CEIL))
17162    (use (match_operand:HI 2 "memory_operand" ""))
17163    (use (match_operand:HI 3 "memory_operand" ""))
17164    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17165   "reload_completed"
17166   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17167                                   UNSPEC_FIST_CEIL))
17168               (use (match_dup 2))
17169               (use (match_dup 3))])]
17170   "")
17171
17172 (define_expand "lceil<mode>2"
17173   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17174                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17175                     UNSPEC_FIST_CEIL))
17176               (clobber (reg:CC FLAGS_REG))])]
17177   "TARGET_USE_FANCY_MATH_387
17178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17179    && flag_unsafe_math_optimizations"
17180   "")
17181
17182 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17183 (define_insn_and_split "frndintxf2_trunc"
17184   [(set (match_operand:XF 0 "register_operand" "=f")
17185         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17186          UNSPEC_FRNDINT_TRUNC))
17187    (clobber (reg:CC FLAGS_REG))]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations
17190    && !(reload_completed || reload_in_progress)"
17191   "#"
17192   "&& 1"
17193   [(const_int 0)]
17194 {
17195   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17196
17197   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17198   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17199
17200   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17201                                         operands[2], operands[3]));
17202   DONE;
17203 }
17204   [(set_attr "type" "frndint")
17205    (set_attr "i387_cw" "trunc")
17206    (set_attr "mode" "XF")])
17207
17208 (define_insn "frndintxf2_trunc_i387"
17209   [(set (match_operand:XF 0 "register_operand" "=f")
17210         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17211          UNSPEC_FRNDINT_TRUNC))
17212    (use (match_operand:HI 2 "memory_operand" "m"))
17213    (use (match_operand:HI 3 "memory_operand" "m"))]
17214   "TARGET_USE_FANCY_MATH_387
17215    && flag_unsafe_math_optimizations"
17216   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17217   [(set_attr "type" "frndint")
17218    (set_attr "i387_cw" "trunc")
17219    (set_attr "mode" "XF")])
17220
17221 (define_expand "btruncxf2"
17222   [(use (match_operand:XF 0 "register_operand" ""))
17223    (use (match_operand:XF 1 "register_operand" ""))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && flag_unsafe_math_optimizations"
17226 {
17227   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17228   DONE;
17229 })
17230
17231 (define_expand "btruncdf2"
17232   [(use (match_operand:DF 0 "register_operand" ""))
17233    (use (match_operand:DF 1 "register_operand" ""))]
17234   "TARGET_USE_FANCY_MATH_387
17235    && (!(TARGET_SSE2 && 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_extenddfxf2 (op1, operands[1]));
17242   emit_insn (gen_frndintxf2_trunc (op0, op1));
17243
17244   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17245   DONE;
17246 })
17247
17248 (define_expand "btruncsf2"
17249   [(use (match_operand:SF 0 "register_operand" ""))
17250    (use (match_operand:SF 1 "register_operand" ""))]
17251   "TARGET_USE_FANCY_MATH_387
17252    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17253    && flag_unsafe_math_optimizations"
17254 {
17255   rtx op0 = gen_reg_rtx (XFmode);
17256   rtx op1 = gen_reg_rtx (XFmode);
17257
17258   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17259   emit_insn (gen_frndintxf2_trunc (op0, op1));
17260
17261   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17262   DONE;
17263 })
17264
17265 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17266 (define_insn_and_split "frndintxf2_mask_pm"
17267   [(set (match_operand:XF 0 "register_operand" "=f")
17268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17269          UNSPEC_FRNDINT_MASK_PM))
17270    (clobber (reg:CC FLAGS_REG))]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations
17273    && !(reload_completed || reload_in_progress)"
17274   "#"
17275   "&& 1"
17276   [(const_int 0)]
17277 {
17278   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17279
17280   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17281   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17282
17283   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17284                                           operands[2], operands[3]));
17285   DONE;
17286 }
17287   [(set_attr "type" "frndint")
17288    (set_attr "i387_cw" "mask_pm")
17289    (set_attr "mode" "XF")])
17290
17291 (define_insn "frndintxf2_mask_pm_i387"
17292   [(set (match_operand:XF 0 "register_operand" "=f")
17293         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17294          UNSPEC_FRNDINT_MASK_PM))
17295    (use (match_operand:HI 2 "memory_operand" "m"))
17296    (use (match_operand:HI 3 "memory_operand" "m"))]
17297   "TARGET_USE_FANCY_MATH_387
17298    && flag_unsafe_math_optimizations"
17299   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17300   [(set_attr "type" "frndint")
17301    (set_attr "i387_cw" "mask_pm")
17302    (set_attr "mode" "XF")])
17303
17304 (define_expand "nearbyintxf2"
17305   [(use (match_operand:XF 0 "register_operand" ""))
17306    (use (match_operand:XF 1 "register_operand" ""))]
17307   "TARGET_USE_FANCY_MATH_387
17308    && flag_unsafe_math_optimizations"
17309 {
17310   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17311
17312   DONE;
17313 })
17314
17315 (define_expand "nearbyintdf2"
17316   [(use (match_operand:DF 0 "register_operand" ""))
17317    (use (match_operand:DF 1 "register_operand" ""))]
17318   "TARGET_USE_FANCY_MATH_387
17319    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17320    && flag_unsafe_math_optimizations"
17321 {
17322   rtx op0 = gen_reg_rtx (XFmode);
17323   rtx op1 = gen_reg_rtx (XFmode);
17324
17325   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17326   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17327
17328   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17329   DONE;
17330 })
17331
17332 (define_expand "nearbyintsf2"
17333   [(use (match_operand:SF 0 "register_operand" ""))
17334    (use (match_operand:SF 1 "register_operand" ""))]
17335   "TARGET_USE_FANCY_MATH_387
17336    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17337    && flag_unsafe_math_optimizations"
17338 {
17339   rtx op0 = gen_reg_rtx (XFmode);
17340   rtx op1 = gen_reg_rtx (XFmode);
17341
17342   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17343   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17344
17345   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17346   DONE;
17347 })
17348
17349 \f
17350 ;; Block operation instructions
17351
17352 (define_insn "cld"
17353  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17354  ""
17355  "cld"
17356   [(set_attr "type" "cld")])
17357
17358 (define_expand "movmemsi"
17359   [(use (match_operand:BLK 0 "memory_operand" ""))
17360    (use (match_operand:BLK 1 "memory_operand" ""))
17361    (use (match_operand:SI 2 "nonmemory_operand" ""))
17362    (use (match_operand:SI 3 "const_int_operand" ""))]
17363   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17364 {
17365  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17366    DONE;
17367  else
17368    FAIL;
17369 })
17370
17371 (define_expand "movmemdi"
17372   [(use (match_operand:BLK 0 "memory_operand" ""))
17373    (use (match_operand:BLK 1 "memory_operand" ""))
17374    (use (match_operand:DI 2 "nonmemory_operand" ""))
17375    (use (match_operand:DI 3 "const_int_operand" ""))]
17376   "TARGET_64BIT"
17377 {
17378  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17379    DONE;
17380  else
17381    FAIL;
17382 })
17383
17384 ;; Most CPUs don't like single string operations
17385 ;; Handle this case here to simplify previous expander.
17386
17387 (define_expand "strmov"
17388   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17389    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17390    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17391               (clobber (reg:CC FLAGS_REG))])
17392    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17393               (clobber (reg:CC FLAGS_REG))])]
17394   ""
17395 {
17396   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17397
17398   /* If .md ever supports :P for Pmode, these can be directly
17399      in the pattern above.  */
17400   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17401   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17402
17403   if (TARGET_SINGLE_STRINGOP || optimize_size)
17404     {
17405       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17406                                       operands[2], operands[3],
17407                                       operands[5], operands[6]));
17408       DONE;
17409     }
17410
17411   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17412 })
17413
17414 (define_expand "strmov_singleop"
17415   [(parallel [(set (match_operand 1 "memory_operand" "")
17416                    (match_operand 3 "memory_operand" ""))
17417               (set (match_operand 0 "register_operand" "")
17418                    (match_operand 4 "" ""))
17419               (set (match_operand 2 "register_operand" "")
17420                    (match_operand 5 "" ""))
17421               (use (reg:SI DIRFLAG_REG))])]
17422   "TARGET_SINGLE_STRINGOP || optimize_size"
17423   "")
17424
17425 (define_insn "*strmovdi_rex_1"
17426   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17427         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17428    (set (match_operand:DI 0 "register_operand" "=D")
17429         (plus:DI (match_dup 2)
17430                  (const_int 8)))
17431    (set (match_operand:DI 1 "register_operand" "=S")
17432         (plus:DI (match_dup 3)
17433                  (const_int 8)))
17434    (use (reg:SI DIRFLAG_REG))]
17435   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17436   "movsq"
17437   [(set_attr "type" "str")
17438    (set_attr "mode" "DI")
17439    (set_attr "memory" "both")])
17440
17441 (define_insn "*strmovsi_1"
17442   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17443         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17444    (set (match_operand:SI 0 "register_operand" "=D")
17445         (plus:SI (match_dup 2)
17446                  (const_int 4)))
17447    (set (match_operand:SI 1 "register_operand" "=S")
17448         (plus:SI (match_dup 3)
17449                  (const_int 4)))
17450    (use (reg:SI DIRFLAG_REG))]
17451   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17452   "{movsl|movsd}"
17453   [(set_attr "type" "str")
17454    (set_attr "mode" "SI")
17455    (set_attr "memory" "both")])
17456
17457 (define_insn "*strmovsi_rex_1"
17458   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17459         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17460    (set (match_operand:DI 0 "register_operand" "=D")
17461         (plus:DI (match_dup 2)
17462                  (const_int 4)))
17463    (set (match_operand:DI 1 "register_operand" "=S")
17464         (plus:DI (match_dup 3)
17465                  (const_int 4)))
17466    (use (reg:SI DIRFLAG_REG))]
17467   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17468   "{movsl|movsd}"
17469   [(set_attr "type" "str")
17470    (set_attr "mode" "SI")
17471    (set_attr "memory" "both")])
17472
17473 (define_insn "*strmovhi_1"
17474   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17475         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17476    (set (match_operand:SI 0 "register_operand" "=D")
17477         (plus:SI (match_dup 2)
17478                  (const_int 2)))
17479    (set (match_operand:SI 1 "register_operand" "=S")
17480         (plus:SI (match_dup 3)
17481                  (const_int 2)))
17482    (use (reg:SI DIRFLAG_REG))]
17483   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17484   "movsw"
17485   [(set_attr "type" "str")
17486    (set_attr "memory" "both")
17487    (set_attr "mode" "HI")])
17488
17489 (define_insn "*strmovhi_rex_1"
17490   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17491         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17492    (set (match_operand:DI 0 "register_operand" "=D")
17493         (plus:DI (match_dup 2)
17494                  (const_int 2)))
17495    (set (match_operand:DI 1 "register_operand" "=S")
17496         (plus:DI (match_dup 3)
17497                  (const_int 2)))
17498    (use (reg:SI DIRFLAG_REG))]
17499   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17500   "movsw"
17501   [(set_attr "type" "str")
17502    (set_attr "memory" "both")
17503    (set_attr "mode" "HI")])
17504
17505 (define_insn "*strmovqi_1"
17506   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17507         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17508    (set (match_operand:SI 0 "register_operand" "=D")
17509         (plus:SI (match_dup 2)
17510                  (const_int 1)))
17511    (set (match_operand:SI 1 "register_operand" "=S")
17512         (plus:SI (match_dup 3)
17513                  (const_int 1)))
17514    (use (reg:SI DIRFLAG_REG))]
17515   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17516   "movsb"
17517   [(set_attr "type" "str")
17518    (set_attr "memory" "both")
17519    (set_attr "mode" "QI")])
17520
17521 (define_insn "*strmovqi_rex_1"
17522   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17523         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17524    (set (match_operand:DI 0 "register_operand" "=D")
17525         (plus:DI (match_dup 2)
17526                  (const_int 1)))
17527    (set (match_operand:DI 1 "register_operand" "=S")
17528         (plus:DI (match_dup 3)
17529                  (const_int 1)))
17530    (use (reg:SI DIRFLAG_REG))]
17531   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17532   "movsb"
17533   [(set_attr "type" "str")
17534    (set_attr "memory" "both")
17535    (set_attr "mode" "QI")])
17536
17537 (define_expand "rep_mov"
17538   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17539               (set (match_operand 0 "register_operand" "")
17540                    (match_operand 5 "" ""))
17541               (set (match_operand 2 "register_operand" "")
17542                    (match_operand 6 "" ""))
17543               (set (match_operand 1 "memory_operand" "")
17544                    (match_operand 3 "memory_operand" ""))
17545               (use (match_dup 4))
17546               (use (reg:SI DIRFLAG_REG))])]
17547   ""
17548   "")
17549
17550 (define_insn "*rep_movdi_rex64"
17551   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17552    (set (match_operand:DI 0 "register_operand" "=D") 
17553         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17554                             (const_int 3))
17555                  (match_operand:DI 3 "register_operand" "0")))
17556    (set (match_operand:DI 1 "register_operand" "=S") 
17557         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17558                  (match_operand:DI 4 "register_operand" "1")))
17559    (set (mem:BLK (match_dup 3))
17560         (mem:BLK (match_dup 4)))
17561    (use (match_dup 5))
17562    (use (reg:SI DIRFLAG_REG))]
17563   "TARGET_64BIT"
17564   "{rep\;movsq|rep movsq}"
17565   [(set_attr "type" "str")
17566    (set_attr "prefix_rep" "1")
17567    (set_attr "memory" "both")
17568    (set_attr "mode" "DI")])
17569
17570 (define_insn "*rep_movsi"
17571   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17572    (set (match_operand:SI 0 "register_operand" "=D") 
17573         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17574                             (const_int 2))
17575                  (match_operand:SI 3 "register_operand" "0")))
17576    (set (match_operand:SI 1 "register_operand" "=S") 
17577         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17578                  (match_operand:SI 4 "register_operand" "1")))
17579    (set (mem:BLK (match_dup 3))
17580         (mem:BLK (match_dup 4)))
17581    (use (match_dup 5))
17582    (use (reg:SI DIRFLAG_REG))]
17583   "!TARGET_64BIT"
17584   "{rep\;movsl|rep movsd}"
17585   [(set_attr "type" "str")
17586    (set_attr "prefix_rep" "1")
17587    (set_attr "memory" "both")
17588    (set_attr "mode" "SI")])
17589
17590 (define_insn "*rep_movsi_rex64"
17591   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17592    (set (match_operand:DI 0 "register_operand" "=D") 
17593         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17594                             (const_int 2))
17595                  (match_operand:DI 3 "register_operand" "0")))
17596    (set (match_operand:DI 1 "register_operand" "=S") 
17597         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17598                  (match_operand:DI 4 "register_operand" "1")))
17599    (set (mem:BLK (match_dup 3))
17600         (mem:BLK (match_dup 4)))
17601    (use (match_dup 5))
17602    (use (reg:SI DIRFLAG_REG))]
17603   "TARGET_64BIT"
17604   "{rep\;movsl|rep movsd}"
17605   [(set_attr "type" "str")
17606    (set_attr "prefix_rep" "1")
17607    (set_attr "memory" "both")
17608    (set_attr "mode" "SI")])
17609
17610 (define_insn "*rep_movqi"
17611   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17612    (set (match_operand:SI 0 "register_operand" "=D") 
17613         (plus:SI (match_operand:SI 3 "register_operand" "0")
17614                  (match_operand:SI 5 "register_operand" "2")))
17615    (set (match_operand:SI 1 "register_operand" "=S") 
17616         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17617    (set (mem:BLK (match_dup 3))
17618         (mem:BLK (match_dup 4)))
17619    (use (match_dup 5))
17620    (use (reg:SI DIRFLAG_REG))]
17621   "!TARGET_64BIT"
17622   "{rep\;movsb|rep movsb}"
17623   [(set_attr "type" "str")
17624    (set_attr "prefix_rep" "1")
17625    (set_attr "memory" "both")
17626    (set_attr "mode" "SI")])
17627
17628 (define_insn "*rep_movqi_rex64"
17629   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17630    (set (match_operand:DI 0 "register_operand" "=D") 
17631         (plus:DI (match_operand:DI 3 "register_operand" "0")
17632                  (match_operand:DI 5 "register_operand" "2")))
17633    (set (match_operand:DI 1 "register_operand" "=S") 
17634         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17635    (set (mem:BLK (match_dup 3))
17636         (mem:BLK (match_dup 4)))
17637    (use (match_dup 5))
17638    (use (reg:SI DIRFLAG_REG))]
17639   "TARGET_64BIT"
17640   "{rep\;movsb|rep movsb}"
17641   [(set_attr "type" "str")
17642    (set_attr "prefix_rep" "1")
17643    (set_attr "memory" "both")
17644    (set_attr "mode" "SI")])
17645
17646 (define_expand "setmemsi"
17647    [(use (match_operand:BLK 0 "memory_operand" ""))
17648     (use (match_operand:SI 1 "nonmemory_operand" ""))
17649     (use (match_operand 2 "const_int_operand" ""))
17650     (use (match_operand 3 "const_int_operand" ""))]
17651   ""
17652 {
17653  /* If value to set is not zero, use the library routine.  */
17654  if (operands[2] != const0_rtx)
17655    FAIL;
17656
17657  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17658    DONE;
17659  else
17660    FAIL;
17661 })
17662
17663 (define_expand "setmemdi"
17664    [(use (match_operand:BLK 0 "memory_operand" ""))
17665     (use (match_operand:DI 1 "nonmemory_operand" ""))
17666     (use (match_operand 2 "const_int_operand" ""))
17667     (use (match_operand 3 "const_int_operand" ""))]
17668   "TARGET_64BIT"
17669 {
17670  /* If value to set is not zero, use the library routine.  */
17671  if (operands[2] != const0_rtx)
17672    FAIL;
17673
17674  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17675    DONE;
17676  else
17677    FAIL;
17678 })
17679
17680 ;; Most CPUs don't like single string operations
17681 ;; Handle this case here to simplify previous expander.
17682
17683 (define_expand "strset"
17684   [(set (match_operand 1 "memory_operand" "")
17685         (match_operand 2 "register_operand" ""))
17686    (parallel [(set (match_operand 0 "register_operand" "")
17687                    (match_dup 3))
17688               (clobber (reg:CC FLAGS_REG))])]
17689   ""
17690 {
17691   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17692     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17693
17694   /* If .md ever supports :P for Pmode, this can be directly
17695      in the pattern above.  */
17696   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17697                               GEN_INT (GET_MODE_SIZE (GET_MODE
17698                                                       (operands[2]))));
17699   if (TARGET_SINGLE_STRINGOP || optimize_size)
17700     {
17701       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17702                                       operands[3]));
17703       DONE;
17704     }
17705 })
17706
17707 (define_expand "strset_singleop"
17708   [(parallel [(set (match_operand 1 "memory_operand" "")
17709                    (match_operand 2 "register_operand" ""))
17710               (set (match_operand 0 "register_operand" "")
17711                    (match_operand 3 "" ""))
17712               (use (reg:SI DIRFLAG_REG))])]
17713   "TARGET_SINGLE_STRINGOP || optimize_size"
17714   "")
17715
17716 (define_insn "*strsetdi_rex_1"
17717   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17718         (match_operand:DI 2 "register_operand" "a"))
17719    (set (match_operand:DI 0 "register_operand" "=D")
17720         (plus:DI (match_dup 1)
17721                  (const_int 8)))
17722    (use (reg:SI DIRFLAG_REG))]
17723   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17724   "stosq"
17725   [(set_attr "type" "str")
17726    (set_attr "memory" "store")
17727    (set_attr "mode" "DI")])
17728
17729 (define_insn "*strsetsi_1"
17730   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17731         (match_operand:SI 2 "register_operand" "a"))
17732    (set (match_operand:SI 0 "register_operand" "=D")
17733         (plus:SI (match_dup 1)
17734                  (const_int 4)))
17735    (use (reg:SI DIRFLAG_REG))]
17736   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17737   "{stosl|stosd}"
17738   [(set_attr "type" "str")
17739    (set_attr "memory" "store")
17740    (set_attr "mode" "SI")])
17741
17742 (define_insn "*strsetsi_rex_1"
17743   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17744         (match_operand:SI 2 "register_operand" "a"))
17745    (set (match_operand:DI 0 "register_operand" "=D")
17746         (plus:DI (match_dup 1)
17747                  (const_int 4)))
17748    (use (reg:SI DIRFLAG_REG))]
17749   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17750   "{stosl|stosd}"
17751   [(set_attr "type" "str")
17752    (set_attr "memory" "store")
17753    (set_attr "mode" "SI")])
17754
17755 (define_insn "*strsethi_1"
17756   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17757         (match_operand:HI 2 "register_operand" "a"))
17758    (set (match_operand:SI 0 "register_operand" "=D")
17759         (plus:SI (match_dup 1)
17760                  (const_int 2)))
17761    (use (reg:SI DIRFLAG_REG))]
17762   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17763   "stosw"
17764   [(set_attr "type" "str")
17765    (set_attr "memory" "store")
17766    (set_attr "mode" "HI")])
17767
17768 (define_insn "*strsethi_rex_1"
17769   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17770         (match_operand:HI 2 "register_operand" "a"))
17771    (set (match_operand:DI 0 "register_operand" "=D")
17772         (plus:DI (match_dup 1)
17773                  (const_int 2)))
17774    (use (reg:SI DIRFLAG_REG))]
17775   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17776   "stosw"
17777   [(set_attr "type" "str")
17778    (set_attr "memory" "store")
17779    (set_attr "mode" "HI")])
17780
17781 (define_insn "*strsetqi_1"
17782   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17783         (match_operand:QI 2 "register_operand" "a"))
17784    (set (match_operand:SI 0 "register_operand" "=D")
17785         (plus:SI (match_dup 1)
17786                  (const_int 1)))
17787    (use (reg:SI DIRFLAG_REG))]
17788   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17789   "stosb"
17790   [(set_attr "type" "str")
17791    (set_attr "memory" "store")
17792    (set_attr "mode" "QI")])
17793
17794 (define_insn "*strsetqi_rex_1"
17795   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17796         (match_operand:QI 2 "register_operand" "a"))
17797    (set (match_operand:DI 0 "register_operand" "=D")
17798         (plus:DI (match_dup 1)
17799                  (const_int 1)))
17800    (use (reg:SI DIRFLAG_REG))]
17801   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17802   "stosb"
17803   [(set_attr "type" "str")
17804    (set_attr "memory" "store")
17805    (set_attr "mode" "QI")])
17806
17807 (define_expand "rep_stos"
17808   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17809               (set (match_operand 0 "register_operand" "")
17810                    (match_operand 4 "" ""))
17811               (set (match_operand 2 "memory_operand" "") (const_int 0))
17812               (use (match_operand 3 "register_operand" ""))
17813               (use (match_dup 1))
17814               (use (reg:SI DIRFLAG_REG))])]
17815   ""
17816   "")
17817
17818 (define_insn "*rep_stosdi_rex64"
17819   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17820    (set (match_operand:DI 0 "register_operand" "=D") 
17821         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17822                             (const_int 3))
17823                  (match_operand:DI 3 "register_operand" "0")))
17824    (set (mem:BLK (match_dup 3))
17825         (const_int 0))
17826    (use (match_operand:DI 2 "register_operand" "a"))
17827    (use (match_dup 4))
17828    (use (reg:SI DIRFLAG_REG))]
17829   "TARGET_64BIT"
17830   "{rep\;stosq|rep stosq}"
17831   [(set_attr "type" "str")
17832    (set_attr "prefix_rep" "1")
17833    (set_attr "memory" "store")
17834    (set_attr "mode" "DI")])
17835
17836 (define_insn "*rep_stossi"
17837   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17838    (set (match_operand:SI 0 "register_operand" "=D") 
17839         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17840                             (const_int 2))
17841                  (match_operand:SI 3 "register_operand" "0")))
17842    (set (mem:BLK (match_dup 3))
17843         (const_int 0))
17844    (use (match_operand:SI 2 "register_operand" "a"))
17845    (use (match_dup 4))
17846    (use (reg:SI DIRFLAG_REG))]
17847   "!TARGET_64BIT"
17848   "{rep\;stosl|rep stosd}"
17849   [(set_attr "type" "str")
17850    (set_attr "prefix_rep" "1")
17851    (set_attr "memory" "store")
17852    (set_attr "mode" "SI")])
17853
17854 (define_insn "*rep_stossi_rex64"
17855   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17856    (set (match_operand:DI 0 "register_operand" "=D") 
17857         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17858                             (const_int 2))
17859                  (match_operand:DI 3 "register_operand" "0")))
17860    (set (mem:BLK (match_dup 3))
17861         (const_int 0))
17862    (use (match_operand:SI 2 "register_operand" "a"))
17863    (use (match_dup 4))
17864    (use (reg:SI DIRFLAG_REG))]
17865   "TARGET_64BIT"
17866   "{rep\;stosl|rep stosd}"
17867   [(set_attr "type" "str")
17868    (set_attr "prefix_rep" "1")
17869    (set_attr "memory" "store")
17870    (set_attr "mode" "SI")])
17871
17872 (define_insn "*rep_stosqi"
17873   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17874    (set (match_operand:SI 0 "register_operand" "=D") 
17875         (plus:SI (match_operand:SI 3 "register_operand" "0")
17876                  (match_operand:SI 4 "register_operand" "1")))
17877    (set (mem:BLK (match_dup 3))
17878         (const_int 0))
17879    (use (match_operand:QI 2 "register_operand" "a"))
17880    (use (match_dup 4))
17881    (use (reg:SI DIRFLAG_REG))]
17882   "!TARGET_64BIT"
17883   "{rep\;stosb|rep stosb}"
17884   [(set_attr "type" "str")
17885    (set_attr "prefix_rep" "1")
17886    (set_attr "memory" "store")
17887    (set_attr "mode" "QI")])
17888
17889 (define_insn "*rep_stosqi_rex64"
17890   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17891    (set (match_operand:DI 0 "register_operand" "=D") 
17892         (plus:DI (match_operand:DI 3 "register_operand" "0")
17893                  (match_operand:DI 4 "register_operand" "1")))
17894    (set (mem:BLK (match_dup 3))
17895         (const_int 0))
17896    (use (match_operand:QI 2 "register_operand" "a"))
17897    (use (match_dup 4))
17898    (use (reg:SI DIRFLAG_REG))]
17899   "TARGET_64BIT"
17900   "{rep\;stosb|rep stosb}"
17901   [(set_attr "type" "str")
17902    (set_attr "prefix_rep" "1")
17903    (set_attr "memory" "store")
17904    (set_attr "mode" "QI")])
17905
17906 (define_expand "cmpstrnsi"
17907   [(set (match_operand:SI 0 "register_operand" "")
17908         (compare:SI (match_operand:BLK 1 "general_operand" "")
17909                     (match_operand:BLK 2 "general_operand" "")))
17910    (use (match_operand 3 "general_operand" ""))
17911    (use (match_operand 4 "immediate_operand" ""))]
17912   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17913 {
17914   rtx addr1, addr2, out, outlow, count, countreg, align;
17915
17916   /* Can't use this if the user has appropriated esi or edi.  */
17917   if (global_regs[4] || global_regs[5])
17918     FAIL;
17919
17920   out = operands[0];
17921   if (GET_CODE (out) != REG)
17922     out = gen_reg_rtx (SImode);
17923
17924   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17925   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17926   if (addr1 != XEXP (operands[1], 0))
17927     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17928   if (addr2 != XEXP (operands[2], 0))
17929     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17930
17931   count = operands[3];
17932   countreg = ix86_zero_extend_to_Pmode (count);
17933
17934   /* %%% Iff we are testing strict equality, we can use known alignment
17935      to good advantage.  This may be possible with combine, particularly
17936      once cc0 is dead.  */
17937   align = operands[4];
17938
17939   emit_insn (gen_cld ());
17940   if (GET_CODE (count) == CONST_INT)
17941     {
17942       if (INTVAL (count) == 0)
17943         {
17944           emit_move_insn (operands[0], const0_rtx);
17945           DONE;
17946         }
17947       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17948                                      operands[1], operands[2]));
17949     }
17950   else
17951     {
17952       if (TARGET_64BIT)
17953         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17954       else
17955         emit_insn (gen_cmpsi_1 (countreg, countreg));
17956       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17957                                   operands[1], operands[2]));
17958     }
17959
17960   outlow = gen_lowpart (QImode, out);
17961   emit_insn (gen_cmpintqi (outlow));
17962   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17963
17964   if (operands[0] != out)
17965     emit_move_insn (operands[0], out);
17966
17967   DONE;
17968 })
17969
17970 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17971
17972 (define_expand "cmpintqi"
17973   [(set (match_dup 1)
17974         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17975    (set (match_dup 2)
17976         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17977    (parallel [(set (match_operand:QI 0 "register_operand" "")
17978                    (minus:QI (match_dup 1)
17979                              (match_dup 2)))
17980               (clobber (reg:CC FLAGS_REG))])]
17981   ""
17982   "operands[1] = gen_reg_rtx (QImode);
17983    operands[2] = gen_reg_rtx (QImode);")
17984
17985 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17986 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17987
17988 (define_expand "cmpstrnqi_nz_1"
17989   [(parallel [(set (reg:CC FLAGS_REG)
17990                    (compare:CC (match_operand 4 "memory_operand" "")
17991                                (match_operand 5 "memory_operand" "")))
17992               (use (match_operand 2 "register_operand" ""))
17993               (use (match_operand:SI 3 "immediate_operand" ""))
17994               (use (reg:SI DIRFLAG_REG))
17995               (clobber (match_operand 0 "register_operand" ""))
17996               (clobber (match_operand 1 "register_operand" ""))
17997               (clobber (match_dup 2))])]
17998   ""
17999   "")
18000
18001 (define_insn "*cmpstrnqi_nz_1"
18002   [(set (reg:CC FLAGS_REG)
18003         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18004                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18005    (use (match_operand:SI 6 "register_operand" "2"))
18006    (use (match_operand:SI 3 "immediate_operand" "i"))
18007    (use (reg:SI DIRFLAG_REG))
18008    (clobber (match_operand:SI 0 "register_operand" "=S"))
18009    (clobber (match_operand:SI 1 "register_operand" "=D"))
18010    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18011   "!TARGET_64BIT"
18012   "repz{\;| }cmpsb"
18013   [(set_attr "type" "str")
18014    (set_attr "mode" "QI")
18015    (set_attr "prefix_rep" "1")])
18016
18017 (define_insn "*cmpstrnqi_nz_rex_1"
18018   [(set (reg:CC FLAGS_REG)
18019         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18020                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18021    (use (match_operand:DI 6 "register_operand" "2"))
18022    (use (match_operand:SI 3 "immediate_operand" "i"))
18023    (use (reg:SI DIRFLAG_REG))
18024    (clobber (match_operand:DI 0 "register_operand" "=S"))
18025    (clobber (match_operand:DI 1 "register_operand" "=D"))
18026    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18027   "TARGET_64BIT"
18028   "repz{\;| }cmpsb"
18029   [(set_attr "type" "str")
18030    (set_attr "mode" "QI")
18031    (set_attr "prefix_rep" "1")])
18032
18033 ;; The same, but the count is not known to not be zero.
18034
18035 (define_expand "cmpstrnqi_1"
18036   [(parallel [(set (reg:CC FLAGS_REG)
18037                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18038                                      (const_int 0))
18039                   (compare:CC (match_operand 4 "memory_operand" "")
18040                               (match_operand 5 "memory_operand" ""))
18041                   (const_int 0)))
18042               (use (match_operand:SI 3 "immediate_operand" ""))
18043               (use (reg:CC FLAGS_REG))
18044               (use (reg:SI DIRFLAG_REG))
18045               (clobber (match_operand 0 "register_operand" ""))
18046               (clobber (match_operand 1 "register_operand" ""))
18047               (clobber (match_dup 2))])]
18048   ""
18049   "")
18050
18051 (define_insn "*cmpstrnqi_1"
18052   [(set (reg:CC FLAGS_REG)
18053         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18054                              (const_int 0))
18055           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18056                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18057           (const_int 0)))
18058    (use (match_operand:SI 3 "immediate_operand" "i"))
18059    (use (reg:CC FLAGS_REG))
18060    (use (reg:SI DIRFLAG_REG))
18061    (clobber (match_operand:SI 0 "register_operand" "=S"))
18062    (clobber (match_operand:SI 1 "register_operand" "=D"))
18063    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18064   "!TARGET_64BIT"
18065   "repz{\;| }cmpsb"
18066   [(set_attr "type" "str")
18067    (set_attr "mode" "QI")
18068    (set_attr "prefix_rep" "1")])
18069
18070 (define_insn "*cmpstrnqi_rex_1"
18071   [(set (reg:CC FLAGS_REG)
18072         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18073                              (const_int 0))
18074           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18075                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18076           (const_int 0)))
18077    (use (match_operand:SI 3 "immediate_operand" "i"))
18078    (use (reg:CC FLAGS_REG))
18079    (use (reg:SI DIRFLAG_REG))
18080    (clobber (match_operand:DI 0 "register_operand" "=S"))
18081    (clobber (match_operand:DI 1 "register_operand" "=D"))
18082    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18083   "TARGET_64BIT"
18084   "repz{\;| }cmpsb"
18085   [(set_attr "type" "str")
18086    (set_attr "mode" "QI")
18087    (set_attr "prefix_rep" "1")])
18088
18089 (define_expand "strlensi"
18090   [(set (match_operand:SI 0 "register_operand" "")
18091         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18092                     (match_operand:QI 2 "immediate_operand" "")
18093                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18094   ""
18095 {
18096  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18097    DONE;
18098  else
18099    FAIL;
18100 })
18101
18102 (define_expand "strlendi"
18103   [(set (match_operand:DI 0 "register_operand" "")
18104         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18105                     (match_operand:QI 2 "immediate_operand" "")
18106                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18107   ""
18108 {
18109  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18110    DONE;
18111  else
18112    FAIL;
18113 })
18114
18115 (define_expand "strlenqi_1"
18116   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18117               (use (reg:SI DIRFLAG_REG))
18118               (clobber (match_operand 1 "register_operand" ""))
18119               (clobber (reg:CC FLAGS_REG))])]
18120   ""
18121   "")
18122
18123 (define_insn "*strlenqi_1"
18124   [(set (match_operand:SI 0 "register_operand" "=&c")
18125         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18126                     (match_operand:QI 2 "register_operand" "a")
18127                     (match_operand:SI 3 "immediate_operand" "i")
18128                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18129    (use (reg:SI DIRFLAG_REG))
18130    (clobber (match_operand:SI 1 "register_operand" "=D"))
18131    (clobber (reg:CC FLAGS_REG))]
18132   "!TARGET_64BIT"
18133   "repnz{\;| }scasb"
18134   [(set_attr "type" "str")
18135    (set_attr "mode" "QI")
18136    (set_attr "prefix_rep" "1")])
18137
18138 (define_insn "*strlenqi_rex_1"
18139   [(set (match_operand:DI 0 "register_operand" "=&c")
18140         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18141                     (match_operand:QI 2 "register_operand" "a")
18142                     (match_operand:DI 3 "immediate_operand" "i")
18143                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18144    (use (reg:SI DIRFLAG_REG))
18145    (clobber (match_operand:DI 1 "register_operand" "=D"))
18146    (clobber (reg:CC FLAGS_REG))]
18147   "TARGET_64BIT"
18148   "repnz{\;| }scasb"
18149   [(set_attr "type" "str")
18150    (set_attr "mode" "QI")
18151    (set_attr "prefix_rep" "1")])
18152
18153 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18154 ;; handled in combine, but it is not currently up to the task.
18155 ;; When used for their truth value, the cmpstrn* expanders generate
18156 ;; code like this:
18157 ;;
18158 ;;   repz cmpsb
18159 ;;   seta       %al
18160 ;;   setb       %dl
18161 ;;   cmpb       %al, %dl
18162 ;;   jcc        label
18163 ;;
18164 ;; The intermediate three instructions are unnecessary.
18165
18166 ;; This one handles cmpstrn*_nz_1...
18167 (define_peephole2
18168   [(parallel[
18169      (set (reg:CC FLAGS_REG)
18170           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18171                       (mem:BLK (match_operand 5 "register_operand" ""))))
18172      (use (match_operand 6 "register_operand" ""))
18173      (use (match_operand:SI 3 "immediate_operand" ""))
18174      (use (reg:SI DIRFLAG_REG))
18175      (clobber (match_operand 0 "register_operand" ""))
18176      (clobber (match_operand 1 "register_operand" ""))
18177      (clobber (match_operand 2 "register_operand" ""))])
18178    (set (match_operand:QI 7 "register_operand" "")
18179         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18180    (set (match_operand:QI 8 "register_operand" "")
18181         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18182    (set (reg FLAGS_REG)
18183         (compare (match_dup 7) (match_dup 8)))
18184   ]
18185   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18186   [(parallel[
18187      (set (reg:CC FLAGS_REG)
18188           (compare:CC (mem:BLK (match_dup 4))
18189                       (mem:BLK (match_dup 5))))
18190      (use (match_dup 6))
18191      (use (match_dup 3))
18192      (use (reg:SI DIRFLAG_REG))
18193      (clobber (match_dup 0))
18194      (clobber (match_dup 1))
18195      (clobber (match_dup 2))])]
18196   "")
18197
18198 ;; ...and this one handles cmpstrn*_1.
18199 (define_peephole2
18200   [(parallel[
18201      (set (reg:CC FLAGS_REG)
18202           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18203                                (const_int 0))
18204             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18205                         (mem:BLK (match_operand 5 "register_operand" "")))
18206             (const_int 0)))
18207      (use (match_operand:SI 3 "immediate_operand" ""))
18208      (use (reg:CC FLAGS_REG))
18209      (use (reg:SI DIRFLAG_REG))
18210      (clobber (match_operand 0 "register_operand" ""))
18211      (clobber (match_operand 1 "register_operand" ""))
18212      (clobber (match_operand 2 "register_operand" ""))])
18213    (set (match_operand:QI 7 "register_operand" "")
18214         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18215    (set (match_operand:QI 8 "register_operand" "")
18216         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18217    (set (reg FLAGS_REG)
18218         (compare (match_dup 7) (match_dup 8)))
18219   ]
18220   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18221   [(parallel[
18222      (set (reg:CC FLAGS_REG)
18223           (if_then_else:CC (ne (match_dup 6)
18224                                (const_int 0))
18225             (compare:CC (mem:BLK (match_dup 4))
18226                         (mem:BLK (match_dup 5)))
18227             (const_int 0)))
18228      (use (match_dup 3))
18229      (use (reg:CC FLAGS_REG))
18230      (use (reg:SI DIRFLAG_REG))
18231      (clobber (match_dup 0))
18232      (clobber (match_dup 1))
18233      (clobber (match_dup 2))])]
18234   "")
18235
18236
18237 \f
18238 ;; Conditional move instructions.
18239
18240 (define_expand "movdicc"
18241   [(set (match_operand:DI 0 "register_operand" "")
18242         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18243                          (match_operand:DI 2 "general_operand" "")
18244                          (match_operand:DI 3 "general_operand" "")))]
18245   "TARGET_64BIT"
18246   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18247
18248 (define_insn "x86_movdicc_0_m1_rex64"
18249   [(set (match_operand:DI 0 "register_operand" "=r")
18250         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18251           (const_int -1)
18252           (const_int 0)))
18253    (clobber (reg:CC FLAGS_REG))]
18254   "TARGET_64BIT"
18255   "sbb{q}\t%0, %0"
18256   ; Since we don't have the proper number of operands for an alu insn,
18257   ; fill in all the blanks.
18258   [(set_attr "type" "alu")
18259    (set_attr "pent_pair" "pu")
18260    (set_attr "memory" "none")
18261    (set_attr "imm_disp" "false")
18262    (set_attr "mode" "DI")
18263    (set_attr "length_immediate" "0")])
18264
18265 (define_insn "*movdicc_c_rex64"
18266   [(set (match_operand:DI 0 "register_operand" "=r,r")
18267         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18268                                 [(reg FLAGS_REG) (const_int 0)])
18269                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18270                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18271   "TARGET_64BIT && TARGET_CMOVE
18272    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18273   "@
18274    cmov%O2%C1\t{%2, %0|%0, %2}
18275    cmov%O2%c1\t{%3, %0|%0, %3}"
18276   [(set_attr "type" "icmov")
18277    (set_attr "mode" "DI")])
18278
18279 (define_expand "movsicc"
18280   [(set (match_operand:SI 0 "register_operand" "")
18281         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18282                          (match_operand:SI 2 "general_operand" "")
18283                          (match_operand:SI 3 "general_operand" "")))]
18284   ""
18285   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18286
18287 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18288 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18289 ;; So just document what we're doing explicitly.
18290
18291 (define_insn "x86_movsicc_0_m1"
18292   [(set (match_operand:SI 0 "register_operand" "=r")
18293         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18294           (const_int -1)
18295           (const_int 0)))
18296    (clobber (reg:CC FLAGS_REG))]
18297   ""
18298   "sbb{l}\t%0, %0"
18299   ; Since we don't have the proper number of operands for an alu insn,
18300   ; fill in all the blanks.
18301   [(set_attr "type" "alu")
18302    (set_attr "pent_pair" "pu")
18303    (set_attr "memory" "none")
18304    (set_attr "imm_disp" "false")
18305    (set_attr "mode" "SI")
18306    (set_attr "length_immediate" "0")])
18307
18308 (define_insn "*movsicc_noc"
18309   [(set (match_operand:SI 0 "register_operand" "=r,r")
18310         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18311                                 [(reg FLAGS_REG) (const_int 0)])
18312                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18313                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18314   "TARGET_CMOVE
18315    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18316   "@
18317    cmov%O2%C1\t{%2, %0|%0, %2}
18318    cmov%O2%c1\t{%3, %0|%0, %3}"
18319   [(set_attr "type" "icmov")
18320    (set_attr "mode" "SI")])
18321
18322 (define_expand "movhicc"
18323   [(set (match_operand:HI 0 "register_operand" "")
18324         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18325                          (match_operand:HI 2 "general_operand" "")
18326                          (match_operand:HI 3 "general_operand" "")))]
18327   "TARGET_HIMODE_MATH"
18328   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18329
18330 (define_insn "*movhicc_noc"
18331   [(set (match_operand:HI 0 "register_operand" "=r,r")
18332         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18333                                 [(reg FLAGS_REG) (const_int 0)])
18334                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18335                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18336   "TARGET_CMOVE
18337    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18338   "@
18339    cmov%O2%C1\t{%2, %0|%0, %2}
18340    cmov%O2%c1\t{%3, %0|%0, %3}"
18341   [(set_attr "type" "icmov")
18342    (set_attr "mode" "HI")])
18343
18344 (define_expand "movqicc"
18345   [(set (match_operand:QI 0 "register_operand" "")
18346         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18347                          (match_operand:QI 2 "general_operand" "")
18348                          (match_operand:QI 3 "general_operand" "")))]
18349   "TARGET_QIMODE_MATH"
18350   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18351
18352 (define_insn_and_split "*movqicc_noc"
18353   [(set (match_operand:QI 0 "register_operand" "=r,r")
18354         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18355                                 [(match_operand 4 "flags_reg_operand" "")
18356                                  (const_int 0)])
18357                       (match_operand:QI 2 "register_operand" "r,0")
18358                       (match_operand:QI 3 "register_operand" "0,r")))]
18359   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18360   "#"
18361   "&& reload_completed"
18362   [(set (match_dup 0)
18363         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18364                       (match_dup 2)
18365                       (match_dup 3)))]
18366   "operands[0] = gen_lowpart (SImode, operands[0]);
18367    operands[2] = gen_lowpart (SImode, operands[2]);
18368    operands[3] = gen_lowpart (SImode, operands[3]);"
18369   [(set_attr "type" "icmov")
18370    (set_attr "mode" "SI")])
18371
18372 (define_expand "movsfcc"
18373   [(set (match_operand:SF 0 "register_operand" "")
18374         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18375                          (match_operand:SF 2 "register_operand" "")
18376                          (match_operand:SF 3 "register_operand" "")))]
18377   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18378   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18379
18380 (define_insn "*movsfcc_1_387"
18381   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18382         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18383                                 [(reg FLAGS_REG) (const_int 0)])
18384                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18385                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18386   "TARGET_80387 && TARGET_CMOVE
18387    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18388   "@
18389    fcmov%F1\t{%2, %0|%0, %2}
18390    fcmov%f1\t{%3, %0|%0, %3}
18391    cmov%O2%C1\t{%2, %0|%0, %2}
18392    cmov%O2%c1\t{%3, %0|%0, %3}"
18393   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18394    (set_attr "mode" "SF,SF,SI,SI")])
18395
18396 (define_expand "movdfcc"
18397   [(set (match_operand:DF 0 "register_operand" "")
18398         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18399                          (match_operand:DF 2 "register_operand" "")
18400                          (match_operand:DF 3 "register_operand" "")))]
18401   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18402   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18403
18404 (define_insn "*movdfcc_1"
18405   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18406         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18407                                 [(reg FLAGS_REG) (const_int 0)])
18408                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18409                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18410   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18411    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18412   "@
18413    fcmov%F1\t{%2, %0|%0, %2}
18414    fcmov%f1\t{%3, %0|%0, %3}
18415    #
18416    #"
18417   [(set_attr "type" "fcmov,fcmov,multi,multi")
18418    (set_attr "mode" "DF")])
18419
18420 (define_insn "*movdfcc_1_rex64"
18421   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18422         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18423                                 [(reg FLAGS_REG) (const_int 0)])
18424                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18425                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18426   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18427    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18428   "@
18429    fcmov%F1\t{%2, %0|%0, %2}
18430    fcmov%f1\t{%3, %0|%0, %3}
18431    cmov%O2%C1\t{%2, %0|%0, %2}
18432    cmov%O2%c1\t{%3, %0|%0, %3}"
18433   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18434    (set_attr "mode" "DF")])
18435
18436 (define_split
18437   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18438         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18439                                 [(match_operand 4 "flags_reg_operand" "")
18440                                  (const_int 0)])
18441                       (match_operand:DF 2 "nonimmediate_operand" "")
18442                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18443   "!TARGET_64BIT && reload_completed"
18444   [(set (match_dup 2)
18445         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18446                       (match_dup 5)
18447                       (match_dup 7)))
18448    (set (match_dup 3)
18449         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18450                       (match_dup 6)
18451                       (match_dup 8)))]
18452   "split_di (operands+2, 1, operands+5, operands+6);
18453    split_di (operands+3, 1, operands+7, operands+8);
18454    split_di (operands, 1, operands+2, operands+3);")
18455
18456 (define_expand "movxfcc"
18457   [(set (match_operand:XF 0 "register_operand" "")
18458         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18459                          (match_operand:XF 2 "register_operand" "")
18460                          (match_operand:XF 3 "register_operand" "")))]
18461   "TARGET_80387 && TARGET_CMOVE"
18462   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18463
18464 (define_insn "*movxfcc_1"
18465   [(set (match_operand:XF 0 "register_operand" "=f,f")
18466         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18467                                 [(reg FLAGS_REG) (const_int 0)])
18468                       (match_operand:XF 2 "register_operand" "f,0")
18469                       (match_operand:XF 3 "register_operand" "0,f")))]
18470   "TARGET_80387 && TARGET_CMOVE"
18471   "@
18472    fcmov%F1\t{%2, %0|%0, %2}
18473    fcmov%f1\t{%3, %0|%0, %3}"
18474   [(set_attr "type" "fcmov")
18475    (set_attr "mode" "XF")])
18476
18477 ;; These versions of the min/max patterns are intentionally ignorant of
18478 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18479 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18480 ;; are undefined in this condition, we're certain this is correct.
18481
18482 (define_insn "sminsf3"
18483   [(set (match_operand:SF 0 "register_operand" "=x")
18484         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18485                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18486   "TARGET_SSE_MATH"
18487   "minss\t{%2, %0|%0, %2}"
18488   [(set_attr "type" "sseadd")
18489    (set_attr "mode" "SF")])
18490
18491 (define_insn "smaxsf3"
18492   [(set (match_operand:SF 0 "register_operand" "=x")
18493         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18494                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18495   "TARGET_SSE_MATH"
18496   "maxss\t{%2, %0|%0, %2}"
18497   [(set_attr "type" "sseadd")
18498    (set_attr "mode" "SF")])
18499
18500 (define_insn "smindf3"
18501   [(set (match_operand:DF 0 "register_operand" "=x")
18502         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18503                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18504   "TARGET_SSE2 && TARGET_SSE_MATH"
18505   "minsd\t{%2, %0|%0, %2}"
18506   [(set_attr "type" "sseadd")
18507    (set_attr "mode" "DF")])
18508
18509 (define_insn "smaxdf3"
18510   [(set (match_operand:DF 0 "register_operand" "=x")
18511         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18512                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18513   "TARGET_SSE2 && TARGET_SSE_MATH"
18514   "maxsd\t{%2, %0|%0, %2}"
18515   [(set_attr "type" "sseadd")
18516    (set_attr "mode" "DF")])
18517
18518 ;; These versions of the min/max patterns implement exactly the operations
18519 ;;   min = (op1 < op2 ? op1 : op2)
18520 ;;   max = (!(op1 < op2) ? op1 : op2)
18521 ;; Their operands are not commutative, and thus they may be used in the
18522 ;; presence of -0.0 and NaN.
18523
18524 (define_insn "*ieee_sminsf3"
18525   [(set (match_operand:SF 0 "register_operand" "=x")
18526         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18527                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18528                    UNSPEC_IEEE_MIN))]
18529   "TARGET_SSE_MATH"
18530   "minss\t{%2, %0|%0, %2}"
18531   [(set_attr "type" "sseadd")
18532    (set_attr "mode" "SF")])
18533
18534 (define_insn "*ieee_smaxsf3"
18535   [(set (match_operand:SF 0 "register_operand" "=x")
18536         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18537                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18538                    UNSPEC_IEEE_MAX))]
18539   "TARGET_SSE_MATH"
18540   "maxss\t{%2, %0|%0, %2}"
18541   [(set_attr "type" "sseadd")
18542    (set_attr "mode" "SF")])
18543
18544 (define_insn "*ieee_smindf3"
18545   [(set (match_operand:DF 0 "register_operand" "=x")
18546         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18547                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18548                    UNSPEC_IEEE_MIN))]
18549   "TARGET_SSE2 && TARGET_SSE_MATH"
18550   "minsd\t{%2, %0|%0, %2}"
18551   [(set_attr "type" "sseadd")
18552    (set_attr "mode" "DF")])
18553
18554 (define_insn "*ieee_smaxdf3"
18555   [(set (match_operand:DF 0 "register_operand" "=x")
18556         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18557                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18558                    UNSPEC_IEEE_MAX))]
18559   "TARGET_SSE2 && TARGET_SSE_MATH"
18560   "maxsd\t{%2, %0|%0, %2}"
18561   [(set_attr "type" "sseadd")
18562    (set_attr "mode" "DF")])
18563
18564 ;; Conditional addition patterns
18565 (define_expand "addqicc"
18566   [(match_operand:QI 0 "register_operand" "")
18567    (match_operand 1 "comparison_operator" "")
18568    (match_operand:QI 2 "register_operand" "")
18569    (match_operand:QI 3 "const_int_operand" "")]
18570   ""
18571   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18572
18573 (define_expand "addhicc"
18574   [(match_operand:HI 0 "register_operand" "")
18575    (match_operand 1 "comparison_operator" "")
18576    (match_operand:HI 2 "register_operand" "")
18577    (match_operand:HI 3 "const_int_operand" "")]
18578   ""
18579   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18580
18581 (define_expand "addsicc"
18582   [(match_operand:SI 0 "register_operand" "")
18583    (match_operand 1 "comparison_operator" "")
18584    (match_operand:SI 2 "register_operand" "")
18585    (match_operand:SI 3 "const_int_operand" "")]
18586   ""
18587   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18588
18589 (define_expand "adddicc"
18590   [(match_operand:DI 0 "register_operand" "")
18591    (match_operand 1 "comparison_operator" "")
18592    (match_operand:DI 2 "register_operand" "")
18593    (match_operand:DI 3 "const_int_operand" "")]
18594   "TARGET_64BIT"
18595   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18596
18597 \f
18598 ;; Misc patterns (?)
18599
18600 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18601 ;; Otherwise there will be nothing to keep
18602 ;; 
18603 ;; [(set (reg ebp) (reg esp))]
18604 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18605 ;;  (clobber (eflags)]
18606 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18607 ;;
18608 ;; in proper program order.
18609 (define_insn "pro_epilogue_adjust_stack_1"
18610   [(set (match_operand:SI 0 "register_operand" "=r,r")
18611         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18612                  (match_operand:SI 2 "immediate_operand" "i,i")))
18613    (clobber (reg:CC FLAGS_REG))
18614    (clobber (mem:BLK (scratch)))]
18615   "!TARGET_64BIT"
18616 {
18617   switch (get_attr_type (insn))
18618     {
18619     case TYPE_IMOV:
18620       return "mov{l}\t{%1, %0|%0, %1}";
18621
18622     case TYPE_ALU:
18623       if (GET_CODE (operands[2]) == CONST_INT
18624           && (INTVAL (operands[2]) == 128
18625               || (INTVAL (operands[2]) < 0
18626                   && INTVAL (operands[2]) != -128)))
18627         {
18628           operands[2] = GEN_INT (-INTVAL (operands[2]));
18629           return "sub{l}\t{%2, %0|%0, %2}";
18630         }
18631       return "add{l}\t{%2, %0|%0, %2}";
18632
18633     case TYPE_LEA:
18634       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18635       return "lea{l}\t{%a2, %0|%0, %a2}";
18636
18637     default:
18638       gcc_unreachable ();
18639     }
18640 }
18641   [(set (attr "type")
18642         (cond [(eq_attr "alternative" "0")
18643                  (const_string "alu")
18644                (match_operand:SI 2 "const0_operand" "")
18645                  (const_string "imov")
18646               ]
18647               (const_string "lea")))
18648    (set_attr "mode" "SI")])
18649
18650 (define_insn "pro_epilogue_adjust_stack_rex64"
18651   [(set (match_operand:DI 0 "register_operand" "=r,r")
18652         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18653                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18654    (clobber (reg:CC FLAGS_REG))
18655    (clobber (mem:BLK (scratch)))]
18656   "TARGET_64BIT"
18657 {
18658   switch (get_attr_type (insn))
18659     {
18660     case TYPE_IMOV:
18661       return "mov{q}\t{%1, %0|%0, %1}";
18662
18663     case TYPE_ALU:
18664       if (GET_CODE (operands[2]) == CONST_INT
18665           /* Avoid overflows.  */
18666           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18667           && (INTVAL (operands[2]) == 128
18668               || (INTVAL (operands[2]) < 0
18669                   && INTVAL (operands[2]) != -128)))
18670         {
18671           operands[2] = GEN_INT (-INTVAL (operands[2]));
18672           return "sub{q}\t{%2, %0|%0, %2}";
18673         }
18674       return "add{q}\t{%2, %0|%0, %2}";
18675
18676     case TYPE_LEA:
18677       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18678       return "lea{q}\t{%a2, %0|%0, %a2}";
18679
18680     default:
18681       gcc_unreachable ();
18682     }
18683 }
18684   [(set (attr "type")
18685         (cond [(eq_attr "alternative" "0")
18686                  (const_string "alu")
18687                (match_operand:DI 2 "const0_operand" "")
18688                  (const_string "imov")
18689               ]
18690               (const_string "lea")))
18691    (set_attr "mode" "DI")])
18692
18693 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18694   [(set (match_operand:DI 0 "register_operand" "=r,r")
18695         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18696                  (match_operand:DI 3 "immediate_operand" "i,i")))
18697    (use (match_operand:DI 2 "register_operand" "r,r"))
18698    (clobber (reg:CC FLAGS_REG))
18699    (clobber (mem:BLK (scratch)))]
18700   "TARGET_64BIT"
18701 {
18702   switch (get_attr_type (insn))
18703     {
18704     case TYPE_ALU:
18705       return "add{q}\t{%2, %0|%0, %2}";
18706
18707     case TYPE_LEA:
18708       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18709       return "lea{q}\t{%a2, %0|%0, %a2}";
18710
18711     default:
18712       gcc_unreachable ();
18713     }
18714 }
18715   [(set_attr "type" "alu,lea")
18716    (set_attr "mode" "DI")])
18717
18718 (define_expand "allocate_stack_worker"
18719   [(match_operand:SI 0 "register_operand" "")]
18720   "TARGET_STACK_PROBE"
18721 {
18722   if (reload_completed)
18723     {
18724       if (TARGET_64BIT)
18725         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18726       else
18727         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18728     }
18729   else
18730     {
18731       if (TARGET_64BIT)
18732         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18733       else
18734         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18735     }
18736   DONE;
18737 })
18738
18739 (define_insn "allocate_stack_worker_1"
18740   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18741     UNSPECV_STACK_PROBE)
18742    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18743    (clobber (match_scratch:SI 1 "=0"))
18744    (clobber (reg:CC FLAGS_REG))]
18745   "!TARGET_64BIT && TARGET_STACK_PROBE"
18746   "call\t__alloca"
18747   [(set_attr "type" "multi")
18748    (set_attr "length" "5")])
18749
18750 (define_expand "allocate_stack_worker_postreload"
18751   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18752                                     UNSPECV_STACK_PROBE)
18753               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18754               (clobber (match_dup 0))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   ""
18757   "")
18758
18759 (define_insn "allocate_stack_worker_rex64"
18760   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18761     UNSPECV_STACK_PROBE)
18762    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18763    (clobber (match_scratch:DI 1 "=0"))
18764    (clobber (reg:CC FLAGS_REG))]
18765   "TARGET_64BIT && TARGET_STACK_PROBE"
18766   "call\t__alloca"
18767   [(set_attr "type" "multi")
18768    (set_attr "length" "5")])
18769
18770 (define_expand "allocate_stack_worker_rex64_postreload"
18771   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18772                                     UNSPECV_STACK_PROBE)
18773               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18774               (clobber (match_dup 0))
18775               (clobber (reg:CC FLAGS_REG))])]
18776   ""
18777   "")
18778
18779 (define_expand "allocate_stack"
18780   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18781                    (minus:SI (reg:SI SP_REG)
18782                              (match_operand:SI 1 "general_operand" "")))
18783               (clobber (reg:CC FLAGS_REG))])
18784    (parallel [(set (reg:SI SP_REG)
18785                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18786               (clobber (reg:CC FLAGS_REG))])]
18787   "TARGET_STACK_PROBE"
18788 {
18789 #ifdef CHECK_STACK_LIMIT
18790   if (GET_CODE (operands[1]) == CONST_INT
18791       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18792     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18793                            operands[1]));
18794   else 
18795 #endif
18796     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18797                                                             operands[1])));
18798
18799   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18800   DONE;
18801 })
18802
18803 (define_expand "builtin_setjmp_receiver"
18804   [(label_ref (match_operand 0 "" ""))]
18805   "!TARGET_64BIT && flag_pic"
18806 {
18807   emit_insn (gen_set_got (pic_offset_table_rtx));
18808   DONE;
18809 })
18810 \f
18811 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18812
18813 (define_split
18814   [(set (match_operand 0 "register_operand" "")
18815         (match_operator 3 "promotable_binary_operator"
18816            [(match_operand 1 "register_operand" "")
18817             (match_operand 2 "aligned_operand" "")]))
18818    (clobber (reg:CC FLAGS_REG))]
18819   "! TARGET_PARTIAL_REG_STALL && reload_completed
18820    && ((GET_MODE (operands[0]) == HImode 
18821         && ((!optimize_size && !TARGET_FAST_PREFIX)
18822             || GET_CODE (operands[2]) != CONST_INT
18823             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18824        || (GET_MODE (operands[0]) == QImode 
18825            && (TARGET_PROMOTE_QImode || optimize_size)))"
18826   [(parallel [(set (match_dup 0)
18827                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18828               (clobber (reg:CC FLAGS_REG))])]
18829   "operands[0] = gen_lowpart (SImode, operands[0]);
18830    operands[1] = gen_lowpart (SImode, operands[1]);
18831    if (GET_CODE (operands[3]) != ASHIFT)
18832      operands[2] = gen_lowpart (SImode, operands[2]);
18833    PUT_MODE (operands[3], SImode);")
18834
18835 ; Promote the QImode tests, as i386 has encoding of the AND
18836 ; instruction with 32-bit sign-extended immediate and thus the
18837 ; instruction size is unchanged, except in the %eax case for
18838 ; which it is increased by one byte, hence the ! optimize_size.
18839 (define_split
18840   [(set (match_operand 0 "flags_reg_operand" "")
18841         (match_operator 2 "compare_operator"
18842           [(and (match_operand 3 "aligned_operand" "")
18843                 (match_operand 4 "const_int_operand" ""))
18844            (const_int 0)]))
18845    (set (match_operand 1 "register_operand" "")
18846         (and (match_dup 3) (match_dup 4)))]
18847   "! TARGET_PARTIAL_REG_STALL && reload_completed
18848    /* Ensure that the operand will remain sign-extended immediate.  */
18849    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18850    && ! optimize_size
18851    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18852        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18853   [(parallel [(set (match_dup 0)
18854                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18855                                     (const_int 0)]))
18856               (set (match_dup 1)
18857                    (and:SI (match_dup 3) (match_dup 4)))])]
18858 {
18859   operands[4]
18860     = gen_int_mode (INTVAL (operands[4])
18861                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18862   operands[1] = gen_lowpart (SImode, operands[1]);
18863   operands[3] = gen_lowpart (SImode, operands[3]);
18864 })
18865
18866 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18867 ; the TEST instruction with 32-bit sign-extended immediate and thus
18868 ; the instruction size would at least double, which is not what we
18869 ; want even with ! optimize_size.
18870 (define_split
18871   [(set (match_operand 0 "flags_reg_operand" "")
18872         (match_operator 1 "compare_operator"
18873           [(and (match_operand:HI 2 "aligned_operand" "")
18874                 (match_operand:HI 3 "const_int_operand" ""))
18875            (const_int 0)]))]
18876   "! TARGET_PARTIAL_REG_STALL && reload_completed
18877    /* Ensure that the operand will remain sign-extended immediate.  */
18878    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18879    && ! TARGET_FAST_PREFIX
18880    && ! optimize_size"
18881   [(set (match_dup 0)
18882         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18883                          (const_int 0)]))]
18884 {
18885   operands[3]
18886     = gen_int_mode (INTVAL (operands[3])
18887                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18888   operands[2] = gen_lowpart (SImode, operands[2]);
18889 })
18890
18891 (define_split
18892   [(set (match_operand 0 "register_operand" "")
18893         (neg (match_operand 1 "register_operand" "")))
18894    (clobber (reg:CC FLAGS_REG))]
18895   "! TARGET_PARTIAL_REG_STALL && reload_completed
18896    && (GET_MODE (operands[0]) == HImode
18897        || (GET_MODE (operands[0]) == QImode 
18898            && (TARGET_PROMOTE_QImode || optimize_size)))"
18899   [(parallel [(set (match_dup 0)
18900                    (neg:SI (match_dup 1)))
18901               (clobber (reg:CC FLAGS_REG))])]
18902   "operands[0] = gen_lowpart (SImode, operands[0]);
18903    operands[1] = gen_lowpart (SImode, operands[1]);")
18904
18905 (define_split
18906   [(set (match_operand 0 "register_operand" "")
18907         (not (match_operand 1 "register_operand" "")))]
18908   "! TARGET_PARTIAL_REG_STALL && reload_completed
18909    && (GET_MODE (operands[0]) == HImode
18910        || (GET_MODE (operands[0]) == QImode 
18911            && (TARGET_PROMOTE_QImode || optimize_size)))"
18912   [(set (match_dup 0)
18913         (not:SI (match_dup 1)))]
18914   "operands[0] = gen_lowpart (SImode, operands[0]);
18915    operands[1] = gen_lowpart (SImode, operands[1]);")
18916
18917 (define_split 
18918   [(set (match_operand 0 "register_operand" "")
18919         (if_then_else (match_operator 1 "comparison_operator" 
18920                                 [(reg FLAGS_REG) (const_int 0)])
18921                       (match_operand 2 "register_operand" "")
18922                       (match_operand 3 "register_operand" "")))]
18923   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18924    && (GET_MODE (operands[0]) == HImode
18925        || (GET_MODE (operands[0]) == QImode 
18926            && (TARGET_PROMOTE_QImode || optimize_size)))"
18927   [(set (match_dup 0)
18928         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18929   "operands[0] = gen_lowpart (SImode, operands[0]);
18930    operands[2] = gen_lowpart (SImode, operands[2]);
18931    operands[3] = gen_lowpart (SImode, operands[3]);")
18932                         
18933 \f
18934 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18935 ;; transform a complex memory operation into two memory to register operations.
18936
18937 ;; Don't push memory operands
18938 (define_peephole2
18939   [(set (match_operand:SI 0 "push_operand" "")
18940         (match_operand:SI 1 "memory_operand" ""))
18941    (match_scratch:SI 2 "r")]
18942   "!optimize_size && !TARGET_PUSH_MEMORY
18943    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18944   [(set (match_dup 2) (match_dup 1))
18945    (set (match_dup 0) (match_dup 2))]
18946   "")
18947
18948 (define_peephole2
18949   [(set (match_operand:DI 0 "push_operand" "")
18950         (match_operand:DI 1 "memory_operand" ""))
18951    (match_scratch:DI 2 "r")]
18952   "!optimize_size && !TARGET_PUSH_MEMORY
18953    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18954   [(set (match_dup 2) (match_dup 1))
18955    (set (match_dup 0) (match_dup 2))]
18956   "")
18957
18958 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18959 ;; SImode pushes.
18960 (define_peephole2
18961   [(set (match_operand:SF 0 "push_operand" "")
18962         (match_operand:SF 1 "memory_operand" ""))
18963    (match_scratch:SF 2 "r")]
18964   "!optimize_size && !TARGET_PUSH_MEMORY
18965    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18966   [(set (match_dup 2) (match_dup 1))
18967    (set (match_dup 0) (match_dup 2))]
18968   "")
18969
18970 (define_peephole2
18971   [(set (match_operand:HI 0 "push_operand" "")
18972         (match_operand:HI 1 "memory_operand" ""))
18973    (match_scratch:HI 2 "r")]
18974   "!optimize_size && !TARGET_PUSH_MEMORY
18975    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18976   [(set (match_dup 2) (match_dup 1))
18977    (set (match_dup 0) (match_dup 2))]
18978   "")
18979
18980 (define_peephole2
18981   [(set (match_operand:QI 0 "push_operand" "")
18982         (match_operand:QI 1 "memory_operand" ""))
18983    (match_scratch:QI 2 "q")]
18984   "!optimize_size && !TARGET_PUSH_MEMORY
18985    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18986   [(set (match_dup 2) (match_dup 1))
18987    (set (match_dup 0) (match_dup 2))]
18988   "")
18989
18990 ;; Don't move an immediate directly to memory when the instruction
18991 ;; gets too big.
18992 (define_peephole2
18993   [(match_scratch:SI 1 "r")
18994    (set (match_operand:SI 0 "memory_operand" "")
18995         (const_int 0))]
18996   "! optimize_size
18997    && ! TARGET_USE_MOV0
18998    && TARGET_SPLIT_LONG_MOVES
18999    && get_attr_length (insn) >= ix86_cost->large_insn
19000    && peep2_regno_dead_p (0, FLAGS_REG)"
19001   [(parallel [(set (match_dup 1) (const_int 0))
19002               (clobber (reg:CC FLAGS_REG))])
19003    (set (match_dup 0) (match_dup 1))]
19004   "")
19005
19006 (define_peephole2
19007   [(match_scratch:HI 1 "r")
19008    (set (match_operand:HI 0 "memory_operand" "")
19009         (const_int 0))]
19010   "! optimize_size
19011    && ! TARGET_USE_MOV0
19012    && TARGET_SPLIT_LONG_MOVES
19013    && get_attr_length (insn) >= ix86_cost->large_insn
19014    && peep2_regno_dead_p (0, FLAGS_REG)"
19015   [(parallel [(set (match_dup 2) (const_int 0))
19016               (clobber (reg:CC FLAGS_REG))])
19017    (set (match_dup 0) (match_dup 1))]
19018   "operands[2] = gen_lowpart (SImode, operands[1]);")
19019
19020 (define_peephole2
19021   [(match_scratch:QI 1 "q")
19022    (set (match_operand:QI 0 "memory_operand" "")
19023         (const_int 0))]
19024   "! optimize_size
19025    && ! TARGET_USE_MOV0
19026    && TARGET_SPLIT_LONG_MOVES
19027    && get_attr_length (insn) >= ix86_cost->large_insn
19028    && peep2_regno_dead_p (0, FLAGS_REG)"
19029   [(parallel [(set (match_dup 2) (const_int 0))
19030               (clobber (reg:CC FLAGS_REG))])
19031    (set (match_dup 0) (match_dup 1))]
19032   "operands[2] = gen_lowpart (SImode, operands[1]);")
19033
19034 (define_peephole2
19035   [(match_scratch:SI 2 "r")
19036    (set (match_operand:SI 0 "memory_operand" "")
19037         (match_operand:SI 1 "immediate_operand" ""))]
19038   "! optimize_size
19039    && get_attr_length (insn) >= ix86_cost->large_insn
19040    && TARGET_SPLIT_LONG_MOVES"
19041   [(set (match_dup 2) (match_dup 1))
19042    (set (match_dup 0) (match_dup 2))]
19043   "")
19044
19045 (define_peephole2
19046   [(match_scratch:HI 2 "r")
19047    (set (match_operand:HI 0 "memory_operand" "")
19048         (match_operand:HI 1 "immediate_operand" ""))]
19049   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19050   && TARGET_SPLIT_LONG_MOVES"
19051   [(set (match_dup 2) (match_dup 1))
19052    (set (match_dup 0) (match_dup 2))]
19053   "")
19054
19055 (define_peephole2
19056   [(match_scratch:QI 2 "q")
19057    (set (match_operand:QI 0 "memory_operand" "")
19058         (match_operand:QI 1 "immediate_operand" ""))]
19059   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19060   && TARGET_SPLIT_LONG_MOVES"
19061   [(set (match_dup 2) (match_dup 1))
19062    (set (match_dup 0) (match_dup 2))]
19063   "")
19064
19065 ;; Don't compare memory with zero, load and use a test instead.
19066 (define_peephole2
19067   [(set (match_operand 0 "flags_reg_operand" "")
19068         (match_operator 1 "compare_operator"
19069           [(match_operand:SI 2 "memory_operand" "")
19070            (const_int 0)]))
19071    (match_scratch:SI 3 "r")]
19072   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19073   [(set (match_dup 3) (match_dup 2))
19074    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19075   "")
19076
19077 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19078 ;; Don't split NOTs with a displacement operand, because resulting XOR
19079 ;; will not be pairable anyway.
19080 ;;
19081 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19082 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19083 ;; so this split helps here as well.
19084 ;;
19085 ;; Note: Can't do this as a regular split because we can't get proper
19086 ;; lifetime information then.
19087
19088 (define_peephole2
19089   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19090         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19091   "!optimize_size
19092    && peep2_regno_dead_p (0, FLAGS_REG)
19093    && ((TARGET_PENTIUM 
19094         && (GET_CODE (operands[0]) != MEM
19095             || !memory_displacement_operand (operands[0], SImode)))
19096        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19097   [(parallel [(set (match_dup 0)
19098                    (xor:SI (match_dup 1) (const_int -1)))
19099               (clobber (reg:CC FLAGS_REG))])]
19100   "")
19101
19102 (define_peephole2
19103   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19104         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19105   "!optimize_size
19106    && peep2_regno_dead_p (0, FLAGS_REG)
19107    && ((TARGET_PENTIUM 
19108         && (GET_CODE (operands[0]) != MEM
19109             || !memory_displacement_operand (operands[0], HImode)))
19110        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19111   [(parallel [(set (match_dup 0)
19112                    (xor:HI (match_dup 1) (const_int -1)))
19113               (clobber (reg:CC FLAGS_REG))])]
19114   "")
19115
19116 (define_peephole2
19117   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19118         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19119   "!optimize_size
19120    && peep2_regno_dead_p (0, FLAGS_REG)
19121    && ((TARGET_PENTIUM 
19122         && (GET_CODE (operands[0]) != MEM
19123             || !memory_displacement_operand (operands[0], QImode)))
19124        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19125   [(parallel [(set (match_dup 0)
19126                    (xor:QI (match_dup 1) (const_int -1)))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   "")
19129
19130 ;; Non pairable "test imm, reg" instructions can be translated to
19131 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19132 ;; byte opcode instead of two, have a short form for byte operands),
19133 ;; so do it for other CPUs as well.  Given that the value was dead,
19134 ;; this should not create any new dependencies.  Pass on the sub-word
19135 ;; versions if we're concerned about partial register stalls.
19136
19137 (define_peephole2
19138   [(set (match_operand 0 "flags_reg_operand" "")
19139         (match_operator 1 "compare_operator"
19140           [(and:SI (match_operand:SI 2 "register_operand" "")
19141                    (match_operand:SI 3 "immediate_operand" ""))
19142            (const_int 0)]))]
19143   "ix86_match_ccmode (insn, CCNOmode)
19144    && (true_regnum (operands[2]) != 0
19145        || (GET_CODE (operands[3]) == CONST_INT
19146            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19147    && peep2_reg_dead_p (1, operands[2])"
19148   [(parallel
19149      [(set (match_dup 0)
19150            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19151                             (const_int 0)]))
19152       (set (match_dup 2)
19153            (and:SI (match_dup 2) (match_dup 3)))])]
19154   "")
19155
19156 ;; We don't need to handle HImode case, because it will be promoted to SImode
19157 ;; on ! TARGET_PARTIAL_REG_STALL
19158
19159 (define_peephole2
19160   [(set (match_operand 0 "flags_reg_operand" "")
19161         (match_operator 1 "compare_operator"
19162           [(and:QI (match_operand:QI 2 "register_operand" "")
19163                    (match_operand:QI 3 "immediate_operand" ""))
19164            (const_int 0)]))]
19165   "! TARGET_PARTIAL_REG_STALL
19166    && ix86_match_ccmode (insn, CCNOmode)
19167    && true_regnum (operands[2]) != 0
19168    && peep2_reg_dead_p (1, operands[2])"
19169   [(parallel
19170      [(set (match_dup 0)
19171            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19172                             (const_int 0)]))
19173       (set (match_dup 2)
19174            (and:QI (match_dup 2) (match_dup 3)))])]
19175   "")
19176
19177 (define_peephole2
19178   [(set (match_operand 0 "flags_reg_operand" "")
19179         (match_operator 1 "compare_operator"
19180           [(and:SI
19181              (zero_extract:SI
19182                (match_operand 2 "ext_register_operand" "")
19183                (const_int 8)
19184                (const_int 8))
19185              (match_operand 3 "const_int_operand" ""))
19186            (const_int 0)]))]
19187   "! TARGET_PARTIAL_REG_STALL
19188    && ix86_match_ccmode (insn, CCNOmode)
19189    && true_regnum (operands[2]) != 0
19190    && peep2_reg_dead_p (1, operands[2])"
19191   [(parallel [(set (match_dup 0)
19192                    (match_op_dup 1
19193                      [(and:SI
19194                         (zero_extract:SI
19195                           (match_dup 2)
19196                           (const_int 8)
19197                           (const_int 8))
19198                         (match_dup 3))
19199                       (const_int 0)]))
19200               (set (zero_extract:SI (match_dup 2)
19201                                     (const_int 8)
19202                                     (const_int 8))
19203                    (and:SI 
19204                      (zero_extract:SI
19205                        (match_dup 2)
19206                        (const_int 8)
19207                        (const_int 8))
19208                      (match_dup 3)))])]
19209   "")
19210
19211 ;; Don't do logical operations with memory inputs.
19212 (define_peephole2
19213   [(match_scratch:SI 2 "r")
19214    (parallel [(set (match_operand:SI 0 "register_operand" "")
19215                    (match_operator:SI 3 "arith_or_logical_operator"
19216                      [(match_dup 0)
19217                       (match_operand:SI 1 "memory_operand" "")]))
19218               (clobber (reg:CC FLAGS_REG))])]
19219   "! optimize_size && ! TARGET_READ_MODIFY"
19220   [(set (match_dup 2) (match_dup 1))
19221    (parallel [(set (match_dup 0)
19222                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   "")
19225
19226 (define_peephole2
19227   [(match_scratch:SI 2 "r")
19228    (parallel [(set (match_operand:SI 0 "register_operand" "")
19229                    (match_operator:SI 3 "arith_or_logical_operator"
19230                      [(match_operand:SI 1 "memory_operand" "")
19231                       (match_dup 0)]))
19232               (clobber (reg:CC FLAGS_REG))])]
19233   "! optimize_size && ! TARGET_READ_MODIFY"
19234   [(set (match_dup 2) (match_dup 1))
19235    (parallel [(set (match_dup 0)
19236                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19237               (clobber (reg:CC FLAGS_REG))])]
19238   "")
19239
19240 ; Don't do logical operations with memory outputs
19241 ;
19242 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19243 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19244 ; the same decoder scheduling characteristics as the original.
19245
19246 (define_peephole2
19247   [(match_scratch:SI 2 "r")
19248    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19249                    (match_operator:SI 3 "arith_or_logical_operator"
19250                      [(match_dup 0)
19251                       (match_operand:SI 1 "nonmemory_operand" "")]))
19252               (clobber (reg:CC FLAGS_REG))])]
19253   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19254   [(set (match_dup 2) (match_dup 0))
19255    (parallel [(set (match_dup 2)
19256                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19257               (clobber (reg:CC FLAGS_REG))])
19258    (set (match_dup 0) (match_dup 2))]
19259   "")
19260
19261 (define_peephole2
19262   [(match_scratch:SI 2 "r")
19263    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19264                    (match_operator:SI 3 "arith_or_logical_operator"
19265                      [(match_operand:SI 1 "nonmemory_operand" "")
19266                       (match_dup 0)]))
19267               (clobber (reg:CC FLAGS_REG))])]
19268   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19269   [(set (match_dup 2) (match_dup 0))
19270    (parallel [(set (match_dup 2)
19271                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19272               (clobber (reg:CC FLAGS_REG))])
19273    (set (match_dup 0) (match_dup 2))]
19274   "")
19275
19276 ;; Attempt to always use XOR for zeroing registers.
19277 (define_peephole2
19278   [(set (match_operand 0 "register_operand" "")
19279         (match_operand 1 "const0_operand" ""))]
19280   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19281    && (! TARGET_USE_MOV0 || optimize_size)
19282    && GENERAL_REG_P (operands[0])
19283    && peep2_regno_dead_p (0, FLAGS_REG)"
19284   [(parallel [(set (match_dup 0) (const_int 0))
19285               (clobber (reg:CC FLAGS_REG))])]
19286 {
19287   operands[0] = gen_lowpart (word_mode, operands[0]);
19288 })
19289
19290 (define_peephole2
19291   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19292         (const_int 0))]
19293   "(GET_MODE (operands[0]) == QImode
19294     || GET_MODE (operands[0]) == HImode)
19295    && (! TARGET_USE_MOV0 || optimize_size)
19296    && peep2_regno_dead_p (0, FLAGS_REG)"
19297   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19298               (clobber (reg:CC FLAGS_REG))])])
19299
19300 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19301 (define_peephole2
19302   [(set (match_operand 0 "register_operand" "")
19303         (const_int -1))]
19304   "(GET_MODE (operands[0]) == HImode
19305     || GET_MODE (operands[0]) == SImode 
19306     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19307    && (optimize_size || TARGET_PENTIUM)
19308    && peep2_regno_dead_p (0, FLAGS_REG)"
19309   [(parallel [(set (match_dup 0) (const_int -1))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19312                               operands[0]);")
19313
19314 ;; Attempt to convert simple leas to adds. These can be created by
19315 ;; move expanders.
19316 (define_peephole2
19317   [(set (match_operand:SI 0 "register_operand" "")
19318         (plus:SI (match_dup 0)
19319                  (match_operand:SI 1 "nonmemory_operand" "")))]
19320   "peep2_regno_dead_p (0, FLAGS_REG)"
19321   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19322               (clobber (reg:CC FLAGS_REG))])]
19323   "")
19324
19325 (define_peephole2
19326   [(set (match_operand:SI 0 "register_operand" "")
19327         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19328                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19329   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19330   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "operands[2] = gen_lowpart (SImode, operands[2]);")
19333
19334 (define_peephole2
19335   [(set (match_operand:DI 0 "register_operand" "")
19336         (plus:DI (match_dup 0)
19337                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19338   "peep2_regno_dead_p (0, FLAGS_REG)"
19339   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19340               (clobber (reg:CC FLAGS_REG))])]
19341   "")
19342
19343 (define_peephole2
19344   [(set (match_operand:SI 0 "register_operand" "")
19345         (mult:SI (match_dup 0)
19346                  (match_operand:SI 1 "const_int_operand" "")))]
19347   "exact_log2 (INTVAL (operands[1])) >= 0
19348    && peep2_regno_dead_p (0, FLAGS_REG)"
19349   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19352
19353 (define_peephole2
19354   [(set (match_operand:DI 0 "register_operand" "")
19355         (mult:DI (match_dup 0)
19356                  (match_operand:DI 1 "const_int_operand" "")))]
19357   "exact_log2 (INTVAL (operands[1])) >= 0
19358    && peep2_regno_dead_p (0, FLAGS_REG)"
19359   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19360               (clobber (reg:CC FLAGS_REG))])]
19361   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19362
19363 (define_peephole2
19364   [(set (match_operand:SI 0 "register_operand" "")
19365         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19366                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19367   "exact_log2 (INTVAL (operands[2])) >= 0
19368    && REGNO (operands[0]) == REGNO (operands[1])
19369    && peep2_regno_dead_p (0, FLAGS_REG)"
19370   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19371               (clobber (reg:CC FLAGS_REG))])]
19372   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19373
19374 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19375 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19376 ;; many CPUs it is also faster, since special hardware to avoid esp
19377 ;; dependencies is present.
19378
19379 ;; While some of these conversions may be done using splitters, we use peepholes
19380 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19381
19382 ;; Convert prologue esp subtractions to push.
19383 ;; We need register to push.  In order to keep verify_flow_info happy we have
19384 ;; two choices
19385 ;; - use scratch and clobber it in order to avoid dependencies
19386 ;; - use already live register
19387 ;; We can't use the second way right now, since there is no reliable way how to
19388 ;; verify that given register is live.  First choice will also most likely in
19389 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19390 ;; call clobbered registers are dead.  We may want to use base pointer as an
19391 ;; alternative when no register is available later.
19392
19393 (define_peephole2
19394   [(match_scratch:SI 0 "r")
19395    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19396               (clobber (reg:CC FLAGS_REG))
19397               (clobber (mem:BLK (scratch)))])]
19398   "optimize_size || !TARGET_SUB_ESP_4"
19399   [(clobber (match_dup 0))
19400    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19401               (clobber (mem:BLK (scratch)))])])
19402
19403 (define_peephole2
19404   [(match_scratch:SI 0 "r")
19405    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19406               (clobber (reg:CC FLAGS_REG))
19407               (clobber (mem:BLK (scratch)))])]
19408   "optimize_size || !TARGET_SUB_ESP_8"
19409   [(clobber (match_dup 0))
19410    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19411    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19412               (clobber (mem:BLK (scratch)))])])
19413
19414 ;; Convert esp subtractions to push.
19415 (define_peephole2
19416   [(match_scratch:SI 0 "r")
19417    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19418               (clobber (reg:CC FLAGS_REG))])]
19419   "optimize_size || !TARGET_SUB_ESP_4"
19420   [(clobber (match_dup 0))
19421    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19422
19423 (define_peephole2
19424   [(match_scratch:SI 0 "r")
19425    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19426               (clobber (reg:CC FLAGS_REG))])]
19427   "optimize_size || !TARGET_SUB_ESP_8"
19428   [(clobber (match_dup 0))
19429    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19430    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19431
19432 ;; Convert epilogue deallocator to pop.
19433 (define_peephole2
19434   [(match_scratch:SI 0 "r")
19435    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19436               (clobber (reg:CC FLAGS_REG))
19437               (clobber (mem:BLK (scratch)))])]
19438   "optimize_size || !TARGET_ADD_ESP_4"
19439   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19440               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19441               (clobber (mem:BLK (scratch)))])]
19442   "")
19443
19444 ;; Two pops case is tricky, since pop causes dependency on destination register.
19445 ;; We use two registers if available.
19446 (define_peephole2
19447   [(match_scratch:SI 0 "r")
19448    (match_scratch:SI 1 "r")
19449    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19450               (clobber (reg:CC FLAGS_REG))
19451               (clobber (mem:BLK (scratch)))])]
19452   "optimize_size || !TARGET_ADD_ESP_8"
19453   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19455               (clobber (mem:BLK (scratch)))])
19456    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19457               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19458   "")
19459
19460 (define_peephole2
19461   [(match_scratch:SI 0 "r")
19462    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19463               (clobber (reg:CC FLAGS_REG))
19464               (clobber (mem:BLK (scratch)))])]
19465   "optimize_size"
19466   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19467               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19468               (clobber (mem:BLK (scratch)))])
19469    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19470               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19471   "")
19472
19473 ;; Convert esp additions to pop.
19474 (define_peephole2
19475   [(match_scratch:SI 0 "r")
19476    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19477               (clobber (reg:CC FLAGS_REG))])]
19478   ""
19479   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19480               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19481   "")
19482
19483 ;; Two pops case is tricky, since pop causes dependency on destination register.
19484 ;; We use two registers if available.
19485 (define_peephole2
19486   [(match_scratch:SI 0 "r")
19487    (match_scratch:SI 1 "r")
19488    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19489               (clobber (reg:CC FLAGS_REG))])]
19490   ""
19491   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19492               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19493    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19494               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19495   "")
19496
19497 (define_peephole2
19498   [(match_scratch:SI 0 "r")
19499    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19500               (clobber (reg:CC FLAGS_REG))])]
19501   "optimize_size"
19502   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19503               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19504    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19505               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19506   "")
19507 \f
19508 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19509 ;; required and register dies.  Similarly for 128 to plus -128.
19510 (define_peephole2
19511   [(set (match_operand 0 "flags_reg_operand" "")
19512         (match_operator 1 "compare_operator"
19513           [(match_operand 2 "register_operand" "")
19514            (match_operand 3 "const_int_operand" "")]))]
19515   "(INTVAL (operands[3]) == -1
19516     || INTVAL (operands[3]) == 1
19517     || INTVAL (operands[3]) == 128)
19518    && ix86_match_ccmode (insn, CCGCmode)
19519    && peep2_reg_dead_p (1, operands[2])"
19520   [(parallel [(set (match_dup 0)
19521                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19522               (clobber (match_dup 2))])]
19523   "")
19524 \f
19525 (define_peephole2
19526   [(match_scratch:DI 0 "r")
19527    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19528               (clobber (reg:CC FLAGS_REG))
19529               (clobber (mem:BLK (scratch)))])]
19530   "optimize_size || !TARGET_SUB_ESP_4"
19531   [(clobber (match_dup 0))
19532    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19533               (clobber (mem:BLK (scratch)))])])
19534
19535 (define_peephole2
19536   [(match_scratch:DI 0 "r")
19537    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19538               (clobber (reg:CC FLAGS_REG))
19539               (clobber (mem:BLK (scratch)))])]
19540   "optimize_size || !TARGET_SUB_ESP_8"
19541   [(clobber (match_dup 0))
19542    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19543    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19544               (clobber (mem:BLK (scratch)))])])
19545
19546 ;; Convert esp subtractions to push.
19547 (define_peephole2
19548   [(match_scratch:DI 0 "r")
19549    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19550               (clobber (reg:CC FLAGS_REG))])]
19551   "optimize_size || !TARGET_SUB_ESP_4"
19552   [(clobber (match_dup 0))
19553    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19554
19555 (define_peephole2
19556   [(match_scratch:DI 0 "r")
19557    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "optimize_size || !TARGET_SUB_ESP_8"
19560   [(clobber (match_dup 0))
19561    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19562    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19563
19564 ;; Convert epilogue deallocator to pop.
19565 (define_peephole2
19566   [(match_scratch:DI 0 "r")
19567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19568               (clobber (reg:CC FLAGS_REG))
19569               (clobber (mem:BLK (scratch)))])]
19570   "optimize_size || !TARGET_ADD_ESP_4"
19571   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19572               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19573               (clobber (mem:BLK (scratch)))])]
19574   "")
19575
19576 ;; Two pops case is tricky, since pop causes dependency on destination register.
19577 ;; We use two registers if available.
19578 (define_peephole2
19579   [(match_scratch:DI 0 "r")
19580    (match_scratch:DI 1 "r")
19581    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19582               (clobber (reg:CC FLAGS_REG))
19583               (clobber (mem:BLK (scratch)))])]
19584   "optimize_size || !TARGET_ADD_ESP_8"
19585   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19586               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19587               (clobber (mem:BLK (scratch)))])
19588    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19589               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19590   "")
19591
19592 (define_peephole2
19593   [(match_scratch:DI 0 "r")
19594    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19595               (clobber (reg:CC FLAGS_REG))
19596               (clobber (mem:BLK (scratch)))])]
19597   "optimize_size"
19598   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19599               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19600               (clobber (mem:BLK (scratch)))])
19601    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19602               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19603   "")
19604
19605 ;; Convert esp additions to pop.
19606 (define_peephole2
19607   [(match_scratch:DI 0 "r")
19608    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19609               (clobber (reg:CC FLAGS_REG))])]
19610   ""
19611   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19612               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19613   "")
19614
19615 ;; Two pops case is tricky, since pop causes dependency on destination register.
19616 ;; We use two registers if available.
19617 (define_peephole2
19618   [(match_scratch:DI 0 "r")
19619    (match_scratch:DI 1 "r")
19620    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19621               (clobber (reg:CC FLAGS_REG))])]
19622   ""
19623   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19624               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19625    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19626               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19627   "")
19628
19629 (define_peephole2
19630   [(match_scratch:DI 0 "r")
19631    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19632               (clobber (reg:CC FLAGS_REG))])]
19633   "optimize_size"
19634   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19635               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19636    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19637               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19638   "")
19639 \f
19640 ;; Convert imul by three, five and nine into lea
19641 (define_peephole2
19642   [(parallel
19643     [(set (match_operand:SI 0 "register_operand" "")
19644           (mult:SI (match_operand:SI 1 "register_operand" "")
19645                    (match_operand:SI 2 "const_int_operand" "")))
19646      (clobber (reg:CC FLAGS_REG))])]
19647   "INTVAL (operands[2]) == 3
19648    || INTVAL (operands[2]) == 5
19649    || INTVAL (operands[2]) == 9"
19650   [(set (match_dup 0)
19651         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19652                  (match_dup 1)))]
19653   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19654
19655 (define_peephole2
19656   [(parallel
19657     [(set (match_operand:SI 0 "register_operand" "")
19658           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19659                    (match_operand:SI 2 "const_int_operand" "")))
19660      (clobber (reg:CC FLAGS_REG))])]
19661   "!optimize_size 
19662    && (INTVAL (operands[2]) == 3
19663        || INTVAL (operands[2]) == 5
19664        || INTVAL (operands[2]) == 9)"
19665   [(set (match_dup 0) (match_dup 1))
19666    (set (match_dup 0)
19667         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19668                  (match_dup 0)))]
19669   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19670
19671 (define_peephole2
19672   [(parallel
19673     [(set (match_operand:DI 0 "register_operand" "")
19674           (mult:DI (match_operand:DI 1 "register_operand" "")
19675                    (match_operand:DI 2 "const_int_operand" "")))
19676      (clobber (reg:CC FLAGS_REG))])]
19677   "TARGET_64BIT
19678    && (INTVAL (operands[2]) == 3
19679        || INTVAL (operands[2]) == 5
19680        || INTVAL (operands[2]) == 9)"
19681   [(set (match_dup 0)
19682         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19683                  (match_dup 1)))]
19684   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19685
19686 (define_peephole2
19687   [(parallel
19688     [(set (match_operand:DI 0 "register_operand" "")
19689           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19690                    (match_operand:DI 2 "const_int_operand" "")))
19691      (clobber (reg:CC FLAGS_REG))])]
19692   "TARGET_64BIT
19693    && !optimize_size 
19694    && (INTVAL (operands[2]) == 3
19695        || INTVAL (operands[2]) == 5
19696        || INTVAL (operands[2]) == 9)"
19697   [(set (match_dup 0) (match_dup 1))
19698    (set (match_dup 0)
19699         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19700                  (match_dup 0)))]
19701   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19702
19703 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19704 ;; imul $32bit_imm, reg, reg is direct decoded.
19705 (define_peephole2
19706   [(match_scratch:DI 3 "r")
19707    (parallel [(set (match_operand:DI 0 "register_operand" "")
19708                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19709                             (match_operand:DI 2 "immediate_operand" "")))
19710               (clobber (reg:CC FLAGS_REG))])]
19711   "TARGET_K8 && !optimize_size
19712    && (GET_CODE (operands[2]) != CONST_INT
19713        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19714   [(set (match_dup 3) (match_dup 1))
19715    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19716               (clobber (reg:CC FLAGS_REG))])]
19717 "")
19718
19719 (define_peephole2
19720   [(match_scratch:SI 3 "r")
19721    (parallel [(set (match_operand:SI 0 "register_operand" "")
19722                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19723                             (match_operand:SI 2 "immediate_operand" "")))
19724               (clobber (reg:CC FLAGS_REG))])]
19725   "TARGET_K8 && !optimize_size
19726    && (GET_CODE (operands[2]) != CONST_INT
19727        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19728   [(set (match_dup 3) (match_dup 1))
19729    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19730               (clobber (reg:CC FLAGS_REG))])]
19731 "")
19732
19733 (define_peephole2
19734   [(match_scratch:SI 3 "r")
19735    (parallel [(set (match_operand:DI 0 "register_operand" "")
19736                    (zero_extend:DI
19737                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19738                               (match_operand:SI 2 "immediate_operand" ""))))
19739               (clobber (reg:CC FLAGS_REG))])]
19740   "TARGET_K8 && !optimize_size
19741    && (GET_CODE (operands[2]) != CONST_INT
19742        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19743   [(set (match_dup 3) (match_dup 1))
19744    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19745               (clobber (reg:CC FLAGS_REG))])]
19746 "")
19747
19748 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19749 ;; Convert it into imul reg, reg
19750 ;; It would be better to force assembler to encode instruction using long
19751 ;; immediate, but there is apparently no way to do so.
19752 (define_peephole2
19753   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19754                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19755                             (match_operand:DI 2 "const_int_operand" "")))
19756               (clobber (reg:CC FLAGS_REG))])
19757    (match_scratch:DI 3 "r")]
19758   "TARGET_K8 && !optimize_size
19759    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19760   [(set (match_dup 3) (match_dup 2))
19761    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19762               (clobber (reg:CC FLAGS_REG))])]
19763 {
19764   if (!rtx_equal_p (operands[0], operands[1]))
19765     emit_move_insn (operands[0], operands[1]);
19766 })
19767
19768 (define_peephole2
19769   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19770                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19771                             (match_operand:SI 2 "const_int_operand" "")))
19772               (clobber (reg:CC FLAGS_REG))])
19773    (match_scratch:SI 3 "r")]
19774   "TARGET_K8 && !optimize_size
19775    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19776   [(set (match_dup 3) (match_dup 2))
19777    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779 {
19780   if (!rtx_equal_p (operands[0], operands[1]))
19781     emit_move_insn (operands[0], operands[1]);
19782 })
19783
19784 (define_peephole2
19785   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19786                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19787                             (match_operand:HI 2 "immediate_operand" "")))
19788               (clobber (reg:CC FLAGS_REG))])
19789    (match_scratch:HI 3 "r")]
19790   "TARGET_K8 && !optimize_size"
19791   [(set (match_dup 3) (match_dup 2))
19792    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19793               (clobber (reg:CC FLAGS_REG))])]
19794 {
19795   if (!rtx_equal_p (operands[0], operands[1]))
19796     emit_move_insn (operands[0], operands[1]);
19797 })
19798
19799 ;; After splitting up read-modify operations, array accesses with memory
19800 ;; operands might end up in form:
19801 ;;  sall    $2, %eax
19802 ;;  movl    4(%esp), %edx
19803 ;;  addl    %edx, %eax
19804 ;; instead of pre-splitting:
19805 ;;  sall    $2, %eax
19806 ;;  addl    4(%esp), %eax
19807 ;; Turn it into:
19808 ;;  movl    4(%esp), %edx
19809 ;;  leal    (%edx,%eax,4), %eax
19810
19811 (define_peephole2
19812   [(parallel [(set (match_operand 0 "register_operand" "")
19813                    (ashift (match_operand 1 "register_operand" "")
19814                            (match_operand 2 "const_int_operand" "")))
19815                (clobber (reg:CC FLAGS_REG))])
19816    (set (match_operand 3 "register_operand")
19817         (match_operand 4 "x86_64_general_operand" ""))
19818    (parallel [(set (match_operand 5 "register_operand" "")
19819                    (plus (match_operand 6 "register_operand" "")
19820                          (match_operand 7 "register_operand" "")))
19821                    (clobber (reg:CC FLAGS_REG))])]
19822   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19823    /* Validate MODE for lea.  */
19824    && ((!TARGET_PARTIAL_REG_STALL
19825         && (GET_MODE (operands[0]) == QImode
19826             || GET_MODE (operands[0]) == HImode))
19827        || GET_MODE (operands[0]) == SImode 
19828        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19829    /* We reorder load and the shift.  */
19830    && !rtx_equal_p (operands[1], operands[3])
19831    && !reg_overlap_mentioned_p (operands[0], operands[4])
19832    /* Last PLUS must consist of operand 0 and 3.  */
19833    && !rtx_equal_p (operands[0], operands[3])
19834    && (rtx_equal_p (operands[3], operands[6])
19835        || rtx_equal_p (operands[3], operands[7]))
19836    && (rtx_equal_p (operands[0], operands[6])
19837        || rtx_equal_p (operands[0], operands[7]))
19838    /* The intermediate operand 0 must die or be same as output.  */
19839    && (rtx_equal_p (operands[0], operands[5])
19840        || peep2_reg_dead_p (3, operands[0]))"
19841   [(set (match_dup 3) (match_dup 4))
19842    (set (match_dup 0) (match_dup 1))]
19843 {
19844   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19845   int scale = 1 << INTVAL (operands[2]);
19846   rtx index = gen_lowpart (Pmode, operands[1]);
19847   rtx base = gen_lowpart (Pmode, operands[3]);
19848   rtx dest = gen_lowpart (mode, operands[5]);
19849
19850   operands[1] = gen_rtx_PLUS (Pmode, base,
19851                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19852   if (mode != Pmode)
19853     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19854   operands[0] = dest;
19855 })
19856 \f
19857 ;; Call-value patterns last so that the wildcard operand does not
19858 ;; disrupt insn-recog's switch tables.
19859
19860 (define_insn "*call_value_pop_0"
19861   [(set (match_operand 0 "" "")
19862         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19863               (match_operand:SI 2 "" "")))
19864    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19865                             (match_operand:SI 3 "immediate_operand" "")))]
19866   "!TARGET_64BIT"
19867 {
19868   if (SIBLING_CALL_P (insn))
19869     return "jmp\t%P1";
19870   else
19871     return "call\t%P1";
19872 }
19873   [(set_attr "type" "callv")])
19874
19875 (define_insn "*call_value_pop_1"
19876   [(set (match_operand 0 "" "")
19877         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19878               (match_operand:SI 2 "" "")))
19879    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19880                             (match_operand:SI 3 "immediate_operand" "i")))]
19881   "!TARGET_64BIT"
19882 {
19883   if (constant_call_address_operand (operands[1], Pmode))
19884     {
19885       if (SIBLING_CALL_P (insn))
19886         return "jmp\t%P1";
19887       else
19888         return "call\t%P1";
19889     }
19890   if (SIBLING_CALL_P (insn))
19891     return "jmp\t%A1";
19892   else
19893     return "call\t%A1";
19894 }
19895   [(set_attr "type" "callv")])
19896
19897 (define_insn "*call_value_0"
19898   [(set (match_operand 0 "" "")
19899         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19900               (match_operand:SI 2 "" "")))]
19901   "!TARGET_64BIT"
19902 {
19903   if (SIBLING_CALL_P (insn))
19904     return "jmp\t%P1";
19905   else
19906     return "call\t%P1";
19907 }
19908   [(set_attr "type" "callv")])
19909
19910 (define_insn "*call_value_0_rex64"
19911   [(set (match_operand 0 "" "")
19912         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19913               (match_operand:DI 2 "const_int_operand" "")))]
19914   "TARGET_64BIT"
19915 {
19916   if (SIBLING_CALL_P (insn))
19917     return "jmp\t%P1";
19918   else
19919     return "call\t%P1";
19920 }
19921   [(set_attr "type" "callv")])
19922
19923 (define_insn "*call_value_1"
19924   [(set (match_operand 0 "" "")
19925         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19926               (match_operand:SI 2 "" "")))]
19927   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19928 {
19929   if (constant_call_address_operand (operands[1], Pmode))
19930     return "call\t%P1";
19931   return "call\t%A1";
19932 }
19933   [(set_attr "type" "callv")])
19934
19935 (define_insn "*sibcall_value_1"
19936   [(set (match_operand 0 "" "")
19937         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19938               (match_operand:SI 2 "" "")))]
19939   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19940 {
19941   if (constant_call_address_operand (operands[1], Pmode))
19942     return "jmp\t%P1";
19943   return "jmp\t%A1";
19944 }
19945   [(set_attr "type" "callv")])
19946
19947 (define_insn "*call_value_1_rex64"
19948   [(set (match_operand 0 "" "")
19949         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19950               (match_operand:DI 2 "" "")))]
19951   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19952 {
19953   if (constant_call_address_operand (operands[1], Pmode))
19954     return "call\t%P1";
19955   return "call\t%A1";
19956 }
19957   [(set_attr "type" "callv")])
19958
19959 (define_insn "*sibcall_value_1_rex64"
19960   [(set (match_operand 0 "" "")
19961         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19962               (match_operand:DI 2 "" "")))]
19963   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19964   "jmp\t%P1"
19965   [(set_attr "type" "callv")])
19966
19967 (define_insn "*sibcall_value_1_rex64_v"
19968   [(set (match_operand 0 "" "")
19969         (call (mem:QI (reg:DI 40))
19970               (match_operand:DI 1 "" "")))]
19971   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19972   "jmp\t*%%r11"
19973   [(set_attr "type" "callv")])
19974 \f
19975 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19976 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19977 ;; caught for use by garbage collectors and the like.  Using an insn that
19978 ;; maps to SIGILL makes it more likely the program will rightfully die.
19979 ;; Keeping with tradition, "6" is in honor of #UD.
19980 (define_insn "trap"
19981   [(trap_if (const_int 1) (const_int 6))]
19982   ""
19983   { return ASM_SHORT "0x0b0f"; }
19984   [(set_attr "length" "2")])
19985
19986 (define_expand "sse_prologue_save"
19987   [(parallel [(set (match_operand:BLK 0 "" "")
19988                    (unspec:BLK [(reg:DI 21)
19989                                 (reg:DI 22)
19990                                 (reg:DI 23)
19991                                 (reg:DI 24)
19992                                 (reg:DI 25)
19993                                 (reg:DI 26)
19994                                 (reg:DI 27)
19995                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19996               (use (match_operand:DI 1 "register_operand" ""))
19997               (use (match_operand:DI 2 "immediate_operand" ""))
19998               (use (label_ref:DI (match_operand 3 "" "")))])]
19999   "TARGET_64BIT"
20000   "")
20001
20002 (define_insn "*sse_prologue_save_insn"
20003   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20004                           (match_operand:DI 4 "const_int_operand" "n")))
20005         (unspec:BLK [(reg:DI 21)
20006                      (reg:DI 22)
20007                      (reg:DI 23)
20008                      (reg:DI 24)
20009                      (reg:DI 25)
20010                      (reg:DI 26)
20011                      (reg:DI 27)
20012                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20013    (use (match_operand:DI 1 "register_operand" "r"))
20014    (use (match_operand:DI 2 "const_int_operand" "i"))
20015    (use (label_ref:DI (match_operand 3 "" "X")))]
20016   "TARGET_64BIT
20017    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20018    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20019   "*
20020 {
20021   int i;
20022   operands[0] = gen_rtx_MEM (Pmode,
20023                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20024   output_asm_insn (\"jmp\\t%A1\", operands);
20025   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20026     {
20027       operands[4] = adjust_address (operands[0], DImode, i*16);
20028       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20029       PUT_MODE (operands[4], TImode);
20030       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20031         output_asm_insn (\"rex\", operands);
20032       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20033     }
20034   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20035                              CODE_LABEL_NUMBER (operands[3]));
20036   RET;
20037 }
20038   "
20039   [(set_attr "type" "other")
20040    (set_attr "length_immediate" "0")
20041    (set_attr "length_address" "0")
20042    (set_attr "length" "135")
20043    (set_attr "memory" "store")
20044    (set_attr "modrm" "0")
20045    (set_attr "mode" "DI")])
20046
20047 (define_expand "prefetch"
20048   [(prefetch (match_operand 0 "address_operand" "")
20049              (match_operand:SI 1 "const_int_operand" "")
20050              (match_operand:SI 2 "const_int_operand" ""))]
20051   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20052 {
20053   int rw = INTVAL (operands[1]);
20054   int locality = INTVAL (operands[2]);
20055
20056   gcc_assert (rw == 0 || rw == 1);
20057   gcc_assert (locality >= 0 && locality <= 3);
20058   gcc_assert (GET_MODE (operands[0]) == Pmode
20059               || GET_MODE (operands[0]) == VOIDmode);
20060
20061   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20062      supported by SSE counterpart or the SSE prefetch is not available
20063      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20064      of locality.  */
20065   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20066     operands[2] = GEN_INT (3);
20067   else
20068     operands[1] = const0_rtx;
20069 })
20070
20071 (define_insn "*prefetch_sse"
20072   [(prefetch (match_operand:SI 0 "address_operand" "p")
20073              (const_int 0)
20074              (match_operand:SI 1 "const_int_operand" ""))]
20075   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20076 {
20077   static const char * const patterns[4] = {
20078    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20079   };
20080
20081   int locality = INTVAL (operands[1]);
20082   gcc_assert (locality >= 0 && locality <= 3);
20083
20084   return patterns[locality];  
20085 }
20086   [(set_attr "type" "sse")
20087    (set_attr "memory" "none")])
20088
20089 (define_insn "*prefetch_sse_rex"
20090   [(prefetch (match_operand:DI 0 "address_operand" "p")
20091              (const_int 0)
20092              (match_operand:SI 1 "const_int_operand" ""))]
20093   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20094 {
20095   static const char * const patterns[4] = {
20096    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20097   };
20098
20099   int locality = INTVAL (operands[1]);
20100   gcc_assert (locality >= 0 && locality <= 3);
20101
20102   return patterns[locality];  
20103 }
20104   [(set_attr "type" "sse")
20105    (set_attr "memory" "none")])
20106
20107 (define_insn "*prefetch_3dnow"
20108   [(prefetch (match_operand:SI 0 "address_operand" "p")
20109              (match_operand:SI 1 "const_int_operand" "n")
20110              (const_int 3))]
20111   "TARGET_3DNOW && !TARGET_64BIT"
20112 {
20113   if (INTVAL (operands[1]) == 0)
20114     return "prefetch\t%a0";
20115   else
20116     return "prefetchw\t%a0";
20117 }
20118   [(set_attr "type" "mmx")
20119    (set_attr "memory" "none")])
20120
20121 (define_insn "*prefetch_3dnow_rex"
20122   [(prefetch (match_operand:DI 0 "address_operand" "p")
20123              (match_operand:SI 1 "const_int_operand" "n")
20124              (const_int 3))]
20125   "TARGET_3DNOW && TARGET_64BIT"
20126 {
20127   if (INTVAL (operands[1]) == 0)
20128     return "prefetch\t%a0";
20129   else
20130     return "prefetchw\t%a0";
20131 }
20132   [(set_attr "type" "mmx")
20133    (set_attr "memory" "none")])
20134
20135 (define_expand "stack_protect_set"
20136   [(match_operand 0 "memory_operand" "")
20137    (match_operand 1 "memory_operand" "")]
20138   ""
20139 {
20140 #ifdef TARGET_THREAD_SSP_OFFSET
20141   if (TARGET_64BIT)
20142     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20143                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20144   else
20145     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20146                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20147 #else
20148   if (TARGET_64BIT)
20149     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20150   else
20151     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20152 #endif
20153   DONE;
20154 })
20155
20156 (define_insn "stack_protect_set_si"
20157   [(set (match_operand:SI 0 "memory_operand" "=m")
20158         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20159    (set (match_scratch:SI 2 "=&r") (const_int 0))
20160    (clobber (reg:CC FLAGS_REG))]
20161   ""
20162   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20163   [(set_attr "type" "multi")])
20164
20165 (define_insn "stack_protect_set_di"
20166   [(set (match_operand:DI 0 "memory_operand" "=m")
20167         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20168    (set (match_scratch:DI 2 "=&r") (const_int 0))
20169    (clobber (reg:CC FLAGS_REG))]
20170   "TARGET_64BIT"
20171   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20172   [(set_attr "type" "multi")])
20173
20174 (define_insn "stack_tls_protect_set_si"
20175   [(set (match_operand:SI 0 "memory_operand" "=m")
20176         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20177    (set (match_scratch:SI 2 "=&r") (const_int 0))
20178    (clobber (reg:CC FLAGS_REG))]
20179   ""
20180   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20181   [(set_attr "type" "multi")])
20182
20183 (define_insn "stack_tls_protect_set_di"
20184   [(set (match_operand:DI 0 "memory_operand" "=m")
20185         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20186    (set (match_scratch:DI 2 "=&r") (const_int 0))
20187    (clobber (reg:CC FLAGS_REG))]
20188   "TARGET_64BIT"
20189   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20190   [(set_attr "type" "multi")])
20191
20192 (define_expand "stack_protect_test"
20193   [(match_operand 0 "memory_operand" "")
20194    (match_operand 1 "memory_operand" "")
20195    (match_operand 2 "" "")]
20196   ""
20197 {
20198   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20199   ix86_compare_op0 = operands[0];
20200   ix86_compare_op1 = operands[1];
20201   ix86_compare_emitted = flags;
20202
20203 #ifdef TARGET_THREAD_SSP_OFFSET
20204   if (TARGET_64BIT)
20205     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20206                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20207   else
20208     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20209                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20210 #else
20211   if (TARGET_64BIT)
20212     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20213   else
20214     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20215 #endif
20216   emit_jump_insn (gen_beq (operands[2]));
20217   DONE;
20218 })
20219
20220 (define_insn "stack_protect_test_si"
20221   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20222         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20223                      (match_operand:SI 2 "memory_operand" "m")]
20224                     UNSPEC_SP_TEST))
20225    (clobber (match_scratch:SI 3 "=&r"))]
20226   ""
20227   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20228   [(set_attr "type" "multi")])
20229
20230 (define_insn "stack_protect_test_di"
20231   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20232         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20233                      (match_operand:DI 2 "memory_operand" "m")]
20234                     UNSPEC_SP_TEST))
20235    (clobber (match_scratch:DI 3 "=&r"))]
20236   "TARGET_64BIT"
20237   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20238   [(set_attr "type" "multi")])
20239
20240 (define_insn "stack_tls_protect_test_si"
20241   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20242         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20243                      (match_operand:SI 2 "const_int_operand" "i")]
20244                     UNSPEC_SP_TLS_TEST))
20245    (clobber (match_scratch:SI 3 "=r"))]
20246   ""
20247   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20248   [(set_attr "type" "multi")])
20249
20250 (define_insn "stack_tls_protect_test_di"
20251   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20252         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20253                      (match_operand:DI 2 "const_int_operand" "i")]
20254                     UNSPEC_SP_TLS_TEST))
20255    (clobber (match_scratch:DI 3 "=r"))]
20256   "TARGET_64BIT"
20257   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20258   [(set_attr "type" "multi")])
20259
20260 (include "sse.md")
20261 (include "mmx.md")
20262 (include "sync.md")