OSDN Git Service

PR target/9350
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (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" "=<,<")
1274         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1275   "!TARGET_64BIT"
1276   "@
1277    push{w}\t{|WORD PTR }%1
1278    push{w}\t%1"
1279   [(set_attr "type" "push")
1280    (set_attr "mode" "HI")])
1281
1282 ;; For 64BIT abi we always round up to 8 bytes.
1283 (define_insn "*pushhi2_rex64"
1284   [(set (match_operand:HI 0 "push_operand" "=X")
1285         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1286   "TARGET_64BIT"
1287   "push{q}\t%q1"
1288   [(set_attr "type" "push")
1289    (set_attr "mode" "QI")])
1290
1291 (define_insn "*movhi_1"
1292   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1293         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1294   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1295 {
1296   switch (get_attr_type (insn))
1297     {
1298     case TYPE_IMOVX:
1299       /* movzwl is faster than movw on p2 due to partial word stalls,
1300          though not as fast as an aligned movl.  */
1301       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1302     default:
1303       if (get_attr_mode (insn) == MODE_SI)
1304         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1305       else
1306         return "mov{w}\t{%1, %0|%0, %1}";
1307     }
1308 }
1309   [(set (attr "type")
1310      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1311               (const_string "imov")
1312             (and (eq_attr "alternative" "0")
1313                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1314                           (const_int 0))
1315                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1316                           (const_int 0))))
1317               (const_string "imov")
1318             (and (eq_attr "alternative" "1,2")
1319                  (match_operand:HI 1 "aligned_operand" ""))
1320               (const_string "imov")
1321             (and (ne (symbol_ref "TARGET_MOVX")
1322                      (const_int 0))
1323                  (eq_attr "alternative" "0,2"))
1324               (const_string "imovx")
1325            ]
1326            (const_string "imov")))
1327     (set (attr "mode")
1328       (cond [(eq_attr "type" "imovx")
1329                (const_string "SI")
1330              (and (eq_attr "alternative" "1,2")
1331                   (match_operand:HI 1 "aligned_operand" ""))
1332                (const_string "SI")
1333              (and (eq_attr "alternative" "0")
1334                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1335                            (const_int 0))
1336                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1337                            (const_int 0))))
1338                (const_string "SI")
1339             ]
1340             (const_string "HI")))])
1341
1342 ;; Stores and loads of ax to arbitrary constant address.
1343 ;; We fake an second form of instruction to force reload to load address
1344 ;; into register when rax is not available
1345 (define_insn "*movabshi_1_rex64"
1346   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1347         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1348   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1349   "@
1350    movabs{w}\t{%1, %P0|%P0, %1}
1351    mov{w}\t{%1, %a0|%a0, %1}"
1352   [(set_attr "type" "imov")
1353    (set_attr "modrm" "0,*")
1354    (set_attr "length_address" "8,0")
1355    (set_attr "length_immediate" "0,*")
1356    (set_attr "memory" "store")
1357    (set_attr "mode" "HI")])
1358
1359 (define_insn "*movabshi_2_rex64"
1360   [(set (match_operand:HI 0 "register_operand" "=a,r")
1361         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1362   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1363   "@
1364    movabs{w}\t{%P1, %0|%0, %P1}
1365    mov{w}\t{%a1, %0|%0, %a1}"
1366   [(set_attr "type" "imov")
1367    (set_attr "modrm" "0,*")
1368    (set_attr "length_address" "8,0")
1369    (set_attr "length_immediate" "0")
1370    (set_attr "memory" "load")
1371    (set_attr "mode" "HI")])
1372
1373 (define_insn "*swaphi_1"
1374   [(set (match_operand:HI 0 "register_operand" "+r")
1375         (match_operand:HI 1 "register_operand" "+r"))
1376    (set (match_dup 1)
1377         (match_dup 0))]
1378   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1379   "xchg{l}\t%k1, %k0"
1380   [(set_attr "type" "imov")
1381    (set_attr "mode" "SI")
1382    (set_attr "pent_pair" "np")
1383    (set_attr "athlon_decode" "vector")])
1384
1385 (define_insn "*swaphi_2"
1386   [(set (match_operand:HI 0 "register_operand" "+r")
1387         (match_operand:HI 1 "register_operand" "+r"))
1388    (set (match_dup 1)
1389         (match_dup 0))]
1390   "TARGET_PARTIAL_REG_STALL"
1391   "xchg{w}\t%1, %0"
1392   [(set_attr "type" "imov")
1393    (set_attr "mode" "HI")
1394    (set_attr "pent_pair" "np")
1395    (set_attr "athlon_decode" "vector")])
1396
1397 (define_expand "movstricthi"
1398   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1399         (match_operand:HI 1 "general_operand" ""))]
1400   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1401 {
1402   /* Don't generate memory->memory moves, go through a register */
1403   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1404     operands[1] = force_reg (HImode, operands[1]);
1405 })
1406
1407 (define_insn "*movstricthi_1"
1408   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1409         (match_operand:HI 1 "general_operand" "rn,m"))]
1410   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1411    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1412   "mov{w}\t{%1, %0|%0, %1}"
1413   [(set_attr "type" "imov")
1414    (set_attr "mode" "HI")])
1415
1416 (define_insn "*movstricthi_xor"
1417   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1418         (match_operand:HI 1 "const0_operand" "i"))
1419    (clobber (reg:CC FLAGS_REG))]
1420   "reload_completed
1421    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1422   "xor{w}\t{%0, %0|%0, %0}"
1423   [(set_attr "type" "alu1")
1424    (set_attr "mode" "HI")
1425    (set_attr "length_immediate" "0")])
1426
1427 (define_expand "movqi"
1428   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1429         (match_operand:QI 1 "general_operand" ""))]
1430   ""
1431   "ix86_expand_move (QImode, operands); DONE;")
1432
1433 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1434 ;; "push a byte".  But actually we use pushw, which has the effect
1435 ;; of rounding the amount pushed up to a halfword.
1436
1437 (define_insn "*pushqi2"
1438   [(set (match_operand:QI 0 "push_operand" "=X,X")
1439         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1440   "!TARGET_64BIT"
1441   "@
1442    push{w}\t{|word ptr }%1
1443    push{w}\t%w1"
1444   [(set_attr "type" "push")
1445    (set_attr "mode" "HI")])
1446
1447 ;; For 64BIT abi we always round up to 8 bytes.
1448 (define_insn "*pushqi2_rex64"
1449   [(set (match_operand:QI 0 "push_operand" "=X")
1450         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1451   "TARGET_64BIT"
1452   "push{q}\t%q1"
1453   [(set_attr "type" "push")
1454    (set_attr "mode" "QI")])
1455
1456 ;; Situation is quite tricky about when to choose full sized (SImode) move
1457 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1458 ;; partial register dependency machines (such as AMD Athlon), where QImode
1459 ;; moves issue extra dependency and for partial register stalls machines
1460 ;; that don't use QImode patterns (and QImode move cause stall on the next
1461 ;; instruction).
1462 ;;
1463 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1464 ;; register stall machines with, where we use QImode instructions, since
1465 ;; partial register stall can be caused there.  Then we use movzx.
1466 (define_insn "*movqi_1"
1467   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1468         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1469   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1470 {
1471   switch (get_attr_type (insn))
1472     {
1473     case TYPE_IMOVX:
1474       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1475       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1476     default:
1477       if (get_attr_mode (insn) == MODE_SI)
1478         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1479       else
1480         return "mov{b}\t{%1, %0|%0, %1}";
1481     }
1482 }
1483   [(set (attr "type")
1484      (cond [(eq_attr "alternative" "5")
1485               (const_string "imovx")
1486             (ne (symbol_ref "optimize_size") (const_int 0))
1487               (const_string "imov")
1488             (and (eq_attr "alternative" "3")
1489                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1490                           (const_int 0))
1491                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1492                           (const_int 0))))
1493               (const_string "imov")
1494             (eq_attr "alternative" "3")
1495               (const_string "imovx")
1496             (and (ne (symbol_ref "TARGET_MOVX")
1497                      (const_int 0))
1498                  (eq_attr "alternative" "2"))
1499               (const_string "imovx")
1500            ]
1501            (const_string "imov")))
1502    (set (attr "mode")
1503       (cond [(eq_attr "alternative" "3,4,5")
1504                (const_string "SI")
1505              (eq_attr "alternative" "6")
1506                (const_string "QI")
1507              (eq_attr "type" "imovx")
1508                (const_string "SI")
1509              (and (eq_attr "type" "imov")
1510                   (and (eq_attr "alternative" "0,1")
1511                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1512                            (const_int 0))))
1513                (const_string "SI")
1514              ;; Avoid partial register stalls when not using QImode arithmetic
1515              (and (eq_attr "type" "imov")
1516                   (and (eq_attr "alternative" "0,1")
1517                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518                                 (const_int 0))
1519                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1520                                 (const_int 0)))))
1521                (const_string "SI")
1522            ]
1523            (const_string "QI")))])
1524
1525 (define_expand "reload_outqi"
1526   [(parallel [(match_operand:QI 0 "" "=m")
1527               (match_operand:QI 1 "register_operand" "r")
1528               (match_operand:QI 2 "register_operand" "=&q")])]
1529   ""
1530 {
1531   rtx op0, op1, op2;
1532   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1533
1534   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1535   if (! q_regs_operand (op1, QImode))
1536     {
1537       emit_insn (gen_movqi (op2, op1));
1538       op1 = op2;
1539     }
1540   emit_insn (gen_movqi (op0, op1));
1541   DONE;
1542 })
1543
1544 (define_insn "*swapqi_1"
1545   [(set (match_operand:QI 0 "register_operand" "+r")
1546         (match_operand:QI 1 "register_operand" "+r"))
1547    (set (match_dup 1)
1548         (match_dup 0))]
1549   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1550   "xchg{l}\t%k1, %k0"
1551   [(set_attr "type" "imov")
1552    (set_attr "mode" "SI")
1553    (set_attr "pent_pair" "np")
1554    (set_attr "athlon_decode" "vector")])
1555
1556 (define_insn "*swapqi_2"
1557   [(set (match_operand:QI 0 "register_operand" "+q")
1558         (match_operand:QI 1 "register_operand" "+q"))
1559    (set (match_dup 1)
1560         (match_dup 0))]
1561   "TARGET_PARTIAL_REG_STALL"
1562   "xchg{b}\t%1, %0"
1563   [(set_attr "type" "imov")
1564    (set_attr "mode" "QI")
1565    (set_attr "pent_pair" "np")
1566    (set_attr "athlon_decode" "vector")])
1567
1568 (define_expand "movstrictqi"
1569   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1570         (match_operand:QI 1 "general_operand" ""))]
1571   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1572 {
1573   /* Don't generate memory->memory moves, go through a register.  */
1574   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1575     operands[1] = force_reg (QImode, operands[1]);
1576 })
1577
1578 (define_insn "*movstrictqi_1"
1579   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1580         (match_operand:QI 1 "general_operand" "*qn,m"))]
1581   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1582    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1583   "mov{b}\t{%1, %0|%0, %1}"
1584   [(set_attr "type" "imov")
1585    (set_attr "mode" "QI")])
1586
1587 (define_insn "*movstrictqi_xor"
1588   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1589         (match_operand:QI 1 "const0_operand" "i"))
1590    (clobber (reg:CC FLAGS_REG))]
1591   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1592   "xor{b}\t{%0, %0|%0, %0}"
1593   [(set_attr "type" "alu1")
1594    (set_attr "mode" "QI")
1595    (set_attr "length_immediate" "0")])
1596
1597 (define_insn "*movsi_extv_1"
1598   [(set (match_operand:SI 0 "register_operand" "=R")
1599         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1600                          (const_int 8)
1601                          (const_int 8)))]
1602   ""
1603   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1604   [(set_attr "type" "imovx")
1605    (set_attr "mode" "SI")])
1606
1607 (define_insn "*movhi_extv_1"
1608   [(set (match_operand:HI 0 "register_operand" "=R")
1609         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1610                          (const_int 8)
1611                          (const_int 8)))]
1612   ""
1613   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1614   [(set_attr "type" "imovx")
1615    (set_attr "mode" "SI")])
1616
1617 (define_insn "*movqi_extv_1"
1618   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1619         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1620                          (const_int 8)
1621                          (const_int 8)))]
1622   "!TARGET_64BIT"
1623 {
1624   switch (get_attr_type (insn))
1625     {
1626     case TYPE_IMOVX:
1627       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1628     default:
1629       return "mov{b}\t{%h1, %0|%0, %h1}";
1630     }
1631 }
1632   [(set (attr "type")
1633      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1634                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1635                              (ne (symbol_ref "TARGET_MOVX")
1636                                  (const_int 0))))
1637         (const_string "imovx")
1638         (const_string "imov")))
1639    (set (attr "mode")
1640      (if_then_else (eq_attr "type" "imovx")
1641         (const_string "SI")
1642         (const_string "QI")))])
1643
1644 (define_insn "*movqi_extv_1_rex64"
1645   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1646         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1647                          (const_int 8)
1648                          (const_int 8)))]
1649   "TARGET_64BIT"
1650 {
1651   switch (get_attr_type (insn))
1652     {
1653     case TYPE_IMOVX:
1654       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1655     default:
1656       return "mov{b}\t{%h1, %0|%0, %h1}";
1657     }
1658 }
1659   [(set (attr "type")
1660      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1661                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1662                              (ne (symbol_ref "TARGET_MOVX")
1663                                  (const_int 0))))
1664         (const_string "imovx")
1665         (const_string "imov")))
1666    (set (attr "mode")
1667      (if_then_else (eq_attr "type" "imovx")
1668         (const_string "SI")
1669         (const_string "QI")))])
1670
1671 ;; Stores and loads of ax to arbitrary constant address.
1672 ;; We fake an second form of instruction to force reload to load address
1673 ;; into register when rax is not available
1674 (define_insn "*movabsqi_1_rex64"
1675   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1676         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1677   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1678   "@
1679    movabs{b}\t{%1, %P0|%P0, %1}
1680    mov{b}\t{%1, %a0|%a0, %1}"
1681   [(set_attr "type" "imov")
1682    (set_attr "modrm" "0,*")
1683    (set_attr "length_address" "8,0")
1684    (set_attr "length_immediate" "0,*")
1685    (set_attr "memory" "store")
1686    (set_attr "mode" "QI")])
1687
1688 (define_insn "*movabsqi_2_rex64"
1689   [(set (match_operand:QI 0 "register_operand" "=a,r")
1690         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1691   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1692   "@
1693    movabs{b}\t{%P1, %0|%0, %P1}
1694    mov{b}\t{%a1, %0|%0, %a1}"
1695   [(set_attr "type" "imov")
1696    (set_attr "modrm" "0,*")
1697    (set_attr "length_address" "8,0")
1698    (set_attr "length_immediate" "0")
1699    (set_attr "memory" "load")
1700    (set_attr "mode" "QI")])
1701
1702 (define_insn "*movdi_extzv_1"
1703   [(set (match_operand:DI 0 "register_operand" "=R")
1704         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1705                          (const_int 8)
1706                          (const_int 8)))]
1707   "TARGET_64BIT"
1708   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1709   [(set_attr "type" "imovx")
1710    (set_attr "mode" "DI")])
1711
1712 (define_insn "*movsi_extzv_1"
1713   [(set (match_operand:SI 0 "register_operand" "=R")
1714         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1715                          (const_int 8)
1716                          (const_int 8)))]
1717   ""
1718   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1719   [(set_attr "type" "imovx")
1720    (set_attr "mode" "SI")])
1721
1722 (define_insn "*movqi_extzv_2"
1723   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "!TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1739                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1740                              (ne (symbol_ref "TARGET_MOVX")
1741                                  (const_int 0))))
1742         (const_string "imovx")
1743         (const_string "imov")))
1744    (set (attr "mode")
1745      (if_then_else (eq_attr "type" "imovx")
1746         (const_string "SI")
1747         (const_string "QI")))])
1748
1749 (define_insn "*movqi_extzv_2_rex64"
1750   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1751         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1752                                     (const_int 8)
1753                                     (const_int 8)) 0))]
1754   "TARGET_64BIT"
1755 {
1756   switch (get_attr_type (insn))
1757     {
1758     case TYPE_IMOVX:
1759       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1760     default:
1761       return "mov{b}\t{%h1, %0|%0, %h1}";
1762     }
1763 }
1764   [(set (attr "type")
1765      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1766                         (ne (symbol_ref "TARGET_MOVX")
1767                             (const_int 0)))
1768         (const_string "imovx")
1769         (const_string "imov")))
1770    (set (attr "mode")
1771      (if_then_else (eq_attr "type" "imovx")
1772         (const_string "SI")
1773         (const_string "QI")))])
1774
1775 (define_insn "movsi_insv_1"
1776   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1777                          (const_int 8)
1778                          (const_int 8))
1779         (match_operand:SI 1 "general_operand" "Qmn"))]
1780   "!TARGET_64BIT"
1781   "mov{b}\t{%b1, %h0|%h0, %b1}"
1782   [(set_attr "type" "imov")
1783    (set_attr "mode" "QI")])
1784
1785 (define_insn "movdi_insv_1_rex64"
1786   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1787                          (const_int 8)
1788                          (const_int 8))
1789         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1790   "TARGET_64BIT"
1791   "mov{b}\t{%b1, %h0|%h0, %b1}"
1792   [(set_attr "type" "imov")
1793    (set_attr "mode" "QI")])
1794
1795 (define_insn "*movqi_insv_2"
1796   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1797                          (const_int 8)
1798                          (const_int 8))
1799         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1800                      (const_int 8)))]
1801   ""
1802   "mov{b}\t{%h1, %h0|%h0, %h1}"
1803   [(set_attr "type" "imov")
1804    (set_attr "mode" "QI")])
1805
1806 (define_expand "movdi"
1807   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1808         (match_operand:DI 1 "general_operand" ""))]
1809   ""
1810   "ix86_expand_move (DImode, operands); DONE;")
1811
1812 (define_insn "*pushdi"
1813   [(set (match_operand:DI 0 "push_operand" "=<")
1814         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1815   "!TARGET_64BIT"
1816   "#")
1817
1818 (define_insn "*pushdi2_rex64"
1819   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1820         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1821   "TARGET_64BIT"
1822   "@
1823    push{q}\t%1
1824    #"
1825   [(set_attr "type" "push,multi")
1826    (set_attr "mode" "DI")])
1827
1828 ;; Convert impossible pushes of immediate to existing instructions.
1829 ;; First try to get scratch register and go through it.  In case this
1830 ;; fails, push sign extended lower part first and then overwrite
1831 ;; upper part by 32bit move.
1832 (define_peephole2
1833   [(match_scratch:DI 2 "r")
1834    (set (match_operand:DI 0 "push_operand" "")
1835         (match_operand:DI 1 "immediate_operand" ""))]
1836   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1837    && !x86_64_immediate_operand (operands[1], DImode)"
1838   [(set (match_dup 2) (match_dup 1))
1839    (set (match_dup 0) (match_dup 2))]
1840   "")
1841
1842 ;; We need to define this as both peepholer and splitter for case
1843 ;; peephole2 pass is not run.
1844 ;; "&& 1" is needed to keep it from matching the previous pattern.
1845 (define_peephole2
1846   [(set (match_operand:DI 0 "push_operand" "")
1847         (match_operand:DI 1 "immediate_operand" ""))]
1848   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1849    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1850   [(set (match_dup 0) (match_dup 1))
1851    (set (match_dup 2) (match_dup 3))]
1852   "split_di (operands + 1, 1, operands + 2, operands + 3);
1853    operands[1] = gen_lowpart (DImode, operands[2]);
1854    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1855                                                     GEN_INT (4)));
1856   ")
1857
1858 (define_split
1859   [(set (match_operand:DI 0 "push_operand" "")
1860         (match_operand:DI 1 "immediate_operand" ""))]
1861   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1862                     ? flow2_completed : reload_completed)
1863    && !symbolic_operand (operands[1], DImode)
1864    && !x86_64_immediate_operand (operands[1], DImode)"
1865   [(set (match_dup 0) (match_dup 1))
1866    (set (match_dup 2) (match_dup 3))]
1867   "split_di (operands + 1, 1, operands + 2, operands + 3);
1868    operands[1] = gen_lowpart (DImode, operands[2]);
1869    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1870                                                     GEN_INT (4)));
1871   ")
1872
1873 (define_insn "*pushdi2_prologue_rex64"
1874   [(set (match_operand:DI 0 "push_operand" "=<")
1875         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1876    (clobber (mem:BLK (scratch)))]
1877   "TARGET_64BIT"
1878   "push{q}\t%1"
1879   [(set_attr "type" "push")
1880    (set_attr "mode" "DI")])
1881
1882 (define_insn "*popdi1_epilogue_rex64"
1883   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1884         (mem:DI (reg:DI SP_REG)))
1885    (set (reg:DI SP_REG)
1886         (plus:DI (reg:DI SP_REG) (const_int 8)))
1887    (clobber (mem:BLK (scratch)))]
1888   "TARGET_64BIT"
1889   "pop{q}\t%0"
1890   [(set_attr "type" "pop")
1891    (set_attr "mode" "DI")])
1892
1893 (define_insn "popdi1"
1894   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1895         (mem:DI (reg:DI SP_REG)))
1896    (set (reg:DI SP_REG)
1897         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1898   "TARGET_64BIT"
1899   "pop{q}\t%0"
1900   [(set_attr "type" "pop")
1901    (set_attr "mode" "DI")])
1902
1903 (define_insn "*movdi_xor_rex64"
1904   [(set (match_operand:DI 0 "register_operand" "=r")
1905         (match_operand:DI 1 "const0_operand" "i"))
1906    (clobber (reg:CC FLAGS_REG))]
1907   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1908    && reload_completed"
1909   "xor{l}\t{%k0, %k0|%k0, %k0}"
1910   [(set_attr "type" "alu1")
1911    (set_attr "mode" "SI")
1912    (set_attr "length_immediate" "0")])
1913
1914 (define_insn "*movdi_or_rex64"
1915   [(set (match_operand:DI 0 "register_operand" "=r")
1916         (match_operand:DI 1 "const_int_operand" "i"))
1917    (clobber (reg:CC FLAGS_REG))]
1918   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1919    && reload_completed
1920    && operands[1] == constm1_rtx"
1921 {
1922   operands[1] = constm1_rtx;
1923   return "or{q}\t{%1, %0|%0, %1}";
1924 }
1925   [(set_attr "type" "alu1")
1926    (set_attr "mode" "DI")
1927    (set_attr "length_immediate" "1")])
1928
1929 (define_insn "*movdi_2"
1930   [(set (match_operand:DI 0 "nonimmediate_operand"
1931                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1932         (match_operand:DI 1 "general_operand"
1933                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1934   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935   "@
1936    #
1937    #
1938    pxor\t%0, %0
1939    movq\t{%1, %0|%0, %1}
1940    movq\t{%1, %0|%0, %1}
1941    pxor\t%0, %0
1942    movq\t{%1, %0|%0, %1}
1943    movdqa\t{%1, %0|%0, %1}
1944    movq\t{%1, %0|%0, %1}
1945    xorps\t%0, %0
1946    movlps\t{%1, %0|%0, %1}
1947    movaps\t{%1, %0|%0, %1}
1948    movlps\t{%1, %0|%0, %1}"
1949   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1950    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1951
1952 (define_split
1953   [(set (match_operand:DI 0 "push_operand" "")
1954         (match_operand:DI 1 "general_operand" ""))]
1955   "!TARGET_64BIT && reload_completed
1956    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1957   [(const_int 0)]
1958   "ix86_split_long_move (operands); DONE;")
1959
1960 ;; %%% This multiword shite has got to go.
1961 (define_split
1962   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1963         (match_operand:DI 1 "general_operand" ""))]
1964   "!TARGET_64BIT && reload_completed
1965    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1966    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1967   [(const_int 0)]
1968   "ix86_split_long_move (operands); DONE;")
1969
1970 (define_insn "*movdi_1_rex64"
1971   [(set (match_operand:DI 0 "nonimmediate_operand"
1972                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1973         (match_operand:DI 1 "general_operand"
1974                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1975   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1976 {
1977   switch (get_attr_type (insn))
1978     {
1979     case TYPE_SSECVT:
1980       if (which_alternative == 13)
1981         return "movq2dq\t{%1, %0|%0, %1}";
1982       else
1983         return "movdq2q\t{%1, %0|%0, %1}";
1984     case TYPE_SSEMOV:
1985       if (get_attr_mode (insn) == MODE_TI)
1986           return "movdqa\t{%1, %0|%0, %1}";
1987       /* FALLTHRU */
1988     case TYPE_MMXMOV:
1989       /* Moves from and into integer register is done using movd opcode with
1990          REX prefix.  */
1991       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992           return "movd\t{%1, %0|%0, %1}";
1993       return "movq\t{%1, %0|%0, %1}";
1994     case TYPE_SSELOG1:
1995     case TYPE_MMXADD:
1996       return "pxor\t%0, %0";
1997     case TYPE_MULTI:
1998       return "#";
1999     case TYPE_LEA:
2000       return "lea{q}\t{%a1, %0|%0, %a1}";
2001     default:
2002       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2003       if (get_attr_mode (insn) == MODE_SI)
2004         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005       else if (which_alternative == 2)
2006         return "movabs{q}\t{%1, %0|%0, %1}";
2007       else
2008         return "mov{q}\t{%1, %0|%0, %1}";
2009     }
2010 }
2011   [(set (attr "type")
2012      (cond [(eq_attr "alternative" "5")
2013               (const_string "mmxadd")
2014             (eq_attr "alternative" "6,7,8")
2015               (const_string "mmxmov")
2016             (eq_attr "alternative" "9")
2017               (const_string "sselog1")
2018             (eq_attr "alternative" "10,11,12")
2019               (const_string "ssemov")
2020             (eq_attr "alternative" "13,14")
2021               (const_string "ssecvt")
2022             (eq_attr "alternative" "4")
2023               (const_string "multi")
2024             (match_operand:DI 1 "pic_32bit_operand" "")
2025               (const_string "lea")
2026            ]
2027            (const_string "imov")))
2028    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2029    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2030    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2031
2032 ;; Stores and loads of ax to arbitrary constant address.
2033 ;; We fake an second form of instruction to force reload to load address
2034 ;; into register when rax is not available
2035 (define_insn "*movabsdi_1_rex64"
2036   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2037         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2038   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2039   "@
2040    movabs{q}\t{%1, %P0|%P0, %1}
2041    mov{q}\t{%1, %a0|%a0, %1}"
2042   [(set_attr "type" "imov")
2043    (set_attr "modrm" "0,*")
2044    (set_attr "length_address" "8,0")
2045    (set_attr "length_immediate" "0,*")
2046    (set_attr "memory" "store")
2047    (set_attr "mode" "DI")])
2048
2049 (define_insn "*movabsdi_2_rex64"
2050   [(set (match_operand:DI 0 "register_operand" "=a,r")
2051         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2052   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2053   "@
2054    movabs{q}\t{%P1, %0|%0, %P1}
2055    mov{q}\t{%a1, %0|%0, %a1}"
2056   [(set_attr "type" "imov")
2057    (set_attr "modrm" "0,*")
2058    (set_attr "length_address" "8,0")
2059    (set_attr "length_immediate" "0")
2060    (set_attr "memory" "load")
2061    (set_attr "mode" "DI")])
2062
2063 ;; Convert impossible stores of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it.  In case this
2065 ;; fails, move by 32bit parts.
2066 (define_peephole2
2067   [(match_scratch:DI 2 "r")
2068    (set (match_operand:DI 0 "memory_operand" "")
2069         (match_operand:DI 1 "immediate_operand" ""))]
2070   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode)"
2072   [(set (match_dup 2) (match_dup 1))
2073    (set (match_dup 0) (match_dup 2))]
2074   "")
2075
2076 ;; We need to define this as both peepholer and splitter for case
2077 ;; peephole2 pass is not run.
2078 ;; "&& 1" is needed to keep it from matching the previous pattern.
2079 (define_peephole2
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2084   [(set (match_dup 2) (match_dup 3))
2085    (set (match_dup 4) (match_dup 5))]
2086   "split_di (operands, 2, operands + 2, operands + 4);")
2087
2088 (define_split
2089   [(set (match_operand:DI 0 "memory_operand" "")
2090         (match_operand:DI 1 "immediate_operand" ""))]
2091   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2092                     ? flow2_completed : reload_completed)
2093    && !symbolic_operand (operands[1], DImode)
2094    && !x86_64_immediate_operand (operands[1], DImode)"
2095   [(set (match_dup 2) (match_dup 3))
2096    (set (match_dup 4) (match_dup 5))]
2097   "split_di (operands, 2, operands + 2, operands + 4);")
2098
2099 (define_insn "*swapdi_rex64"
2100   [(set (match_operand:DI 0 "register_operand" "+r")
2101         (match_operand:DI 1 "register_operand" "+r"))
2102    (set (match_dup 1)
2103         (match_dup 0))]
2104   "TARGET_64BIT"
2105   "xchg{q}\t%1, %0"
2106   [(set_attr "type" "imov")
2107    (set_attr "mode" "DI")
2108    (set_attr "pent_pair" "np")
2109    (set_attr "athlon_decode" "vector")])
2110
2111 (define_expand "movti"
2112   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2113         (match_operand:TI 1 "nonimmediate_operand" ""))]
2114   "TARGET_SSE || TARGET_64BIT"
2115 {
2116   if (TARGET_64BIT)
2117     ix86_expand_move (TImode, operands);
2118   else
2119     ix86_expand_vector_move (TImode, operands);
2120   DONE;
2121 })
2122
2123 (define_insn "*movti_internal"
2124   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2125         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2126   "TARGET_SSE && !TARGET_64BIT
2127    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2128 {
2129   switch (which_alternative)
2130     {
2131     case 0:
2132       if (get_attr_mode (insn) == MODE_V4SF)
2133         return "xorps\t%0, %0";
2134       else
2135         return "pxor\t%0, %0";
2136     case 1:
2137     case 2:
2138       if (get_attr_mode (insn) == MODE_V4SF)
2139         return "movaps\t{%1, %0|%0, %1}";
2140       else
2141         return "movdqa\t{%1, %0|%0, %1}";
2142     default:
2143       gcc_unreachable ();
2144     }
2145 }
2146   [(set_attr "type" "ssemov,ssemov,ssemov")
2147    (set (attr "mode")
2148         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2149                  (const_string "V4SF")
2150
2151                (eq_attr "alternative" "0,1")
2152                  (if_then_else
2153                    (ne (symbol_ref "optimize_size")
2154                        (const_int 0))
2155                    (const_string "V4SF")
2156                    (const_string "TI"))
2157                (eq_attr "alternative" "2")
2158                  (if_then_else
2159                    (ne (symbol_ref "optimize_size")
2160                        (const_int 0))
2161                    (const_string "V4SF")
2162                    (const_string "TI"))]
2163                (const_string "TI")))])
2164
2165 (define_insn "*movti_rex64"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168   "TARGET_64BIT
2169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 {
2171   switch (which_alternative)
2172     {
2173     case 0:
2174     case 1:
2175       return "#";
2176     case 2:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "xorps\t%0, %0";
2179       else
2180         return "pxor\t%0, %0";
2181     case 3:
2182     case 4:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "movaps\t{%1, %0|%0, %1}";
2185       else
2186         return "movdqa\t{%1, %0|%0, %1}";
2187     default:
2188       gcc_unreachable ();
2189     }
2190 }
2191   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2192    (set (attr "mode")
2193         (cond [(eq_attr "alternative" "2,3")
2194                  (if_then_else
2195                    (ne (symbol_ref "optimize_size")
2196                        (const_int 0))
2197                    (const_string "V4SF")
2198                    (const_string "TI"))
2199                (eq_attr "alternative" "4")
2200                  (if_then_else
2201                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202                             (const_int 0))
2203                         (ne (symbol_ref "optimize_size")
2204                             (const_int 0)))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))]
2207                (const_string "DI")))])
2208
2209 (define_split
2210   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211         (match_operand:TI 1 "general_operand" ""))]
2212   "reload_completed && !SSE_REG_P (operands[0])
2213    && !SSE_REG_P (operands[1])"
2214   [(const_int 0)]
2215   "ix86_split_long_move (operands); DONE;")
2216
2217 (define_expand "movsf"
2218   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219         (match_operand:SF 1 "general_operand" ""))]
2220   ""
2221   "ix86_expand_move (SFmode, operands); DONE;")
2222
2223 (define_insn "*pushsf"
2224   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2226   "!TARGET_64BIT"
2227 {
2228   /* Anything else should be already split before reg-stack.  */
2229   gcc_assert (which_alternative == 1);
2230   return "push{l}\t%1";
2231 }
2232   [(set_attr "type" "multi,push,multi")
2233    (set_attr "unit" "i387,*,*")
2234    (set_attr "mode" "SF,SI,SF")])
2235
2236 (define_insn "*pushsf_rex64"
2237   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2239   "TARGET_64BIT"
2240 {
2241   /* Anything else should be already split before reg-stack.  */
2242   gcc_assert (which_alternative == 1);
2243   return "push{q}\t%q1";
2244 }
2245   [(set_attr "type" "multi,push,multi")
2246    (set_attr "unit" "i387,*,*")
2247    (set_attr "mode" "SF,DI,SF")])
2248
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "memory_operand" ""))]
2252   "reload_completed
2253    && GET_CODE (operands[1]) == MEM
2254    && constant_pool_reference_p (operands[1])"
2255   [(set (match_dup 0)
2256         (match_dup 1))]
2257   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258
2259
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "!TARGET_64BIT"
2265   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267
2268 (define_split
2269   [(set (match_operand:SF 0 "push_operand" "")
2270         (match_operand:SF 1 "any_fp_register_operand" ""))]
2271   "TARGET_64BIT"
2272   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274
2275 (define_insn "*movsf_1"
2276   [(set (match_operand:SF 0 "nonimmediate_operand"
2277           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2278         (match_operand:SF 1 "general_operand"
2279           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281    && (reload_in_progress || reload_completed
2282        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283        || GET_CODE (operands[1]) != CONST_DOUBLE
2284        || memory_operand (operands[0], SFmode))" 
2285 {
2286   switch (which_alternative)
2287     {
2288     case 0:
2289       return output_387_reg_move (insn, operands);
2290
2291     case 1:
2292       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293         return "fstp%z0\t%y0";
2294       else
2295         return "fst%z0\t%y0";
2296
2297     case 2:
2298       return standard_80387_constant_opcode (operands[1]);
2299
2300     case 3:
2301     case 4:
2302       return "mov{l}\t{%1, %0|%0, %1}";
2303     case 5:
2304       if (get_attr_mode (insn) == MODE_TI)
2305         return "pxor\t%0, %0";
2306       else
2307         return "xorps\t%0, %0";
2308     case 6:
2309       if (get_attr_mode (insn) == MODE_V4SF)
2310         return "movaps\t{%1, %0|%0, %1}";
2311       else
2312         return "movss\t{%1, %0|%0, %1}";
2313     case 7:
2314     case 8:
2315       return "movss\t{%1, %0|%0, %1}";
2316
2317     case 9:
2318     case 10:
2319       return "movd\t{%1, %0|%0, %1}";
2320
2321     case 11:
2322       return "movq\t{%1, %0|%0, %1}";
2323
2324     default:
2325       gcc_unreachable ();
2326     }
2327 }
2328   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329    (set (attr "mode")
2330         (cond [(eq_attr "alternative" "3,4,9,10")
2331                  (const_string "SI")
2332                (eq_attr "alternative" "5")
2333                  (if_then_else
2334                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335                                  (const_int 0))
2336                              (ne (symbol_ref "TARGET_SSE2")
2337                                  (const_int 0)))
2338                         (eq (symbol_ref "optimize_size")
2339                             (const_int 0)))
2340                    (const_string "TI")
2341                    (const_string "V4SF"))
2342                /* For architectures resolving dependencies on
2343                   whole SSE registers use APS move to break dependency
2344                   chains, otherwise use short move to avoid extra work. 
2345
2346                   Do the same for architectures resolving dependencies on
2347                   the parts.  While in DF mode it is better to always handle
2348                   just register parts, the SF mode is different due to lack
2349                   of instructions to load just part of the register.  It is
2350                   better to maintain the whole registers in single format
2351                   to avoid problems on using packed logical operations.  */
2352                (eq_attr "alternative" "6")
2353                  (if_then_else
2354                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355                             (const_int 0))
2356                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357                             (const_int 0)))
2358                    (const_string "V4SF")
2359                    (const_string "SF"))
2360                (eq_attr "alternative" "11")
2361                  (const_string "DI")]
2362                (const_string "SF")))])
2363
2364 (define_insn "*swapsf"
2365   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366         (match_operand:SF 1 "fp_register_operand" "+f"))
2367    (set (match_dup 1)
2368         (match_dup 0))]
2369   "reload_completed || TARGET_80387"
2370 {
2371   if (STACK_TOP_P (operands[0]))
2372     return "fxch\t%1";
2373   else
2374     return "fxch\t%0";
2375 }
2376   [(set_attr "type" "fxch")
2377    (set_attr "mode" "SF")])
2378
2379 (define_expand "movdf"
2380   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381         (match_operand:DF 1 "general_operand" ""))]
2382   ""
2383   "ix86_expand_move (DFmode, operands); DONE;")
2384
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter.  Allow this
2388 ;; pattern for optimize_size too.
2389
2390 (define_insn "*pushdf_nointeger"
2391   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2393   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 {
2395   /* This insn should be already split before reg-stack.  */
2396   gcc_unreachable ();
2397 }
2398   [(set_attr "type" "multi")
2399    (set_attr "unit" "i387,*,*,*")
2400    (set_attr "mode" "DF,SI,SI,DF")])
2401
2402 (define_insn "*pushdf_integer"
2403   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2405   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 {
2407   /* This insn should be already split before reg-stack.  */
2408   gcc_unreachable ();
2409 }
2410   [(set_attr "type" "multi")
2411    (set_attr "unit" "i387,*,*")
2412    (set_attr "mode" "DF,SI,DF")])
2413
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416   [(set (match_operand:DF 0 "push_operand" "")
2417         (match_operand:DF 1 "any_fp_register_operand" ""))]
2418   "!TARGET_64BIT && reload_completed"
2419   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421   "")
2422
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "TARGET_64BIT && reload_completed"
2427   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429   "")
2430
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "general_operand" ""))]
2434   "reload_completed"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2437
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2441
2442 (define_insn "*movdf_nointeger"
2443   [(set (match_operand:DF 0 "nonimmediate_operand"
2444                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2445         (match_operand:DF 1 "general_operand"
2446                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2447   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449    && (reload_in_progress || reload_completed
2450        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451        || GET_CODE (operands[1]) != CONST_DOUBLE
2452        || memory_operand (operands[0], DFmode))" 
2453 {
2454   switch (which_alternative)
2455     {
2456     case 0:
2457       return output_387_reg_move (insn, operands);
2458
2459     case 1:
2460       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461         return "fstp%z0\t%y0";
2462       else
2463         return "fst%z0\t%y0";
2464
2465     case 2:
2466       return standard_80387_constant_opcode (operands[1]);
2467
2468     case 3:
2469     case 4:
2470       return "#";
2471     case 5:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "xorps\t%0, %0";
2476         case MODE_V2DF:
2477           return "xorpd\t%0, %0";
2478         case MODE_TI:
2479           return "pxor\t%0, %0";
2480         default:
2481           gcc_unreachable ();
2482         }
2483     case 6:
2484     case 7:
2485     case 8:
2486       switch (get_attr_mode (insn))
2487         {
2488         case MODE_V4SF:
2489           return "movaps\t{%1, %0|%0, %1}";
2490         case MODE_V2DF:
2491           return "movapd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "movdqa\t{%1, %0|%0, %1}";
2494         case MODE_DI:
2495           return "movq\t{%1, %0|%0, %1}";
2496         case MODE_DF:
2497           return "movsd\t{%1, %0|%0, %1}";
2498         case MODE_V1DF:
2499           return "movlpd\t{%1, %0|%0, %1}";
2500         case MODE_V2SF:
2501           return "movlps\t{%1, %0|%0, %1}";
2502         default:
2503           gcc_unreachable ();
2504         }
2505
2506     default:
2507       gcc_unreachable ();
2508     }
2509 }
2510   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2511    (set (attr "mode")
2512         (cond [(eq_attr "alternative" "0,1,2")
2513                  (const_string "DF")
2514                (eq_attr "alternative" "3,4")
2515                  (const_string "SI")
2516
2517                /* For SSE1, we have many fewer alternatives.  */
2518                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519                  (cond [(eq_attr "alternative" "5,6")
2520                           (const_string "V4SF")
2521                        ]
2522                    (const_string "V2SF"))
2523
2524                /* xorps is one byte shorter.  */
2525                (eq_attr "alternative" "5")
2526                  (cond [(ne (symbol_ref "optimize_size")
2527                             (const_int 0))
2528                           (const_string "V4SF")
2529                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530                             (const_int 0))
2531                           (const_string "TI")
2532                        ]
2533                        (const_string "V2DF"))
2534
2535                /* For architectures resolving dependencies on
2536                   whole SSE registers use APD move to break dependency
2537                   chains, otherwise use short move to avoid extra work.
2538
2539                   movaps encodes one byte shorter.  */
2540                (eq_attr "alternative" "6")
2541                  (cond
2542                    [(ne (symbol_ref "optimize_size")
2543                         (const_int 0))
2544                       (const_string "V4SF")
2545                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546                         (const_int 0))
2547                       (const_string "V2DF")
2548                    ]
2549                    (const_string "DF"))
2550                /* For architectures resolving dependencies on register
2551                   parts we may avoid extra work to zero out upper part
2552                   of register.  */
2553                (eq_attr "alternative" "7")
2554                  (if_then_else
2555                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556                        (const_int 0))
2557                    (const_string "V1DF")
2558                    (const_string "DF"))
2559               ]
2560               (const_string "DF")))])
2561
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand"
2564                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2565         (match_operand:DF 1 "general_operand"
2566                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2567   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569    && (reload_in_progress || reload_completed
2570        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571        || GET_CODE (operands[1]) != CONST_DOUBLE
2572        || memory_operand (operands[0], DFmode))" 
2573 {
2574   switch (which_alternative)
2575     {
2576     case 0:
2577       return output_387_reg_move (insn, operands);
2578
2579     case 1:
2580       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581         return "fstp%z0\t%y0";
2582       else
2583         return "fst%z0\t%y0";
2584
2585     case 2:
2586       return standard_80387_constant_opcode (operands[1]);
2587
2588     case 3:
2589     case 4:
2590       return "#";
2591
2592     case 5:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "xorps\t%0, %0";
2597         case MODE_V2DF:
2598           return "xorpd\t%0, %0";
2599         case MODE_TI:
2600           return "pxor\t%0, %0";
2601         default:
2602           gcc_unreachable ();
2603         }
2604     case 6:
2605     case 7:
2606     case 8:
2607       switch (get_attr_mode (insn))
2608         {
2609         case MODE_V4SF:
2610           return "movaps\t{%1, %0|%0, %1}";
2611         case MODE_V2DF:
2612           return "movapd\t{%1, %0|%0, %1}";
2613         case MODE_TI:
2614           return "movdqa\t{%1, %0|%0, %1}";
2615         case MODE_DI:
2616           return "movq\t{%1, %0|%0, %1}";
2617         case MODE_DF:
2618           return "movsd\t{%1, %0|%0, %1}";
2619         case MODE_V1DF:
2620           return "movlpd\t{%1, %0|%0, %1}";
2621         case MODE_V2SF:
2622           return "movlps\t{%1, %0|%0, %1}";
2623         default:
2624           gcc_unreachable ();
2625         }
2626
2627     default:
2628       gcc_unreachable();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "0,1,2")
2634                  (const_string "DF")
2635                (eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2637
2638                /* For SSE1, we have many fewer alternatives.  */
2639                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640                  (cond [(eq_attr "alternative" "5,6")
2641                           (const_string "V4SF")
2642                        ]
2643                    (const_string "V2SF"))
2644
2645                /* xorps is one byte shorter.  */
2646                (eq_attr "alternative" "5")
2647                  (cond [(ne (symbol_ref "optimize_size")
2648                             (const_int 0))
2649                           (const_string "V4SF")
2650                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                             (const_int 0))
2652                           (const_string "TI")
2653                        ]
2654                        (const_string "V2DF"))
2655
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.
2659
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                    [(ne (symbol_ref "optimize_size")
2664                         (const_int 0))
2665                       (const_string "V4SF")
2666                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                         (const_int 0))
2668                       (const_string "V2DF")
2669                    ]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                        (const_int 0))
2678                    (const_string "V1DF")
2679                    (const_string "DF"))
2680               ]
2681               (const_string "DF")))])
2682
2683 (define_split
2684   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685         (match_operand:DF 1 "general_operand" ""))]
2686   "reload_completed
2687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688    && ! (ANY_FP_REG_P (operands[0]) || 
2689          (GET_CODE (operands[0]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691    && ! (ANY_FP_REG_P (operands[1]) || 
2692          (GET_CODE (operands[1]) == SUBREG
2693           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2696
2697 (define_insn "*swapdf"
2698   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699         (match_operand:DF 1 "fp_register_operand" "+f"))
2700    (set (match_dup 1)
2701         (match_dup 0))]
2702   "reload_completed || TARGET_80387"
2703 {
2704   if (STACK_TOP_P (operands[0]))
2705     return "fxch\t%1";
2706   else
2707     return "fxch\t%0";
2708 }
2709   [(set_attr "type" "fxch")
2710    (set_attr "mode" "DF")])
2711
2712 (define_expand "movxf"
2713   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714         (match_operand:XF 1 "general_operand" ""))]
2715   ""
2716   "ix86_expand_move (XFmode, operands); DONE;")
2717
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;;  handled elsewhere).
2724
2725 (define_insn "*pushxf_nointeger"
2726   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728   "optimize_size"
2729 {
2730   /* This insn should be already split before reg-stack.  */
2731   gcc_unreachable ();
2732 }
2733   [(set_attr "type" "multi")
2734    (set_attr "unit" "i387,*,*")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2784 {
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       return output_387_reg_move (insn, operands);
2789
2790     case 1:
2791       /* There is no non-popping store to memory for XFmode.  So if
2792          we need one, follow the store with a load.  */
2793       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794         return "fstp%z0\t%y0\;fld%z0\t%y0";
2795       else
2796         return "fstp%z0\t%y0";
2797
2798     case 2:
2799       return standard_80387_constant_opcode (operands[1]);
2800
2801     case 3: case 4:
2802       return "#";
2803     default:
2804       gcc_unreachable ();
2805     }
2806 }
2807   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808    (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810 (define_insn "*movxf_integer"
2811   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2812         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2813   "!optimize_size
2814    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815    && (reload_in_progress || reload_completed
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], XFmode))" 
2818 {
2819   switch (which_alternative)
2820     {
2821     case 0:
2822       return output_387_reg_move (insn, operands);
2823
2824     case 1:
2825       /* There is no non-popping store to memory for XFmode.  So if
2826          we need one, follow the store with a load.  */
2827       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828         return "fstp%z0\t%y0\;fld%z0\t%y0";
2829       else
2830         return "fstp%z0\t%y0";
2831
2832     case 2:
2833       return standard_80387_constant_opcode (operands[1]);
2834
2835     case 3: case 4:
2836       return "#";
2837
2838     default:
2839       gcc_unreachable ();
2840     }
2841 }
2842   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843    (set_attr "mode" "XF,XF,XF,SI,SI")])
2844
2845 (define_split
2846   [(set (match_operand 0 "nonimmediate_operand" "")
2847         (match_operand 1 "general_operand" ""))]
2848   "reload_completed
2849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850    && GET_MODE (operands[0]) == XFmode
2851    && ! (ANY_FP_REG_P (operands[0]) || 
2852          (GET_CODE (operands[0]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854    && ! (ANY_FP_REG_P (operands[1]) || 
2855          (GET_CODE (operands[1]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857   [(const_int 0)]
2858   "ix86_split_long_move (operands); DONE;")
2859
2860 (define_split
2861   [(set (match_operand 0 "register_operand" "")
2862         (match_operand 1 "memory_operand" ""))]
2863   "reload_completed
2864    && GET_CODE (operands[1]) == MEM
2865    && (GET_MODE (operands[0]) == XFmode
2866        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867    && constant_pool_reference_p (operands[1])"
2868   [(set (match_dup 0) (match_dup 1))]
2869 {
2870   rtx c = avoid_constant_pool_reference (operands[1]);
2871   rtx r = operands[0];
2872
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2875
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2888
2889   operands[1] = c;
2890 })
2891
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2898 {
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2903 }
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2906
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2911 {
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2914 })
2915
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 {
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2941 }
2942   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2959
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2967 \f
2968 ;; Zero extension instructions
2969
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2974 {
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2981 })
2982
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2991
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3000
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3008
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3016
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3025
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3034
3035 (define_insn "*zero_extendqihi2_movzbw"
3036   [(set (match_operand:HI 0 "register_operand" "=r")
3037      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039   "movz{bw|x}\t{%1, %0|%0, %1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "HI")])
3042
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed 
3049    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && ANY_QI_REG_P (operands[0])
3062    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064   [(set (match_dup 0) (const_int 0))
3065    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066   "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
3068 ;; Rest is handled by single and.
3069 (define_split
3070   [(set (match_operand:HI 0 "register_operand" "")
3071         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "reload_completed
3074    && true_regnum (operands[0]) == true_regnum (operands[1])"
3075   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076               (clobber (reg:CC FLAGS_REG))])]
3077   "")
3078
3079 (define_expand "zero_extendqisi2"
3080   [(parallel
3081     [(set (match_operand:SI 0 "register_operand" "")
3082        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083      (clobber (reg:CC FLAGS_REG))])]
3084   ""
3085   "")
3086
3087 (define_insn "*zero_extendqisi2_and"
3088   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092   "#"
3093   [(set_attr "type" "alu1")
3094    (set_attr "mode" "SI")])
3095
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,r")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101   "#"
3102   [(set_attr "type" "imovx,alu1")
3103    (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw"
3106   [(set (match_operand:SI 0 "register_operand" "=r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109   "movz{bl|x}\t{%1, %0|%0, %1}"
3110   [(set_attr "type" "imovx")
3111    (set_attr "mode" "SI")])
3112
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115   [(set (match_operand:SI 0 "register_operand" "")
3116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117    (clobber (reg:CC FLAGS_REG))]
3118   "reload_completed 
3119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121   [(set (match_dup 0)
3122         (zero_extend:SI (match_dup 1)))])
3123
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127   [(set (match_operand:SI 0 "register_operand" "")
3128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129    (clobber (reg:CC FLAGS_REG))]
3130   "reload_completed
3131    && ANY_QI_REG_P (operands[0])
3132    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135   [(set (match_dup 0) (const_int 0))
3136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137   "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
3139 ;; Rest is handled by single and.
3140 (define_split
3141   [(set (match_operand:SI 0 "register_operand" "")
3142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143    (clobber (reg:CC FLAGS_REG))]
3144   "reload_completed
3145    && true_regnum (operands[0]) == true_regnum (operands[1])"
3146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147               (clobber (reg:CC FLAGS_REG))])]
3148   "")
3149
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152   [(set (match_operand:DI 0 "register_operand" "=r")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154   ""
3155   "if (!TARGET_64BIT)
3156      {
3157        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158        DONE;
3159      }
3160   ")
3161
3162 (define_insn "zero_extendsidi2_32"
3163   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165    (clobber (reg:CC FLAGS_REG))]
3166   "!TARGET_64BIT"
3167   "@
3168    #
3169    #
3170    #
3171    movd\t{%1, %0|%0, %1}
3172    movd\t{%1, %0|%0, %1}"
3173   [(set_attr "mode" "SI,SI,SI,DI,TI")
3174    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
3176 (define_insn "zero_extendsidi2_rex64"
3177   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179   "TARGET_64BIT"
3180   "@
3181    mov\t{%k1, %k0|%k0, %k1}
3182    #
3183    movd\t{%1, %0|%0, %1}
3184    movd\t{%1, %0|%0, %1}"
3185   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186    (set_attr "mode" "SI,DI,SI,SI")])
3187
3188 (define_split
3189   [(set (match_operand:DI 0 "memory_operand" "")
3190      (zero_extend:DI (match_dup 0)))]
3191   "TARGET_64BIT"
3192   [(set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_split 
3196   [(set (match_operand:DI 0 "register_operand" "")
3197         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198    (clobber (reg:CC FLAGS_REG))]
3199   "!TARGET_64BIT && reload_completed
3200    && true_regnum (operands[0]) == true_regnum (operands[1])"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split 
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210   [(set (match_dup 3) (match_dup 1))
3211    (set (match_dup 4) (const_int 0))]
3212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
3214 (define_insn "zero_extendhidi2"
3215   [(set (match_operand:DI 0 "register_operand" "=r")
3216      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217   "TARGET_64BIT"
3218   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219   [(set_attr "type" "imovx")
3220    (set_attr "mode" "DI")])
3221
3222 (define_insn "zero_extendqidi2"
3223   [(set (match_operand:DI 0 "register_operand" "=r")
3224      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225   "TARGET_64BIT"
3226   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")])
3229 \f
3230 ;; Sign extension instructions
3231
3232 (define_expand "extendsidi2"
3233   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235               (clobber (reg:CC FLAGS_REG))
3236               (clobber (match_scratch:SI 2 ""))])]
3237   ""
3238 {
3239   if (TARGET_64BIT)
3240     {
3241       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242       DONE;
3243     }
3244 })
3245
3246 (define_insn "*extendsidi2_1"
3247   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249    (clobber (reg:CC FLAGS_REG))
3250    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251   "!TARGET_64BIT"
3252   "#")
3253
3254 (define_insn "extendsidi2_rex64"
3255   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257   "TARGET_64BIT"
3258   "@
3259    {cltq|cdqe}
3260    movs{lq|x}\t{%1,%0|%0, %1}"
3261   [(set_attr "type" "imovx")
3262    (set_attr "mode" "DI")
3263    (set_attr "prefix_0f" "0")
3264    (set_attr "modrm" "0,1")])
3265
3266 (define_insn "extendhidi2"
3267   [(set (match_operand:DI 0 "register_operand" "=r")
3268         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269   "TARGET_64BIT"
3270   "movs{wq|x}\t{%1,%0|%0, %1}"
3271   [(set_attr "type" "imovx")
3272    (set_attr "mode" "DI")])
3273
3274 (define_insn "extendqidi2"
3275   [(set (match_operand:DI 0 "register_operand" "=r")
3276         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277   "TARGET_64BIT"
3278   "movs{bq|x}\t{%1,%0|%0, %1}"
3279    [(set_attr "type" "imovx")
3280     (set_attr "mode" "DI")])
3281
3282 ;; Extend to memory case when source register does die.
3283 (define_split 
3284   [(set (match_operand:DI 0 "memory_operand" "")
3285         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286    (clobber (reg:CC FLAGS_REG))
3287    (clobber (match_operand:SI 2 "register_operand" ""))]
3288   "(reload_completed
3289     && dead_or_set_p (insn, operands[1])
3290     && !reg_mentioned_p (operands[1], operands[0]))"
3291   [(set (match_dup 3) (match_dup 1))
3292    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293               (clobber (reg:CC FLAGS_REG))])
3294    (set (match_dup 4) (match_dup 1))]
3295   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
3297 ;; Extend to memory case when source register does not die.
3298 (define_split 
3299   [(set (match_operand:DI 0 "memory_operand" "")
3300         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301    (clobber (reg:CC FLAGS_REG))
3302    (clobber (match_operand:SI 2 "register_operand" ""))]
3303   "reload_completed"
3304   [(const_int 0)]
3305 {
3306   split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
3308   emit_move_insn (operands[3], operands[1]);
3309
3310   /* Generate a cltd if possible and doing so it profitable.  */
3311   if (true_regnum (operands[1]) == 0
3312       && true_regnum (operands[2]) == 1
3313       && (optimize_size || TARGET_USE_CLTD))
3314     {
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316     }
3317   else
3318     {
3319       emit_move_insn (operands[2], operands[1]);
3320       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321     }
3322   emit_move_insn (operands[4], operands[2]);
3323   DONE;
3324 })
3325
3326 ;; Extend to register case.  Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split 
3329   [(set (match_operand:DI 0 "register_operand" "")
3330         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331    (clobber (reg:CC FLAGS_REG))
3332    (clobber (match_scratch:SI 2 ""))]
3333   "reload_completed"
3334   [(const_int 0)]
3335 {
3336   split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339     emit_move_insn (operands[3], operands[1]);
3340
3341   /* Generate a cltd if possible and doing so it profitable.  */
3342   if (true_regnum (operands[3]) == 0
3343       && (optimize_size || TARGET_USE_CLTD))
3344     {
3345       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346       DONE;
3347     }
3348
3349   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350     emit_move_insn (operands[4], operands[1]);
3351
3352   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353   DONE;
3354 })
3355
3356 (define_insn "extendhisi2"
3357   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359   ""
3360 {
3361   switch (get_attr_prefix_0f (insn))
3362     {
3363     case 0:
3364       return "{cwtl|cwde}";
3365     default:
3366       return "movs{wl|x}\t{%1,%0|%0, %1}";
3367     }
3368 }
3369   [(set_attr "type" "imovx")
3370    (set_attr "mode" "SI")
3371    (set (attr "prefix_0f")
3372      ;; movsx is short decodable while cwtl is vector decoded.
3373      (if_then_else (and (eq_attr "cpu" "!k6")
3374                         (eq_attr "alternative" "0"))
3375         (const_string "0")
3376         (const_string "1")))
3377    (set (attr "modrm")
3378      (if_then_else (eq_attr "prefix_0f" "0")
3379         (const_string "0")
3380         (const_string "1")))])
3381
3382 (define_insn "*extendhisi2_zext"
3383   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384         (zero_extend:DI
3385           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386   "TARGET_64BIT"
3387 {
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cwtl|cwde}";
3392     default:
3393       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394     }
3395 }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "SI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3408
3409 (define_insn "extendqihi2"
3410   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412   ""
3413 {
3414   switch (get_attr_prefix_0f (insn))
3415     {
3416     case 0:
3417       return "{cbtw|cbw}";
3418     default:
3419       return "movs{bw|x}\t{%1,%0|%0, %1}";
3420     }
3421 }
3422   [(set_attr "type" "imovx")
3423    (set_attr "mode" "HI")
3424    (set (attr "prefix_0f")
3425      ;; movsx is short decodable while cwtl is vector decoded.
3426      (if_then_else (and (eq_attr "cpu" "!k6")
3427                         (eq_attr "alternative" "0"))
3428         (const_string "0")
3429         (const_string "1")))
3430    (set (attr "modrm")
3431      (if_then_else (eq_attr "prefix_0f" "0")
3432         (const_string "0")
3433         (const_string "1")))])
3434
3435 (define_insn "extendqisi2"
3436   [(set (match_operand:SI 0 "register_operand" "=r")
3437         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438   ""
3439   "movs{bl|x}\t{%1,%0|%0, %1}"
3440    [(set_attr "type" "imovx")
3441     (set_attr "mode" "SI")])
3442
3443 (define_insn "*extendqisi2_zext"
3444   [(set (match_operand:DI 0 "register_operand" "=r")
3445         (zero_extend:DI
3446           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447   "TARGET_64BIT"
3448   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3451 \f
3452 ;; Conversions between float and double.
3453
3454 ;; These are all no-ops in the model used for the 80387.  So just
3455 ;; emit moves.
3456
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3458 (define_insn "*dummy_extendsfdf2"
3459   [(set (match_operand:DF 0 "push_operand" "=<")
3460         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461   "0"
3462   "#")
3463
3464 (define_split
3465   [(set (match_operand:DF 0 "push_operand" "")
3466         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467   "!TARGET_64BIT"
3468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
3471 (define_split
3472   [(set (match_operand:DF 0 "push_operand" "")
3473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_insn "*dummy_extendsfxf2"
3479   [(set (match_operand:XF 0 "push_operand" "=<")
3480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481   "0"
3482   "#")
3483
3484 (define_split
3485   [(set (match_operand:XF 0 "push_operand" "")
3486         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487   ""
3488   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
3492 (define_split
3493   [(set (match_operand:XF 0 "push_operand" "")
3494         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "TARGET_64BIT"
3496   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
3500 (define_split
3501   [(set (match_operand:XF 0 "push_operand" "")
3502         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503   ""
3504   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 (define_split
3509   [(set (match_operand:XF 0 "push_operand" "")
3510         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511   "TARGET_64BIT"
3512   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
3516 (define_expand "extendsfdf2"
3517   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520 {
3521   /* ??? Needed for compress_float_constant since all fp constants
3522      are LEGITIMATE_CONSTANT_P.  */
3523   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526     operands[1] = force_reg (SFmode, operands[1]);
3527 })
3528
3529 (define_insn "*extendsfdf2_mixed"
3530   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534 {
3535   switch (which_alternative)
3536     {
3537     case 0:
3538       return output_387_reg_move (insn, operands);
3539
3540     case 1:
3541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542         return "fstp%z0\t%y0";
3543       else
3544         return "fst%z0\t%y0";
3545
3546     case 2:
3547       return "cvtss2sd\t{%1, %0|%0, %1}";
3548
3549     default:
3550       gcc_unreachable ();
3551     }
3552 }
3553   [(set_attr "type" "fmov,fmov,ssecvt")
3554    (set_attr "mode" "SF,XF,DF")])
3555
3556 (define_insn "*extendsfdf2_sse"
3557   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559   "TARGET_SSE2 && TARGET_SSE_MATH
3560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561   "cvtss2sd\t{%1, %0|%0, %1}"
3562   [(set_attr "type" "ssecvt")
3563    (set_attr "mode" "DF")])
3564
3565 (define_insn "*extendsfdf2_i387"
3566   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3568   "TARGET_80387
3569    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3570 {
3571   switch (which_alternative)
3572     {
3573     case 0:
3574       return output_387_reg_move (insn, operands);
3575
3576     case 1:
3577       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578         return "fstp%z0\t%y0";
3579       else
3580         return "fst%z0\t%y0";
3581
3582     default:
3583       gcc_unreachable ();
3584     }
3585 }
3586   [(set_attr "type" "fmov")
3587    (set_attr "mode" "SF,XF")])
3588
3589 (define_expand "extendsfxf2"
3590   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3592   "TARGET_80387"
3593 {
3594   /* ??? Needed for compress_float_constant since all fp constants
3595      are LEGITIMATE_CONSTANT_P.  */
3596   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599     operands[1] = force_reg (SFmode, operands[1]);
3600 })
3601
3602 (define_insn "*extendsfxf2_i387"
3603   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605   "TARGET_80387
3606    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3607 {
3608   switch (which_alternative)
3609     {
3610     case 0:
3611       return output_387_reg_move (insn, operands);
3612
3613     case 1:
3614       /* There is no non-popping store to memory for XFmode.  So if
3615          we need one, follow the store with a load.  */
3616       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617         return "fstp%z0\t%y0";
3618       else
3619         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3620
3621     default:
3622       gcc_unreachable ();
3623     }
3624 }
3625   [(set_attr "type" "fmov")
3626    (set_attr "mode" "SF,XF")])
3627
3628 (define_expand "extenddfxf2"
3629   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3631   "TARGET_80387"
3632 {
3633   /* ??? Needed for compress_float_constant since all fp constants
3634      are LEGITIMATE_CONSTANT_P.  */
3635   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638     operands[1] = force_reg (DFmode, operands[1]);
3639 })
3640
3641 (define_insn "*extenddfxf2_i387"
3642   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3644   "TARGET_80387
3645    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3646 {
3647   switch (which_alternative)
3648     {
3649     case 0:
3650       return output_387_reg_move (insn, operands);
3651
3652     case 1:
3653       /* There is no non-popping store to memory for XFmode.  So if
3654          we need one, follow the store with a load.  */
3655       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3657       else
3658         return "fstp%z0\t%y0";
3659
3660     default:
3661       gcc_unreachable ();
3662     }
3663 }
3664   [(set_attr "type" "fmov")
3665    (set_attr "mode" "DF,XF")])
3666
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case.  Otherwise this is just like a simple move
3670 ;; insn.  So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3672
3673 ;; Conversion from DFmode to SFmode.
3674
3675 (define_expand "truncdfsf2"
3676   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3677         (float_truncate:SF
3678           (match_operand:DF 1 "nonimmediate_operand" "")))]
3679   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3680 {
3681   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682     operands[1] = force_reg (DFmode, operands[1]);
3683
3684   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3685     ;
3686   else if (flag_unsafe_math_optimizations)
3687     ;
3688   else
3689     {
3690       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3692       DONE;
3693     }
3694 })
3695
3696 (define_expand "truncdfsf2_with_temp"
3697   [(parallel [(set (match_operand:SF 0 "" "")
3698                    (float_truncate:SF (match_operand:DF 1 "" "")))
3699               (clobber (match_operand:SF 2 "" ""))])]
3700   "")
3701
3702 (define_insn "*truncdfsf_fast_mixed"
3703   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3704         (float_truncate:SF
3705           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3707 {
3708   switch (which_alternative)
3709     {
3710     case 0:
3711       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0";
3713       else
3714         return "fst%z0\t%y0";
3715     case 1:
3716       return output_387_reg_move (insn, operands);
3717     case 2:
3718       return "cvtsd2ss\t{%1, %0|%0, %1}";
3719     default:
3720       gcc_unreachable ();
3721     }
3722 }
3723   [(set_attr "type" "fmov,fmov,ssecvt")
3724    (set_attr "mode" "SF")])
3725
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3730         (float_truncate:SF
3731           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732   "TARGET_SSE2 && TARGET_SSE_MATH"
3733   "cvtsd2ss\t{%1, %0|%0, %1}"
3734   [(set_attr "type" "ssecvt")
3735    (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_fast_i387"
3738   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741   "TARGET_80387 && flag_unsafe_math_optimizations"
3742   "* return output_387_reg_move (insn, operands);"
3743   [(set_attr "type" "fmov")
3744    (set_attr "mode" "SF")])
3745
3746 (define_insn "*truncdfsf_mixed"
3747   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3748         (float_truncate:SF
3749           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3750    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3751   "TARGET_MIX_SSE_I387"
3752 {
3753   switch (which_alternative)
3754     {
3755     case 0:
3756       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757         return "fstp%z0\t%y0";
3758       else
3759         return "fst%z0\t%y0";
3760     case 1:
3761       return "#";
3762     case 2:
3763       return "cvtsd2ss\t{%1, %0|%0, %1}";
3764     default:
3765       gcc_unreachable ();
3766     }
3767 }
3768   [(set_attr "type" "fmov,multi,ssecvt")
3769    (set_attr "unit" "*,i387,*")
3770    (set_attr "mode" "SF")])
3771
3772 (define_insn "*truncdfsf_i387"
3773   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3774         (float_truncate:SF
3775           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3777   "TARGET_80387"
3778 {
3779   switch (which_alternative)
3780     {
3781     case 0:
3782       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783         return "fstp%z0\t%y0";
3784       else
3785         return "fst%z0\t%y0";
3786     case 1:
3787       return "#";
3788     default:
3789       gcc_unreachable ();
3790     }
3791 }
3792   [(set_attr "type" "fmov,multi")
3793    (set_attr "unit" "*,i387")
3794    (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_i387_1"
3797   [(set (match_operand:SF 0 "memory_operand" "=m")
3798         (float_truncate:SF
3799           (match_operand:DF 1 "register_operand" "f")))]
3800   "TARGET_80387
3801    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802    && !TARGET_MIX_SSE_I387"
3803 {
3804   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805     return "fstp%z0\t%y0";
3806   else
3807     return "fst%z0\t%y0";
3808 }
3809   [(set_attr "type" "fmov")
3810    (set_attr "mode" "SF")])
3811
3812 (define_split
3813   [(set (match_operand:SF 0 "register_operand" "")
3814         (float_truncate:SF
3815          (match_operand:DF 1 "fp_register_operand" "")))
3816    (clobber (match_operand 2 "" ""))]
3817   "reload_completed"
3818   [(set (match_dup 2) (match_dup 1))
3819    (set (match_dup 0) (match_dup 2))]
3820 {
3821   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3822 })
3823
3824 ;; Conversion from XFmode to SFmode.
3825
3826 (define_expand "truncxfsf2"
3827   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3828                    (float_truncate:SF
3829                     (match_operand:XF 1 "register_operand" "")))
3830               (clobber (match_dup 2))])]
3831   "TARGET_80387"
3832 {
3833   if (flag_unsafe_math_optimizations)
3834     {
3835       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837       if (reg != operands[0])
3838         emit_move_insn (operands[0], reg);
3839       DONE;
3840     }
3841   else
3842     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3843 })
3844
3845 (define_insn "*truncxfsf2_mixed"
3846   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3847         (float_truncate:SF
3848          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850   "TARGET_MIX_SSE_I387"
3851 {
3852   gcc_assert (!which_alternative);
3853   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854     return "fstp%z0\t%y0";
3855   else
3856     return "fst%z0\t%y0";
3857 }
3858   [(set_attr "type" "fmov,multi,multi,multi")
3859    (set_attr "unit" "*,i387,i387,i387")
3860    (set_attr "mode" "SF")])
3861
3862 (define_insn "truncxfsf2_i387_noop"
3863   [(set (match_operand:SF 0 "register_operand" "=f")
3864         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865   "TARGET_80387 && flag_unsafe_math_optimizations"
3866 {
3867   return output_387_reg_move (insn, operands);
3868 }
3869   [(set_attr "type" "fmov")
3870    (set_attr "mode" "SF")])
3871
3872 (define_insn "*truncxfsf2_i387"
3873   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3874         (float_truncate:SF
3875          (match_operand:XF 1 "register_operand" "f,f,f")))
3876    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3877   "TARGET_80387"
3878 {
3879   gcc_assert (!which_alternative);
3880   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881     return "fstp%z0\t%y0";
3882    else
3883      return "fst%z0\t%y0";
3884 }
3885   [(set_attr "type" "fmov,multi,multi")
3886    (set_attr "unit" "*,i387,i387")
3887    (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncxfsf2_i387_1"
3890   [(set (match_operand:SF 0 "memory_operand" "=m")
3891         (float_truncate:SF
3892          (match_operand:XF 1 "register_operand" "f")))]
3893   "TARGET_80387"
3894 {
3895   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896     return "fstp%z0\t%y0";
3897   else
3898     return "fst%z0\t%y0";
3899 }
3900   [(set_attr "type" "fmov")
3901    (set_attr "mode" "SF")])
3902
3903 (define_split
3904   [(set (match_operand:SF 0 "register_operand" "")
3905         (float_truncate:SF
3906          (match_operand:XF 1 "register_operand" "")))
3907    (clobber (match_operand:SF 2 "memory_operand" ""))]
3908   "TARGET_80387 && reload_completed"
3909   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910    (set (match_dup 0) (match_dup 2))]
3911   "")
3912
3913 (define_split
3914   [(set (match_operand:SF 0 "memory_operand" "")
3915         (float_truncate:SF
3916          (match_operand:XF 1 "register_operand" "")))
3917    (clobber (match_operand:SF 2 "memory_operand" ""))]
3918   "TARGET_80387"
3919   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3920   "")
3921
3922 ;; Conversion from XFmode to DFmode.
3923
3924 (define_expand "truncxfdf2"
3925   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3926                    (float_truncate:DF
3927                     (match_operand:XF 1 "register_operand" "")))
3928               (clobber (match_dup 2))])]
3929   "TARGET_80387"
3930 {
3931   if (flag_unsafe_math_optimizations)
3932     {
3933       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935       if (reg != operands[0])
3936         emit_move_insn (operands[0], reg);
3937       DONE;
3938     }
3939   else
3940     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3941 })
3942
3943 (define_insn "*truncxfdf2_mixed"
3944   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945         (float_truncate:DF
3946          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3949 {
3950   gcc_assert (!which_alternative);
3951   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952     return "fstp%z0\t%y0";
3953   else
3954     return "fst%z0\t%y0";
3955 }
3956   [(set_attr "type" "fmov,multi,multi,multi")
3957    (set_attr "unit" "*,i387,i387,i387")
3958    (set_attr "mode" "DF")])
3959
3960 (define_insn "truncxfdf2_i387_noop"
3961   [(set (match_operand:DF 0 "register_operand" "=f")
3962         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963   "TARGET_80387 && flag_unsafe_math_optimizations"
3964 {
3965   return output_387_reg_move (insn, operands);
3966 }
3967   [(set_attr "type" "fmov")
3968    (set_attr "mode" "DF")])
3969
3970 (define_insn "*truncxfdf2_i387"
3971   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3972         (float_truncate:DF
3973          (match_operand:XF 1 "register_operand" "f,f,f")))
3974    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3975   "TARGET_80387"
3976 {
3977   gcc_assert (!which_alternative);
3978   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979     return "fstp%z0\t%y0";
3980   else
3981     return "fst%z0\t%y0";
3982 }
3983   [(set_attr "type" "fmov,multi,multi")
3984    (set_attr "unit" "*,i387,i387")
3985    (set_attr "mode" "DF")])
3986
3987 (define_insn "*truncxfdf2_i387_1"
3988   [(set (match_operand:DF 0 "memory_operand" "=m")
3989         (float_truncate:DF
3990           (match_operand:XF 1 "register_operand" "f")))]
3991   "TARGET_80387"
3992 {
3993   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994     return "fstp%z0\t%y0";
3995   else
3996     return "fst%z0\t%y0";
3997 }
3998   [(set_attr "type" "fmov")
3999    (set_attr "mode" "DF")])
4000
4001 (define_split
4002   [(set (match_operand:DF 0 "register_operand" "")
4003         (float_truncate:DF
4004          (match_operand:XF 1 "register_operand" "")))
4005    (clobber (match_operand:DF 2 "memory_operand" ""))]
4006   "TARGET_80387 && reload_completed"
4007   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008    (set (match_dup 0) (match_dup 2))]
4009   "")
4010
4011 (define_split
4012   [(set (match_operand:DF 0 "memory_operand" "")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "")))
4015    (clobber (match_operand:DF 2 "memory_operand" ""))]
4016   "TARGET_80387"
4017   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4018   "")
4019 \f
4020 ;; Signed conversion to DImode.
4021
4022 (define_expand "fix_truncxfdi2"
4023   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4025               (clobber (reg:CC FLAGS_REG))])]
4026   "TARGET_80387"
4027 {
4028   if (TARGET_FISTTP)
4029    {
4030      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4031      DONE;
4032    }
4033 })
4034
4035 (define_expand "fix_trunc<mode>di2"
4036   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038               (clobber (reg:CC FLAGS_REG))])]
4039   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4040 {
4041   if (TARGET_FISTTP
4042       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4043    {
4044      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4045      DONE;
4046    }
4047   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4048    {
4049      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051      if (out != operands[0])
4052         emit_move_insn (operands[0], out);
4053      DONE;
4054    }
4055 })
4056
4057 ;; Signed conversion to SImode.
4058
4059 (define_expand "fix_truncxfsi2"
4060   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4062               (clobber (reg:CC FLAGS_REG))])]
4063   "TARGET_80387"
4064 {
4065   if (TARGET_FISTTP)
4066    {
4067      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4068      DONE;
4069    }
4070 })
4071
4072 (define_expand "fix_trunc<mode>si2"
4073   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075               (clobber (reg:CC FLAGS_REG))])]
4076   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4077 {
4078   if (TARGET_FISTTP
4079       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4080    {
4081      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4082      DONE;
4083    }
4084   if (SSE_FLOAT_MODE_P (<MODE>mode))
4085    {
4086      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088      if (out != operands[0])
4089         emit_move_insn (operands[0], out);
4090      DONE;
4091    }
4092 })
4093
4094 ;; Signed conversion to HImode.
4095
4096 (define_expand "fix_trunc<mode>hi2"
4097   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099               (clobber (reg:CC FLAGS_REG))])]
4100   "TARGET_80387
4101    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4102 {
4103   if (TARGET_FISTTP)
4104    {
4105      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4106      DONE;
4107    }
4108 })
4109
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112   [(set (match_operand:DI 0 "register_operand" "=r,r")
4113         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115   "cvttss2si{q}\t{%1, %0|%0, %1}"
4116   [(set_attr "type" "sseicvt")
4117    (set_attr "mode" "SF")
4118    (set_attr "athlon_decode" "double,vector")])
4119
4120 (define_insn "fix_truncdfdi_sse"
4121   [(set (match_operand:DI 0 "register_operand" "=r,r")
4122         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125   [(set_attr "type" "sseicvt")
4126    (set_attr "mode" "DF")
4127    (set_attr "athlon_decode" "double,vector")])
4128
4129 (define_insn "fix_truncsfsi_sse"
4130   [(set (match_operand:SI 0 "register_operand" "=r,r")
4131         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133   "cvttss2si\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 (define_insn "fix_truncdfsi_sse"
4139   [(set (match_operand:SI 0 "register_operand" "=r,r")
4140         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142   "cvttsd2si\t{%1, %0|%0, %1}"
4143   [(set_attr "type" "sseicvt")
4144    (set_attr "mode" "DF")
4145    (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded forms of the instruction.
4148 (define_peephole2
4149   [(match_scratch:DF 2 "Y")
4150    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152   "TARGET_K8 && !optimize_size"
4153   [(set (match_dup 2) (match_dup 1))
4154    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4155   "")
4156
4157 (define_peephole2
4158   [(match_scratch:SF 2 "x")
4159    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161   "TARGET_K8 && !optimize_size"
4162   [(set (match_dup 2) (match_dup 1))
4163    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4164   "")
4165
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4169   "TARGET_FISTTP
4170    && FLOAT_MODE_P (GET_MODE (operands[1]))
4171    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172          && (TARGET_64BIT || <MODE>mode != DImode))
4173         && TARGET_SSE_MATH)
4174    && !(reload_completed || reload_in_progress)"
4175   "#"
4176   "&& 1"
4177   [(const_int 0)]
4178 {
4179   if (memory_operand (operands[0], VOIDmode))
4180     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181   else
4182     {
4183       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4185                                                             operands[1],
4186                                                             operands[2]));
4187     }
4188   DONE;
4189 }
4190   [(set_attr "type" "fisttp")
4191    (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196    (clobber (match_scratch:XF 2 "=&1f"))]
4197   "TARGET_FISTTP
4198    && FLOAT_MODE_P (GET_MODE (operands[1]))
4199    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200          && (TARGET_64BIT || <MODE>mode != DImode))
4201         && TARGET_SSE_MATH)"
4202   "* return output_fix_trunc (insn, operands, 1);"
4203   [(set_attr "type" "fisttp")
4204    (set_attr "mode" "<MODE>")])
4205
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211   "TARGET_FISTTP
4212    && FLOAT_MODE_P (GET_MODE (operands[1]))
4213    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214         && (TARGET_64BIT || <MODE>mode != DImode))
4215         && TARGET_SSE_MATH)"
4216   "#"
4217   [(set_attr "type" "fisttp")
4218    (set_attr "mode" "<MODE>")])
4219
4220 (define_split
4221   [(set (match_operand:X87MODEI 0 "register_operand" "")
4222         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224    (clobber (match_scratch 3 ""))]
4225   "reload_completed"
4226   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227               (clobber (match_dup 3))])
4228    (set (match_dup 0) (match_dup 2))]
4229   "")
4230
4231 (define_split
4232   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235    (clobber (match_scratch 3 ""))]
4236   "reload_completed"
4237   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238               (clobber (match_dup 3))])]
4239   "")
4240
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249    (clobber (reg:CC FLAGS_REG))]
4250   "TARGET_80387 && !TARGET_FISTTP
4251    && FLOAT_MODE_P (GET_MODE (operands[1]))
4252    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253          && (TARGET_64BIT || <MODE>mode != DImode))
4254    && !(reload_completed || reload_in_progress)"
4255   "#"
4256   "&& 1"
4257   [(const_int 0)]
4258 {
4259   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4260
4261   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265                                          operands[2], operands[3]));
4266   else
4267     {
4268       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270                                                      operands[2], operands[3],
4271                                                      operands[4]));
4272     }
4273   DONE;
4274 }
4275   [(set_attr "type" "fistp")
4276    (set_attr "i387_cw" "trunc")
4277    (set_attr "mode" "<MODE>")])
4278
4279 (define_insn "fix_truncdi_i387"
4280   [(set (match_operand:DI 0 "memory_operand" "=m")
4281         (fix:DI (match_operand 1 "register_operand" "f")))
4282    (use (match_operand:HI 2 "memory_operand" "m"))
4283    (use (match_operand:HI 3 "memory_operand" "m"))
4284    (clobber (match_scratch:XF 4 "=&1f"))]
4285   "TARGET_80387 && !TARGET_FISTTP
4286    && FLOAT_MODE_P (GET_MODE (operands[1]))
4287    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288   "* return output_fix_trunc (insn, operands, 0);"
4289   [(set_attr "type" "fistp")
4290    (set_attr "i387_cw" "trunc")
4291    (set_attr "mode" "DI")])
4292
4293 (define_insn "fix_truncdi_i387_with_temp"
4294   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295         (fix:DI (match_operand 1 "register_operand" "f,f")))
4296    (use (match_operand:HI 2 "memory_operand" "m,m"))
4297    (use (match_operand:HI 3 "memory_operand" "m,m"))
4298    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300   "TARGET_80387 && !TARGET_FISTTP
4301    && FLOAT_MODE_P (GET_MODE (operands[1]))
4302    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303   "#"
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "DI")])
4307
4308 (define_split 
4309   [(set (match_operand:DI 0 "register_operand" "")
4310         (fix:DI (match_operand 1 "register_operand" "")))
4311    (use (match_operand:HI 2 "memory_operand" ""))
4312    (use (match_operand:HI 3 "memory_operand" ""))
4313    (clobber (match_operand:DI 4 "memory_operand" ""))
4314    (clobber (match_scratch 5 ""))]
4315   "reload_completed"
4316   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317               (use (match_dup 2))
4318               (use (match_dup 3))
4319               (clobber (match_dup 5))])
4320    (set (match_dup 0) (match_dup 4))]
4321   "")
4322
4323 (define_split 
4324   [(set (match_operand:DI 0 "memory_operand" "")
4325         (fix:DI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:DI 4 "memory_operand" ""))
4329    (clobber (match_scratch 5 ""))]
4330   "reload_completed"
4331   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332               (use (match_dup 2))
4333               (use (match_dup 3))
4334               (clobber (match_dup 5))])]
4335   "")
4336
4337 (define_insn "fix_trunc<mode>_i387"
4338   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340    (use (match_operand:HI 2 "memory_operand" "m"))
4341    (use (match_operand:HI 3 "memory_operand" "m"))]
4342   "TARGET_80387 && !TARGET_FISTTP
4343    && FLOAT_MODE_P (GET_MODE (operands[1]))
4344    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345   "* return output_fix_trunc (insn, operands, 0);"
4346   [(set_attr "type" "fistp")
4347    (set_attr "i387_cw" "trunc")
4348    (set_attr "mode" "<MODE>")])
4349
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353    (use (match_operand:HI 2 "memory_operand" "m,m"))
4354    (use (match_operand:HI 3 "memory_operand" "m,m"))
4355    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356   "TARGET_80387 && !TARGET_FISTTP
4357    && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359   "#"
4360   [(set_attr "type" "fistp")
4361    (set_attr "i387_cw" "trunc")
4362    (set_attr "mode" "<MODE>")])
4363
4364 (define_split 
4365   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367    (use (match_operand:HI 2 "memory_operand" ""))
4368    (use (match_operand:HI 3 "memory_operand" ""))
4369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370   "reload_completed"
4371   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372               (use (match_dup 2))
4373               (use (match_dup 3))])
4374    (set (match_dup 0) (match_dup 4))]
4375   "")
4376
4377 (define_split 
4378   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380    (use (match_operand:HI 2 "memory_operand" ""))
4381    (use (match_operand:HI 3 "memory_operand" ""))
4382    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383   "reload_completed"
4384   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385               (use (match_dup 2))
4386               (use (match_dup 3))])]
4387   "")
4388
4389 (define_insn "x86_fnstcw_1"
4390   [(set (match_operand:HI 0 "memory_operand" "=m")
4391         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392   "TARGET_80387"
4393   "fnstcw\t%0"
4394   [(set_attr "length" "2")
4395    (set_attr "mode" "HI")
4396    (set_attr "unit" "i387")])
4397
4398 (define_insn "x86_fldcw_1"
4399   [(set (reg:HI FPSR_REG)
4400         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401   "TARGET_80387"
4402   "fldcw\t%0"
4403   [(set_attr "length" "2")
4404    (set_attr "mode" "HI")
4405    (set_attr "unit" "i387")
4406    (set_attr "athlon_decode" "vector")])
4407 \f
4408 ;; Conversion between fixed point and floating point.
4409
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4412
4413 (define_expand "floathisf2"
4414   [(set (match_operand:SF 0 "register_operand" "")
4415         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416   "TARGET_80387 || TARGET_SSE_MATH"
4417 {
4418   if (TARGET_SSE_MATH)
4419     {
4420       emit_insn (gen_floatsisf2 (operands[0],
4421                                  convert_to_mode (SImode, operands[1], 0)));
4422       DONE;
4423     }
4424 })
4425
4426 (define_insn "*floathisf2_i387"
4427   [(set (match_operand:SF 0 "register_operand" "=f,f")
4428         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430   "@
4431    fild%z1\t%1
4432    #"
4433   [(set_attr "type" "fmov,multi")
4434    (set_attr "mode" "SF")
4435    (set_attr "unit" "*,i387")
4436    (set_attr "fp_int_src" "true")])
4437
4438 (define_expand "floatsisf2"
4439   [(set (match_operand:SF 0 "register_operand" "")
4440         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441   "TARGET_80387 || TARGET_SSE_MATH"
4442   "")
4443
4444 (define_insn "*floatsisf2_mixed"
4445   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447   "TARGET_MIX_SSE_I387"
4448   "@
4449    fild%z1\t%1
4450    #
4451    cvtsi2ss\t{%1, %0|%0, %1}
4452    cvtsi2ss\t{%1, %0|%0, %1}"
4453   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454    (set_attr "mode" "SF")
4455    (set_attr "unit" "*,i387,*,*")
4456    (set_attr "athlon_decode" "*,*,vector,double")
4457    (set_attr "fp_int_src" "true")])
4458
4459 (define_insn "*floatsisf2_sse"
4460   [(set (match_operand:SF 0 "register_operand" "=x,x")
4461         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4462   "TARGET_SSE_MATH"
4463   "cvtsi2ss\t{%1, %0|%0, %1}"
4464   [(set_attr "type" "sseicvt")
4465    (set_attr "mode" "SF")
4466    (set_attr "athlon_decode" "vector,double")
4467    (set_attr "fp_int_src" "true")])
4468
4469 (define_insn "*floatsisf2_i387"
4470   [(set (match_operand:SF 0 "register_operand" "=f,f")
4471         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4472   "TARGET_80387"
4473   "@
4474    fild%z1\t%1
4475    #"
4476   [(set_attr "type" "fmov,multi")
4477    (set_attr "mode" "SF")
4478    (set_attr "unit" "*,i387")
4479    (set_attr "fp_int_src" "true")])
4480
4481 (define_expand "floatdisf2"
4482   [(set (match_operand:SF 0 "register_operand" "")
4483         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4485   "")
4486
4487 (define_insn "*floatdisf2_mixed"
4488   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4491   "@
4492    fild%z1\t%1
4493    #
4494    cvtsi2ss{q}\t{%1, %0|%0, %1}
4495    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "unit" "*,i387,*,*")
4499    (set_attr "athlon_decode" "*,*,vector,double")
4500    (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatdisf2_sse"
4503   [(set (match_operand:SF 0 "register_operand" "=x,x")
4504         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505   "TARGET_64BIT && TARGET_SSE_MATH"
4506   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507   [(set_attr "type" "sseicvt")
4508    (set_attr "mode" "SF")
4509    (set_attr "athlon_decode" "vector,double")
4510    (set_attr "fp_int_src" "true")])
4511
4512 (define_insn "*floatdisf2_i387"
4513   [(set (match_operand:SF 0 "register_operand" "=f,f")
4514         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515   "TARGET_80387"
4516   "@
4517    fild%z1\t%1
4518    #"
4519   [(set_attr "type" "fmov,multi")
4520    (set_attr "mode" "SF")
4521    (set_attr "unit" "*,i387")
4522    (set_attr "fp_int_src" "true")])
4523
4524 (define_expand "floathidf2"
4525   [(set (match_operand:DF 0 "register_operand" "")
4526         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528 {
4529   if (TARGET_SSE2 && TARGET_SSE_MATH)
4530     {
4531       emit_insn (gen_floatsidf2 (operands[0],
4532                                  convert_to_mode (SImode, operands[1], 0)));
4533       DONE;
4534     }
4535 })
4536
4537 (define_insn "*floathidf2_i387"
4538   [(set (match_operand:DF 0 "register_operand" "=f,f")
4539         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4541   "@
4542    fild%z1\t%1
4543    #"
4544   [(set_attr "type" "fmov,multi")
4545    (set_attr "mode" "DF")
4546    (set_attr "unit" "*,i387")
4547    (set_attr "fp_int_src" "true")])
4548
4549 (define_expand "floatsidf2"
4550   [(set (match_operand:DF 0 "register_operand" "")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4553   "")
4554
4555 (define_insn "*floatsidf2_mixed"
4556   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4559   "@
4560    fild%z1\t%1
4561    #
4562    cvtsi2sd\t{%1, %0|%0, %1}
4563    cvtsi2sd\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565    (set_attr "mode" "DF")
4566    (set_attr "unit" "*,i387,*,*")
4567    (set_attr "athlon_decode" "*,*,double,direct")
4568    (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatsidf2_sse"
4571   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573   "TARGET_SSE2 && TARGET_SSE_MATH"
4574   "cvtsi2sd\t{%1, %0|%0, %1}"
4575   [(set_attr "type" "sseicvt")
4576    (set_attr "mode" "DF")
4577    (set_attr "athlon_decode" "double,direct")
4578    (set_attr "fp_int_src" "true")])
4579
4580 (define_insn "*floatsidf2_i387"
4581   [(set (match_operand:DF 0 "register_operand" "=f,f")
4582         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4583   "TARGET_80387"
4584   "@
4585    fild%z1\t%1
4586    #"
4587   [(set_attr "type" "fmov,multi")
4588    (set_attr "mode" "DF")
4589    (set_attr "unit" "*,i387")
4590    (set_attr "fp_int_src" "true")])
4591
4592 (define_expand "floatdidf2"
4593   [(set (match_operand:DF 0 "register_operand" "")
4594         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4596   "")
4597
4598 (define_insn "*floatdidf2_mixed"
4599   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4602   "@
4603    fild%z1\t%1
4604    #
4605    cvtsi2sd{q}\t{%1, %0|%0, %1}
4606    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608    (set_attr "mode" "DF")
4609    (set_attr "unit" "*,i387,*,*")
4610    (set_attr "athlon_decode" "*,*,double,direct")
4611    (set_attr "fp_int_src" "true")])
4612
4613 (define_insn "*floatdidf2_sse"
4614   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618   [(set_attr "type" "sseicvt")
4619    (set_attr "mode" "DF")
4620    (set_attr "athlon_decode" "double,direct")
4621    (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatdidf2_i387"
4624   [(set (match_operand:DF 0 "register_operand" "=f,f")
4625         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4626   "TARGET_80387"
4627   "@
4628    fild%z1\t%1
4629    #"
4630   [(set_attr "type" "fmov,multi")
4631    (set_attr "mode" "DF")
4632    (set_attr "unit" "*,i387")
4633    (set_attr "fp_int_src" "true")])
4634
4635 (define_insn "floathixf2"
4636   [(set (match_operand:XF 0 "register_operand" "=f,f")
4637         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638   "TARGET_80387"
4639   "@
4640    fild%z1\t%1
4641    #"
4642   [(set_attr "type" "fmov,multi")
4643    (set_attr "mode" "XF")
4644    (set_attr "unit" "*,i387")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "floatsixf2"
4648   [(set (match_operand:XF 0 "register_operand" "=f,f")
4649         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "XF")
4656    (set_attr "unit" "*,i387")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floatdixf2"
4660   [(set (match_operand:XF 0 "register_operand" "=f,f")
4661         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "XF")
4668    (set_attr "unit" "*,i387")
4669    (set_attr "fp_int_src" "true")])
4670
4671 ;; %%% Kill these when reload knows how to do it.
4672 (define_split
4673   [(set (match_operand 0 "fp_register_operand" "")
4674         (float (match_operand 1 "register_operand" "")))]
4675   "reload_completed
4676    && TARGET_80387
4677    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4678   [(const_int 0)]
4679 {
4680   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683   ix86_free_from_memory (GET_MODE (operands[1]));
4684   DONE;
4685 })
4686
4687 (define_expand "floatunssisf2"
4688   [(use (match_operand:SF 0 "register_operand" ""))
4689    (use (match_operand:SI 1 "register_operand" ""))]
4690   "!TARGET_64BIT && TARGET_SSE_MATH"
4691   "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdisf2"
4694   [(use (match_operand:SF 0 "register_operand" ""))
4695    (use (match_operand:DI 1 "register_operand" ""))]
4696   "TARGET_64BIT && TARGET_SSE_MATH"
4697   "x86_emit_floatuns (operands); DONE;")
4698
4699 (define_expand "floatunsdidf2"
4700   [(use (match_operand:DF 0 "register_operand" ""))
4701    (use (match_operand:DI 1 "register_operand" ""))]
4702   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703   "x86_emit_floatuns (operands); DONE;")
4704 \f
4705 ;; SSE extract/set expanders
4706
4707 \f
4708 ;; Add instructions
4709
4710 ;; %%% splits for addditi3
4711
4712 (define_expand "addti3"
4713   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715                  (match_operand:TI 2 "x86_64_general_operand" "")))
4716    (clobber (reg:CC FLAGS_REG))]
4717   "TARGET_64BIT"
4718   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4719
4720 (define_insn "*addti3_1"
4721   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4724    (clobber (reg:CC FLAGS_REG))]
4725   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4726   "#")
4727
4728 (define_split
4729   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731                  (match_operand:TI 2 "general_operand" "")))
4732    (clobber (reg:CC FLAGS_REG))]
4733   "TARGET_64BIT && reload_completed"
4734   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4735                                           UNSPEC_ADD_CARRY))
4736               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737    (parallel [(set (match_dup 3)
4738                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4739                                      (match_dup 4))
4740                             (match_dup 5)))
4741               (clobber (reg:CC FLAGS_REG))])]
4742   "split_ti (operands+0, 1, operands+0, operands+3);
4743    split_ti (operands+1, 1, operands+1, operands+4);
4744    split_ti (operands+2, 1, operands+2, operands+5);")
4745
4746 ;; %%% splits for addsidi3
4747 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4750
4751 (define_expand "adddi3"
4752   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754                  (match_operand:DI 2 "x86_64_general_operand" "")))
4755    (clobber (reg:CC FLAGS_REG))]
4756   ""
4757   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4758
4759 (define_insn "*adddi3_1"
4760   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4763    (clobber (reg:CC FLAGS_REG))]
4764   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4765   "#")
4766
4767 (define_split
4768   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770                  (match_operand:DI 2 "general_operand" "")))
4771    (clobber (reg:CC FLAGS_REG))]
4772   "!TARGET_64BIT && reload_completed"
4773   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4774                                           UNSPEC_ADD_CARRY))
4775               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776    (parallel [(set (match_dup 3)
4777                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4778                                      (match_dup 4))
4779                             (match_dup 5)))
4780               (clobber (reg:CC FLAGS_REG))])]
4781   "split_di (operands+0, 1, operands+0, operands+3);
4782    split_di (operands+1, 1, operands+1, operands+4);
4783    split_di (operands+2, 1, operands+2, operands+5);")
4784
4785 (define_insn "adddi3_carry_rex64"
4786   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790    (clobber (reg:CC FLAGS_REG))]
4791   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792   "adc{q}\t{%2, %0|%0, %2}"
4793   [(set_attr "type" "alu")
4794    (set_attr "pent_pair" "pu")
4795    (set_attr "mode" "DI")])
4796
4797 (define_insn "*adddi3_cc_rex64"
4798   [(set (reg:CC FLAGS_REG)
4799         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4801                    UNSPEC_ADD_CARRY))
4802    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803         (plus:DI (match_dup 1) (match_dup 2)))]
4804   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805   "add{q}\t{%2, %0|%0, %2}"
4806   [(set_attr "type" "alu")
4807    (set_attr "mode" "DI")])
4808
4809 (define_insn "addqi3_carry"
4810   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813                    (match_operand:QI 2 "general_operand" "qi,qm")))
4814    (clobber (reg:CC FLAGS_REG))]
4815   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816   "adc{b}\t{%2, %0|%0, %2}"
4817   [(set_attr "type" "alu")
4818    (set_attr "pent_pair" "pu")
4819    (set_attr "mode" "QI")])
4820
4821 (define_insn "addhi3_carry"
4822   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825                    (match_operand:HI 2 "general_operand" "ri,rm")))
4826    (clobber (reg:CC FLAGS_REG))]
4827   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828   "adc{w}\t{%2, %0|%0, %2}"
4829   [(set_attr "type" "alu")
4830    (set_attr "pent_pair" "pu")
4831    (set_attr "mode" "HI")])
4832
4833 (define_insn "addsi3_carry"
4834   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837                    (match_operand:SI 2 "general_operand" "ri,rm")))
4838    (clobber (reg:CC FLAGS_REG))]
4839   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840   "adc{l}\t{%2, %0|%0, %2}"
4841   [(set_attr "type" "alu")
4842    (set_attr "pent_pair" "pu")
4843    (set_attr "mode" "SI")])
4844
4845 (define_insn "*addsi3_carry_zext"
4846   [(set (match_operand:DI 0 "register_operand" "=r")
4847           (zero_extend:DI 
4848             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850                      (match_operand:SI 2 "general_operand" "rim"))))
4851    (clobber (reg:CC FLAGS_REG))]
4852   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853   "adc{l}\t{%2, %k0|%k0, %2}"
4854   [(set_attr "type" "alu")
4855    (set_attr "pent_pair" "pu")
4856    (set_attr "mode" "SI")])
4857
4858 (define_insn "*addsi3_cc"
4859   [(set (reg:CC FLAGS_REG)
4860         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861                     (match_operand:SI 2 "general_operand" "ri,rm")]
4862                    UNSPEC_ADD_CARRY))
4863    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864         (plus:SI (match_dup 1) (match_dup 2)))]
4865   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866   "add{l}\t{%2, %0|%0, %2}"
4867   [(set_attr "type" "alu")
4868    (set_attr "mode" "SI")])
4869
4870 (define_insn "addqi3_cc"
4871   [(set (reg:CC FLAGS_REG)
4872         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873                     (match_operand:QI 2 "general_operand" "qi,qm")]
4874                    UNSPEC_ADD_CARRY))
4875    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876         (plus:QI (match_dup 1) (match_dup 2)))]
4877   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878   "add{b}\t{%2, %0|%0, %2}"
4879   [(set_attr "type" "alu")
4880    (set_attr "mode" "QI")])
4881
4882 (define_expand "addsi3"
4883   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885                             (match_operand:SI 2 "general_operand" "")))
4886               (clobber (reg:CC FLAGS_REG))])]
4887   ""
4888   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4889
4890 (define_insn "*lea_1"
4891   [(set (match_operand:SI 0 "register_operand" "=r")
4892         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4893   "!TARGET_64BIT"
4894   "lea{l}\t{%a1, %0|%0, %a1}"
4895   [(set_attr "type" "lea")
4896    (set_attr "mode" "SI")])
4897
4898 (define_insn "*lea_1_rex64"
4899   [(set (match_operand:SI 0 "register_operand" "=r")
4900         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4901   "TARGET_64BIT"
4902   "lea{l}\t{%a1, %0|%0, %a1}"
4903   [(set_attr "type" "lea")
4904    (set_attr "mode" "SI")])
4905
4906 (define_insn "*lea_1_zext"
4907   [(set (match_operand:DI 0 "register_operand" "=r")
4908         (zero_extend:DI
4909          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4910   "TARGET_64BIT"
4911   "lea{l}\t{%a1, %k0|%k0, %a1}"
4912   [(set_attr "type" "lea")
4913    (set_attr "mode" "SI")])
4914
4915 (define_insn "*lea_2_rex64"
4916   [(set (match_operand:DI 0 "register_operand" "=r")
4917         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4918   "TARGET_64BIT"
4919   "lea{q}\t{%a1, %0|%0, %a1}"
4920   [(set_attr "type" "lea")
4921    (set_attr "mode" "DI")])
4922
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4925
4926 (define_insn_and_split "*lea_general_1"
4927   [(set (match_operand 0 "register_operand" "=r")
4928         (plus (plus (match_operand 1 "index_register_operand" "l")
4929                     (match_operand 2 "register_operand" "r"))
4930               (match_operand 3 "immediate_operand" "i")))]
4931   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937        || GET_MODE (operands[3]) == VOIDmode)"
4938   "#"
4939   "&& reload_completed"
4940   [(const_int 0)]
4941 {
4942   rtx pat;
4943   operands[0] = gen_lowpart (SImode, operands[0]);
4944   operands[1] = gen_lowpart (Pmode, operands[1]);
4945   operands[2] = gen_lowpart (Pmode, operands[2]);
4946   operands[3] = gen_lowpart (Pmode, operands[3]);
4947   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4948                       operands[3]);
4949   if (Pmode != SImode)
4950     pat = gen_rtx_SUBREG (SImode, pat, 0);
4951   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4952   DONE;
4953 }
4954   [(set_attr "type" "lea")
4955    (set_attr "mode" "SI")])
4956
4957 (define_insn_and_split "*lea_general_1_zext"
4958   [(set (match_operand:DI 0 "register_operand" "=r")
4959         (zero_extend:DI
4960           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961                             (match_operand:SI 2 "register_operand" "r"))
4962                    (match_operand:SI 3 "immediate_operand" "i"))))]
4963   "TARGET_64BIT"
4964   "#"
4965   "&& reload_completed"
4966   [(set (match_dup 0)
4967         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4968                                                      (match_dup 2))
4969                                             (match_dup 3)) 0)))]
4970 {
4971   operands[1] = gen_lowpart (Pmode, operands[1]);
4972   operands[2] = gen_lowpart (Pmode, operands[2]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975   [(set_attr "type" "lea")
4976    (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_2"
4979   [(set (match_operand 0 "register_operand" "=r")
4980         (plus (mult (match_operand 1 "index_register_operand" "l")
4981                     (match_operand 2 "const248_operand" "i"))
4982               (match_operand 3 "nonmemory_operand" "ri")))]
4983   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988        || GET_MODE (operands[3]) == VOIDmode)"
4989   "#"
4990   "&& reload_completed"
4991   [(const_int 0)]
4992 {
4993   rtx pat;
4994   operands[0] = gen_lowpart (SImode, operands[0]);
4995   operands[1] = gen_lowpart (Pmode, operands[1]);
4996   operands[3] = gen_lowpart (Pmode, operands[3]);
4997   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4998                       operands[3]);
4999   if (Pmode != SImode)
5000     pat = gen_rtx_SUBREG (SImode, pat, 0);
5001   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002   DONE;
5003 }
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2_zext"
5008   [(set (match_operand:DI 0 "register_operand" "=r")
5009         (zero_extend:DI
5010           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011                             (match_operand:SI 2 "const248_operand" "n"))
5012                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5013   "TARGET_64BIT"
5014   "#"
5015   "&& reload_completed"
5016   [(set (match_dup 0)
5017         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5018                                                      (match_dup 2))
5019                                             (match_dup 3)) 0)))]
5020 {
5021   operands[1] = gen_lowpart (Pmode, operands[1]);
5022   operands[3] = gen_lowpart (Pmode, operands[3]);
5023 }
5024   [(set_attr "type" "lea")
5025    (set_attr "mode" "SI")])
5026
5027 (define_insn_and_split "*lea_general_3"
5028   [(set (match_operand 0 "register_operand" "=r")
5029         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030                           (match_operand 2 "const248_operand" "i"))
5031                     (match_operand 3 "register_operand" "r"))
5032               (match_operand 4 "immediate_operand" "i")))]
5033   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5038   "#"
5039   "&& reload_completed"
5040   [(const_int 0)]
5041 {
5042   rtx pat;
5043   operands[0] = gen_lowpart (SImode, operands[0]);
5044   operands[1] = gen_lowpart (Pmode, operands[1]);
5045   operands[3] = gen_lowpart (Pmode, operands[3]);
5046   operands[4] = gen_lowpart (Pmode, operands[4]);
5047   pat = gen_rtx_PLUS (Pmode,
5048                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5049                                                          operands[2]),
5050                                     operands[3]),
5051                       operands[4]);
5052   if (Pmode != SImode)
5053     pat = gen_rtx_SUBREG (SImode, pat, 0);
5054   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5055   DONE;
5056 }
5057   [(set_attr "type" "lea")
5058    (set_attr "mode" "SI")])
5059
5060 (define_insn_and_split "*lea_general_3_zext"
5061   [(set (match_operand:DI 0 "register_operand" "=r")
5062         (zero_extend:DI
5063           (plus:SI (plus:SI (mult:SI
5064                               (match_operand:SI 1 "index_register_operand" "l")
5065                               (match_operand:SI 2 "const248_operand" "n"))
5066                             (match_operand:SI 3 "register_operand" "r"))
5067                    (match_operand:SI 4 "immediate_operand" "i"))))]
5068   "TARGET_64BIT"
5069   "#"
5070   "&& reload_completed"
5071   [(set (match_dup 0)
5072         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5073                                                               (match_dup 2))
5074                                                      (match_dup 3))
5075                                             (match_dup 4)) 0)))]
5076 {
5077   operands[1] = gen_lowpart (Pmode, operands[1]);
5078   operands[3] = gen_lowpart (Pmode, operands[3]);
5079   operands[4] = gen_lowpart (Pmode, operands[4]);
5080 }
5081   [(set_attr "type" "lea")
5082    (set_attr "mode" "SI")])
5083
5084 (define_insn "*adddi_1_rex64"
5085   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088    (clobber (reg:CC FLAGS_REG))]
5089   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5090 {
5091   switch (get_attr_type (insn))
5092     {
5093     case TYPE_LEA:
5094       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095       return "lea{q}\t{%a2, %0|%0, %a2}";
5096
5097     case TYPE_INCDEC:
5098       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099       if (operands[2] == const1_rtx)
5100         return "inc{q}\t%0";
5101       else
5102         {
5103           gcc_assert (operands[2] == constm1_rtx);
5104           return "dec{q}\t%0";
5105         }
5106
5107     default:
5108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5109
5110       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5112       if (GET_CODE (operands[2]) == CONST_INT
5113           /* Avoid overflows.  */
5114           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115           && (INTVAL (operands[2]) == 128
5116               || (INTVAL (operands[2]) < 0
5117                   && INTVAL (operands[2]) != -128)))
5118         {
5119           operands[2] = GEN_INT (-INTVAL (operands[2]));
5120           return "sub{q}\t{%2, %0|%0, %2}";
5121         }
5122       return "add{q}\t{%2, %0|%0, %2}";
5123     }
5124 }
5125   [(set (attr "type")
5126      (cond [(eq_attr "alternative" "2")
5127               (const_string "lea")
5128             ; Current assemblers are broken and do not allow @GOTOFF in
5129             ; ought but a memory context.
5130             (match_operand:DI 2 "pic_symbolic_operand" "")
5131               (const_string "lea")
5132             (match_operand:DI 2 "incdec_operand" "")
5133               (const_string "incdec")
5134            ]
5135            (const_string "alu")))
5136    (set_attr "mode" "DI")])
5137
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5139 (define_split
5140   [(set (match_operand:DI 0 "register_operand" "")
5141         (plus:DI (match_operand:DI 1 "register_operand" "")
5142                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143    (clobber (reg:CC FLAGS_REG))]
5144   "TARGET_64BIT && reload_completed
5145    && true_regnum (operands[0]) != true_regnum (operands[1])"
5146   [(set (match_dup 0)
5147         (plus:DI (match_dup 1)
5148                  (match_dup 2)))]
5149   "")
5150
5151 (define_insn "*adddi_2_rex64"
5152   [(set (reg FLAGS_REG)
5153         (compare
5154           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5156           (const_int 0)))                       
5157    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158         (plus:DI (match_dup 1) (match_dup 2)))]
5159   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160    && ix86_binary_operator_ok (PLUS, DImode, operands)
5161    /* Current assemblers are broken and do not allow @GOTOFF in
5162       ought but a memory context.  */
5163    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164 {
5165   switch (get_attr_type (insn))
5166     {
5167     case TYPE_INCDEC:
5168       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169       if (operands[2] == const1_rtx)
5170         return "inc{q}\t%0";
5171       else
5172         {
5173           gcc_assert (operands[2] == constm1_rtx);
5174           return "dec{q}\t%0";
5175         }
5176
5177     default:
5178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179       /* ???? We ought to handle there the 32bit case too
5180          - do we need new constraint?  */
5181       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5183       if (GET_CODE (operands[2]) == CONST_INT
5184           /* Avoid overflows.  */
5185           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186           && (INTVAL (operands[2]) == 128
5187               || (INTVAL (operands[2]) < 0
5188                   && INTVAL (operands[2]) != -128)))
5189         {
5190           operands[2] = GEN_INT (-INTVAL (operands[2]));
5191           return "sub{q}\t{%2, %0|%0, %2}";
5192         }
5193       return "add{q}\t{%2, %0|%0, %2}";
5194     }
5195 }
5196   [(set (attr "type")
5197      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198         (const_string "incdec")
5199         (const_string "alu")))
5200    (set_attr "mode" "DI")])
5201
5202 (define_insn "*adddi_3_rex64"
5203   [(set (reg FLAGS_REG)
5204         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206    (clobber (match_scratch:DI 0 "=r"))]
5207   "TARGET_64BIT
5208    && ix86_match_ccmode (insn, CCZmode)
5209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210    /* Current assemblers are broken and do not allow @GOTOFF in
5211       ought but a memory context.  */
5212    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 {
5214   switch (get_attr_type (insn))
5215     {
5216     case TYPE_INCDEC:
5217       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218       if (operands[2] == const1_rtx)
5219         return "inc{q}\t%0";
5220       else
5221         {
5222           gcc_assert (operands[2] == constm1_rtx);
5223           return "dec{q}\t%0";
5224         }
5225
5226     default:
5227       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228       /* ???? We ought to handle there the 32bit case too
5229          - do we need new constraint?  */
5230       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5232       if (GET_CODE (operands[2]) == CONST_INT
5233           /* Avoid overflows.  */
5234           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235           && (INTVAL (operands[2]) == 128
5236               || (INTVAL (operands[2]) < 0
5237                   && INTVAL (operands[2]) != -128)))
5238         {
5239           operands[2] = GEN_INT (-INTVAL (operands[2]));
5240           return "sub{q}\t{%2, %0|%0, %2}";
5241         }
5242       return "add{q}\t{%2, %0|%0, %2}";
5243     }
5244 }
5245   [(set (attr "type")
5246      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247         (const_string "incdec")
5248         (const_string "alu")))
5249    (set_attr "mode" "DI")])
5250
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5253 ; is matched then.  We can't accept general immediate, because for
5254 ; case of overflows,  the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5256 ; when negated.
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260   [(set (reg FLAGS_REG)
5261         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263    (clobber (match_scratch:DI 0 "=rm"))]
5264   "TARGET_64BIT
5265    &&  ix86_match_ccmode (insn, CCGCmode)"
5266 {
5267   switch (get_attr_type (insn))
5268     {
5269     case TYPE_INCDEC:
5270       if (operands[2] == constm1_rtx)
5271         return "inc{q}\t%0";
5272       else
5273         {
5274           gcc_assert (operands[2] == const1_rtx);
5275           return "dec{q}\t%0";
5276         }
5277
5278     default:
5279       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5282       if ((INTVAL (operands[2]) == -128
5283            || (INTVAL (operands[2]) > 0
5284                && INTVAL (operands[2]) != 128))
5285           /* Avoid overflows.  */
5286           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287         return "sub{q}\t{%2, %0|%0, %2}";
5288       operands[2] = GEN_INT (-INTVAL (operands[2]));
5289       return "add{q}\t{%2, %0|%0, %2}";
5290     }
5291 }
5292   [(set (attr "type")
5293      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294         (const_string "incdec")
5295         (const_string "alu")))
5296    (set_attr "mode" "DI")])
5297
5298 (define_insn "*adddi_5_rex64"
5299   [(set (reg FLAGS_REG)
5300         (compare
5301           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5303           (const_int 0)))                       
5304    (clobber (match_scratch:DI 0 "=r"))]
5305   "TARGET_64BIT
5306    && ix86_match_ccmode (insn, CCGOCmode)
5307    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308    /* Current assemblers are broken and do not allow @GOTOFF in
5309       ought but a memory context.  */
5310    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5311 {
5312   switch (get_attr_type (insn))
5313     {
5314     case TYPE_INCDEC:
5315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else
5319         {
5320           gcc_assert (operands[2] == constm1_rtx);
5321           return "dec{q}\t%0";
5322         }
5323
5324     default:
5325       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5328       if (GET_CODE (operands[2]) == CONST_INT
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331           && (INTVAL (operands[2]) == 128
5332               || (INTVAL (operands[2]) < 0
5333                   && INTVAL (operands[2]) != -128)))
5334         {
5335           operands[2] = GEN_INT (-INTVAL (operands[2]));
5336           return "sub{q}\t{%2, %0|%0, %2}";
5337         }
5338       return "add{q}\t{%2, %0|%0, %2}";
5339     }
5340 }
5341   [(set (attr "type")
5342      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343         (const_string "incdec")
5344         (const_string "alu")))
5345    (set_attr "mode" "DI")])
5346
5347
5348 (define_insn "*addsi_1"
5349   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352    (clobber (reg:CC FLAGS_REG))]
5353   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5354 {
5355   switch (get_attr_type (insn))
5356     {
5357     case TYPE_LEA:
5358       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359       return "lea{l}\t{%a2, %0|%0, %a2}";
5360
5361     case TYPE_INCDEC:
5362       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363       if (operands[2] == const1_rtx)
5364         return "inc{l}\t%0";
5365       else
5366         {
5367           gcc_assert (operands[2] == constm1_rtx);
5368           return "dec{l}\t%0";
5369         }
5370
5371     default:
5372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373
5374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5376       if (GET_CODE (operands[2]) == CONST_INT
5377           && (INTVAL (operands[2]) == 128
5378               || (INTVAL (operands[2]) < 0
5379                   && INTVAL (operands[2]) != -128)))
5380         {
5381           operands[2] = GEN_INT (-INTVAL (operands[2]));
5382           return "sub{l}\t{%2, %0|%0, %2}";
5383         }
5384       return "add{l}\t{%2, %0|%0, %2}";
5385     }
5386 }
5387   [(set (attr "type")
5388      (cond [(eq_attr "alternative" "2")
5389               (const_string "lea")
5390             ; Current assemblers are broken and do not allow @GOTOFF in
5391             ; ought but a memory context.
5392             (match_operand:SI 2 "pic_symbolic_operand" "")
5393               (const_string "lea")
5394             (match_operand:SI 2 "incdec_operand" "")
5395               (const_string "incdec")
5396            ]
5397            (const_string "alu")))
5398    (set_attr "mode" "SI")])
5399
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5401 (define_split
5402   [(set (match_operand 0 "register_operand" "")
5403         (plus (match_operand 1 "register_operand" "")
5404               (match_operand 2 "nonmemory_operand" "")))
5405    (clobber (reg:CC FLAGS_REG))]
5406   "reload_completed
5407    && true_regnum (operands[0]) != true_regnum (operands[1])"
5408   [(const_int 0)]
5409 {
5410   rtx pat;
5411   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412      may confuse gen_lowpart.  */
5413   if (GET_MODE (operands[0]) != Pmode)
5414     {
5415       operands[1] = gen_lowpart (Pmode, operands[1]);
5416       operands[2] = gen_lowpart (Pmode, operands[2]);
5417     }
5418   operands[0] = gen_lowpart (SImode, operands[0]);
5419   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420   if (Pmode != SImode)
5421     pat = gen_rtx_SUBREG (SImode, pat, 0);
5422   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5423   DONE;
5424 })
5425
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload.  This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432   [(set (match_operand:DI 0 "register_operand" "=r,r")
5433         (zero_extend:DI
5434           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436    (clobber (reg:CC FLAGS_REG))]
5437   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439   switch (get_attr_type (insn))
5440     {
5441     case TYPE_LEA:
5442       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5444
5445     case TYPE_INCDEC:
5446       if (operands[2] == const1_rtx)
5447         return "inc{l}\t%k0";
5448       else
5449         {
5450           gcc_assert (operands[2] == constm1_rtx);
5451           return "dec{l}\t%k0";
5452         }
5453
5454     default:
5455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5457       if (GET_CODE (operands[2]) == CONST_INT
5458           && (INTVAL (operands[2]) == 128
5459               || (INTVAL (operands[2]) < 0
5460                   && INTVAL (operands[2]) != -128)))
5461         {
5462           operands[2] = GEN_INT (-INTVAL (operands[2]));
5463           return "sub{l}\t{%2, %k0|%k0, %2}";
5464         }
5465       return "add{l}\t{%2, %k0|%k0, %2}";
5466     }
5467 }
5468   [(set (attr "type")
5469      (cond [(eq_attr "alternative" "1")
5470               (const_string "lea")
5471             ; Current assemblers are broken and do not allow @GOTOFF in
5472             ; ought but a memory context.
5473             (match_operand:SI 2 "pic_symbolic_operand" "")
5474               (const_string "lea")
5475             (match_operand:SI 2 "incdec_operand" "")
5476               (const_string "incdec")
5477            ]
5478            (const_string "alu")))
5479    (set_attr "mode" "SI")])
5480
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483   [(set (match_operand:DI 0 "register_operand" "")
5484         (zero_extend:DI
5485           (plus:SI (match_operand:SI 1 "register_operand" "")
5486                    (match_operand:SI 2 "nonmemory_operand" ""))))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "TARGET_64BIT && reload_completed
5489    && true_regnum (operands[0]) != true_regnum (operands[1])"
5490   [(set (match_dup 0)
5491         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5492 {
5493   operands[1] = gen_lowpart (Pmode, operands[1]);
5494   operands[2] = gen_lowpart (Pmode, operands[2]);
5495 })
5496
5497 (define_insn "*addsi_2"
5498   [(set (reg FLAGS_REG)
5499         (compare
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5502           (const_int 0)))                       
5503    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504         (plus:SI (match_dup 1) (match_dup 2)))]
5505   "ix86_match_ccmode (insn, CCGOCmode)
5506    && ix86_binary_operator_ok (PLUS, SImode, operands)
5507    /* Current assemblers are broken and do not allow @GOTOFF in
5508       ought but a memory context.  */
5509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_INCDEC:
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (operands[2] == const1_rtx)
5516         return "inc{l}\t%0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{l}\t%0";
5521         }
5522
5523     default:
5524       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5527       if (GET_CODE (operands[2]) == CONST_INT
5528           && (INTVAL (operands[2]) == 128
5529               || (INTVAL (operands[2]) < 0
5530                   && INTVAL (operands[2]) != -128)))
5531         {
5532           operands[2] = GEN_INT (-INTVAL (operands[2]));
5533           return "sub{l}\t{%2, %0|%0, %2}";
5534         }
5535       return "add{l}\t{%2, %0|%0, %2}";
5536     }
5537 }
5538   [(set (attr "type")
5539      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540         (const_string "incdec")
5541         (const_string "alu")))
5542    (set_attr "mode" "SI")])
5543
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546   [(set (reg FLAGS_REG)
5547         (compare
5548           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549                    (match_operand:SI 2 "general_operand" "rmni"))
5550           (const_int 0)))                       
5551    (set (match_operand:DI 0 "register_operand" "=r")
5552         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554    && ix86_binary_operator_ok (PLUS, SImode, operands)
5555    /* Current assemblers are broken and do not allow @GOTOFF in
5556       ought but a memory context.  */
5557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       if (operands[2] == const1_rtx)
5563         return "inc{l}\t%k0";
5564       else
5565         {
5566           gcc_assert (operands[2] == constm1_rtx);
5567           return "dec{l}\t%k0";
5568         }
5569
5570     default:
5571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5573       if (GET_CODE (operands[2]) == CONST_INT
5574           && (INTVAL (operands[2]) == 128
5575               || (INTVAL (operands[2]) < 0
5576                   && INTVAL (operands[2]) != -128)))
5577         {
5578           operands[2] = GEN_INT (-INTVAL (operands[2]));
5579           return "sub{l}\t{%2, %k0|%k0, %2}";
5580         }
5581       return "add{l}\t{%2, %k0|%k0, %2}";
5582     }
5583 }
5584   [(set (attr "type")
5585      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586         (const_string "incdec")
5587         (const_string "alu")))
5588    (set_attr "mode" "SI")])
5589
5590 (define_insn "*addsi_3"
5591   [(set (reg FLAGS_REG)
5592         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594    (clobber (match_scratch:SI 0 "=r"))]
5595   "ix86_match_ccmode (insn, CCZmode)
5596    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597    /* Current assemblers are broken and do not allow @GOTOFF in
5598       ought but a memory context.  */
5599    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5600 {
5601   switch (get_attr_type (insn))
5602     {
5603     case TYPE_INCDEC:
5604       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605       if (operands[2] == const1_rtx)
5606         return "inc{l}\t%0";
5607       else
5608         {
5609           gcc_assert (operands[2] == constm1_rtx);
5610           return "dec{l}\t%0";
5611         }
5612
5613     default:
5614       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5617       if (GET_CODE (operands[2]) == CONST_INT
5618           && (INTVAL (operands[2]) == 128
5619               || (INTVAL (operands[2]) < 0
5620                   && INTVAL (operands[2]) != -128)))
5621         {
5622           operands[2] = GEN_INT (-INTVAL (operands[2]));
5623           return "sub{l}\t{%2, %0|%0, %2}";
5624         }
5625       return "add{l}\t{%2, %0|%0, %2}";
5626     }
5627 }
5628   [(set (attr "type")
5629      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630         (const_string "incdec")
5631         (const_string "alu")))
5632    (set_attr "mode" "SI")])
5633
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636   [(set (reg FLAGS_REG)
5637         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639    (set (match_operand:DI 0 "register_operand" "=r")
5640         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642    && ix86_binary_operator_ok (PLUS, SImode, operands)
5643    /* Current assemblers are broken and do not allow @GOTOFF in
5644       ought but a memory context.  */
5645    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647   switch (get_attr_type (insn))
5648     {
5649     case TYPE_INCDEC:
5650       if (operands[2] == const1_rtx)
5651         return "inc{l}\t%k0";
5652       else
5653         {
5654           gcc_assert (operands[2] == constm1_rtx);
5655           return "dec{l}\t%k0";
5656         }
5657
5658     default:
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %k0|%k0, %2}";
5668         }
5669       return "add{l}\t{%2, %k0|%k0, %2}";
5670     }
5671 }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5677
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5680 ; is matched then.  We can't accept general immediate, because for
5681 ; case of overflows,  the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687   [(set (reg FLAGS_REG)
5688         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689                  (match_operand:SI 2 "const_int_operand" "n")))
5690    (clobber (match_scratch:SI 0 "=rm"))]
5691   "ix86_match_ccmode (insn, CCGCmode)
5692    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5693 {
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_INCDEC:
5697       if (operands[2] == constm1_rtx)
5698         return "inc{l}\t%0";
5699       else
5700         {
5701           gcc_assert (operands[2] == const1_rtx);
5702           return "dec{l}\t%0";
5703         }
5704
5705     default:
5706       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5709       if ((INTVAL (operands[2]) == -128
5710            || (INTVAL (operands[2]) > 0
5711                && INTVAL (operands[2]) != 128)))
5712         return "sub{l}\t{%2, %0|%0, %2}";
5713       operands[2] = GEN_INT (-INTVAL (operands[2]));
5714       return "add{l}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set_attr "mode" "SI")])
5722
5723 (define_insn "*addsi_5"
5724   [(set (reg FLAGS_REG)
5725         (compare
5726           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727                    (match_operand:SI 2 "general_operand" "rmni"))
5728           (const_int 0)))                       
5729    (clobber (match_scratch:SI 0 "=r"))]
5730   "ix86_match_ccmode (insn, CCGOCmode)
5731    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732    /* Current assemblers are broken and do not allow @GOTOFF in
5733       ought but a memory context.  */
5734    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736   switch (get_attr_type (insn))
5737     {
5738     case TYPE_INCDEC:
5739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740       if (operands[2] == const1_rtx)
5741         return "inc{l}\t%0";
5742       else
5743         {
5744           gcc_assert (operands[2] == constm1_rtx);
5745           return "dec{l}\t%0";
5746         }
5747
5748     default:
5749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5752       if (GET_CODE (operands[2]) == CONST_INT
5753           && (INTVAL (operands[2]) == 128
5754               || (INTVAL (operands[2]) < 0
5755                   && INTVAL (operands[2]) != -128)))
5756         {
5757           operands[2] = GEN_INT (-INTVAL (operands[2]));
5758           return "sub{l}\t{%2, %0|%0, %2}";
5759         }
5760       return "add{l}\t{%2, %0|%0, %2}";
5761     }
5762 }
5763   [(set (attr "type")
5764      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765         (const_string "incdec")
5766         (const_string "alu")))
5767    (set_attr "mode" "SI")])
5768
5769 (define_expand "addhi3"
5770   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772                             (match_operand:HI 2 "general_operand" "")))
5773               (clobber (reg:CC FLAGS_REG))])]
5774   "TARGET_HIMODE_MATH"
5775   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5776
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits.  This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5780
5781 (define_insn "*addhi_1_lea"
5782   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785    (clobber (reg:CC FLAGS_REG))]
5786   "!TARGET_PARTIAL_REG_STALL
5787    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5788 {
5789   switch (get_attr_type (insn))
5790     {
5791     case TYPE_LEA:
5792       return "#";
5793     case TYPE_INCDEC:
5794       if (operands[2] == const1_rtx)
5795         return "inc{w}\t%0";
5796       else
5797         {
5798           gcc_assert (operands[2] == constm1_rtx);
5799           return "dec{w}\t%0";
5800         }
5801
5802     default:
5803       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5805       if (GET_CODE (operands[2]) == CONST_INT
5806           && (INTVAL (operands[2]) == 128
5807               || (INTVAL (operands[2]) < 0
5808                   && INTVAL (operands[2]) != -128)))
5809         {
5810           operands[2] = GEN_INT (-INTVAL (operands[2]));
5811           return "sub{w}\t{%2, %0|%0, %2}";
5812         }
5813       return "add{w}\t{%2, %0|%0, %2}";
5814     }
5815 }
5816   [(set (attr "type")
5817      (if_then_else (eq_attr "alternative" "2")
5818         (const_string "lea")
5819         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820            (const_string "incdec")
5821            (const_string "alu"))))
5822    (set_attr "mode" "HI,HI,SI")])
5823
5824 (define_insn "*addhi_1"
5825   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827                  (match_operand:HI 2 "general_operand" "ri,rm")))
5828    (clobber (reg:CC FLAGS_REG))]
5829   "TARGET_PARTIAL_REG_STALL
5830    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5831 {
5832   switch (get_attr_type (insn))
5833     {
5834     case TYPE_INCDEC:
5835       if (operands[2] == const1_rtx)
5836         return "inc{w}\t%0";
5837       else
5838         {
5839           gcc_assert (operands[2] == constm1_rtx);
5840           return "dec{w}\t%0";
5841         }
5842
5843     default:
5844       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5846       if (GET_CODE (operands[2]) == CONST_INT
5847           && (INTVAL (operands[2]) == 128
5848               || (INTVAL (operands[2]) < 0
5849                   && INTVAL (operands[2]) != -128)))
5850         {
5851           operands[2] = GEN_INT (-INTVAL (operands[2]));
5852           return "sub{w}\t{%2, %0|%0, %2}";
5853         }
5854       return "add{w}\t{%2, %0|%0, %2}";
5855     }
5856 }
5857   [(set (attr "type")
5858      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859         (const_string "incdec")
5860         (const_string "alu")))
5861    (set_attr "mode" "HI")])
5862
5863 (define_insn "*addhi_2"
5864   [(set (reg FLAGS_REG)
5865         (compare
5866           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5868           (const_int 0)))                       
5869    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870         (plus:HI (match_dup 1) (match_dup 2)))]
5871   "ix86_match_ccmode (insn, CCGOCmode)
5872    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{w}\t%0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{w}\t%0";
5883         }
5884
5885     default:
5886       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5888       if (GET_CODE (operands[2]) == CONST_INT
5889           && (INTVAL (operands[2]) == 128
5890               || (INTVAL (operands[2]) < 0
5891                   && INTVAL (operands[2]) != -128)))
5892         {
5893           operands[2] = GEN_INT (-INTVAL (operands[2]));
5894           return "sub{w}\t{%2, %0|%0, %2}";
5895         }
5896       return "add{w}\t{%2, %0|%0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "HI")])
5904
5905 (define_insn "*addhi_3"
5906   [(set (reg FLAGS_REG)
5907         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909    (clobber (match_scratch:HI 0 "=r"))]
5910   "ix86_match_ccmode (insn, CCZmode)
5911    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5912 {
5913   switch (get_attr_type (insn))
5914     {
5915     case TYPE_INCDEC:
5916       if (operands[2] == const1_rtx)
5917         return "inc{w}\t%0";
5918       else
5919         {
5920           gcc_assert (operands[2] == constm1_rtx);
5921           return "dec{w}\t%0";
5922         }
5923
5924     default:
5925       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5927       if (GET_CODE (operands[2]) == CONST_INT
5928           && (INTVAL (operands[2]) == 128
5929               || (INTVAL (operands[2]) < 0
5930                   && INTVAL (operands[2]) != -128)))
5931         {
5932           operands[2] = GEN_INT (-INTVAL (operands[2]));
5933           return "sub{w}\t{%2, %0|%0, %2}";
5934         }
5935       return "add{w}\t{%2, %0|%0, %2}";
5936     }
5937 }
5938   [(set (attr "type")
5939      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940         (const_string "incdec")
5941         (const_string "alu")))
5942    (set_attr "mode" "HI")])
5943
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946   [(set (reg FLAGS_REG)
5947         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948                  (match_operand:HI 2 "const_int_operand" "n")))
5949    (clobber (match_scratch:HI 0 "=rm"))]
5950   "ix86_match_ccmode (insn, CCGCmode)
5951    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5952 {
5953   switch (get_attr_type (insn))
5954     {
5955     case TYPE_INCDEC:
5956       if (operands[2] == constm1_rtx)
5957         return "inc{w}\t%0";
5958       else
5959         {
5960           gcc_assert (operands[2] == const1_rtx);
5961           return "dec{w}\t%0";
5962         }
5963
5964     default:
5965       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5968       if ((INTVAL (operands[2]) == -128
5969            || (INTVAL (operands[2]) > 0
5970                && INTVAL (operands[2]) != 128)))
5971         return "sub{w}\t{%2, %0|%0, %2}";
5972       operands[2] = GEN_INT (-INTVAL (operands[2]));
5973       return "add{w}\t{%2, %0|%0, %2}";
5974     }
5975 }
5976   [(set (attr "type")
5977      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978         (const_string "incdec")
5979         (const_string "alu")))
5980    (set_attr "mode" "SI")])
5981
5982
5983 (define_insn "*addhi_5"
5984   [(set (reg FLAGS_REG)
5985         (compare
5986           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987                    (match_operand:HI 2 "general_operand" "rmni"))
5988           (const_int 0)))                       
5989    (clobber (match_scratch:HI 0 "=r"))]
5990   "ix86_match_ccmode (insn, CCGOCmode)
5991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5992 {
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_INCDEC:
5996       if (operands[2] == const1_rtx)
5997         return "inc{w}\t%0";
5998       else
5999         {
6000           gcc_assert (operands[2] == constm1_rtx);
6001           return "dec{w}\t%0";
6002         }
6003
6004     default:
6005       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6007       if (GET_CODE (operands[2]) == CONST_INT
6008           && (INTVAL (operands[2]) == 128
6009               || (INTVAL (operands[2]) < 0
6010                   && INTVAL (operands[2]) != -128)))
6011         {
6012           operands[2] = GEN_INT (-INTVAL (operands[2]));
6013           return "sub{w}\t{%2, %0|%0, %2}";
6014         }
6015       return "add{w}\t{%2, %0|%0, %2}";
6016     }
6017 }
6018   [(set (attr "type")
6019      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020         (const_string "incdec")
6021         (const_string "alu")))
6022    (set_attr "mode" "HI")])
6023
6024 (define_expand "addqi3"
6025   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027                             (match_operand:QI 2 "general_operand" "")))
6028               (clobber (reg:CC FLAGS_REG))])]
6029   "TARGET_QIMODE_MATH"
6030   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6031
6032 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6033 (define_insn "*addqi_1_lea"
6034   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037    (clobber (reg:CC FLAGS_REG))]
6038   "!TARGET_PARTIAL_REG_STALL
6039    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6040 {
6041   int widen = (which_alternative == 2);
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_LEA:
6045       return "#";
6046     case TYPE_INCDEC:
6047       if (operands[2] == const1_rtx)
6048         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6049       else
6050         {
6051           gcc_assert (operands[2] == constm1_rtx);
6052           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6053         }
6054
6055     default:
6056       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6058       if (GET_CODE (operands[2]) == CONST_INT
6059           && (INTVAL (operands[2]) == 128
6060               || (INTVAL (operands[2]) < 0
6061                   && INTVAL (operands[2]) != -128)))
6062         {
6063           operands[2] = GEN_INT (-INTVAL (operands[2]));
6064           if (widen)
6065             return "sub{l}\t{%2, %k0|%k0, %2}";
6066           else
6067             return "sub{b}\t{%2, %0|%0, %2}";
6068         }
6069       if (widen)
6070         return "add{l}\t{%k2, %k0|%k0, %k2}";
6071       else
6072         return "add{b}\t{%2, %0|%0, %2}";
6073     }
6074 }
6075   [(set (attr "type")
6076      (if_then_else (eq_attr "alternative" "3")
6077         (const_string "lea")
6078         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079            (const_string "incdec")
6080            (const_string "alu"))))
6081    (set_attr "mode" "QI,QI,SI,SI")])
6082
6083 (define_insn "*addqi_1"
6084   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087    (clobber (reg:CC FLAGS_REG))]
6088   "TARGET_PARTIAL_REG_STALL
6089    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6090 {
6091   int widen = (which_alternative == 2);
6092   switch (get_attr_type (insn))
6093     {
6094     case TYPE_INCDEC:
6095       if (operands[2] == const1_rtx)
6096         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6097       else
6098         {
6099           gcc_assert (operands[2] == constm1_rtx);
6100           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6101         }
6102
6103     default:
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if (GET_CODE (operands[2]) == CONST_INT
6107           && (INTVAL (operands[2]) == 128
6108               || (INTVAL (operands[2]) < 0
6109                   && INTVAL (operands[2]) != -128)))
6110         {
6111           operands[2] = GEN_INT (-INTVAL (operands[2]));
6112           if (widen)
6113             return "sub{l}\t{%2, %k0|%k0, %2}";
6114           else
6115             return "sub{b}\t{%2, %0|%0, %2}";
6116         }
6117       if (widen)
6118         return "add{l}\t{%k2, %k0|%k0, %k2}";
6119       else
6120         return "add{b}\t{%2, %0|%0, %2}";
6121     }
6122 }
6123   [(set (attr "type")
6124      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125         (const_string "incdec")
6126         (const_string "alu")))
6127    (set_attr "mode" "QI,QI,SI")])
6128
6129 (define_insn "*addqi_1_slp"
6130   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131         (plus:QI (match_dup 0)
6132                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6133    (clobber (reg:CC FLAGS_REG))]
6134   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6136 {
6137   switch (get_attr_type (insn))
6138     {
6139     case TYPE_INCDEC:
6140       if (operands[1] == const1_rtx)
6141         return "inc{b}\t%0";
6142       else
6143         {
6144           gcc_assert (operands[1] == constm1_rtx);
6145           return "dec{b}\t%0";
6146         }
6147
6148     default:
6149       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6150       if (GET_CODE (operands[1]) == CONST_INT
6151           && INTVAL (operands[1]) < 0)
6152         {
6153           operands[1] = GEN_INT (-INTVAL (operands[1]));
6154           return "sub{b}\t{%1, %0|%0, %1}";
6155         }
6156       return "add{b}\t{%1, %0|%0, %1}";
6157     }
6158 }
6159   [(set (attr "type")
6160      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161         (const_string "incdec")
6162         (const_string "alu1")))
6163    (set (attr "memory")
6164      (if_then_else (match_operand 1 "memory_operand" "")
6165         (const_string "load")
6166         (const_string "none")))
6167    (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_2"
6170   [(set (reg FLAGS_REG)
6171         (compare
6172           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6174           (const_int 0)))
6175    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176         (plus:QI (match_dup 1) (match_dup 2)))]
6177   "ix86_match_ccmode (insn, CCGOCmode)
6178    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6179 {
6180   switch (get_attr_type (insn))
6181     {
6182     case TYPE_INCDEC:
6183       if (operands[2] == const1_rtx)
6184         return "inc{b}\t%0";
6185       else
6186         {
6187           gcc_assert (operands[2] == constm1_rtx
6188                       || (GET_CODE (operands[2]) == CONST_INT
6189                           && INTVAL (operands[2]) == 255));
6190           return "dec{b}\t%0";
6191         }
6192
6193     default:
6194       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6195       if (GET_CODE (operands[2]) == CONST_INT
6196           && INTVAL (operands[2]) < 0)
6197         {
6198           operands[2] = GEN_INT (-INTVAL (operands[2]));
6199           return "sub{b}\t{%2, %0|%0, %2}";
6200         }
6201       return "add{b}\t{%2, %0|%0, %2}";
6202     }
6203 }
6204   [(set (attr "type")
6205      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206         (const_string "incdec")
6207         (const_string "alu")))
6208    (set_attr "mode" "QI")])
6209
6210 (define_insn "*addqi_3"
6211   [(set (reg FLAGS_REG)
6212         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214    (clobber (match_scratch:QI 0 "=q"))]
6215   "ix86_match_ccmode (insn, CCZmode)
6216    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6217 {
6218   switch (get_attr_type (insn))
6219     {
6220     case TYPE_INCDEC:
6221       if (operands[2] == const1_rtx)
6222         return "inc{b}\t%0";
6223       else
6224         {
6225           gcc_assert (operands[2] == constm1_rtx
6226                       || (GET_CODE (operands[2]) == CONST_INT
6227                           && INTVAL (operands[2]) == 255));
6228           return "dec{b}\t%0";
6229         }
6230
6231     default:
6232       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6233       if (GET_CODE (operands[2]) == CONST_INT
6234           && INTVAL (operands[2]) < 0)
6235         {
6236           operands[2] = GEN_INT (-INTVAL (operands[2]));
6237           return "sub{b}\t{%2, %0|%0, %2}";
6238         }
6239       return "add{b}\t{%2, %0|%0, %2}";
6240     }
6241 }
6242   [(set (attr "type")
6243      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244         (const_string "incdec")
6245         (const_string "alu")))
6246    (set_attr "mode" "QI")])
6247
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250   [(set (reg FLAGS_REG)
6251         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252                  (match_operand:QI 2 "const_int_operand" "n")))
6253    (clobber (match_scratch:QI 0 "=qm"))]
6254   "ix86_match_ccmode (insn, CCGCmode)
6255    && (INTVAL (operands[2]) & 0xff) != 0x80"
6256 {
6257   switch (get_attr_type (insn))
6258     {
6259     case TYPE_INCDEC:
6260       if (operands[2] == constm1_rtx
6261           || (GET_CODE (operands[2]) == CONST_INT
6262               && INTVAL (operands[2]) == 255))
6263         return "inc{b}\t%0";
6264       else
6265         {
6266           gcc_assert (operands[2] == const1_rtx);
6267           return "dec{b}\t%0";
6268         }
6269
6270     default:
6271       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272       if (INTVAL (operands[2]) < 0)
6273         {
6274           operands[2] = GEN_INT (-INTVAL (operands[2]));
6275           return "add{b}\t{%2, %0|%0, %2}";
6276         }
6277       return "sub{b}\t{%2, %0|%0, %2}";
6278     }
6279 }
6280   [(set (attr "type")
6281      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282         (const_string "incdec")
6283         (const_string "alu")))
6284    (set_attr "mode" "QI")])
6285
6286
6287 (define_insn "*addqi_5"
6288   [(set (reg FLAGS_REG)
6289         (compare
6290           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291                    (match_operand:QI 2 "general_operand" "qmni"))
6292           (const_int 0)))
6293    (clobber (match_scratch:QI 0 "=q"))]
6294   "ix86_match_ccmode (insn, CCGOCmode)
6295    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6296 {
6297   switch (get_attr_type (insn))
6298     {
6299     case TYPE_INCDEC:
6300       if (operands[2] == const1_rtx)
6301         return "inc{b}\t%0";
6302       else
6303         {
6304           gcc_assert (operands[2] == constm1_rtx
6305                       || (GET_CODE (operands[2]) == CONST_INT
6306                           && INTVAL (operands[2]) == 255));
6307           return "dec{b}\t%0";
6308         }
6309
6310     default:
6311       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6312       if (GET_CODE (operands[2]) == CONST_INT
6313           && INTVAL (operands[2]) < 0)
6314         {
6315           operands[2] = GEN_INT (-INTVAL (operands[2]));
6316           return "sub{b}\t{%2, %0|%0, %2}";
6317         }
6318       return "add{b}\t{%2, %0|%0, %2}";
6319     }
6320 }
6321   [(set (attr "type")
6322      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323         (const_string "incdec")
6324         (const_string "alu")))
6325    (set_attr "mode" "QI")])
6326
6327
6328 (define_insn "addqi_ext_1"
6329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6330                          (const_int 8)
6331                          (const_int 8))
6332         (plus:SI
6333           (zero_extract:SI
6334             (match_operand 1 "ext_register_operand" "0")
6335             (const_int 8)
6336             (const_int 8))
6337           (match_operand:QI 2 "general_operand" "Qmn")))
6338    (clobber (reg:CC FLAGS_REG))]
6339   "!TARGET_64BIT"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == const1_rtx)
6345         return "inc{b}\t%h0";
6346       else
6347         {
6348           gcc_assert (operands[2] == constm1_rtx
6349                       || (GET_CODE (operands[2]) == CONST_INT
6350                           && INTVAL (operands[2]) == 255));
6351           return "dec{b}\t%h0";
6352         }
6353
6354     default:
6355       return "add{b}\t{%2, %h0|%h0, %2}";
6356     }
6357 }
6358   [(set (attr "type")
6359      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360         (const_string "incdec")
6361         (const_string "alu")))
6362    (set_attr "mode" "QI")])
6363
6364 (define_insn "*addqi_ext_1_rex64"
6365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366                          (const_int 8)
6367                          (const_int 8))
6368         (plus:SI
6369           (zero_extract:SI
6370             (match_operand 1 "ext_register_operand" "0")
6371             (const_int 8)
6372             (const_int 8))
6373           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "TARGET_64BIT"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%h0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx
6385                       || (GET_CODE (operands[2]) == CONST_INT
6386                           && INTVAL (operands[2]) == 255));
6387           return "dec{b}\t%h0";
6388         }
6389
6390     default:
6391       return "add{b}\t{%2, %h0|%h0, %2}";
6392     }
6393 }
6394   [(set (attr "type")
6395      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396         (const_string "incdec")
6397         (const_string "alu")))
6398    (set_attr "mode" "QI")])
6399
6400 (define_insn "*addqi_ext_2"
6401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402                          (const_int 8)
6403                          (const_int 8))
6404         (plus:SI
6405           (zero_extract:SI
6406             (match_operand 1 "ext_register_operand" "%0")
6407             (const_int 8)
6408             (const_int 8))
6409           (zero_extract:SI
6410             (match_operand 2 "ext_register_operand" "Q")
6411             (const_int 8)
6412             (const_int 8))))
6413    (clobber (reg:CC FLAGS_REG))]
6414   ""
6415   "add{b}\t{%h2, %h0|%h0, %h2}"
6416   [(set_attr "type" "alu")
6417    (set_attr "mode" "QI")])
6418
6419 ;; The patterns that match these are at the end of this file.
6420
6421 (define_expand "addxf3"
6422   [(set (match_operand:XF 0 "register_operand" "")
6423         (plus:XF (match_operand:XF 1 "register_operand" "")
6424                  (match_operand:XF 2 "register_operand" "")))]
6425   "TARGET_80387"
6426   "")
6427
6428 (define_expand "adddf3"
6429   [(set (match_operand:DF 0 "register_operand" "")
6430         (plus:DF (match_operand:DF 1 "register_operand" "")
6431                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6432   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6433   "")
6434
6435 (define_expand "addsf3"
6436   [(set (match_operand:SF 0 "register_operand" "")
6437         (plus:SF (match_operand:SF 1 "register_operand" "")
6438                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6439   "TARGET_80387 || TARGET_SSE_MATH"
6440   "")
6441 \f
6442 ;; Subtract instructions
6443
6444 ;; %%% splits for subditi3
6445
6446 (define_expand "subti3"
6447   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449                              (match_operand:TI 2 "x86_64_general_operand" "")))
6450               (clobber (reg:CC FLAGS_REG))])]
6451   "TARGET_64BIT"
6452   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6453
6454 (define_insn "*subti3_1"
6455   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6460   "#")
6461
6462 (define_split
6463   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465                   (match_operand:TI 2 "general_operand" "")))
6466    (clobber (reg:CC FLAGS_REG))]
6467   "TARGET_64BIT && reload_completed"
6468   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470    (parallel [(set (match_dup 3)
6471                    (minus:DI (match_dup 4)
6472                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6473                                       (match_dup 5))))
6474               (clobber (reg:CC FLAGS_REG))])]
6475   "split_ti (operands+0, 1, operands+0, operands+3);
6476    split_ti (operands+1, 1, operands+1, operands+4);
6477    split_ti (operands+2, 1, operands+2, operands+5);")
6478
6479 ;; %%% splits for subsidi3
6480
6481 (define_expand "subdi3"
6482   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484                              (match_operand:DI 2 "x86_64_general_operand" "")))
6485               (clobber (reg:CC FLAGS_REG))])]
6486   ""
6487   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6488
6489 (define_insn "*subdi3_1"
6490   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6495   "#")
6496
6497 (define_split
6498   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500                   (match_operand:DI 2 "general_operand" "")))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "!TARGET_64BIT && reload_completed"
6503   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6505    (parallel [(set (match_dup 3)
6506                    (minus:SI (match_dup 4)
6507                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6508                                       (match_dup 5))))
6509               (clobber (reg:CC FLAGS_REG))])]
6510   "split_di (operands+0, 1, operands+0, operands+3);
6511    split_di (operands+1, 1, operands+1, operands+4);
6512    split_di (operands+2, 1, operands+2, operands+5);")
6513
6514 (define_insn "subdi3_carry_rex64"
6515   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521   "sbb{q}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "pent_pair" "pu")
6524    (set_attr "mode" "DI")])
6525
6526 (define_insn "*subdi_1_rex64"
6527   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532   "sub{q}\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "mode" "DI")])
6535
6536 (define_insn "*subdi_2_rex64"
6537   [(set (reg FLAGS_REG)
6538         (compare
6539           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6541           (const_int 0)))
6542    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543         (minus:DI (match_dup 1) (match_dup 2)))]
6544   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546   "sub{q}\t{%2, %0|%0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "mode" "DI")])
6549
6550 (define_insn "*subdi_3_rex63"
6551   [(set (reg FLAGS_REG)
6552         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555         (minus:DI (match_dup 1) (match_dup 2)))]
6556   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558   "sub{q}\t{%2, %0|%0, %2}"
6559   [(set_attr "type" "alu")
6560    (set_attr "mode" "DI")])
6561
6562 (define_insn "subqi3_carry"
6563   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566                (match_operand:QI 2 "general_operand" "qi,qm"))))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569   "sbb{b}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "alu")
6571    (set_attr "pent_pair" "pu")
6572    (set_attr "mode" "QI")])
6573
6574 (define_insn "subhi3_carry"
6575   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578                (match_operand:HI 2 "general_operand" "ri,rm"))))
6579    (clobber (reg:CC FLAGS_REG))]
6580   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581   "sbb{w}\t{%2, %0|%0, %2}"
6582   [(set_attr "type" "alu")
6583    (set_attr "pent_pair" "pu")
6584    (set_attr "mode" "HI")])
6585
6586 (define_insn "subsi3_carry"
6587   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590                (match_operand:SI 2 "general_operand" "ri,rm"))))
6591    (clobber (reg:CC FLAGS_REG))]
6592   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593   "sbb{l}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "alu")
6595    (set_attr "pent_pair" "pu")
6596    (set_attr "mode" "SI")])
6597
6598 (define_insn "subsi3_carry_zext"
6599   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6600           (zero_extend:DI
6601             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6604    (clobber (reg:CC FLAGS_REG))]
6605   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606   "sbb{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "pent_pair" "pu")
6609    (set_attr "mode" "SI")])
6610
6611 (define_expand "subsi3"
6612   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614                              (match_operand:SI 2 "general_operand" "")))
6615               (clobber (reg:CC FLAGS_REG))])]
6616   ""
6617   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6618
6619 (define_insn "*subsi_1"
6620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622                   (match_operand:SI 2 "general_operand" "ri,rm")))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625   "sub{l}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "mode" "SI")])
6628
6629 (define_insn "*subsi_1_zext"
6630   [(set (match_operand:DI 0 "register_operand" "=r")
6631         (zero_extend:DI
6632           (minus:SI (match_operand:SI 1 "register_operand" "0")
6633                     (match_operand:SI 2 "general_operand" "rim"))))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636   "sub{l}\t{%2, %k0|%k0, %2}"
6637   [(set_attr "type" "alu")
6638    (set_attr "mode" "SI")])
6639
6640 (define_insn "*subsi_2"
6641   [(set (reg FLAGS_REG)
6642         (compare
6643           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644                     (match_operand:SI 2 "general_operand" "ri,rm"))
6645           (const_int 0)))
6646    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:SI (match_dup 1) (match_dup 2)))]
6648   "ix86_match_ccmode (insn, CCGOCmode)
6649    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sub{l}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "SI")])
6653
6654 (define_insn "*subsi_2_zext"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:SI (match_operand:SI 1 "register_operand" "0")
6658                     (match_operand:SI 2 "general_operand" "rim"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "register_operand" "=r")
6661         (zero_extend:DI
6662           (minus:SI (match_dup 1)
6663                     (match_dup 2))))]
6664   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666   "sub{l}\t{%2, %k0|%k0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "SI")])
6669
6670 (define_insn "*subsi_3"
6671   [(set (reg FLAGS_REG)
6672         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673                  (match_operand:SI 2 "general_operand" "ri,rm")))
6674    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675         (minus:SI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCmode)
6677    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678   "sub{l}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "SI")])
6681
6682 (define_insn "*subsi_3_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare (match_operand:SI 1 "register_operand" "0")
6685                  (match_operand:SI 2 "general_operand" "rim")))
6686    (set (match_operand:DI 0 "register_operand" "=r")
6687         (zero_extend:DI
6688           (minus:SI (match_dup 1)
6689                     (match_dup 2))))]
6690   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692   "sub{q}\t{%2, %0|%0, %2}"
6693   [(set_attr "type" "alu")
6694    (set_attr "mode" "DI")])
6695
6696 (define_expand "subhi3"
6697   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699                              (match_operand:HI 2 "general_operand" "")))
6700               (clobber (reg:CC FLAGS_REG))])]
6701   "TARGET_HIMODE_MATH"
6702   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6703
6704 (define_insn "*subhi_1"
6705   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707                   (match_operand:HI 2 "general_operand" "ri,rm")))
6708    (clobber (reg:CC FLAGS_REG))]
6709   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710   "sub{w}\t{%2, %0|%0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "HI")])
6713
6714 (define_insn "*subhi_2"
6715   [(set (reg FLAGS_REG)
6716         (compare
6717           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718                     (match_operand:HI 2 "general_operand" "ri,rm"))
6719           (const_int 0)))
6720    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721         (minus:HI (match_dup 1) (match_dup 2)))]
6722   "ix86_match_ccmode (insn, CCGOCmode)
6723    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724   "sub{w}\t{%2, %0|%0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "mode" "HI")])
6727
6728 (define_insn "*subhi_3"
6729   [(set (reg FLAGS_REG)
6730         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731                  (match_operand:HI 2 "general_operand" "ri,rm")))
6732    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733         (minus:HI (match_dup 1) (match_dup 2)))]
6734   "ix86_match_ccmode (insn, CCmode)
6735    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736   "sub{w}\t{%2, %0|%0, %2}"
6737   [(set_attr "type" "alu")
6738    (set_attr "mode" "HI")])
6739
6740 (define_expand "subqi3"
6741   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743                              (match_operand:QI 2 "general_operand" "")))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   "TARGET_QIMODE_MATH"
6746   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6747
6748 (define_insn "*subqi_1"
6749   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754   "sub{b}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "QI")])
6757
6758 (define_insn "*subqi_1_slp"
6759   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760         (minus:QI (match_dup 0)
6761                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6762    (clobber (reg:CC FLAGS_REG))]
6763   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765   "sub{b}\t{%1, %0|%0, %1}"
6766   [(set_attr "type" "alu1")
6767    (set_attr "mode" "QI")])
6768
6769 (define_insn "*subqi_2"
6770   [(set (reg FLAGS_REG)
6771         (compare
6772           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773                     (match_operand:QI 2 "general_operand" "qi,qm"))
6774           (const_int 0)))
6775    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776         (minus:HI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCGOCmode)
6778    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779   "sub{b}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "QI")])
6782
6783 (define_insn "*subqi_3"
6784   [(set (reg FLAGS_REG)
6785         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786                  (match_operand:QI 2 "general_operand" "qi,qm")))
6787    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788         (minus:HI (match_dup 1) (match_dup 2)))]
6789   "ix86_match_ccmode (insn, CCmode)
6790    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791   "sub{b}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "mode" "QI")])
6794
6795 ;; The patterns that match these are at the end of this file.
6796
6797 (define_expand "subxf3"
6798   [(set (match_operand:XF 0 "register_operand" "")
6799         (minus:XF (match_operand:XF 1 "register_operand" "")
6800                   (match_operand:XF 2 "register_operand" "")))]
6801   "TARGET_80387"
6802   "")
6803
6804 (define_expand "subdf3"
6805   [(set (match_operand:DF 0 "register_operand" "")
6806         (minus:DF (match_operand:DF 1 "register_operand" "")
6807                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6808   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6809   "")
6810
6811 (define_expand "subsf3"
6812   [(set (match_operand:SF 0 "register_operand" "")
6813         (minus:SF (match_operand:SF 1 "register_operand" "")
6814                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6815   "TARGET_80387 || TARGET_SSE_MATH"
6816   "")
6817 \f
6818 ;; Multiply instructions
6819
6820 (define_expand "muldi3"
6821   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822                    (mult:DI (match_operand:DI 1 "register_operand" "")
6823                             (match_operand:DI 2 "x86_64_general_operand" "")))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   "TARGET_64BIT"
6826   "")
6827
6828 (define_insn "*muldi3_1_rex64"
6829   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832    (clobber (reg:CC FLAGS_REG))]
6833   "TARGET_64BIT
6834    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6835   "@
6836    imul{q}\t{%2, %1, %0|%0, %1, %2}
6837    imul{q}\t{%2, %1, %0|%0, %1, %2}
6838    imul{q}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "imul")
6840    (set_attr "prefix_0f" "0,0,1")
6841    (set (attr "athlon_decode")
6842         (cond [(eq_attr "cpu" "athlon")
6843                   (const_string "vector")
6844                (eq_attr "alternative" "1")
6845                   (const_string "vector")
6846                (and (eq_attr "alternative" "2")
6847                     (match_operand 1 "memory_operand" ""))
6848                   (const_string "vector")]
6849               (const_string "direct")))
6850    (set_attr "mode" "DI")])
6851
6852 (define_expand "mulsi3"
6853   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854                    (mult:SI (match_operand:SI 1 "register_operand" "")
6855                             (match_operand:SI 2 "general_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   ""
6858   "")
6859
6860 (define_insn "*mulsi3_1"
6861   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6866   "@
6867    imul{l}\t{%2, %1, %0|%0, %1, %2}
6868    imul{l}\t{%2, %1, %0|%0, %1, %2}
6869    imul{l}\t{%2, %0|%0, %2}"
6870   [(set_attr "type" "imul")
6871    (set_attr "prefix_0f" "0,0,1")
6872    (set (attr "athlon_decode")
6873         (cond [(eq_attr "cpu" "athlon")
6874                   (const_string "vector")
6875                (eq_attr "alternative" "1")
6876                   (const_string "vector")
6877                (and (eq_attr "alternative" "2")
6878                     (match_operand 1 "memory_operand" ""))
6879                   (const_string "vector")]
6880               (const_string "direct")))
6881    (set_attr "mode" "SI")])
6882
6883 (define_insn "*mulsi3_1_zext"
6884   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6885         (zero_extend:DI
6886           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "TARGET_64BIT
6890    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891   "@
6892    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894    imul{l}\t{%2, %k0|%k0, %2}"
6895   [(set_attr "type" "imul")
6896    (set_attr "prefix_0f" "0,0,1")
6897    (set (attr "athlon_decode")
6898         (cond [(eq_attr "cpu" "athlon")
6899                   (const_string "vector")
6900                (eq_attr "alternative" "1")
6901                   (const_string "vector")
6902                (and (eq_attr "alternative" "2")
6903                     (match_operand 1 "memory_operand" ""))
6904                   (const_string "vector")]
6905               (const_string "direct")))
6906    (set_attr "mode" "SI")])
6907
6908 (define_expand "mulhi3"
6909   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910                    (mult:HI (match_operand:HI 1 "register_operand" "")
6911                             (match_operand:HI 2 "general_operand" "")))
6912               (clobber (reg:CC FLAGS_REG))])]
6913   "TARGET_HIMODE_MATH"
6914   "")
6915
6916 (define_insn "*mulhi3_1"
6917   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6920    (clobber (reg:CC FLAGS_REG))]
6921   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6922   "@
6923    imul{w}\t{%2, %1, %0|%0, %1, %2}
6924    imul{w}\t{%2, %1, %0|%0, %1, %2}
6925    imul{w}\t{%2, %0|%0, %2}"
6926   [(set_attr "type" "imul")
6927    (set_attr "prefix_0f" "0,0,1")
6928    (set (attr "athlon_decode")
6929         (cond [(eq_attr "cpu" "athlon")
6930                   (const_string "vector")
6931                (eq_attr "alternative" "1,2")
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "HI")])
6935
6936 (define_expand "mulqi3"
6937   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939                             (match_operand:QI 2 "register_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_QIMODE_MATH"
6942   "")
6943
6944 (define_insn "*mulqi3_1"
6945   [(set (match_operand:QI 0 "register_operand" "=a")
6946         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "TARGET_QIMODE_MATH
6950    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6951   "mul{b}\t%2"
6952   [(set_attr "type" "imul")
6953    (set_attr "length_immediate" "0")
6954    (set (attr "athlon_decode")
6955      (if_then_else (eq_attr "cpu" "athlon")
6956         (const_string "vector")
6957         (const_string "direct")))
6958    (set_attr "mode" "QI")])
6959
6960 (define_expand "umulqihi3"
6961   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962                    (mult:HI (zero_extend:HI
6963                               (match_operand:QI 1 "nonimmediate_operand" ""))
6964                             (zero_extend:HI
6965                               (match_operand:QI 2 "register_operand" ""))))
6966               (clobber (reg:CC FLAGS_REG))])]
6967   "TARGET_QIMODE_MATH"
6968   "")
6969
6970 (define_insn "*umulqihi3_1"
6971   [(set (match_operand:HI 0 "register_operand" "=a")
6972         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974    (clobber (reg:CC FLAGS_REG))]
6975   "TARGET_QIMODE_MATH
6976    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6977   "mul{b}\t%2"
6978   [(set_attr "type" "imul")
6979    (set_attr "length_immediate" "0")
6980    (set (attr "athlon_decode")
6981      (if_then_else (eq_attr "cpu" "athlon")
6982         (const_string "vector")
6983         (const_string "direct")))
6984    (set_attr "mode" "QI")])
6985
6986 (define_expand "mulqihi3"
6987   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990               (clobber (reg:CC FLAGS_REG))])]
6991   "TARGET_QIMODE_MATH"
6992   "")
6993
6994 (define_insn "*mulqihi3_insn"
6995   [(set (match_operand:HI 0 "register_operand" "=a")
6996         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998    (clobber (reg:CC FLAGS_REG))]
6999   "TARGET_QIMODE_MATH
7000    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001   "imul{b}\t%2"
7002   [(set_attr "type" "imul")
7003    (set_attr "length_immediate" "0")
7004    (set (attr "athlon_decode")
7005      (if_then_else (eq_attr "cpu" "athlon")
7006         (const_string "vector")
7007         (const_string "direct")))
7008    (set_attr "mode" "QI")])
7009
7010 (define_expand "umulditi3"
7011   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012                    (mult:TI (zero_extend:TI
7013                               (match_operand:DI 1 "nonimmediate_operand" ""))
7014                             (zero_extend:TI
7015                               (match_operand:DI 2 "register_operand" ""))))
7016               (clobber (reg:CC FLAGS_REG))])]
7017   "TARGET_64BIT"
7018   "")
7019
7020 (define_insn "*umulditi3_insn"
7021   [(set (match_operand:TI 0 "register_operand" "=A")
7022         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024    (clobber (reg:CC FLAGS_REG))]
7025   "TARGET_64BIT
7026    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7027   "mul{q}\t%2"
7028   [(set_attr "type" "imul")
7029    (set_attr "length_immediate" "0")
7030    (set (attr "athlon_decode")
7031      (if_then_else (eq_attr "cpu" "athlon")
7032         (const_string "vector")
7033         (const_string "double")))
7034    (set_attr "mode" "DI")])
7035
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039                    (mult:DI (zero_extend:DI
7040                               (match_operand:SI 1 "nonimmediate_operand" ""))
7041                             (zero_extend:DI
7042                               (match_operand:SI 2 "register_operand" ""))))
7043               (clobber (reg:CC FLAGS_REG))])]
7044   "!TARGET_64BIT"
7045   "")
7046
7047 (define_insn "*umulsidi3_insn"
7048   [(set (match_operand:DI 0 "register_operand" "=A")
7049         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051    (clobber (reg:CC FLAGS_REG))]
7052   "!TARGET_64BIT
7053    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054   "mul{l}\t%2"
7055   [(set_attr "type" "imul")
7056    (set_attr "length_immediate" "0")
7057    (set (attr "athlon_decode")
7058      (if_then_else (eq_attr "cpu" "athlon")
7059         (const_string "vector")
7060         (const_string "double")))
7061    (set_attr "mode" "SI")])
7062
7063 (define_expand "mulditi3"
7064   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065                    (mult:TI (sign_extend:TI
7066                               (match_operand:DI 1 "nonimmediate_operand" ""))
7067                             (sign_extend:TI
7068                               (match_operand:DI 2 "register_operand" ""))))
7069               (clobber (reg:CC FLAGS_REG))])]
7070   "TARGET_64BIT"
7071   "")
7072
7073 (define_insn "*mulditi3_insn"
7074   [(set (match_operand:TI 0 "register_operand" "=A")
7075         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "TARGET_64BIT
7079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080   "imul{q}\t%2"
7081   [(set_attr "type" "imul")
7082    (set_attr "length_immediate" "0")
7083    (set (attr "athlon_decode")
7084      (if_then_else (eq_attr "cpu" "athlon")
7085         (const_string "vector")
7086         (const_string "double")))
7087    (set_attr "mode" "DI")])
7088
7089 (define_expand "mulsidi3"
7090   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091                    (mult:DI (sign_extend:DI
7092                               (match_operand:SI 1 "nonimmediate_operand" ""))
7093                             (sign_extend:DI
7094                               (match_operand:SI 2 "register_operand" ""))))
7095               (clobber (reg:CC FLAGS_REG))])]
7096   "!TARGET_64BIT"
7097   "")
7098
7099 (define_insn "*mulsidi3_insn"
7100   [(set (match_operand:DI 0 "register_operand" "=A")
7101         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103    (clobber (reg:CC FLAGS_REG))]
7104   "!TARGET_64BIT
7105    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106   "imul{l}\t%2"
7107   [(set_attr "type" "imul")
7108    (set_attr "length_immediate" "0")
7109    (set (attr "athlon_decode")
7110      (if_then_else (eq_attr "cpu" "athlon")
7111         (const_string "vector")
7112         (const_string "double")))
7113    (set_attr "mode" "SI")])
7114
7115 (define_expand "umuldi3_highpart"
7116   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7117                    (truncate:DI
7118                      (lshiftrt:TI
7119                        (mult:TI (zero_extend:TI
7120                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7121                                 (zero_extend:TI
7122                                   (match_operand:DI 2 "register_operand" "")))
7123                        (const_int 64))))
7124               (clobber (match_scratch:DI 3 ""))
7125               (clobber (reg:CC FLAGS_REG))])]
7126   "TARGET_64BIT"
7127   "")
7128
7129 (define_insn "*umuldi3_highpart_rex64"
7130   [(set (match_operand:DI 0 "register_operand" "=d")
7131         (truncate:DI
7132           (lshiftrt:TI
7133             (mult:TI (zero_extend:TI
7134                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7135                      (zero_extend:TI
7136                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7137             (const_int 64))))
7138    (clobber (match_scratch:DI 3 "=1"))
7139    (clobber (reg:CC FLAGS_REG))]
7140   "TARGET_64BIT
7141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142   "mul{q}\t%2"
7143   [(set_attr "type" "imul")
7144    (set_attr "length_immediate" "0")
7145    (set (attr "athlon_decode")
7146      (if_then_else (eq_attr "cpu" "athlon")
7147         (const_string "vector")
7148         (const_string "double")))
7149    (set_attr "mode" "DI")])
7150
7151 (define_expand "umulsi3_highpart"
7152   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7153                    (truncate:SI
7154                      (lshiftrt:DI
7155                        (mult:DI (zero_extend:DI
7156                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7157                                 (zero_extend:DI
7158                                   (match_operand:SI 2 "register_operand" "")))
7159                        (const_int 32))))
7160               (clobber (match_scratch:SI 3 ""))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   ""
7163   "")
7164
7165 (define_insn "*umulsi3_highpart_insn"
7166   [(set (match_operand:SI 0 "register_operand" "=d")
7167         (truncate:SI
7168           (lshiftrt:DI
7169             (mult:DI (zero_extend:DI
7170                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7171                      (zero_extend:DI
7172                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7173             (const_int 32))))
7174    (clobber (match_scratch:SI 3 "=1"))
7175    (clobber (reg:CC FLAGS_REG))]
7176   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7177   "mul{l}\t%2"
7178   [(set_attr "type" "imul")
7179    (set_attr "length_immediate" "0")
7180    (set (attr "athlon_decode")
7181      (if_then_else (eq_attr "cpu" "athlon")
7182         (const_string "vector")
7183         (const_string "double")))
7184    (set_attr "mode" "SI")])
7185
7186 (define_insn "*umulsi3_highpart_zext"
7187   [(set (match_operand:DI 0 "register_operand" "=d")
7188         (zero_extend:DI (truncate:SI
7189           (lshiftrt:DI
7190             (mult:DI (zero_extend:DI
7191                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7192                      (zero_extend:DI
7193                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7194             (const_int 32)))))
7195    (clobber (match_scratch:SI 3 "=1"))
7196    (clobber (reg:CC FLAGS_REG))]
7197   "TARGET_64BIT
7198    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7199   "mul{l}\t%2"
7200   [(set_attr "type" "imul")
7201    (set_attr "length_immediate" "0")
7202    (set (attr "athlon_decode")
7203      (if_then_else (eq_attr "cpu" "athlon")
7204         (const_string "vector")
7205         (const_string "double")))
7206    (set_attr "mode" "SI")])
7207
7208 (define_expand "smuldi3_highpart"
7209   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7210                    (truncate:DI
7211                      (lshiftrt:TI
7212                        (mult:TI (sign_extend:TI
7213                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7214                                 (sign_extend:TI
7215                                   (match_operand:DI 2 "register_operand" "")))
7216                        (const_int 64))))
7217               (clobber (match_scratch:DI 3 ""))
7218               (clobber (reg:CC FLAGS_REG))])]
7219   "TARGET_64BIT"
7220   "")
7221
7222 (define_insn "*smuldi3_highpart_rex64"
7223   [(set (match_operand:DI 0 "register_operand" "=d")
7224         (truncate:DI
7225           (lshiftrt:TI
7226             (mult:TI (sign_extend:TI
7227                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7228                      (sign_extend:TI
7229                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7230             (const_int 64))))
7231    (clobber (match_scratch:DI 3 "=1"))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_64BIT
7234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235   "imul{q}\t%2"
7236   [(set_attr "type" "imul")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "DI")])
7242
7243 (define_expand "smulsi3_highpart"
7244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245                    (truncate:SI
7246                      (lshiftrt:DI
7247                        (mult:DI (sign_extend:DI
7248                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7249                                 (sign_extend:DI
7250                                   (match_operand:SI 2 "register_operand" "")))
7251                        (const_int 32))))
7252               (clobber (match_scratch:SI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   "")
7256
7257 (define_insn "*smulsi3_highpart_insn"
7258   [(set (match_operand:SI 0 "register_operand" "=d")
7259         (truncate:SI
7260           (lshiftrt:DI
7261             (mult:DI (sign_extend:DI
7262                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263                      (sign_extend:DI
7264                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269   "imul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "mode" "SI")])
7276
7277 (define_insn "*smulsi3_highpart_zext"
7278   [(set (match_operand:DI 0 "register_operand" "=d")
7279         (zero_extend:DI (truncate:SI
7280           (lshiftrt:DI
7281             (mult:DI (sign_extend:DI
7282                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283                      (sign_extend:DI
7284                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285             (const_int 32)))))
7286    (clobber (match_scratch:SI 3 "=1"))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_64BIT
7289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290   "imul{l}\t%2"
7291   [(set_attr "type" "imul")
7292    (set (attr "athlon_decode")
7293      (if_then_else (eq_attr "cpu" "athlon")
7294         (const_string "vector")
7295         (const_string "double")))
7296    (set_attr "mode" "SI")])
7297
7298 ;; The patterns that match these are at the end of this file.
7299
7300 (define_expand "mulxf3"
7301   [(set (match_operand:XF 0 "register_operand" "")
7302         (mult:XF (match_operand:XF 1 "register_operand" "")
7303                  (match_operand:XF 2 "register_operand" "")))]
7304   "TARGET_80387"
7305   "")
7306
7307 (define_expand "muldf3"
7308   [(set (match_operand:DF 0 "register_operand" "")
7309         (mult:DF (match_operand:DF 1 "register_operand" "")
7310                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7311   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7312   "")
7313
7314 (define_expand "mulsf3"
7315   [(set (match_operand:SF 0 "register_operand" "")
7316         (mult:SF (match_operand:SF 1 "register_operand" "")
7317                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7318   "TARGET_80387 || TARGET_SSE_MATH"
7319   "")
7320 \f
7321 ;; Divide instructions
7322
7323 (define_insn "divqi3"
7324   [(set (match_operand:QI 0 "register_operand" "=a")
7325         (div:QI (match_operand:HI 1 "register_operand" "0")
7326                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_QIMODE_MATH"
7329   "idiv{b}\t%2"
7330   [(set_attr "type" "idiv")
7331    (set_attr "mode" "QI")])
7332
7333 (define_insn "udivqi3"
7334   [(set (match_operand:QI 0 "register_operand" "=a")
7335         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_QIMODE_MATH"
7339   "div{b}\t%2"
7340   [(set_attr "type" "idiv")
7341    (set_attr "mode" "QI")])
7342
7343 ;; The patterns that match these are at the end of this file.
7344
7345 (define_expand "divxf3"
7346   [(set (match_operand:XF 0 "register_operand" "")
7347         (div:XF (match_operand:XF 1 "register_operand" "")
7348                 (match_operand:XF 2 "register_operand" "")))]
7349   "TARGET_80387"
7350   "")
7351
7352 (define_expand "divdf3"
7353   [(set (match_operand:DF 0 "register_operand" "")
7354         (div:DF (match_operand:DF 1 "register_operand" "")
7355                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7357    "")
7358  
7359 (define_expand "divsf3"
7360   [(set (match_operand:SF 0 "register_operand" "")
7361         (div:SF (match_operand:SF 1 "register_operand" "")
7362                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363   "TARGET_80387 || TARGET_SSE_MATH"
7364   "")
7365 \f
7366 ;; Remainder instructions.
7367
7368 (define_expand "divmoddi4"
7369   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370                    (div:DI (match_operand:DI 1 "register_operand" "")
7371                            (match_operand:DI 2 "nonimmediate_operand" "")))
7372               (set (match_operand:DI 3 "register_operand" "")
7373                    (mod:DI (match_dup 1) (match_dup 2)))
7374               (clobber (reg:CC FLAGS_REG))])]
7375   "TARGET_64BIT"
7376   "")
7377
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7380 ;; of code.
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386         (mod:DI (match_dup 2) (match_dup 3)))
7387    (clobber (reg:CC FLAGS_REG))]
7388   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7389   "#"
7390   [(set_attr "type" "multi")])
7391
7392 (define_insn "*divmoddi4_cltd_rex64"
7393   [(set (match_operand:DI 0 "register_operand" "=a")
7394         (div:DI (match_operand:DI 2 "register_operand" "a")
7395                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396    (set (match_operand:DI 1 "register_operand" "=&d")
7397         (mod:DI (match_dup 2) (match_dup 3)))
7398    (clobber (reg:CC FLAGS_REG))]
7399   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7400   "#"
7401   [(set_attr "type" "multi")])
7402
7403 (define_insn "*divmoddi_noext_rex64"
7404   [(set (match_operand:DI 0 "register_operand" "=a")
7405         (div:DI (match_operand:DI 1 "register_operand" "0")
7406                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407    (set (match_operand:DI 3 "register_operand" "=d")
7408         (mod:DI (match_dup 1) (match_dup 2)))
7409    (use (match_operand:DI 4 "register_operand" "3"))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "TARGET_64BIT"
7412   "idiv{q}\t%2"
7413   [(set_attr "type" "idiv")
7414    (set_attr "mode" "DI")])
7415
7416 (define_split
7417   [(set (match_operand:DI 0 "register_operand" "")
7418         (div:DI (match_operand:DI 1 "register_operand" "")
7419                 (match_operand:DI 2 "nonimmediate_operand" "")))
7420    (set (match_operand:DI 3 "register_operand" "")
7421         (mod:DI (match_dup 1) (match_dup 2)))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "TARGET_64BIT && reload_completed"
7424   [(parallel [(set (match_dup 3)
7425                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7426               (clobber (reg:CC FLAGS_REG))])
7427    (parallel [(set (match_dup 0)
7428                    (div:DI (reg:DI 0) (match_dup 2)))
7429               (set (match_dup 3)
7430                    (mod:DI (reg:DI 0) (match_dup 2)))
7431               (use (match_dup 3))
7432               (clobber (reg:CC FLAGS_REG))])]
7433 {
7434   /* Avoid use of cltd in favor of a mov+shift.  */
7435   if (!TARGET_USE_CLTD && !optimize_size)
7436     {
7437       if (true_regnum (operands[1]))
7438         emit_move_insn (operands[0], operands[1]);
7439       else
7440         emit_move_insn (operands[3], operands[1]);
7441       operands[4] = operands[3];
7442     }
7443   else
7444     {
7445       gcc_assert (!true_regnum (operands[1]));
7446       operands[4] = operands[1];
7447     }
7448 })
7449
7450
7451 (define_expand "divmodsi4"
7452   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453                    (div:SI (match_operand:SI 1 "register_operand" "")
7454                            (match_operand:SI 2 "nonimmediate_operand" "")))
7455               (set (match_operand:SI 3 "register_operand" "")
7456                    (mod:SI (match_dup 1) (match_dup 2)))
7457               (clobber (reg:CC FLAGS_REG))])]
7458   ""
7459   "")
7460
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7463 ;; of code.
7464 (define_insn "*divmodsi4_nocltd"
7465   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469         (mod:SI (match_dup 2) (match_dup 3)))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "!optimize_size && !TARGET_USE_CLTD"
7472   "#"
7473   [(set_attr "type" "multi")])
7474
7475 (define_insn "*divmodsi4_cltd"
7476   [(set (match_operand:SI 0 "register_operand" "=a")
7477         (div:SI (match_operand:SI 2 "register_operand" "a")
7478                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479    (set (match_operand:SI 1 "register_operand" "=&d")
7480         (mod:SI (match_dup 2) (match_dup 3)))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "optimize_size || TARGET_USE_CLTD"
7483   "#"
7484   [(set_attr "type" "multi")])
7485
7486 (define_insn "*divmodsi_noext"
7487   [(set (match_operand:SI 0 "register_operand" "=a")
7488         (div:SI (match_operand:SI 1 "register_operand" "0")
7489                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490    (set (match_operand:SI 3 "register_operand" "=d")
7491         (mod:SI (match_dup 1) (match_dup 2)))
7492    (use (match_operand:SI 4 "register_operand" "3"))
7493    (clobber (reg:CC FLAGS_REG))]
7494   ""
7495   "idiv{l}\t%2"
7496   [(set_attr "type" "idiv")
7497    (set_attr "mode" "SI")])
7498
7499 (define_split
7500   [(set (match_operand:SI 0 "register_operand" "")
7501         (div:SI (match_operand:SI 1 "register_operand" "")
7502                 (match_operand:SI 2 "nonimmediate_operand" "")))
7503    (set (match_operand:SI 3 "register_operand" "")
7504         (mod:SI (match_dup 1) (match_dup 2)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "reload_completed"
7507   [(parallel [(set (match_dup 3)
7508                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7509               (clobber (reg:CC FLAGS_REG))])
7510    (parallel [(set (match_dup 0)
7511                    (div:SI (reg:SI 0) (match_dup 2)))
7512               (set (match_dup 3)
7513                    (mod:SI (reg:SI 0) (match_dup 2)))
7514               (use (match_dup 3))
7515               (clobber (reg:CC FLAGS_REG))])]
7516 {
7517   /* Avoid use of cltd in favor of a mov+shift.  */
7518   if (!TARGET_USE_CLTD && !optimize_size)
7519     {
7520       if (true_regnum (operands[1]))
7521         emit_move_insn (operands[0], operands[1]);
7522       else
7523         emit_move_insn (operands[3], operands[1]);
7524       operands[4] = operands[3];
7525     }
7526   else
7527     {
7528       gcc_assert (!true_regnum (operands[1]));
7529       operands[4] = operands[1];
7530     }
7531 })
7532 ;; %%% Split me.
7533 (define_insn "divmodhi4"
7534   [(set (match_operand:HI 0 "register_operand" "=a")
7535         (div:HI (match_operand:HI 1 "register_operand" "0")
7536                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537    (set (match_operand:HI 3 "register_operand" "=&d")
7538         (mod:HI (match_dup 1) (match_dup 2)))
7539    (clobber (reg:CC FLAGS_REG))]
7540   "TARGET_HIMODE_MATH"
7541   "cwtd\;idiv{w}\t%2"
7542   [(set_attr "type" "multi")
7543    (set_attr "length_immediate" "0")
7544    (set_attr "mode" "SI")])
7545
7546 (define_insn "udivmoddi4"
7547   [(set (match_operand:DI 0 "register_operand" "=a")
7548         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550    (set (match_operand:DI 3 "register_operand" "=&d")
7551         (umod:DI (match_dup 1) (match_dup 2)))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "TARGET_64BIT"
7554   "xor{q}\t%3, %3\;div{q}\t%2"
7555   [(set_attr "type" "multi")
7556    (set_attr "length_immediate" "0")
7557    (set_attr "mode" "DI")])
7558
7559 (define_insn "*udivmoddi4_noext"
7560   [(set (match_operand:DI 0 "register_operand" "=a")
7561         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563    (set (match_operand:DI 3 "register_operand" "=d")
7564         (umod:DI (match_dup 1) (match_dup 2)))
7565    (use (match_dup 3))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT"
7568   "div{q}\t%2"
7569   [(set_attr "type" "idiv")
7570    (set_attr "mode" "DI")])
7571
7572 (define_split
7573   [(set (match_operand:DI 0 "register_operand" "")
7574         (udiv:DI (match_operand:DI 1 "register_operand" "")
7575                  (match_operand:DI 2 "nonimmediate_operand" "")))
7576    (set (match_operand:DI 3 "register_operand" "")
7577         (umod:DI (match_dup 1) (match_dup 2)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && reload_completed"
7580   [(set (match_dup 3) (const_int 0))
7581    (parallel [(set (match_dup 0)
7582                    (udiv:DI (match_dup 1) (match_dup 2)))
7583               (set (match_dup 3)
7584                    (umod:DI (match_dup 1) (match_dup 2)))
7585               (use (match_dup 3))
7586               (clobber (reg:CC FLAGS_REG))])]
7587   "")
7588
7589 (define_insn "udivmodsi4"
7590   [(set (match_operand:SI 0 "register_operand" "=a")
7591         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593    (set (match_operand:SI 3 "register_operand" "=&d")
7594         (umod:SI (match_dup 1) (match_dup 2)))
7595    (clobber (reg:CC FLAGS_REG))]
7596   ""
7597   "xor{l}\t%3, %3\;div{l}\t%2"
7598   [(set_attr "type" "multi")
7599    (set_attr "length_immediate" "0")
7600    (set_attr "mode" "SI")])
7601
7602 (define_insn "*udivmodsi4_noext"
7603   [(set (match_operand:SI 0 "register_operand" "=a")
7604         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606    (set (match_operand:SI 3 "register_operand" "=d")
7607         (umod:SI (match_dup 1) (match_dup 2)))
7608    (use (match_dup 3))
7609    (clobber (reg:CC FLAGS_REG))]
7610   ""
7611   "div{l}\t%2"
7612   [(set_attr "type" "idiv")
7613    (set_attr "mode" "SI")])
7614
7615 (define_split
7616   [(set (match_operand:SI 0 "register_operand" "")
7617         (udiv:SI (match_operand:SI 1 "register_operand" "")
7618                  (match_operand:SI 2 "nonimmediate_operand" "")))
7619    (set (match_operand:SI 3 "register_operand" "")
7620         (umod:SI (match_dup 1) (match_dup 2)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "reload_completed"
7623   [(set (match_dup 3) (const_int 0))
7624    (parallel [(set (match_dup 0)
7625                    (udiv:SI (match_dup 1) (match_dup 2)))
7626               (set (match_dup 3)
7627                    (umod:SI (match_dup 1) (match_dup 2)))
7628               (use (match_dup 3))
7629               (clobber (reg:CC FLAGS_REG))])]
7630   "")
7631
7632 (define_expand "udivmodhi4"
7633   [(set (match_dup 4) (const_int 0))
7634    (parallel [(set (match_operand:HI 0 "register_operand" "")
7635                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7636                             (match_operand:HI 2 "nonimmediate_operand" "")))
7637               (set (match_operand:HI 3 "register_operand" "")
7638                    (umod:HI (match_dup 1) (match_dup 2)))
7639               (use (match_dup 4))
7640               (clobber (reg:CC FLAGS_REG))])]
7641   "TARGET_HIMODE_MATH"
7642   "operands[4] = gen_reg_rtx (HImode);")
7643
7644 (define_insn "*udivmodhi_noext"
7645   [(set (match_operand:HI 0 "register_operand" "=a")
7646         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648    (set (match_operand:HI 3 "register_operand" "=d")
7649         (umod:HI (match_dup 1) (match_dup 2)))
7650    (use (match_operand:HI 4 "register_operand" "3"))
7651    (clobber (reg:CC FLAGS_REG))]
7652   ""
7653   "div{w}\t%2"
7654   [(set_attr "type" "idiv")
7655    (set_attr "mode" "HI")])
7656
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate.  Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7661 ;
7662 ;(define_insn ""
7663 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7664 ;       (truncate:SI
7665 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7666 ;                  (zero_extend:DI
7667 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ;   (set (match_operand:SI 3 "register_operand" "=d")
7669 ;       (truncate:SI
7670 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ;   (clobber (reg:CC FLAGS_REG))]
7672 ;  ""
7673 ;  "div{l}\t{%2, %0|%0, %2}"
7674 ;  [(set_attr "type" "idiv")])
7675 \f
7676 ;;- Logical AND instructions
7677
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7680
7681 (define_insn "*testdi_1_rex64"
7682   [(set (reg FLAGS_REG)
7683         (compare
7684           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7686           (const_int 0)))]
7687   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7689   "@
7690    test{l}\t{%k1, %k0|%k0, %k1}
7691    test{l}\t{%k1, %k0|%k0, %k1}
7692    test{q}\t{%1, %0|%0, %1}
7693    test{q}\t{%1, %0|%0, %1}
7694    test{q}\t{%1, %0|%0, %1}"
7695   [(set_attr "type" "test")
7696    (set_attr "modrm" "0,1,0,1,1")
7697    (set_attr "mode" "SI,SI,DI,DI,DI")
7698    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7699
7700 (define_insn "testsi_1"
7701   [(set (reg FLAGS_REG)
7702         (compare
7703           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7705           (const_int 0)))]
7706   "ix86_match_ccmode (insn, CCNOmode)
7707    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708   "test{l}\t{%1, %0|%0, %1}"
7709   [(set_attr "type" "test")
7710    (set_attr "modrm" "0,1,1")
7711    (set_attr "mode" "SI")
7712    (set_attr "pent_pair" "uv,np,uv")])
7713
7714 (define_expand "testsi_ccno_1"
7715   [(set (reg:CCNO FLAGS_REG)
7716         (compare:CCNO
7717           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718                   (match_operand:SI 1 "nonmemory_operand" ""))
7719           (const_int 0)))]
7720   ""
7721   "")
7722
7723 (define_insn "*testhi_1"
7724   [(set (reg FLAGS_REG)
7725         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7727                  (const_int 0)))]
7728   "ix86_match_ccmode (insn, CCNOmode)
7729    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730   "test{w}\t{%1, %0|%0, %1}"
7731   [(set_attr "type" "test")
7732    (set_attr "modrm" "0,1,1")
7733    (set_attr "mode" "HI")
7734    (set_attr "pent_pair" "uv,np,uv")])
7735
7736 (define_expand "testqi_ccz_1"
7737   [(set (reg:CCZ FLAGS_REG)
7738         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739                              (match_operand:QI 1 "nonmemory_operand" ""))
7740                  (const_int 0)))]
7741   ""
7742   "")
7743
7744 (define_insn "*testqi_1_maybe_si"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:QI
7748             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7750           (const_int 0)))]
7751    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752     && ix86_match_ccmode (insn,
7753                          GET_CODE (operands[1]) == CONST_INT
7754                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7755 {
7756   if (which_alternative == 3)
7757     {
7758       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760       return "test{l}\t{%1, %k0|%k0, %1}";
7761     }
7762   return "test{b}\t{%1, %0|%0, %1}";
7763 }
7764   [(set_attr "type" "test")
7765    (set_attr "modrm" "0,1,1,1")
7766    (set_attr "mode" "QI,QI,QI,SI")
7767    (set_attr "pent_pair" "uv,np,uv,np")])
7768
7769 (define_insn "*testqi_1"
7770   [(set (reg FLAGS_REG)
7771         (compare
7772           (and:QI
7773             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774             (match_operand:QI 1 "general_operand" "n,n,qn"))
7775           (const_int 0)))]
7776   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777    && ix86_match_ccmode (insn, CCNOmode)"
7778   "test{b}\t{%1, %0|%0, %1}"
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,1")
7781    (set_attr "mode" "QI")
7782    (set_attr "pent_pair" "uv,np,uv")])
7783
7784 (define_expand "testqi_ext_ccno_0"
7785   [(set (reg:CCNO FLAGS_REG)
7786         (compare:CCNO
7787           (and:SI
7788             (zero_extract:SI
7789               (match_operand 0 "ext_register_operand" "")
7790               (const_int 8)
7791               (const_int 8))
7792             (match_operand 1 "const_int_operand" ""))
7793           (const_int 0)))]
7794   ""
7795   "")
7796
7797 (define_insn "*testqi_ext_0"
7798   [(set (reg FLAGS_REG)
7799         (compare
7800           (and:SI
7801             (zero_extract:SI
7802               (match_operand 0 "ext_register_operand" "Q")
7803               (const_int 8)
7804               (const_int 8))
7805             (match_operand 1 "const_int_operand" "n"))
7806           (const_int 0)))]
7807   "ix86_match_ccmode (insn, CCNOmode)"
7808   "test{b}\t{%1, %h0|%h0, %1}"
7809   [(set_attr "type" "test")
7810    (set_attr "mode" "QI")
7811    (set_attr "length_immediate" "1")
7812    (set_attr "pent_pair" "np")])
7813
7814 (define_insn "*testqi_ext_1"
7815   [(set (reg FLAGS_REG)
7816         (compare
7817           (and:SI
7818             (zero_extract:SI
7819               (match_operand 0 "ext_register_operand" "Q")
7820               (const_int 8)
7821               (const_int 8))
7822             (zero_extend:SI
7823               (match_operand:QI 1 "general_operand" "Qm")))
7824           (const_int 0)))]
7825   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827   "test{b}\t{%1, %h0|%h0, %1}"
7828   [(set_attr "type" "test")
7829    (set_attr "mode" "QI")])
7830
7831 (define_insn "*testqi_ext_1_rex64"
7832   [(set (reg FLAGS_REG)
7833         (compare
7834           (and:SI
7835             (zero_extract:SI
7836               (match_operand 0 "ext_register_operand" "Q")
7837               (const_int 8)
7838               (const_int 8))
7839             (zero_extend:SI
7840               (match_operand:QI 1 "register_operand" "Q")))
7841           (const_int 0)))]
7842   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843   "test{b}\t{%1, %h0|%h0, %1}"
7844   [(set_attr "type" "test")
7845    (set_attr "mode" "QI")])
7846
7847 (define_insn "*testqi_ext_2"
7848   [(set (reg FLAGS_REG)
7849         (compare
7850           (and:SI
7851             (zero_extract:SI
7852               (match_operand 0 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8))
7855             (zero_extract:SI
7856               (match_operand 1 "ext_register_operand" "Q")
7857               (const_int 8)
7858               (const_int 8)))
7859           (const_int 0)))]
7860   "ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%h1, %h0|%h0, %h1}"
7862   [(set_attr "type" "test")
7863    (set_attr "mode" "QI")])
7864
7865 ;; Combine likes to form bit extractions for some tests.  Humor it.
7866 (define_insn "*testqi_ext_3"
7867   [(set (reg FLAGS_REG)
7868         (compare (zero_extract:SI
7869                    (match_operand 0 "nonimmediate_operand" "rm")
7870                    (match_operand:SI 1 "const_int_operand" "")
7871                    (match_operand:SI 2 "const_int_operand" ""))
7872                  (const_int 0)))]
7873   "ix86_match_ccmode (insn, CCNOmode)
7874    && (GET_MODE (operands[0]) == SImode
7875        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876        || GET_MODE (operands[0]) == HImode
7877        || GET_MODE (operands[0]) == QImode)"
7878   "#")
7879
7880 (define_insn "*testqi_ext_3_rex64"
7881   [(set (reg FLAGS_REG)
7882         (compare (zero_extract:DI
7883                    (match_operand 0 "nonimmediate_operand" "rm")
7884                    (match_operand:DI 1 "const_int_operand" "")
7885                    (match_operand:DI 2 "const_int_operand" ""))
7886                  (const_int 0)))]
7887   "TARGET_64BIT
7888    && ix86_match_ccmode (insn, CCNOmode)
7889    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7890    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7891    /* Ensure that resulting mask is zero or sign extended operand.  */
7892    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894            && INTVAL (operands[1]) > 32))
7895    && (GET_MODE (operands[0]) == SImode
7896        || GET_MODE (operands[0]) == DImode
7897        || GET_MODE (operands[0]) == HImode
7898        || GET_MODE (operands[0]) == QImode)"
7899   "#")
7900
7901 (define_split
7902   [(set (match_operand 0 "flags_reg_operand" "")
7903         (match_operator 1 "compare_operator"
7904           [(zero_extract
7905              (match_operand 2 "nonimmediate_operand" "")
7906              (match_operand 3 "const_int_operand" "")
7907              (match_operand 4 "const_int_operand" ""))
7908            (const_int 0)]))]
7909   "ix86_match_ccmode (insn, CCNOmode)"
7910   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911 {
7912   rtx val = operands[2];
7913   HOST_WIDE_INT len = INTVAL (operands[3]);
7914   HOST_WIDE_INT pos = INTVAL (operands[4]);
7915   HOST_WIDE_INT mask;
7916   enum machine_mode mode, submode;
7917
7918   mode = GET_MODE (val);
7919   if (GET_CODE (val) == MEM)
7920     {
7921       /* ??? Combine likes to put non-volatile mem extractions in QImode
7922          no matter the size of the test.  So find a mode that works.  */
7923       if (! MEM_VOLATILE_P (val))
7924         {
7925           mode = smallest_mode_for_size (pos + len, MODE_INT);
7926           val = adjust_address (val, mode, 0);
7927         }
7928     }
7929   else if (GET_CODE (val) == SUBREG
7930            && (submode = GET_MODE (SUBREG_REG (val)),
7931                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932            && pos + len <= GET_MODE_BITSIZE (submode))
7933     {
7934       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7935       mode = submode;
7936       val = SUBREG_REG (val);
7937     }
7938   else if (mode == HImode && pos + len <= 8)
7939     {
7940       /* Small HImode tests can be converted to QImode.  */
7941       mode = QImode;
7942       val = gen_lowpart (QImode, val);
7943     }
7944
7945   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7946   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7947
7948   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7949 })
7950
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7955 ;; to QI regs.
7956 (define_split
7957   [(set (match_operand 0 "flags_reg_operand" "")
7958         (match_operator 1 "compare_operator"
7959           [(and (match_operand 2 "register_operand" "")
7960                 (match_operand 3 "const_int_operand" ""))
7961            (const_int 0)]))]
7962    "reload_completed
7963     && QI_REG_P (operands[2])
7964     && GET_MODE (operands[2]) != QImode
7965     && ((ix86_match_ccmode (insn, CCZmode)
7966          && !(INTVAL (operands[3]) & ~(255 << 8)))
7967         || (ix86_match_ccmode (insn, CCNOmode)
7968             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7969   [(set (match_dup 0)
7970         (match_op_dup 1
7971           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7972                    (match_dup 3))
7973            (const_int 0)]))]
7974   "operands[2] = gen_lowpart (SImode, operands[2]);
7975    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7976
7977 (define_split
7978   [(set (match_operand 0 "flags_reg_operand" "")
7979         (match_operator 1 "compare_operator"
7980           [(and (match_operand 2 "nonimmediate_operand" "")
7981                 (match_operand 3 "const_int_operand" ""))
7982            (const_int 0)]))]
7983    "reload_completed
7984     && GET_MODE (operands[2]) != QImode
7985     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986     && ((ix86_match_ccmode (insn, CCZmode)
7987          && !(INTVAL (operands[3]) & ~255))
7988         || (ix86_match_ccmode (insn, CCNOmode)
7989             && !(INTVAL (operands[3]) & ~127)))"
7990   [(set (match_dup 0)
7991         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7992                          (const_int 0)]))]
7993   "operands[2] = gen_lowpart (QImode, operands[2]);
7994    operands[3] = gen_lowpart (QImode, operands[3]);")
7995
7996
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers.  If this is considered useful,
7999 ;; it should be done with splitters.
8000
8001 (define_expand "anddi3"
8002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005    (clobber (reg:CC FLAGS_REG))]
8006   "TARGET_64BIT"
8007   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8008
8009 (define_insn "*anddi_1_rex64"
8010   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8015 {
8016   switch (get_attr_type (insn))
8017     {
8018     case TYPE_IMOVX:
8019       {
8020         enum machine_mode mode;
8021
8022         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023         if (INTVAL (operands[2]) == 0xff)
8024           mode = QImode;
8025         else
8026           {
8027             gcc_assert (INTVAL (operands[2]) == 0xffff);
8028             mode = HImode;
8029           }
8030         
8031         operands[1] = gen_lowpart (mode, operands[1]);
8032         if (mode == QImode)
8033           return "movz{bq|x}\t{%1,%0|%0, %1}";
8034         else
8035           return "movz{wq|x}\t{%1,%0|%0, %1}";
8036       }
8037
8038     default:
8039       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040       if (get_attr_mode (insn) == MODE_SI)
8041         return "and{l}\t{%k2, %k0|%k0, %k2}";
8042       else
8043         return "and{q}\t{%2, %0|%0, %2}";
8044     }
8045 }
8046   [(set_attr "type" "alu,alu,alu,imovx")
8047    (set_attr "length_immediate" "*,*,*,0")
8048    (set_attr "mode" "SI,DI,DI,DI")])
8049
8050 (define_insn "*anddi_2"
8051   [(set (reg FLAGS_REG)
8052         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054                  (const_int 0)))
8055    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056         (and:DI (match_dup 1) (match_dup 2)))]
8057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058    && ix86_binary_operator_ok (AND, DImode, operands)"
8059   "@
8060    and{l}\t{%k2, %k0|%k0, %k2}
8061    and{q}\t{%2, %0|%0, %2}
8062    and{q}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "SI,DI,DI")])
8065
8066 (define_expand "andsi3"
8067   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069                 (match_operand:SI 2 "general_operand" "")))
8070    (clobber (reg:CC FLAGS_REG))]
8071   ""
8072   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8073
8074 (define_insn "*andsi_1"
8075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "ix86_binary_operator_ok (AND, SImode, operands)"
8080 {
8081   switch (get_attr_type (insn))
8082     {
8083     case TYPE_IMOVX:
8084       {
8085         enum machine_mode mode;
8086
8087         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088         if (INTVAL (operands[2]) == 0xff)
8089           mode = QImode;
8090         else
8091           {
8092             gcc_assert (INTVAL (operands[2]) == 0xffff);
8093             mode = HImode;
8094           }
8095         
8096         operands[1] = gen_lowpart (mode, operands[1]);
8097         if (mode == QImode)
8098           return "movz{bl|x}\t{%1,%0|%0, %1}";
8099         else
8100           return "movz{wl|x}\t{%1,%0|%0, %1}";
8101       }
8102
8103     default:
8104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105       return "and{l}\t{%2, %0|%0, %2}";
8106     }
8107 }
8108   [(set_attr "type" "alu,alu,imovx")
8109    (set_attr "length_immediate" "*,*,0")
8110    (set_attr "mode" "SI")])
8111
8112 (define_split
8113   [(set (match_operand 0 "register_operand" "")
8114         (and (match_dup 0)
8115              (const_int -65536)))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119   "operands[1] = gen_lowpart (HImode, operands[0]);")
8120
8121 (define_split
8122   [(set (match_operand 0 "ext_register_operand" "")
8123         (and (match_dup 0)
8124              (const_int -256)))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128   "operands[1] = gen_lowpart (QImode, operands[0]);")
8129
8130 (define_split
8131   [(set (match_operand 0 "ext_register_operand" "")
8132         (and (match_dup 0)
8133              (const_int -65281)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136   [(parallel [(set (zero_extract:SI (match_dup 0)
8137                                     (const_int 8)
8138                                     (const_int 8))
8139                    (xor:SI 
8140                      (zero_extract:SI (match_dup 0)
8141                                       (const_int 8)
8142                                       (const_int 8))
8143                      (zero_extract:SI (match_dup 0)
8144                                       (const_int 8)
8145                                       (const_int 8))))
8146               (clobber (reg:CC FLAGS_REG))])]
8147   "operands[0] = gen_lowpart (SImode, operands[0]);")
8148
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151   [(set (match_operand:DI 0 "register_operand" "=r")
8152         (zero_extend:DI
8153           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154                   (match_operand:SI 2 "general_operand" "rim"))))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157   "and{l}\t{%2, %k0|%k0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI")])
8160
8161 (define_insn "*andsi_2"
8162   [(set (reg FLAGS_REG)
8163         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164                          (match_operand:SI 2 "general_operand" "rim,ri"))
8165                  (const_int 0)))
8166    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167         (and:SI (match_dup 1) (match_dup 2)))]
8168   "ix86_match_ccmode (insn, CCNOmode)
8169    && ix86_binary_operator_ok (AND, SImode, operands)"
8170   "and{l}\t{%2, %0|%0, %2}"
8171   [(set_attr "type" "alu")
8172    (set_attr "mode" "SI")])
8173
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176   [(set (reg FLAGS_REG)
8177         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178                          (match_operand:SI 2 "general_operand" "rim"))
8179                  (const_int 0)))
8180    (set (match_operand:DI 0 "register_operand" "=r")
8181         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183    && ix86_binary_operator_ok (AND, SImode, operands)"
8184   "and{l}\t{%2, %k0|%k0, %2}"
8185   [(set_attr "type" "alu")
8186    (set_attr "mode" "SI")])
8187
8188 (define_expand "andhi3"
8189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191                 (match_operand:HI 2 "general_operand" "")))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "TARGET_HIMODE_MATH"
8194   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8195
8196 (define_insn "*andhi_1"
8197   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "ix86_binary_operator_ok (AND, HImode, operands)"
8202 {
8203   switch (get_attr_type (insn))
8204     {
8205     case TYPE_IMOVX:
8206       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207       gcc_assert (INTVAL (operands[2]) == 0xff);
8208       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8209
8210     default:
8211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212
8213       return "and{w}\t{%2, %0|%0, %2}";
8214     }
8215 }
8216   [(set_attr "type" "alu,alu,imovx")
8217    (set_attr "length_immediate" "*,*,0")
8218    (set_attr "mode" "HI,HI,SI")])
8219
8220 (define_insn "*andhi_2"
8221   [(set (reg FLAGS_REG)
8222         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223                          (match_operand:HI 2 "general_operand" "rim,ri"))
8224                  (const_int 0)))
8225    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226         (and:HI (match_dup 1) (match_dup 2)))]
8227   "ix86_match_ccmode (insn, CCNOmode)
8228    && ix86_binary_operator_ok (AND, HImode, operands)"
8229   "and{w}\t{%2, %0|%0, %2}"
8230   [(set_attr "type" "alu")
8231    (set_attr "mode" "HI")])
8232
8233 (define_expand "andqi3"
8234   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236                 (match_operand:QI 2 "general_operand" "")))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "TARGET_QIMODE_MATH"
8239   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8240
8241 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8242 (define_insn "*andqi_1"
8243   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246    (clobber (reg:CC FLAGS_REG))]
8247   "ix86_binary_operator_ok (AND, QImode, operands)"
8248   "@
8249    and{b}\t{%2, %0|%0, %2}
8250    and{b}\t{%2, %0|%0, %2}
8251    and{l}\t{%k2, %k0|%k0, %k2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "QI,QI,SI")])
8254
8255 (define_insn "*andqi_1_slp"
8256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257         (and:QI (match_dup 0)
8258                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262   "and{b}\t{%1, %0|%0, %1}"
8263   [(set_attr "type" "alu1")
8264    (set_attr "mode" "QI")])
8265
8266 (define_insn "*andqi_2_maybe_si"
8267   [(set (reg FLAGS_REG)
8268         (compare (and:QI
8269                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8271                  (const_int 0)))
8272    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273         (and:QI (match_dup 1) (match_dup 2)))]
8274   "ix86_binary_operator_ok (AND, QImode, operands)
8275    && ix86_match_ccmode (insn,
8276                          GET_CODE (operands[2]) == CONST_INT
8277                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8278 {
8279   if (which_alternative == 2)
8280     {
8281       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283       return "and{l}\t{%2, %k0|%k0, %2}";
8284     }
8285   return "and{b}\t{%2, %0|%0, %2}";
8286 }
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_2"
8291   [(set (reg FLAGS_REG)
8292         (compare (and:QI
8293                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294                    (match_operand:QI 2 "general_operand" "qim,qi"))
8295                  (const_int 0)))
8296    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297         (and:QI (match_dup 1) (match_dup 2)))]
8298   "ix86_match_ccmode (insn, CCNOmode)
8299    && ix86_binary_operator_ok (AND, QImode, operands)"
8300   "and{b}\t{%2, %0|%0, %2}"
8301   [(set_attr "type" "alu")
8302    (set_attr "mode" "QI")])
8303
8304 (define_insn "*andqi_2_slp"
8305   [(set (reg FLAGS_REG)
8306         (compare (and:QI
8307                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8309                  (const_int 0)))
8310    (set (strict_low_part (match_dup 0))
8311         (and:QI (match_dup 0) (match_dup 1)))]
8312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313    && ix86_match_ccmode (insn, CCNOmode)
8314    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315   "and{b}\t{%1, %0|%0, %1}"
8316   [(set_attr "type" "alu1")
8317    (set_attr "mode" "QI")])
8318
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8322
8323 (define_insn "andqi_ext_0"
8324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325                          (const_int 8)
8326                          (const_int 8))
8327         (and:SI 
8328           (zero_extract:SI
8329             (match_operand 1 "ext_register_operand" "0")
8330             (const_int 8)
8331             (const_int 8))
8332           (match_operand 2 "const_int_operand" "n")))
8333    (clobber (reg:CC FLAGS_REG))]
8334   ""
8335   "and{b}\t{%2, %h0|%h0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "length_immediate" "1")
8338    (set_attr "mode" "QI")])
8339
8340 ;; Generated by peephole translating test to and.  This shows up
8341 ;; often in fp comparisons.
8342
8343 (define_insn "*andqi_ext_0_cc"
8344   [(set (reg FLAGS_REG)
8345         (compare
8346           (and:SI
8347             (zero_extract:SI
8348               (match_operand 1 "ext_register_operand" "0")
8349               (const_int 8)
8350               (const_int 8))
8351             (match_operand 2 "const_int_operand" "n"))
8352           (const_int 0)))
8353    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8354                          (const_int 8)
8355                          (const_int 8))
8356         (and:SI 
8357           (zero_extract:SI
8358             (match_dup 1)
8359             (const_int 8)
8360             (const_int 8))
8361           (match_dup 2)))]
8362   "ix86_match_ccmode (insn, CCNOmode)"
8363   "and{b}\t{%2, %h0|%h0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "length_immediate" "1")
8366    (set_attr "mode" "QI")])
8367
8368 (define_insn "*andqi_ext_1"
8369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370                          (const_int 8)
8371                          (const_int 8))
8372         (and:SI 
8373           (zero_extract:SI
8374             (match_operand 1 "ext_register_operand" "0")
8375             (const_int 8)
8376             (const_int 8))
8377           (zero_extend:SI
8378             (match_operand:QI 2 "general_operand" "Qm"))))
8379    (clobber (reg:CC FLAGS_REG))]
8380   "!TARGET_64BIT"
8381   "and{b}\t{%2, %h0|%h0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "length_immediate" "0")
8384    (set_attr "mode" "QI")])
8385
8386 (define_insn "*andqi_ext_1_rex64"
8387   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388                          (const_int 8)
8389                          (const_int 8))
8390         (and:SI 
8391           (zero_extract:SI
8392             (match_operand 1 "ext_register_operand" "0")
8393             (const_int 8)
8394             (const_int 8))
8395           (zero_extend:SI
8396             (match_operand 2 "ext_register_operand" "Q"))))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "TARGET_64BIT"
8399   "and{b}\t{%2, %h0|%h0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "length_immediate" "0")
8402    (set_attr "mode" "QI")])
8403
8404 (define_insn "*andqi_ext_2"
8405   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406                          (const_int 8)
8407                          (const_int 8))
8408         (and:SI
8409           (zero_extract:SI
8410             (match_operand 1 "ext_register_operand" "%0")
8411             (const_int 8)
8412             (const_int 8))
8413           (zero_extract:SI
8414             (match_operand 2 "ext_register_operand" "Q")
8415             (const_int 8)
8416             (const_int 8))))
8417    (clobber (reg:CC FLAGS_REG))]
8418   ""
8419   "and{b}\t{%h2, %h0|%h0, %h2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "length_immediate" "0")
8422    (set_attr "mode" "QI")])
8423
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8429 (define_split
8430   [(set (match_operand 0 "register_operand" "")
8431         (and (match_operand 1 "register_operand" "")
8432              (match_operand 2 "const_int_operand" "")))
8433    (clobber (reg:CC FLAGS_REG))]
8434    "reload_completed
8435     && QI_REG_P (operands[0])
8436     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437     && !(~INTVAL (operands[2]) & ~(255 << 8))
8438     && GET_MODE (operands[0]) != QImode"
8439   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440                    (and:SI (zero_extract:SI (match_dup 1)
8441                                             (const_int 8) (const_int 8))
8442                            (match_dup 2)))
8443               (clobber (reg:CC FLAGS_REG))])]
8444   "operands[0] = gen_lowpart (SImode, operands[0]);
8445    operands[1] = gen_lowpart (SImode, operands[1]);
8446    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8447
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8450 (define_split
8451   [(set (match_operand 0 "register_operand" "")
8452         (and (match_operand 1 "general_operand" "")
8453              (match_operand 2 "const_int_operand" "")))
8454    (clobber (reg:CC FLAGS_REG))]
8455    "reload_completed
8456     && ANY_QI_REG_P (operands[0])
8457     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458     && !(~INTVAL (operands[2]) & ~255)
8459     && !(INTVAL (operands[2]) & 128)
8460     && GET_MODE (operands[0]) != QImode"
8461   [(parallel [(set (strict_low_part (match_dup 0))
8462                    (and:QI (match_dup 1)
8463                            (match_dup 2)))
8464               (clobber (reg:CC FLAGS_REG))])]
8465   "operands[0] = gen_lowpart (QImode, operands[0]);
8466    operands[1] = gen_lowpart (QImode, operands[1]);
8467    operands[2] = gen_lowpart (QImode, operands[2]);")
8468 \f
8469 ;; Logical inclusive OR instructions
8470
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8473
8474 (define_expand "iordi3"
8475   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477                 (match_operand:DI 2 "x86_64_general_operand" "")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT"
8480   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8481
8482 (define_insn "*iordi_1_rex64"
8483   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "TARGET_64BIT
8488    && ix86_binary_operator_ok (IOR, DImode, operands)"
8489   "or{q}\t{%2, %0|%0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "mode" "DI")])
8492
8493 (define_insn "*iordi_2_rex64"
8494   [(set (reg FLAGS_REG)
8495         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8497                  (const_int 0)))
8498    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499         (ior:DI (match_dup 1) (match_dup 2)))]
8500   "TARGET_64BIT
8501    && ix86_match_ccmode (insn, CCNOmode)
8502    && ix86_binary_operator_ok (IOR, DImode, operands)"
8503   "or{q}\t{%2, %0|%0, %2}"
8504   [(set_attr "type" "alu")
8505    (set_attr "mode" "DI")])
8506
8507 (define_insn "*iordi_3_rex64"
8508   [(set (reg FLAGS_REG)
8509         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8511                  (const_int 0)))
8512    (clobber (match_scratch:DI 0 "=r"))]
8513   "TARGET_64BIT
8514    && ix86_match_ccmode (insn, CCNOmode)
8515    && ix86_binary_operator_ok (IOR, DImode, operands)"
8516   "or{q}\t{%2, %0|%0, %2}"
8517   [(set_attr "type" "alu")
8518    (set_attr "mode" "DI")])
8519
8520
8521 (define_expand "iorsi3"
8522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524                 (match_operand:SI 2 "general_operand" "")))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8528
8529 (define_insn "*iorsi_1"
8530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "ix86_binary_operator_ok (IOR, SImode, operands)"
8535   "or{l}\t{%2, %0|%0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "mode" "SI")])
8538
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541   [(set (match_operand:DI 0 "register_operand" "=rm")
8542         (zero_extend:DI
8543           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544                   (match_operand:SI 2 "general_operand" "rim"))))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547   "or{l}\t{%2, %k0|%k0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI")])
8550
8551 (define_insn "*iorsi_1_zext_imm"
8552   [(set (match_operand:DI 0 "register_operand" "=rm")
8553         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555    (clobber (reg:CC FLAGS_REG))]
8556   "TARGET_64BIT"
8557   "or{l}\t{%2, %k0|%k0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "SI")])
8560
8561 (define_insn "*iorsi_2"
8562   [(set (reg FLAGS_REG)
8563         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564                          (match_operand:SI 2 "general_operand" "rim,ri"))
8565                  (const_int 0)))
8566    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567         (ior:SI (match_dup 1) (match_dup 2)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && ix86_binary_operator_ok (IOR, SImode, operands)"
8570   "or{l}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577   [(set (reg FLAGS_REG)
8578         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                          (match_operand:SI 2 "general_operand" "rim"))
8580                  (const_int 0)))
8581    (set (match_operand:DI 0 "register_operand" "=r")
8582         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (IOR, SImode, operands)"
8585   "or{l}\t{%2, %k0|%k0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8588
8589 (define_insn "*iorsi_2_zext_imm"
8590   [(set (reg FLAGS_REG)
8591         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8593                  (const_int 0)))
8594    (set (match_operand:DI 0 "register_operand" "=r")
8595         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597    && ix86_binary_operator_ok (IOR, SImode, operands)"
8598   "or{l}\t{%2, %k0|%k0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "SI")])
8601
8602 (define_insn "*iorsi_3"
8603   [(set (reg FLAGS_REG)
8604         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605                          (match_operand:SI 2 "general_operand" "rim"))
8606                  (const_int 0)))
8607    (clobber (match_scratch:SI 0 "=r"))]
8608   "ix86_match_ccmode (insn, CCNOmode)
8609    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610   "or{l}\t{%2, %0|%0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "mode" "SI")])
8613
8614 (define_expand "iorhi3"
8615   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617                 (match_operand:HI 2 "general_operand" "")))
8618    (clobber (reg:CC FLAGS_REG))]
8619   "TARGET_HIMODE_MATH"
8620   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8621
8622 (define_insn "*iorhi_1"
8623   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "ix86_binary_operator_ok (IOR, HImode, operands)"
8628   "or{w}\t{%2, %0|%0, %2}"
8629   [(set_attr "type" "alu")
8630    (set_attr "mode" "HI")])
8631
8632 (define_insn "*iorhi_2"
8633   [(set (reg FLAGS_REG)
8634         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635                          (match_operand:HI 2 "general_operand" "rim,ri"))
8636                  (const_int 0)))
8637    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638         (ior:HI (match_dup 1) (match_dup 2)))]
8639   "ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (IOR, HImode, operands)"
8641   "or{w}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "HI")])
8644
8645 (define_insn "*iorhi_3"
8646   [(set (reg FLAGS_REG)
8647         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648                          (match_operand:HI 2 "general_operand" "rim"))
8649                  (const_int 0)))
8650    (clobber (match_scratch:HI 0 "=r"))]
8651   "ix86_match_ccmode (insn, CCNOmode)
8652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653   "or{w}\t{%2, %0|%0, %2}"
8654   [(set_attr "type" "alu")
8655    (set_attr "mode" "HI")])
8656
8657 (define_expand "iorqi3"
8658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660                 (match_operand:QI 2 "general_operand" "")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "TARGET_QIMODE_MATH"
8663   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8664
8665 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8666 (define_insn "*iorqi_1"
8667   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "ix86_binary_operator_ok (IOR, QImode, operands)"
8672   "@
8673    or{b}\t{%2, %0|%0, %2}
8674    or{b}\t{%2, %0|%0, %2}
8675    or{l}\t{%k2, %k0|%k0, %k2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "QI,QI,SI")])
8678
8679 (define_insn "*iorqi_1_slp"
8680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681         (ior:QI (match_dup 0)
8682                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683    (clobber (reg:CC FLAGS_REG))]
8684   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686   "or{b}\t{%1, %0|%0, %1}"
8687   [(set_attr "type" "alu1")
8688    (set_attr "mode" "QI")])
8689
8690 (define_insn "*iorqi_2"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693                          (match_operand:QI 2 "general_operand" "qim,qi"))
8694                  (const_int 0)))
8695    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696         (ior:QI (match_dup 1) (match_dup 2)))]
8697   "ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, QImode, operands)"
8699   "or{b}\t{%2, %0|%0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "QI")])
8702
8703 (define_insn "*iorqi_2_slp"
8704   [(set (reg FLAGS_REG)
8705         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706                          (match_operand:QI 1 "general_operand" "qim,qi"))
8707                  (const_int 0)))
8708    (set (strict_low_part (match_dup 0))
8709         (ior:QI (match_dup 0) (match_dup 1)))]
8710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711    && ix86_match_ccmode (insn, CCNOmode)
8712    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713   "or{b}\t{%1, %0|%0, %1}"
8714   [(set_attr "type" "alu1")
8715    (set_attr "mode" "QI")])
8716
8717 (define_insn "*iorqi_3"
8718   [(set (reg FLAGS_REG)
8719         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720                          (match_operand:QI 2 "general_operand" "qim"))
8721                  (const_int 0)))
8722    (clobber (match_scratch:QI 0 "=q"))]
8723   "ix86_match_ccmode (insn, CCNOmode)
8724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725   "or{b}\t{%2, %0|%0, %2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "QI")])
8728
8729 (define_insn "iorqi_ext_0"
8730   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731                          (const_int 8)
8732                          (const_int 8))
8733         (ior:SI 
8734           (zero_extract:SI
8735             (match_operand 1 "ext_register_operand" "0")
8736             (const_int 8)
8737             (const_int 8))
8738           (match_operand 2 "const_int_operand" "n")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741   "or{b}\t{%2, %h0|%h0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "length_immediate" "1")
8744    (set_attr "mode" "QI")])
8745
8746 (define_insn "*iorqi_ext_1"
8747   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748                          (const_int 8)
8749                          (const_int 8))
8750         (ior:SI 
8751           (zero_extract:SI
8752             (match_operand 1 "ext_register_operand" "0")
8753             (const_int 8)
8754             (const_int 8))
8755           (zero_extend:SI
8756             (match_operand:QI 2 "general_operand" "Qm"))))
8757    (clobber (reg:CC FLAGS_REG))]
8758   "!TARGET_64BIT
8759    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760   "or{b}\t{%2, %h0|%h0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "length_immediate" "0")
8763    (set_attr "mode" "QI")])
8764
8765 (define_insn "*iorqi_ext_1_rex64"
8766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767                          (const_int 8)
8768                          (const_int 8))
8769         (ior:SI 
8770           (zero_extract:SI
8771             (match_operand 1 "ext_register_operand" "0")
8772             (const_int 8)
8773             (const_int 8))
8774           (zero_extend:SI
8775             (match_operand 2 "ext_register_operand" "Q"))))
8776    (clobber (reg:CC FLAGS_REG))]
8777   "TARGET_64BIT
8778    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779   "or{b}\t{%2, %h0|%h0, %2}"
8780   [(set_attr "type" "alu")
8781    (set_attr "length_immediate" "0")
8782    (set_attr "mode" "QI")])
8783
8784 (define_insn "*iorqi_ext_2"
8785   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786                          (const_int 8)
8787                          (const_int 8))
8788         (ior:SI 
8789           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8790                            (const_int 8)
8791                            (const_int 8))
8792           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8793                            (const_int 8)
8794                            (const_int 8))))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797   "ior{b}\t{%h2, %h0|%h0, %h2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "length_immediate" "0")
8800    (set_attr "mode" "QI")])
8801
8802 (define_split
8803   [(set (match_operand 0 "register_operand" "")
8804         (ior (match_operand 1 "register_operand" "")
8805              (match_operand 2 "const_int_operand" "")))
8806    (clobber (reg:CC FLAGS_REG))]
8807    "reload_completed
8808     && QI_REG_P (operands[0])
8809     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810     && !(INTVAL (operands[2]) & ~(255 << 8))
8811     && GET_MODE (operands[0]) != QImode"
8812   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813                    (ior:SI (zero_extract:SI (match_dup 1)
8814                                             (const_int 8) (const_int 8))
8815                            (match_dup 2)))
8816               (clobber (reg:CC FLAGS_REG))])]
8817   "operands[0] = gen_lowpart (SImode, operands[0]);
8818    operands[1] = gen_lowpart (SImode, operands[1]);
8819    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8820
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8823 (define_split
8824   [(set (match_operand 0 "register_operand" "")
8825         (ior (match_operand 1 "general_operand" "")
8826              (match_operand 2 "const_int_operand" "")))
8827    (clobber (reg:CC FLAGS_REG))]
8828    "reload_completed
8829     && ANY_QI_REG_P (operands[0])
8830     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831     && !(INTVAL (operands[2]) & ~255)
8832     && (INTVAL (operands[2]) & 128)
8833     && GET_MODE (operands[0]) != QImode"
8834   [(parallel [(set (strict_low_part (match_dup 0))
8835                    (ior:QI (match_dup 1)
8836                            (match_dup 2)))
8837               (clobber (reg:CC FLAGS_REG))])]
8838   "operands[0] = gen_lowpart (QImode, operands[0]);
8839    operands[1] = gen_lowpart (QImode, operands[1]);
8840    operands[2] = gen_lowpart (QImode, operands[2]);")
8841 \f
8842 ;; Logical XOR instructions
8843
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8846
8847 (define_expand "xordi3"
8848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850                 (match_operand:DI 2 "x86_64_general_operand" "")))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "TARGET_64BIT"
8853   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8854
8855 (define_insn "*xordi_1_rex64"
8856   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859    (clobber (reg:CC FLAGS_REG))]
8860   "TARGET_64BIT
8861    && ix86_binary_operator_ok (XOR, DImode, operands)"
8862   "@
8863    xor{q}\t{%2, %0|%0, %2}
8864    xor{q}\t{%2, %0|%0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "DI,DI")])
8867
8868 (define_insn "*xordi_2_rex64"
8869   [(set (reg FLAGS_REG)
8870         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8872                  (const_int 0)))
8873    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874         (xor:DI (match_dup 1) (match_dup 2)))]
8875   "TARGET_64BIT
8876    && ix86_match_ccmode (insn, CCNOmode)
8877    && ix86_binary_operator_ok (XOR, DImode, operands)"
8878   "@
8879    xor{q}\t{%2, %0|%0, %2}
8880    xor{q}\t{%2, %0|%0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "mode" "DI,DI")])
8883
8884 (define_insn "*xordi_3_rex64"
8885   [(set (reg FLAGS_REG)
8886         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8888                  (const_int 0)))
8889    (clobber (match_scratch:DI 0 "=r"))]
8890   "TARGET_64BIT
8891    && ix86_match_ccmode (insn, CCNOmode)
8892    && ix86_binary_operator_ok (XOR, DImode, operands)"
8893   "xor{q}\t{%2, %0|%0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "mode" "DI")])
8896
8897 (define_expand "xorsi3"
8898   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900                 (match_operand:SI 2 "general_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   ""
8903   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8904
8905 (define_insn "*xorsi_1"
8906   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908                 (match_operand:SI 2 "general_operand" "ri,rm")))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "ix86_binary_operator_ok (XOR, SImode, operands)"
8911   "xor{l}\t{%2, %0|%0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918   [(set (match_operand:DI 0 "register_operand" "=r")
8919         (zero_extend:DI
8920           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921                   (match_operand:SI 2 "general_operand" "rim"))))
8922    (clobber (reg:CC FLAGS_REG))]
8923   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924   "xor{l}\t{%2, %k0|%k0, %2}"
8925   [(set_attr "type" "alu")
8926    (set_attr "mode" "SI")])
8927
8928 (define_insn "*xorsi_1_zext_imm"
8929   [(set (match_operand:DI 0 "register_operand" "=r")
8930         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934   "xor{l}\t{%2, %k0|%k0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "SI")])
8937
8938 (define_insn "*xorsi_2"
8939   [(set (reg FLAGS_REG)
8940         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941                          (match_operand:SI 2 "general_operand" "rim,ri"))
8942                  (const_int 0)))
8943    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944         (xor:SI (match_dup 1) (match_dup 2)))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && ix86_binary_operator_ok (XOR, SImode, operands)"
8947   "xor{l}\t{%2, %0|%0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "mode" "SI")])
8950
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954   [(set (reg FLAGS_REG)
8955         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                          (match_operand:SI 2 "general_operand" "rim"))
8957                  (const_int 0)))
8958    (set (match_operand:DI 0 "register_operand" "=r")
8959         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961    && ix86_binary_operator_ok (XOR, SImode, operands)"
8962   "xor{l}\t{%2, %k0|%k0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "SI")])
8965
8966 (define_insn "*xorsi_2_zext_imm"
8967   [(set (reg FLAGS_REG)
8968         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8970                  (const_int 0)))
8971    (set (match_operand:DI 0 "register_operand" "=r")
8972         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974    && ix86_binary_operator_ok (XOR, SImode, operands)"
8975   "xor{l}\t{%2, %k0|%k0, %2}"
8976   [(set_attr "type" "alu")
8977    (set_attr "mode" "SI")])
8978
8979 (define_insn "*xorsi_3"
8980   [(set (reg FLAGS_REG)
8981         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982                          (match_operand:SI 2 "general_operand" "rim"))
8983                  (const_int 0)))
8984    (clobber (match_scratch:SI 0 "=r"))]
8985   "ix86_match_ccmode (insn, CCNOmode)
8986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987   "xor{l}\t{%2, %0|%0, %2}"
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "SI")])
8990
8991 (define_expand "xorhi3"
8992   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994                 (match_operand:HI 2 "general_operand" "")))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "TARGET_HIMODE_MATH"
8997   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8998
8999 (define_insn "*xorhi_1"
9000   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "ix86_binary_operator_ok (XOR, HImode, operands)"
9005   "xor{w}\t{%2, %0|%0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "HI")])
9008
9009 (define_insn "*xorhi_2"
9010   [(set (reg FLAGS_REG)
9011         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012                          (match_operand:HI 2 "general_operand" "rim,ri"))
9013                  (const_int 0)))
9014    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015         (xor:HI (match_dup 1) (match_dup 2)))]
9016   "ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (XOR, HImode, operands)"
9018   "xor{w}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "HI")])
9021
9022 (define_insn "*xorhi_3"
9023   [(set (reg FLAGS_REG)
9024         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025                          (match_operand:HI 2 "general_operand" "rim"))
9026                  (const_int 0)))
9027    (clobber (match_scratch:HI 0 "=r"))]
9028   "ix86_match_ccmode (insn, CCNOmode)
9029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030   "xor{w}\t{%2, %0|%0, %2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "mode" "HI")])
9033
9034 (define_expand "xorqi3"
9035   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037                 (match_operand:QI 2 "general_operand" "")))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "TARGET_QIMODE_MATH"
9040   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9041
9042 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9043 (define_insn "*xorqi_1"
9044   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047    (clobber (reg:CC FLAGS_REG))]
9048   "ix86_binary_operator_ok (XOR, QImode, operands)"
9049   "@
9050    xor{b}\t{%2, %0|%0, %2}
9051    xor{b}\t{%2, %0|%0, %2}
9052    xor{l}\t{%k2, %k0|%k0, %k2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "QI,QI,SI")])
9055
9056 (define_insn "*xorqi_1_slp"
9057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058         (xor:QI (match_dup 0)
9059                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060    (clobber (reg:CC FLAGS_REG))]
9061   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063   "xor{b}\t{%1, %0|%0, %1}"
9064   [(set_attr "type" "alu1")
9065    (set_attr "mode" "QI")])
9066
9067 (define_insn "xorqi_ext_0"
9068   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9069                          (const_int 8)
9070                          (const_int 8))
9071         (xor:SI 
9072           (zero_extract:SI
9073             (match_operand 1 "ext_register_operand" "0")
9074             (const_int 8)
9075             (const_int 8))
9076           (match_operand 2 "const_int_operand" "n")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079   "xor{b}\t{%2, %h0|%h0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "length_immediate" "1")
9082    (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_ext_1"
9085   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9086                          (const_int 8)
9087                          (const_int 8))
9088         (xor:SI 
9089           (zero_extract:SI
9090             (match_operand 1 "ext_register_operand" "0")
9091             (const_int 8)
9092             (const_int 8))
9093           (zero_extend:SI
9094             (match_operand:QI 2 "general_operand" "Qm"))))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "!TARGET_64BIT
9097    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098   "xor{b}\t{%2, %h0|%h0, %2}"
9099   [(set_attr "type" "alu")
9100    (set_attr "length_immediate" "0")
9101    (set_attr "mode" "QI")])
9102
9103 (define_insn "*xorqi_ext_1_rex64"
9104   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105                          (const_int 8)
9106                          (const_int 8))
9107         (xor:SI 
9108           (zero_extract:SI
9109             (match_operand 1 "ext_register_operand" "0")
9110             (const_int 8)
9111             (const_int 8))
9112           (zero_extend:SI
9113             (match_operand 2 "ext_register_operand" "Q"))))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "TARGET_64BIT
9116    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117   "xor{b}\t{%2, %h0|%h0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "length_immediate" "0")
9120    (set_attr "mode" "QI")])
9121
9122 (define_insn "*xorqi_ext_2"
9123   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (xor:SI 
9127           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9128                            (const_int 8)
9129                            (const_int 8))
9130           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9131                            (const_int 8)
9132                            (const_int 8))))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135   "xor{b}\t{%h2, %h0|%h0, %h2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "length_immediate" "0")
9138    (set_attr "mode" "QI")])
9139
9140 (define_insn "*xorqi_cc_1"
9141   [(set (reg FLAGS_REG)
9142         (compare
9143           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144                   (match_operand:QI 2 "general_operand" "qim,qi"))
9145           (const_int 0)))
9146    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147         (xor:QI (match_dup 1) (match_dup 2)))]
9148   "ix86_match_ccmode (insn, CCNOmode)
9149    && ix86_binary_operator_ok (XOR, QImode, operands)"
9150   "xor{b}\t{%2, %0|%0, %2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI")])
9153
9154 (define_insn "*xorqi_2_slp"
9155   [(set (reg FLAGS_REG)
9156         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157                          (match_operand:QI 1 "general_operand" "qim,qi"))
9158                  (const_int 0)))
9159    (set (strict_low_part (match_dup 0))
9160         (xor:QI (match_dup 0) (match_dup 1)))]
9161   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162    && ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164   "xor{b}\t{%1, %0|%0, %1}"
9165   [(set_attr "type" "alu1")
9166    (set_attr "mode" "QI")])
9167
9168 (define_insn "*xorqi_cc_2"
9169   [(set (reg FLAGS_REG)
9170         (compare
9171           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172                   (match_operand:QI 2 "general_operand" "qim"))
9173           (const_int 0)))
9174    (clobber (match_scratch:QI 0 "=q"))]
9175   "ix86_match_ccmode (insn, CCNOmode)
9176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177   "xor{b}\t{%2, %0|%0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "mode" "QI")])
9180
9181 (define_insn "*xorqi_cc_ext_1"
9182   [(set (reg FLAGS_REG)
9183         (compare
9184           (xor:SI
9185             (zero_extract:SI
9186               (match_operand 1 "ext_register_operand" "0")
9187               (const_int 8)
9188               (const_int 8))
9189             (match_operand:QI 2 "general_operand" "qmn"))
9190           (const_int 0)))
9191    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9192                          (const_int 8)
9193                          (const_int 8))
9194         (xor:SI 
9195           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9196           (match_dup 2)))]
9197   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198   "xor{b}\t{%2, %h0|%h0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:SI
9206             (zero_extract:SI
9207               (match_operand 1 "ext_register_operand" "0")
9208               (const_int 8)
9209               (const_int 8))
9210             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9211           (const_int 0)))
9212    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI 
9216           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9217           (match_dup 2)))]
9218   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219   "xor{b}\t{%2, %h0|%h0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9222
9223 (define_expand "xorqi_cc_ext_1"
9224   [(parallel [
9225      (set (reg:CCNO FLAGS_REG)
9226           (compare:CCNO
9227             (xor:SI
9228               (zero_extract:SI
9229                 (match_operand 1 "ext_register_operand" "")
9230                 (const_int 8)
9231                 (const_int 8))
9232               (match_operand:QI 2 "general_operand" ""))
9233             (const_int 0)))
9234      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9235                            (const_int 8)
9236                            (const_int 8))
9237           (xor:SI 
9238             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9239             (match_dup 2)))])]
9240   ""
9241   "")
9242
9243 (define_split
9244   [(set (match_operand 0 "register_operand" "")
9245         (xor (match_operand 1 "register_operand" "")
9246              (match_operand 2 "const_int_operand" "")))
9247    (clobber (reg:CC FLAGS_REG))]
9248    "reload_completed
9249     && QI_REG_P (operands[0])
9250     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251     && !(INTVAL (operands[2]) & ~(255 << 8))
9252     && GET_MODE (operands[0]) != QImode"
9253   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254                    (xor:SI (zero_extract:SI (match_dup 1)
9255                                             (const_int 8) (const_int 8))
9256                            (match_dup 2)))
9257               (clobber (reg:CC FLAGS_REG))])]
9258   "operands[0] = gen_lowpart (SImode, operands[0]);
9259    operands[1] = gen_lowpart (SImode, operands[1]);
9260    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9261
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9264 (define_split
9265   [(set (match_operand 0 "register_operand" "")
9266         (xor (match_operand 1 "general_operand" "")
9267              (match_operand 2 "const_int_operand" "")))
9268    (clobber (reg:CC FLAGS_REG))]
9269    "reload_completed
9270     && ANY_QI_REG_P (operands[0])
9271     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272     && !(INTVAL (operands[2]) & ~255)
9273     && (INTVAL (operands[2]) & 128)
9274     && GET_MODE (operands[0]) != QImode"
9275   [(parallel [(set (strict_low_part (match_dup 0))
9276                    (xor:QI (match_dup 1)
9277                            (match_dup 2)))
9278               (clobber (reg:CC FLAGS_REG))])]
9279   "operands[0] = gen_lowpart (QImode, operands[0]);
9280    operands[1] = gen_lowpart (QImode, operands[1]);
9281    operands[2] = gen_lowpart (QImode, operands[2]);")
9282 \f
9283 ;; Negation instructions
9284
9285 (define_expand "negti2"
9286   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288               (clobber (reg:CC FLAGS_REG))])]
9289   "TARGET_64BIT"
9290   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9291
9292 (define_insn "*negti2_1"
9293   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295    (clobber (reg:CC FLAGS_REG))]
9296   "TARGET_64BIT
9297    && ix86_unary_operator_ok (NEG, TImode, operands)"
9298   "#")
9299
9300 (define_split
9301   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302         (neg:TI (match_operand:TI 1 "general_operand" "")))
9303    (clobber (reg:CC FLAGS_REG))]
9304   "TARGET_64BIT && reload_completed"
9305   [(parallel
9306     [(set (reg:CCZ FLAGS_REG)
9307           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308      (set (match_dup 0) (neg:DI (match_dup 2)))])
9309    (parallel
9310     [(set (match_dup 1)
9311           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9312                             (match_dup 3))
9313                    (const_int 0)))
9314      (clobber (reg:CC FLAGS_REG))])
9315    (parallel
9316     [(set (match_dup 1)
9317           (neg:DI (match_dup 1)))
9318      (clobber (reg:CC FLAGS_REG))])]
9319   "split_ti (operands+1, 1, operands+2, operands+3);
9320    split_ti (operands+0, 1, operands+0, operands+1);")
9321
9322 (define_expand "negdi2"
9323   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325               (clobber (reg:CC FLAGS_REG))])]
9326   ""
9327   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9328
9329 (define_insn "*negdi2_1"
9330   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "!TARGET_64BIT
9334    && ix86_unary_operator_ok (NEG, DImode, operands)"
9335   "#")
9336
9337 (define_split
9338   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339         (neg:DI (match_operand:DI 1 "general_operand" "")))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "!TARGET_64BIT && reload_completed"
9342   [(parallel
9343     [(set (reg:CCZ FLAGS_REG)
9344           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345      (set (match_dup 0) (neg:SI (match_dup 2)))])
9346    (parallel
9347     [(set (match_dup 1)
9348           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9349                             (match_dup 3))
9350                    (const_int 0)))
9351      (clobber (reg:CC FLAGS_REG))])
9352    (parallel
9353     [(set (match_dup 1)
9354           (neg:SI (match_dup 1)))
9355      (clobber (reg:CC FLAGS_REG))])]
9356   "split_di (operands+1, 1, operands+2, operands+3);
9357    split_di (operands+0, 1, operands+0, operands+1);")
9358
9359 (define_insn "*negdi2_1_rex64"
9360   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9364   "neg{q}\t%0"
9365   [(set_attr "type" "negnot")
9366    (set_attr "mode" "DI")])
9367
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9371
9372 (define_insn "*negdi2_cmpz_rex64"
9373   [(set (reg:CCZ FLAGS_REG)
9374         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9375                      (const_int 0)))
9376    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377         (neg:DI (match_dup 1)))]
9378   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9379   "neg{q}\t%0"
9380   [(set_attr "type" "negnot")
9381    (set_attr "mode" "DI")])
9382
9383
9384 (define_expand "negsi2"
9385   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9390
9391 (define_insn "*negsi2_1"
9392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "ix86_unary_operator_ok (NEG, SImode, operands)"
9396   "neg{l}\t%0"
9397   [(set_attr "type" "negnot")
9398    (set_attr "mode" "SI")])
9399
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402   [(set (match_operand:DI 0 "register_operand" "=r")
9403         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9404                                         (const_int 32)))
9405                      (const_int 32)))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9408   "neg{l}\t%k0"
9409   [(set_attr "type" "negnot")
9410    (set_attr "mode" "SI")])
9411
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9415
9416 (define_insn "*negsi2_cmpz"
9417   [(set (reg:CCZ FLAGS_REG)
9418         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9419                      (const_int 0)))
9420    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421         (neg:SI (match_dup 1)))]
9422   "ix86_unary_operator_ok (NEG, SImode, operands)"
9423   "neg{l}\t%0"
9424   [(set_attr "type" "negnot")
9425    (set_attr "mode" "SI")])
9426
9427 (define_insn "*negsi2_cmpz_zext"
9428   [(set (reg:CCZ FLAGS_REG)
9429         (compare:CCZ (lshiftrt:DI
9430                        (neg:DI (ashift:DI
9431                                  (match_operand:DI 1 "register_operand" "0")
9432                                  (const_int 32)))
9433                        (const_int 32))
9434                      (const_int 0)))
9435    (set (match_operand:DI 0 "register_operand" "=r")
9436         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9437                                         (const_int 32)))
9438                      (const_int 32)))]
9439   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9440   "neg{l}\t%k0"
9441   [(set_attr "type" "negnot")
9442    (set_attr "mode" "SI")])
9443
9444 (define_expand "neghi2"
9445   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447               (clobber (reg:CC FLAGS_REG))])]
9448   "TARGET_HIMODE_MATH"
9449   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9450
9451 (define_insn "*neghi2_1"
9452   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_unary_operator_ok (NEG, HImode, operands)"
9456   "neg{w}\t%0"
9457   [(set_attr "type" "negnot")
9458    (set_attr "mode" "HI")])
9459
9460 (define_insn "*neghi2_cmpz"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465         (neg:HI (match_dup 1)))]
9466   "ix86_unary_operator_ok (NEG, HImode, operands)"
9467   "neg{w}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "HI")])
9470
9471 (define_expand "negqi2"
9472   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474               (clobber (reg:CC FLAGS_REG))])]
9475   "TARGET_QIMODE_MATH"
9476   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9477
9478 (define_insn "*negqi2_1"
9479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "ix86_unary_operator_ok (NEG, QImode, operands)"
9483   "neg{b}\t%0"
9484   [(set_attr "type" "negnot")
9485    (set_attr "mode" "QI")])
9486
9487 (define_insn "*negqi2_cmpz"
9488   [(set (reg:CCZ FLAGS_REG)
9489         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9490                      (const_int 0)))
9491    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492         (neg:QI (match_dup 1)))]
9493   "ix86_unary_operator_ok (NEG, QImode, operands)"
9494   "neg{b}\t%0"
9495   [(set_attr "type" "negnot")
9496    (set_attr "mode" "QI")])
9497
9498 ;; Changing of sign for FP values is doable using integer unit too.
9499
9500 (define_expand "negsf2"
9501   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387 || TARGET_SSE_MATH"
9504   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9505
9506 (define_expand "abssf2"
9507   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509   "TARGET_80387 || TARGET_SSE_MATH"
9510   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9511
9512 (define_insn "*absnegsf2_mixed"
9513   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9514         (match_operator:SF 3 "absneg_operator"
9515           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9516    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9520   "#")
9521
9522 (define_insn "*absnegsf2_sse"
9523   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9524         (match_operator:SF 3 "absneg_operator"
9525           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9527    (clobber (reg:CC FLAGS_REG))]
9528   "TARGET_SSE_MATH
9529    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9530   "#")
9531
9532 (define_insn "*absnegsf2_i387"
9533   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534         (match_operator:SF 3 "absneg_operator"
9535           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536    (use (match_operand 2 "" ""))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "TARGET_80387 && !TARGET_SSE_MATH
9539    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9540   "#")
9541
9542 (define_expand "copysignsf3"
9543   [(match_operand:SF 0 "register_operand" "")
9544    (match_operand:SF 1 "nonmemory_operand" "")
9545    (match_operand:SF 2 "register_operand" "")]
9546   "TARGET_SSE_MATH"
9547 {
9548   ix86_expand_copysign (operands);
9549   DONE;
9550 })
9551
9552 (define_insn_and_split "copysignsf3_const"
9553   [(set (match_operand:SF 0 "register_operand"          "=x")
9554         (unspec:SF
9555           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9556            (match_operand:SF 2 "register_operand"       "0")
9557            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9558           UNSPEC_COPYSIGN))]
9559   "TARGET_SSE_MATH"
9560   "#"
9561   "&& reload_completed"
9562   [(const_int 0)]
9563 {
9564   ix86_split_copysign_const (operands);
9565   DONE;
9566 })
9567
9568 (define_insn "copysignsf3_var"
9569   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9570         (unspec:SF
9571           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9572            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9573            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9575           UNSPEC_COPYSIGN))
9576    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9577   "TARGET_SSE_MATH"
9578   "#")
9579
9580 (define_split
9581   [(set (match_operand:SF 0 "register_operand" "")
9582         (unspec:SF
9583           [(match_operand:SF 2 "register_operand" "")
9584            (match_operand:SF 3 "register_operand" "")
9585            (match_operand:V4SF 4 "" "")
9586            (match_operand:V4SF 5 "" "")]
9587           UNSPEC_COPYSIGN))
9588    (clobber (match_scratch:V4SF 1 ""))]
9589   "TARGET_SSE_MATH && reload_completed"
9590   [(const_int 0)]
9591 {
9592   ix86_split_copysign_var (operands);
9593   DONE;
9594 })
9595
9596 (define_expand "negdf2"
9597   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9601
9602 (define_expand "absdf2"
9603   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9607
9608 (define_insn "*absnegdf2_mixed"
9609   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9610         (match_operator:DF 3 "absneg_operator"
9611           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9612    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9616   "#")
9617
9618 (define_insn "*absnegdf2_sse"
9619   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9620         (match_operator:DF 3 "absneg_operator"
9621           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "TARGET_SSE2 && TARGET_SSE_MATH
9625    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9626   "#")
9627
9628 (define_insn "*absnegdf2_i387"
9629   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630         (match_operator:DF 3 "absneg_operator"
9631           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632    (use (match_operand 2 "" ""))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9636   "#")
9637
9638 (define_expand "copysigndf3"
9639   [(match_operand:DF 0 "register_operand" "")
9640    (match_operand:DF 1 "nonmemory_operand" "")
9641    (match_operand:DF 2 "register_operand" "")]
9642   "TARGET_SSE2 && TARGET_SSE_MATH"
9643 {
9644   ix86_expand_copysign (operands);
9645   DONE;
9646 })
9647
9648 (define_insn_and_split "copysigndf3_const"
9649   [(set (match_operand:DF 0 "register_operand"          "=x")
9650         (unspec:DF
9651           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9652            (match_operand:DF 2 "register_operand"       "0")
9653            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9654           UNSPEC_COPYSIGN))]
9655   "TARGET_SSE2 && TARGET_SSE_MATH"
9656   "#"
9657   "&& reload_completed"
9658   [(const_int 0)]
9659 {
9660   ix86_split_copysign_const (operands);
9661   DONE;
9662 })
9663
9664 (define_insn "copysigndf3_var"
9665   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9666         (unspec:DF
9667           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9668            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9669            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9671           UNSPEC_COPYSIGN))
9672    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9673   "TARGET_SSE2 && TARGET_SSE_MATH"
9674   "#")
9675
9676 (define_split
9677   [(set (match_operand:DF 0 "register_operand" "")
9678         (unspec:DF
9679           [(match_operand:DF 2 "register_operand" "")
9680            (match_operand:DF 3 "register_operand" "")
9681            (match_operand:V2DF 4 "" "")
9682            (match_operand:V2DF 5 "" "")]
9683           UNSPEC_COPYSIGN))
9684    (clobber (match_scratch:V2DF 1 ""))]
9685   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9686   [(const_int 0)]
9687 {
9688   ix86_split_copysign_var (operands);
9689   DONE;
9690 })
9691
9692 (define_expand "negxf2"
9693   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387"
9696   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9697
9698 (define_expand "absxf2"
9699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701   "TARGET_80387"
9702   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9703
9704 (define_insn "*absnegxf2_i387"
9705   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706         (match_operator:XF 3 "absneg_operator"
9707           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "TARGET_80387
9711    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9712   "#")
9713
9714 ;; Splitters for fp abs and neg.
9715
9716 (define_split
9717   [(set (match_operand 0 "fp_register_operand" "")
9718         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719    (use (match_operand 2 "" ""))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "reload_completed"
9722   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9723
9724 (define_split
9725   [(set (match_operand 0 "register_operand" "")
9726         (match_operator 3 "absneg_operator"
9727           [(match_operand 1 "register_operand" "")]))
9728    (use (match_operand 2 "nonimmediate_operand" ""))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "reload_completed && SSE_REG_P (operands[0])"
9731   [(set (match_dup 0) (match_dup 3))]
9732 {
9733   enum machine_mode mode = GET_MODE (operands[0]);
9734   enum machine_mode vmode = GET_MODE (operands[2]);
9735   rtx tmp;
9736   
9737   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739   if (operands_match_p (operands[0], operands[2]))
9740     {
9741       tmp = operands[1];
9742       operands[1] = operands[2];
9743       operands[2] = tmp;
9744     }
9745   if (GET_CODE (operands[3]) == ABS)
9746     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9747   else
9748     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9749   operands[3] = tmp;
9750 })
9751
9752 (define_split
9753   [(set (match_operand:SF 0 "register_operand" "")
9754         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755    (use (match_operand:V4SF 2 "" ""))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "reload_completed"
9758   [(parallel [(set (match_dup 0) (match_dup 1))
9759               (clobber (reg:CC FLAGS_REG))])]
9760
9761   rtx tmp;
9762   operands[0] = gen_lowpart (SImode, operands[0]);
9763   if (GET_CODE (operands[1]) == ABS)
9764     {
9765       tmp = gen_int_mode (0x7fffffff, SImode);
9766       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9767     }
9768   else
9769     {
9770       tmp = gen_int_mode (0x80000000, SImode);
9771       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9772     }
9773   operands[1] = tmp;
9774 })
9775
9776 (define_split
9777   [(set (match_operand:DF 0 "register_operand" "")
9778         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779    (use (match_operand 2 "" ""))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "reload_completed"
9782   [(parallel [(set (match_dup 0) (match_dup 1))
9783               (clobber (reg:CC FLAGS_REG))])]
9784 {
9785   rtx tmp;
9786   if (TARGET_64BIT)
9787     {
9788       tmp = gen_lowpart (DImode, operands[0]);
9789       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9790       operands[0] = tmp;
9791
9792       if (GET_CODE (operands[1]) == ABS)
9793         tmp = const0_rtx;
9794       else
9795         tmp = gen_rtx_NOT (DImode, tmp);
9796     }
9797   else
9798     {
9799       operands[0] = gen_highpart (SImode, operands[0]);
9800       if (GET_CODE (operands[1]) == ABS)
9801         {
9802           tmp = gen_int_mode (0x7fffffff, SImode);
9803           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9804         }
9805       else
9806         {
9807           tmp = gen_int_mode (0x80000000, SImode);
9808           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9809         }
9810     }
9811   operands[1] = tmp;
9812 })
9813
9814 (define_split
9815   [(set (match_operand:XF 0 "register_operand" "")
9816         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817    (use (match_operand 2 "" ""))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "reload_completed"
9820   [(parallel [(set (match_dup 0) (match_dup 1))
9821               (clobber (reg:CC FLAGS_REG))])]
9822 {
9823   rtx tmp;
9824   operands[0] = gen_rtx_REG (SImode,
9825                              true_regnum (operands[0])
9826                              + (TARGET_64BIT ? 1 : 2));
9827   if (GET_CODE (operands[1]) == ABS)
9828     {
9829       tmp = GEN_INT (0x7fff);
9830       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9831     }
9832   else
9833     {
9834       tmp = GEN_INT (0x8000);
9835       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836     }
9837   operands[1] = tmp;
9838 })
9839
9840 (define_split
9841   [(set (match_operand 0 "memory_operand" "")
9842         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843    (use (match_operand 2 "" ""))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "reload_completed"
9846   [(parallel [(set (match_dup 0) (match_dup 1))
9847               (clobber (reg:CC FLAGS_REG))])]
9848 {
9849   enum machine_mode mode = GET_MODE (operands[0]);
9850   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9851   rtx tmp;
9852
9853   operands[0] = adjust_address (operands[0], QImode, size - 1);
9854   if (GET_CODE (operands[1]) == ABS)
9855     {
9856       tmp = gen_int_mode (0x7f, QImode);
9857       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9858     }
9859   else
9860     {
9861       tmp = gen_int_mode (0x80, QImode);
9862       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9863     }
9864   operands[1] = tmp;
9865 })
9866
9867 ;; Conditionalize these after reload. If they match before reload, we 
9868 ;; lose the clobber and ability to use integer instructions.
9869
9870 (define_insn "*negsf2_1"
9871   [(set (match_operand:SF 0 "register_operand" "=f")
9872         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873   "TARGET_80387 && reload_completed"
9874   "fchs"
9875   [(set_attr "type" "fsgn")
9876    (set_attr "mode" "SF")])
9877
9878 (define_insn "*negdf2_1"
9879   [(set (match_operand:DF 0 "register_operand" "=f")
9880         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881   "TARGET_80387 && reload_completed"
9882   "fchs"
9883   [(set_attr "type" "fsgn")
9884    (set_attr "mode" "DF")])
9885
9886 (define_insn "*negxf2_1"
9887   [(set (match_operand:XF 0 "register_operand" "=f")
9888         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889   "TARGET_80387 && reload_completed"
9890   "fchs"
9891   [(set_attr "type" "fsgn")
9892    (set_attr "mode" "XF")])
9893
9894 (define_insn "*abssf2_1"
9895   [(set (match_operand:SF 0 "register_operand" "=f")
9896         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897   "TARGET_80387 && reload_completed"
9898   "fabs"
9899   [(set_attr "type" "fsgn")
9900    (set_attr "mode" "SF")])
9901
9902 (define_insn "*absdf2_1"
9903   [(set (match_operand:DF 0 "register_operand" "=f")
9904         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905   "TARGET_80387 && reload_completed"
9906   "fabs"
9907   [(set_attr "type" "fsgn")
9908    (set_attr "mode" "DF")])
9909
9910 (define_insn "*absxf2_1"
9911   [(set (match_operand:XF 0 "register_operand" "=f")
9912         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913   "TARGET_80387 && reload_completed"
9914   "fabs"
9915   [(set_attr "type" "fsgn")
9916    (set_attr "mode" "DF")])
9917
9918 (define_insn "*negextendsfdf2"
9919   [(set (match_operand:DF 0 "register_operand" "=f")
9920         (neg:DF (float_extend:DF
9921                   (match_operand:SF 1 "register_operand" "0"))))]
9922   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9926
9927 (define_insn "*negextenddfxf2"
9928   [(set (match_operand:XF 0 "register_operand" "=f")
9929         (neg:XF (float_extend:XF
9930                   (match_operand:DF 1 "register_operand" "0"))))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "XF")])
9935
9936 (define_insn "*negextendsfxf2"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (float_extend:XF
9939                   (match_operand:SF 1 "register_operand" "0"))))]
9940   "TARGET_80387"
9941   "fchs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "XF")])
9944
9945 (define_insn "*absextendsfdf2"
9946   [(set (match_operand:DF 0 "register_operand" "=f")
9947         (abs:DF (float_extend:DF
9948                   (match_operand:SF 1 "register_operand" "0"))))]
9949   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9950   "fabs"
9951   [(set_attr "type" "fsgn")
9952    (set_attr "mode" "DF")])
9953
9954 (define_insn "*absextenddfxf2"
9955   [(set (match_operand:XF 0 "register_operand" "=f")
9956         (abs:XF (float_extend:XF
9957           (match_operand:DF 1 "register_operand" "0"))))]
9958   "TARGET_80387"
9959   "fabs"
9960   [(set_attr "type" "fsgn")
9961    (set_attr "mode" "XF")])
9962
9963 (define_insn "*absextendsfxf2"
9964   [(set (match_operand:XF 0 "register_operand" "=f")
9965         (abs:XF (float_extend:XF
9966           (match_operand:SF 1 "register_operand" "0"))))]
9967   "TARGET_80387"
9968   "fabs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "XF")])
9971 \f
9972 ;; One complement instructions
9973
9974 (define_expand "one_cmpldi2"
9975   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9977   "TARGET_64BIT"
9978   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9979
9980 (define_insn "*one_cmpldi2_1_rex64"
9981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9984   "not{q}\t%0"
9985   [(set_attr "type" "negnot")
9986    (set_attr "mode" "DI")])
9987
9988 (define_insn "*one_cmpldi2_2_rex64"
9989   [(set (reg FLAGS_REG)
9990         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9991                  (const_int 0)))
9992    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993         (not:DI (match_dup 1)))]
9994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995    && ix86_unary_operator_ok (NOT, DImode, operands)"
9996   "#"
9997   [(set_attr "type" "alu1")
9998    (set_attr "mode" "DI")])
9999
10000 (define_split
10001   [(set (match_operand 0 "flags_reg_operand" "")
10002         (match_operator 2 "compare_operator"
10003           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10004            (const_int 0)]))
10005    (set (match_operand:DI 1 "nonimmediate_operand" "")
10006         (not:DI (match_dup 3)))]
10007   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008   [(parallel [(set (match_dup 0)
10009                    (match_op_dup 2
10010                      [(xor:DI (match_dup 3) (const_int -1))
10011                       (const_int 0)]))
10012               (set (match_dup 1)
10013                    (xor:DI (match_dup 3) (const_int -1)))])]
10014   "")
10015
10016 (define_expand "one_cmplsi2"
10017   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10019   ""
10020   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10021
10022 (define_insn "*one_cmplsi2_1"
10023   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025   "ix86_unary_operator_ok (NOT, SImode, operands)"
10026   "not{l}\t%0"
10027   [(set_attr "type" "negnot")
10028    (set_attr "mode" "SI")])
10029
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032   [(set (match_operand:DI 0 "register_operand" "=r")
10033         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10035   "not{l}\t%k0"
10036   [(set_attr "type" "negnot")
10037    (set_attr "mode" "SI")])
10038
10039 (define_insn "*one_cmplsi2_2"
10040   [(set (reg FLAGS_REG)
10041         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10042                  (const_int 0)))
10043    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044         (not:SI (match_dup 1)))]
10045   "ix86_match_ccmode (insn, CCNOmode)
10046    && ix86_unary_operator_ok (NOT, SImode, operands)"
10047   "#"
10048   [(set_attr "type" "alu1")
10049    (set_attr "mode" "SI")])
10050
10051 (define_split
10052   [(set (match_operand 0 "flags_reg_operand" "")
10053         (match_operator 2 "compare_operator"
10054           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10055            (const_int 0)]))
10056    (set (match_operand:SI 1 "nonimmediate_operand" "")
10057         (not:SI (match_dup 3)))]
10058   "ix86_match_ccmode (insn, CCNOmode)"
10059   [(parallel [(set (match_dup 0)
10060                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10061                                     (const_int 0)]))
10062               (set (match_dup 1)
10063                    (xor:SI (match_dup 3) (const_int -1)))])]
10064   "")
10065
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068   [(set (reg FLAGS_REG)
10069         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10070                  (const_int 0)))
10071    (set (match_operand:DI 0 "register_operand" "=r")
10072         (zero_extend:DI (not:SI (match_dup 1))))]
10073   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074    && ix86_unary_operator_ok (NOT, SImode, operands)"
10075   "#"
10076   [(set_attr "type" "alu1")
10077    (set_attr "mode" "SI")])
10078
10079 (define_split
10080   [(set (match_operand 0 "flags_reg_operand" "")
10081         (match_operator 2 "compare_operator"
10082           [(not:SI (match_operand:SI 3 "register_operand" ""))
10083            (const_int 0)]))
10084    (set (match_operand:DI 1 "register_operand" "")
10085         (zero_extend:DI (not:SI (match_dup 3))))]
10086   "ix86_match_ccmode (insn, CCNOmode)"
10087   [(parallel [(set (match_dup 0)
10088                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10089                                     (const_int 0)]))
10090               (set (match_dup 1)
10091                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10092   "")
10093
10094 (define_expand "one_cmplhi2"
10095   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097   "TARGET_HIMODE_MATH"
10098   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10099
10100 (define_insn "*one_cmplhi2_1"
10101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103   "ix86_unary_operator_ok (NOT, HImode, operands)"
10104   "not{w}\t%0"
10105   [(set_attr "type" "negnot")
10106    (set_attr "mode" "HI")])
10107
10108 (define_insn "*one_cmplhi2_2"
10109   [(set (reg FLAGS_REG)
10110         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10111                  (const_int 0)))
10112    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113         (not:HI (match_dup 1)))]
10114   "ix86_match_ccmode (insn, CCNOmode)
10115    && ix86_unary_operator_ok (NEG, HImode, operands)"
10116   "#"
10117   [(set_attr "type" "alu1")
10118    (set_attr "mode" "HI")])
10119
10120 (define_split
10121   [(set (match_operand 0 "flags_reg_operand" "")
10122         (match_operator 2 "compare_operator"
10123           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10124            (const_int 0)]))
10125    (set (match_operand:HI 1 "nonimmediate_operand" "")
10126         (not:HI (match_dup 3)))]
10127   "ix86_match_ccmode (insn, CCNOmode)"
10128   [(parallel [(set (match_dup 0)
10129                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10130                                     (const_int 0)]))
10131               (set (match_dup 1)
10132                    (xor:HI (match_dup 3) (const_int -1)))])]
10133   "")
10134
10135 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10136 (define_expand "one_cmplqi2"
10137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139   "TARGET_QIMODE_MATH"
10140   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10141
10142 (define_insn "*one_cmplqi2_1"
10143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145   "ix86_unary_operator_ok (NOT, QImode, operands)"
10146   "@
10147    not{b}\t%0
10148    not{l}\t%k0"
10149   [(set_attr "type" "negnot")
10150    (set_attr "mode" "QI,SI")])
10151
10152 (define_insn "*one_cmplqi2_2"
10153   [(set (reg FLAGS_REG)
10154         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10155                  (const_int 0)))
10156    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157         (not:QI (match_dup 1)))]
10158   "ix86_match_ccmode (insn, CCNOmode)
10159    && ix86_unary_operator_ok (NOT, QImode, operands)"
10160   "#"
10161   [(set_attr "type" "alu1")
10162    (set_attr "mode" "QI")])
10163
10164 (define_split
10165   [(set (match_operand 0 "flags_reg_operand" "")
10166         (match_operator 2 "compare_operator"
10167           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10168            (const_int 0)]))
10169    (set (match_operand:QI 1 "nonimmediate_operand" "")
10170         (not:QI (match_dup 3)))]
10171   "ix86_match_ccmode (insn, CCNOmode)"
10172   [(parallel [(set (match_dup 0)
10173                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10174                                     (const_int 0)]))
10175               (set (match_dup 1)
10176                    (xor:QI (match_dup 3) (const_int -1)))])]
10177   "")
10178 \f
10179 ;; Arithmetic shift instructions
10180
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10185 ;;
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10192 ;;
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10198 ;;
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10201 ;; than 31.
10202
10203 (define_expand "ashlti3"
10204   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10206                               (match_operand:QI 2 "nonmemory_operand" "")))
10207               (clobber (reg:CC FLAGS_REG))])]
10208   "TARGET_64BIT"
10209 {
10210   if (! immediate_operand (operands[2], QImode))
10211     {
10212       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10213       DONE;
10214     }
10215   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10216   DONE;
10217 })
10218
10219 (define_insn "ashlti3_1"
10220   [(set (match_operand:TI 0 "register_operand" "=r")
10221         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222                    (match_operand:QI 2 "register_operand" "c")))
10223    (clobber (match_scratch:DI 3 "=&r"))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "TARGET_64BIT"
10226   "#"
10227   [(set_attr "type" "multi")])
10228
10229 (define_insn "*ashlti3_2"
10230   [(set (match_operand:TI 0 "register_operand" "=r")
10231         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232                    (match_operand:QI 2 "immediate_operand" "O")))
10233    (clobber (reg:CC FLAGS_REG))]
10234   "TARGET_64BIT"
10235   "#"
10236   [(set_attr "type" "multi")])
10237
10238 (define_split
10239   [(set (match_operand:TI 0 "register_operand" "")
10240         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241                    (match_operand:QI 2 "register_operand" "")))
10242    (clobber (match_scratch:DI 3 ""))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "TARGET_64BIT && reload_completed"
10245   [(const_int 0)]
10246   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10247
10248 (define_split
10249   [(set (match_operand:TI 0 "register_operand" "")
10250         (ashift:TI (match_operand:TI 1 "register_operand" "")
10251                    (match_operand:QI 2 "immediate_operand" "")))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_64BIT && reload_completed"
10254   [(const_int 0)]
10255   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10256
10257 (define_insn "x86_64_shld"
10258   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259         (ior:DI (ashift:DI (match_dup 0)
10260                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262                   (minus:QI (const_int 64) (match_dup 2)))))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT"
10265   "@
10266    shld{q}\t{%2, %1, %0|%0, %1, %2}
10267    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268   [(set_attr "type" "ishift")
10269    (set_attr "prefix_0f" "1")
10270    (set_attr "mode" "DI")
10271    (set_attr "athlon_decode" "vector")])
10272
10273 (define_expand "x86_64_shift_adj"
10274   [(set (reg:CCZ FLAGS_REG)
10275         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10276                              (const_int 64))
10277                      (const_int 0)))
10278    (set (match_operand:DI 0 "register_operand" "")
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 1 "register_operand" "")
10281                          (match_dup 0)))
10282    (set (match_dup 1)
10283         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284                          (match_operand:DI 3 "register_operand" "r")
10285                          (match_dup 1)))]
10286   "TARGET_64BIT"
10287   "")
10288
10289 (define_expand "ashldi3"
10290   [(set (match_operand:DI 0 "shiftdi_operand" "")
10291         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292                    (match_operand:QI 2 "nonmemory_operand" "")))]
10293   ""
10294   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10295
10296 (define_insn "*ashldi3_1_rex64"
10297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10302 {
10303   switch (get_attr_type (insn))
10304     {
10305     case TYPE_ALU:
10306       gcc_assert (operands[2] == const1_rtx);
10307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308       return "add{q}\t{%0, %0|%0, %0}";
10309
10310     case TYPE_LEA:
10311       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313       operands[1] = gen_rtx_MULT (DImode, operands[1],
10314                                   GEN_INT (1 << INTVAL (operands[2])));
10315       return "lea{q}\t{%a1, %0|%0, %a1}";
10316
10317     default:
10318       if (REG_P (operands[2]))
10319         return "sal{q}\t{%b2, %0|%0, %b2}";
10320       else if (operands[2] == const1_rtx
10321                && (TARGET_SHIFT1 || optimize_size))
10322         return "sal{q}\t%0";
10323       else
10324         return "sal{q}\t{%2, %0|%0, %2}";
10325     }
10326 }
10327   [(set (attr "type")
10328      (cond [(eq_attr "alternative" "1")
10329               (const_string "lea")
10330             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10331                           (const_int 0))
10332                       (match_operand 0 "register_operand" ""))
10333                  (match_operand 2 "const1_operand" ""))
10334               (const_string "alu")
10335            ]
10336            (const_string "ishift")))
10337    (set_attr "mode" "DI")])
10338
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341   [(set (match_operand:DI 0 "register_operand" "")
10342         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343                    (match_operand:QI 2 "immediate_operand" "")))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT && reload_completed
10346    && true_regnum (operands[0]) != true_regnum (operands[1])"
10347   [(set (match_dup 0)
10348         (mult:DI (match_dup 1)
10349                  (match_dup 2)))]
10350   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10351
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags.  We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356   [(set (reg FLAGS_REG)
10357         (compare
10358           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359                      (match_operand:QI 2 "immediate_operand" "e"))
10360           (const_int 0)))
10361    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362         (ashift:DI (match_dup 1) (match_dup 2)))]
10363   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10365 {
10366   switch (get_attr_type (insn))
10367     {
10368     case TYPE_ALU:
10369       gcc_assert (operands[2] == const1_rtx);
10370       return "add{q}\t{%0, %0|%0, %0}";
10371
10372     default:
10373       if (REG_P (operands[2]))
10374         return "sal{q}\t{%b2, %0|%0, %b2}";
10375       else if (operands[2] == const1_rtx
10376                && (TARGET_SHIFT1 || optimize_size))
10377         return "sal{q}\t%0";
10378       else
10379         return "sal{q}\t{%2, %0|%0, %2}";
10380     }
10381 }
10382   [(set (attr "type")
10383      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10384                           (const_int 0))
10385                       (match_operand 0 "register_operand" ""))
10386                  (match_operand 2 "const1_operand" ""))
10387               (const_string "alu")
10388            ]
10389            (const_string "ishift")))
10390    (set_attr "mode" "DI")])
10391
10392 (define_insn "*ashldi3_1"
10393   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "!TARGET_64BIT"
10398   "#"
10399   [(set_attr "type" "multi")])
10400
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium.  But if
10403 ;; we have one handy, we won't turn it away.
10404 (define_peephole2
10405   [(match_scratch:SI 3 "r")
10406    (parallel [(set (match_operand:DI 0 "register_operand" "")
10407                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408                               (match_operand:QI 2 "nonmemory_operand" "")))
10409               (clobber (reg:CC FLAGS_REG))])
10410    (match_dup 3)]
10411   "!TARGET_64BIT && TARGET_CMOVE"
10412   [(const_int 0)]
10413   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10414
10415 (define_split
10416   [(set (match_operand:DI 0 "register_operand" "")
10417         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418                    (match_operand:QI 2 "nonmemory_operand" "")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10421                      ? flow2_completed : reload_completed)"
10422   [(const_int 0)]
10423   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10424
10425 (define_insn "x86_shld_1"
10426   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10427         (ior:SI (ashift:SI (match_dup 0)
10428                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10429                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10430                   (minus:QI (const_int 32) (match_dup 2)))))
10431    (clobber (reg:CC FLAGS_REG))]
10432   ""
10433   "@
10434    shld{l}\t{%2, %1, %0|%0, %1, %2}
10435    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10436   [(set_attr "type" "ishift")
10437    (set_attr "prefix_0f" "1")
10438    (set_attr "mode" "SI")
10439    (set_attr "pent_pair" "np")
10440    (set_attr "athlon_decode" "vector")])
10441
10442 (define_expand "x86_shift_adj_1"
10443   [(set (reg:CCZ FLAGS_REG)
10444         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10445                              (const_int 32))
10446                      (const_int 0)))
10447    (set (match_operand:SI 0 "register_operand" "")
10448         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10449                          (match_operand:SI 1 "register_operand" "")
10450                          (match_dup 0)))
10451    (set (match_dup 1)
10452         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453                          (match_operand:SI 3 "register_operand" "r")
10454                          (match_dup 1)))]
10455   "TARGET_CMOVE"
10456   "")
10457
10458 (define_expand "x86_shift_adj_2"
10459   [(use (match_operand:SI 0 "register_operand" ""))
10460    (use (match_operand:SI 1 "register_operand" ""))
10461    (use (match_operand:QI 2 "register_operand" ""))]
10462   ""
10463 {
10464   rtx label = gen_label_rtx ();
10465   rtx tmp;
10466
10467   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10468
10469   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472                               gen_rtx_LABEL_REF (VOIDmode, label),
10473                               pc_rtx);
10474   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475   JUMP_LABEL (tmp) = label;
10476
10477   emit_move_insn (operands[0], operands[1]);
10478   ix86_expand_clear (operands[1]);
10479
10480   emit_label (label);
10481   LABEL_NUSES (label) = 1;
10482
10483   DONE;
10484 })
10485
10486 (define_expand "ashlsi3"
10487   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489                    (match_operand:QI 2 "nonmemory_operand" "")))
10490    (clobber (reg:CC FLAGS_REG))]
10491   ""
10492   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10493
10494 (define_insn "*ashlsi3_1"
10495   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10496         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10497                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10498    (clobber (reg:CC FLAGS_REG))]
10499   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10500 {
10501   switch (get_attr_type (insn))
10502     {
10503     case TYPE_ALU:
10504       gcc_assert (operands[2] == const1_rtx);
10505       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10506       return "add{l}\t{%0, %0|%0, %0}";
10507
10508     case TYPE_LEA:
10509       return "#";
10510
10511     default:
10512       if (REG_P (operands[2]))
10513         return "sal{l}\t{%b2, %0|%0, %b2}";
10514       else if (operands[2] == const1_rtx
10515                && (TARGET_SHIFT1 || optimize_size))
10516         return "sal{l}\t%0";
10517       else
10518         return "sal{l}\t{%2, %0|%0, %2}";
10519     }
10520 }
10521   [(set (attr "type")
10522      (cond [(eq_attr "alternative" "1")
10523               (const_string "lea")
10524             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10525                           (const_int 0))
10526                       (match_operand 0 "register_operand" ""))
10527                  (match_operand 2 "const1_operand" ""))
10528               (const_string "alu")
10529            ]
10530            (const_string "ishift")))
10531    (set_attr "mode" "SI")])
10532
10533 ;; Convert lea to the lea pattern to avoid flags dependency.
10534 (define_split
10535   [(set (match_operand 0 "register_operand" "")
10536         (ashift (match_operand 1 "index_register_operand" "")
10537                 (match_operand:QI 2 "const_int_operand" "")))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "reload_completed
10540    && true_regnum (operands[0]) != true_regnum (operands[1])
10541    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10542   [(const_int 0)]
10543 {
10544   rtx pat;
10545   enum machine_mode mode = GET_MODE (operands[0]);
10546
10547   if (GET_MODE_SIZE (mode) < 4)
10548     operands[0] = gen_lowpart (SImode, operands[0]);
10549   if (mode != Pmode)
10550     operands[1] = gen_lowpart (Pmode, operands[1]);
10551   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10552
10553   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10554   if (Pmode != SImode)
10555     pat = gen_rtx_SUBREG (SImode, pat, 0);
10556   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10557   DONE;
10558 })
10559
10560 ;; Rare case of shifting RSP is handled by generating move and shift
10561 (define_split
10562   [(set (match_operand 0 "register_operand" "")
10563         (ashift (match_operand 1 "register_operand" "")
10564                 (match_operand:QI 2 "const_int_operand" "")))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "reload_completed
10567    && true_regnum (operands[0]) != true_regnum (operands[1])"
10568   [(const_int 0)]
10569 {
10570   rtx pat, clob;
10571   emit_move_insn (operands[1], operands[0]);
10572   pat = gen_rtx_SET (VOIDmode, operands[0],
10573                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10574                                      operands[0], operands[2]));
10575   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10576   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10577   DONE;
10578 })
10579
10580 (define_insn "*ashlsi3_1_zext"
10581   [(set (match_operand:DI 0 "register_operand" "=r,r")
10582         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10583                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10584    (clobber (reg:CC FLAGS_REG))]
10585   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10586 {
10587   switch (get_attr_type (insn))
10588     {
10589     case TYPE_ALU:
10590       gcc_assert (operands[2] == const1_rtx);
10591       return "add{l}\t{%k0, %k0|%k0, %k0}";
10592
10593     case TYPE_LEA:
10594       return "#";
10595
10596     default:
10597       if (REG_P (operands[2]))
10598         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10599       else if (operands[2] == const1_rtx
10600                && (TARGET_SHIFT1 || optimize_size))
10601         return "sal{l}\t%k0";
10602       else
10603         return "sal{l}\t{%2, %k0|%k0, %2}";
10604     }
10605 }
10606   [(set (attr "type")
10607      (cond [(eq_attr "alternative" "1")
10608               (const_string "lea")
10609             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10610                      (const_int 0))
10611                  (match_operand 2 "const1_operand" ""))
10612               (const_string "alu")
10613            ]
10614            (const_string "ishift")))
10615    (set_attr "mode" "SI")])
10616
10617 ;; Convert lea to the lea pattern to avoid flags dependency.
10618 (define_split
10619   [(set (match_operand:DI 0 "register_operand" "")
10620         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10621                                 (match_operand:QI 2 "const_int_operand" ""))))
10622    (clobber (reg:CC FLAGS_REG))]
10623   "TARGET_64BIT && reload_completed
10624    && true_regnum (operands[0]) != true_regnum (operands[1])"
10625   [(set (match_dup 0) (zero_extend:DI
10626                         (subreg:SI (mult:SI (match_dup 1)
10627                                             (match_dup 2)) 0)))]
10628 {
10629   operands[1] = gen_lowpart (Pmode, operands[1]);
10630   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10631 })
10632
10633 ;; This pattern can't accept a variable shift count, since shifts by
10634 ;; zero don't affect the flags.  We assume that shifts by constant
10635 ;; zero are optimized away.
10636 (define_insn "*ashlsi3_cmp"
10637   [(set (reg FLAGS_REG)
10638         (compare
10639           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10640                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10641           (const_int 0)))
10642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10643         (ashift:SI (match_dup 1) (match_dup 2)))]
10644   "ix86_match_ccmode (insn, CCGOCmode)
10645    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10646 {
10647   switch (get_attr_type (insn))
10648     {
10649     case TYPE_ALU:
10650       gcc_assert (operands[2] == const1_rtx);
10651       return "add{l}\t{%0, %0|%0, %0}";
10652
10653     default:
10654       if (REG_P (operands[2]))
10655         return "sal{l}\t{%b2, %0|%0, %b2}";
10656       else if (operands[2] == const1_rtx
10657                && (TARGET_SHIFT1 || optimize_size))
10658         return "sal{l}\t%0";
10659       else
10660         return "sal{l}\t{%2, %0|%0, %2}";
10661     }
10662 }
10663   [(set (attr "type")
10664      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10665                           (const_int 0))
10666                       (match_operand 0 "register_operand" ""))
10667                  (match_operand 2 "const1_operand" ""))
10668               (const_string "alu")
10669            ]
10670            (const_string "ishift")))
10671    (set_attr "mode" "SI")])
10672
10673 (define_insn "*ashlsi3_cmp_zext"
10674   [(set (reg FLAGS_REG)
10675         (compare
10676           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10677                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10678           (const_int 0)))
10679    (set (match_operand:DI 0 "register_operand" "=r")
10680         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10681   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10682    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10683 {
10684   switch (get_attr_type (insn))
10685     {
10686     case TYPE_ALU:
10687       gcc_assert (operands[2] == const1_rtx);
10688       return "add{l}\t{%k0, %k0|%k0, %k0}";
10689
10690     default:
10691       if (REG_P (operands[2]))
10692         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10693       else if (operands[2] == const1_rtx
10694                && (TARGET_SHIFT1 || optimize_size))
10695         return "sal{l}\t%k0";
10696       else
10697         return "sal{l}\t{%2, %k0|%k0, %2}";
10698     }
10699 }
10700   [(set (attr "type")
10701      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10702                      (const_int 0))
10703                  (match_operand 2 "const1_operand" ""))
10704               (const_string "alu")
10705            ]
10706            (const_string "ishift")))
10707    (set_attr "mode" "SI")])
10708
10709 (define_expand "ashlhi3"
10710   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10711         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10712                    (match_operand:QI 2 "nonmemory_operand" "")))
10713    (clobber (reg:CC FLAGS_REG))]
10714   "TARGET_HIMODE_MATH"
10715   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10716
10717 (define_insn "*ashlhi3_1_lea"
10718   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10719         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10720                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_PARTIAL_REG_STALL
10723    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10724 {
10725   switch (get_attr_type (insn))
10726     {
10727     case TYPE_LEA:
10728       return "#";
10729     case TYPE_ALU:
10730       gcc_assert (operands[2] == const1_rtx);
10731       return "add{w}\t{%0, %0|%0, %0}";
10732
10733     default:
10734       if (REG_P (operands[2]))
10735         return "sal{w}\t{%b2, %0|%0, %b2}";
10736       else if (operands[2] == const1_rtx
10737                && (TARGET_SHIFT1 || optimize_size))
10738         return "sal{w}\t%0";
10739       else
10740         return "sal{w}\t{%2, %0|%0, %2}";
10741     }
10742 }
10743   [(set (attr "type")
10744      (cond [(eq_attr "alternative" "1")
10745               (const_string "lea")
10746             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747                           (const_int 0))
10748                       (match_operand 0 "register_operand" ""))
10749                  (match_operand 2 "const1_operand" ""))
10750               (const_string "alu")
10751            ]
10752            (const_string "ishift")))
10753    (set_attr "mode" "HI,SI")])
10754
10755 (define_insn "*ashlhi3_1"
10756   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10758                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10759    (clobber (reg:CC FLAGS_REG))]
10760   "TARGET_PARTIAL_REG_STALL
10761    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10762 {
10763   switch (get_attr_type (insn))
10764     {
10765     case TYPE_ALU:
10766       gcc_assert (operands[2] == const1_rtx);
10767       return "add{w}\t{%0, %0|%0, %0}";
10768
10769     default:
10770       if (REG_P (operands[2]))
10771         return "sal{w}\t{%b2, %0|%0, %b2}";
10772       else if (operands[2] == const1_rtx
10773                && (TARGET_SHIFT1 || optimize_size))
10774         return "sal{w}\t%0";
10775       else
10776         return "sal{w}\t{%2, %0|%0, %2}";
10777     }
10778 }
10779   [(set (attr "type")
10780      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781                           (const_int 0))
10782                       (match_operand 0 "register_operand" ""))
10783                  (match_operand 2 "const1_operand" ""))
10784               (const_string "alu")
10785            ]
10786            (const_string "ishift")))
10787    (set_attr "mode" "HI")])
10788
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags.  We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlhi3_cmp"
10793   [(set (reg FLAGS_REG)
10794         (compare
10795           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10797           (const_int 0)))
10798    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10799         (ashift:HI (match_dup 1) (match_dup 2)))]
10800   "ix86_match_ccmode (insn, CCGOCmode)
10801    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10802 {
10803   switch (get_attr_type (insn))
10804     {
10805     case TYPE_ALU:
10806       gcc_assert (operands[2] == const1_rtx);
10807       return "add{w}\t{%0, %0|%0, %0}";
10808
10809     default:
10810       if (REG_P (operands[2]))
10811         return "sal{w}\t{%b2, %0|%0, %b2}";
10812       else if (operands[2] == const1_rtx
10813                && (TARGET_SHIFT1 || optimize_size))
10814         return "sal{w}\t%0";
10815       else
10816         return "sal{w}\t{%2, %0|%0, %2}";
10817     }
10818 }
10819   [(set (attr "type")
10820      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10821                           (const_int 0))
10822                       (match_operand 0 "register_operand" ""))
10823                  (match_operand 2 "const1_operand" ""))
10824               (const_string "alu")
10825            ]
10826            (const_string "ishift")))
10827    (set_attr "mode" "HI")])
10828
10829 (define_expand "ashlqi3"
10830   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10831         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10832                    (match_operand:QI 2 "nonmemory_operand" "")))
10833    (clobber (reg:CC FLAGS_REG))]
10834   "TARGET_QIMODE_MATH"
10835   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10836
10837 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10838
10839 (define_insn "*ashlqi3_1_lea"
10840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10841         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10842                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10843    (clobber (reg:CC FLAGS_REG))]
10844   "!TARGET_PARTIAL_REG_STALL
10845    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10846 {
10847   switch (get_attr_type (insn))
10848     {
10849     case TYPE_LEA:
10850       return "#";
10851     case TYPE_ALU:
10852       gcc_assert (operands[2] == const1_rtx);
10853       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10854         return "add{l}\t{%k0, %k0|%k0, %k0}";
10855       else
10856         return "add{b}\t{%0, %0|%0, %0}";
10857
10858     default:
10859       if (REG_P (operands[2]))
10860         {
10861           if (get_attr_mode (insn) == MODE_SI)
10862             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10863           else
10864             return "sal{b}\t{%b2, %0|%0, %b2}";
10865         }
10866       else if (operands[2] == const1_rtx
10867                && (TARGET_SHIFT1 || optimize_size))
10868         {
10869           if (get_attr_mode (insn) == MODE_SI)
10870             return "sal{l}\t%0";
10871           else
10872             return "sal{b}\t%0";
10873         }
10874       else
10875         {
10876           if (get_attr_mode (insn) == MODE_SI)
10877             return "sal{l}\t{%2, %k0|%k0, %2}";
10878           else
10879             return "sal{b}\t{%2, %0|%0, %2}";
10880         }
10881     }
10882 }
10883   [(set (attr "type")
10884      (cond [(eq_attr "alternative" "2")
10885               (const_string "lea")
10886             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887                           (const_int 0))
10888                       (match_operand 0 "register_operand" ""))
10889                  (match_operand 2 "const1_operand" ""))
10890               (const_string "alu")
10891            ]
10892            (const_string "ishift")))
10893    (set_attr "mode" "QI,SI,SI")])
10894
10895 (define_insn "*ashlqi3_1"
10896   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10897         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10898                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "TARGET_PARTIAL_REG_STALL
10901    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10902 {
10903   switch (get_attr_type (insn))
10904     {
10905     case TYPE_ALU:
10906       gcc_assert (operands[2] == const1_rtx);
10907       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10908         return "add{l}\t{%k0, %k0|%k0, %k0}";
10909       else
10910         return "add{b}\t{%0, %0|%0, %0}";
10911
10912     default:
10913       if (REG_P (operands[2]))
10914         {
10915           if (get_attr_mode (insn) == MODE_SI)
10916             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10917           else
10918             return "sal{b}\t{%b2, %0|%0, %b2}";
10919         }
10920       else if (operands[2] == const1_rtx
10921                && (TARGET_SHIFT1 || optimize_size))
10922         {
10923           if (get_attr_mode (insn) == MODE_SI)
10924             return "sal{l}\t%0";
10925           else
10926             return "sal{b}\t%0";
10927         }
10928       else
10929         {
10930           if (get_attr_mode (insn) == MODE_SI)
10931             return "sal{l}\t{%2, %k0|%k0, %2}";
10932           else
10933             return "sal{b}\t{%2, %0|%0, %2}";
10934         }
10935     }
10936 }
10937   [(set (attr "type")
10938      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10939                           (const_int 0))
10940                       (match_operand 0 "register_operand" ""))
10941                  (match_operand 2 "const1_operand" ""))
10942               (const_string "alu")
10943            ]
10944            (const_string "ishift")))
10945    (set_attr "mode" "QI,SI")])
10946
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags.  We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashlqi3_cmp"
10951   [(set (reg FLAGS_REG)
10952         (compare
10953           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10954                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10955           (const_int 0)))
10956    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10957         (ashift:QI (match_dup 1) (match_dup 2)))]
10958   "ix86_match_ccmode (insn, CCGOCmode)
10959    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10960 {
10961   switch (get_attr_type (insn))
10962     {
10963     case TYPE_ALU:
10964       gcc_assert (operands[2] == const1_rtx);
10965       return "add{b}\t{%0, %0|%0, %0}";
10966
10967     default:
10968       if (REG_P (operands[2]))
10969         return "sal{b}\t{%b2, %0|%0, %b2}";
10970       else if (operands[2] == const1_rtx
10971                && (TARGET_SHIFT1 || optimize_size))
10972         return "sal{b}\t%0";
10973       else
10974         return "sal{b}\t{%2, %0|%0, %2}";
10975     }
10976 }
10977   [(set (attr "type")
10978      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10979                           (const_int 0))
10980                       (match_operand 0 "register_operand" ""))
10981                  (match_operand 2 "const1_operand" ""))
10982               (const_string "alu")
10983            ]
10984            (const_string "ishift")))
10985    (set_attr "mode" "QI")])
10986
10987 ;; See comment above `ashldi3' about how this works.
10988
10989 (define_expand "ashrti3"
10990   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10991                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10992                                 (match_operand:QI 2 "nonmemory_operand" "")))
10993               (clobber (reg:CC FLAGS_REG))])]
10994   "TARGET_64BIT"
10995 {
10996   if (! immediate_operand (operands[2], QImode))
10997     {
10998       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10999       DONE;
11000     }
11001   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11002   DONE;
11003 })
11004
11005 (define_insn "ashrti3_1"
11006   [(set (match_operand:TI 0 "register_operand" "=r")
11007         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11008                      (match_operand:QI 2 "register_operand" "c")))
11009    (clobber (match_scratch:DI 3 "=&r"))
11010    (clobber (reg:CC FLAGS_REG))]
11011   "TARGET_64BIT"
11012   "#"
11013   [(set_attr "type" "multi")])
11014
11015 (define_insn "*ashrti3_2"
11016   [(set (match_operand:TI 0 "register_operand" "=r")
11017         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11018                      (match_operand:QI 2 "immediate_operand" "O")))
11019    (clobber (reg:CC FLAGS_REG))]
11020   "TARGET_64BIT"
11021   "#"
11022   [(set_attr "type" "multi")])
11023
11024 (define_split
11025   [(set (match_operand:TI 0 "register_operand" "")
11026         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027                      (match_operand:QI 2 "register_operand" "")))
11028    (clobber (match_scratch:DI 3 ""))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "TARGET_64BIT && reload_completed"
11031   [(const_int 0)]
11032   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11033
11034 (define_split
11035   [(set (match_operand:TI 0 "register_operand" "")
11036         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11037                      (match_operand:QI 2 "immediate_operand" "")))
11038    (clobber (reg:CC FLAGS_REG))]
11039   "TARGET_64BIT && reload_completed"
11040   [(const_int 0)]
11041   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11042
11043 (define_insn "x86_64_shrd"
11044   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11045         (ior:DI (ashiftrt:DI (match_dup 0)
11046                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11047                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11048                   (minus:QI (const_int 64) (match_dup 2)))))
11049    (clobber (reg:CC FLAGS_REG))]
11050   "TARGET_64BIT"
11051   "@
11052    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11053    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11054   [(set_attr "type" "ishift")
11055    (set_attr "prefix_0f" "1")
11056    (set_attr "mode" "DI")
11057    (set_attr "athlon_decode" "vector")])
11058
11059 (define_expand "ashrdi3"
11060   [(set (match_operand:DI 0 "shiftdi_operand" "")
11061         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11062                      (match_operand:QI 2 "nonmemory_operand" "")))]
11063   ""
11064   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11065
11066 (define_insn "*ashrdi3_63_rex64"
11067   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11068         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11069                      (match_operand:DI 2 "const_int_operand" "i,i")))
11070    (clobber (reg:CC FLAGS_REG))]
11071   "TARGET_64BIT && INTVAL (operands[2]) == 63
11072    && (TARGET_USE_CLTD || optimize_size)
11073    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11074   "@
11075    {cqto|cqo}
11076    sar{q}\t{%2, %0|%0, %2}"
11077   [(set_attr "type" "imovx,ishift")
11078    (set_attr "prefix_0f" "0,*")
11079    (set_attr "length_immediate" "0,*")
11080    (set_attr "modrm" "0,1")
11081    (set_attr "mode" "DI")])
11082
11083 (define_insn "*ashrdi3_1_one_bit_rex64"
11084   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11085         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11086                      (match_operand:QI 2 "const1_operand" "")))
11087    (clobber (reg:CC FLAGS_REG))]
11088   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11089    && (TARGET_SHIFT1 || optimize_size)"
11090   "sar{q}\t%0"
11091   [(set_attr "type" "ishift")
11092    (set (attr "length") 
11093      (if_then_else (match_operand:DI 0 "register_operand" "") 
11094         (const_string "2")
11095         (const_string "*")))])
11096
11097 (define_insn "*ashrdi3_1_rex64"
11098   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11099         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11100                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11101    (clobber (reg:CC FLAGS_REG))]
11102   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11103   "@
11104    sar{q}\t{%2, %0|%0, %2}
11105    sar{q}\t{%b2, %0|%0, %b2}"
11106   [(set_attr "type" "ishift")
11107    (set_attr "mode" "DI")])
11108
11109 ;; This pattern can't accept a variable shift count, since shifts by
11110 ;; zero don't affect the flags.  We assume that shifts by constant
11111 ;; zero are optimized away.
11112 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11113   [(set (reg FLAGS_REG)
11114         (compare
11115           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11116                        (match_operand:QI 2 "const1_operand" ""))
11117           (const_int 0)))
11118    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11120   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11121    && (TARGET_SHIFT1 || optimize_size)
11122    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11123   "sar{q}\t%0"
11124   [(set_attr "type" "ishift")
11125    (set (attr "length") 
11126      (if_then_else (match_operand:DI 0 "register_operand" "") 
11127         (const_string "2")
11128         (const_string "*")))])
11129
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags.  We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrdi3_cmp_rex64"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11137                        (match_operand:QI 2 "const_int_operand" "n"))
11138           (const_int 0)))
11139    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11140         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11141   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11142    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11143   "sar{q}\t{%2, %0|%0, %2}"
11144   [(set_attr "type" "ishift")
11145    (set_attr "mode" "DI")])
11146
11147 (define_insn "*ashrdi3_1"
11148   [(set (match_operand:DI 0 "register_operand" "=r")
11149         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11150                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11151    (clobber (reg:CC FLAGS_REG))]
11152   "!TARGET_64BIT"
11153   "#"
11154   [(set_attr "type" "multi")])
11155
11156 ;; By default we don't ask for a scratch register, because when DImode
11157 ;; values are manipulated, registers are already at a premium.  But if
11158 ;; we have one handy, we won't turn it away.
11159 (define_peephole2
11160   [(match_scratch:SI 3 "r")
11161    (parallel [(set (match_operand:DI 0 "register_operand" "")
11162                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11163                                 (match_operand:QI 2 "nonmemory_operand" "")))
11164               (clobber (reg:CC FLAGS_REG))])
11165    (match_dup 3)]
11166   "!TARGET_64BIT && TARGET_CMOVE"
11167   [(const_int 0)]
11168   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11169
11170 (define_split
11171   [(set (match_operand:DI 0 "register_operand" "")
11172         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11173                      (match_operand:QI 2 "nonmemory_operand" "")))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11176                      ? flow2_completed : reload_completed)"
11177   [(const_int 0)]
11178   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11179
11180 (define_insn "x86_shrd_1"
11181   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11182         (ior:SI (ashiftrt:SI (match_dup 0)
11183                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11184                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11185                   (minus:QI (const_int 32) (match_dup 2)))))
11186    (clobber (reg:CC FLAGS_REG))]
11187   ""
11188   "@
11189    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11190    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11191   [(set_attr "type" "ishift")
11192    (set_attr "prefix_0f" "1")
11193    (set_attr "pent_pair" "np")
11194    (set_attr "mode" "SI")])
11195
11196 (define_expand "x86_shift_adj_3"
11197   [(use (match_operand:SI 0 "register_operand" ""))
11198    (use (match_operand:SI 1 "register_operand" ""))
11199    (use (match_operand:QI 2 "register_operand" ""))]
11200   ""
11201 {
11202   rtx label = gen_label_rtx ();
11203   rtx tmp;
11204
11205   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11206
11207   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11208   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11209   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11210                               gen_rtx_LABEL_REF (VOIDmode, label),
11211                               pc_rtx);
11212   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11213   JUMP_LABEL (tmp) = label;
11214
11215   emit_move_insn (operands[0], operands[1]);
11216   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11217
11218   emit_label (label);
11219   LABEL_NUSES (label) = 1;
11220
11221   DONE;
11222 })
11223
11224 (define_insn "ashrsi3_31"
11225   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11226         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11227                      (match_operand:SI 2 "const_int_operand" "i,i")))
11228    (clobber (reg:CC FLAGS_REG))]
11229   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11230    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11231   "@
11232    {cltd|cdq}
11233    sar{l}\t{%2, %0|%0, %2}"
11234   [(set_attr "type" "imovx,ishift")
11235    (set_attr "prefix_0f" "0,*")
11236    (set_attr "length_immediate" "0,*")
11237    (set_attr "modrm" "0,1")
11238    (set_attr "mode" "SI")])
11239
11240 (define_insn "*ashrsi3_31_zext"
11241   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11242         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11243                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11246    && INTVAL (operands[2]) == 31
11247    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11248   "@
11249    {cltd|cdq}
11250    sar{l}\t{%2, %k0|%k0, %2}"
11251   [(set_attr "type" "imovx,ishift")
11252    (set_attr "prefix_0f" "0,*")
11253    (set_attr "length_immediate" "0,*")
11254    (set_attr "modrm" "0,1")
11255    (set_attr "mode" "SI")])
11256
11257 (define_expand "ashrsi3"
11258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260                      (match_operand:QI 2 "nonmemory_operand" "")))
11261    (clobber (reg:CC FLAGS_REG))]
11262   ""
11263   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11264
11265 (define_insn "*ashrsi3_1_one_bit"
11266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11267         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11268                      (match_operand:QI 2 "const1_operand" "")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11271    && (TARGET_SHIFT1 || optimize_size)"
11272   "sar{l}\t%0"
11273   [(set_attr "type" "ishift")
11274    (set (attr "length") 
11275      (if_then_else (match_operand:SI 0 "register_operand" "") 
11276         (const_string "2")
11277         (const_string "*")))])
11278
11279 (define_insn "*ashrsi3_1_one_bit_zext"
11280   [(set (match_operand:DI 0 "register_operand" "=r")
11281         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11282                                      (match_operand:QI 2 "const1_operand" ""))))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11285    && (TARGET_SHIFT1 || optimize_size)"
11286   "sar{l}\t%k0"
11287   [(set_attr "type" "ishift")
11288    (set_attr "length" "2")])
11289
11290 (define_insn "*ashrsi3_1"
11291   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11292         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11293                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11296   "@
11297    sar{l}\t{%2, %0|%0, %2}
11298    sar{l}\t{%b2, %0|%0, %b2}"
11299   [(set_attr "type" "ishift")
11300    (set_attr "mode" "SI")])
11301
11302 (define_insn "*ashrsi3_1_zext"
11303   [(set (match_operand:DI 0 "register_operand" "=r,r")
11304         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11305                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11308   "@
11309    sar{l}\t{%2, %k0|%k0, %2}
11310    sar{l}\t{%b2, %k0|%k0, %b2}"
11311   [(set_attr "type" "ishift")
11312    (set_attr "mode" "SI")])
11313
11314 ;; This pattern can't accept a variable shift count, since shifts by
11315 ;; zero don't affect the flags.  We assume that shifts by constant
11316 ;; zero are optimized away.
11317 (define_insn "*ashrsi3_one_bit_cmp"
11318   [(set (reg FLAGS_REG)
11319         (compare
11320           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11321                        (match_operand:QI 2 "const1_operand" ""))
11322           (const_int 0)))
11323    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11324         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11325   "ix86_match_ccmode (insn, CCGOCmode)
11326    && (TARGET_SHIFT1 || optimize_size)
11327    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11328   "sar{l}\t%0"
11329   [(set_attr "type" "ishift")
11330    (set (attr "length") 
11331      (if_then_else (match_operand:SI 0 "register_operand" "") 
11332         (const_string "2")
11333         (const_string "*")))])
11334
11335 (define_insn "*ashrsi3_one_bit_cmp_zext"
11336   [(set (reg FLAGS_REG)
11337         (compare
11338           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11339                        (match_operand:QI 2 "const1_operand" ""))
11340           (const_int 0)))
11341    (set (match_operand:DI 0 "register_operand" "=r")
11342         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11343   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11344    && (TARGET_SHIFT1 || optimize_size)
11345    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11346   "sar{l}\t%k0"
11347   [(set_attr "type" "ishift")
11348    (set_attr "length" "2")])
11349
11350 ;; This pattern can't accept a variable shift count, since shifts by
11351 ;; zero don't affect the flags.  We assume that shifts by constant
11352 ;; zero are optimized away.
11353 (define_insn "*ashrsi3_cmp"
11354   [(set (reg FLAGS_REG)
11355         (compare
11356           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11357                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11358           (const_int 0)))
11359    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11361   "ix86_match_ccmode (insn, CCGOCmode)
11362    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363   "sar{l}\t{%2, %0|%0, %2}"
11364   [(set_attr "type" "ishift")
11365    (set_attr "mode" "SI")])
11366
11367 (define_insn "*ashrsi3_cmp_zext"
11368   [(set (reg FLAGS_REG)
11369         (compare
11370           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11371                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11372           (const_int 0)))
11373    (set (match_operand:DI 0 "register_operand" "=r")
11374         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11375   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11376    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11377   "sar{l}\t{%2, %k0|%k0, %2}"
11378   [(set_attr "type" "ishift")
11379    (set_attr "mode" "SI")])
11380
11381 (define_expand "ashrhi3"
11382   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11383         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11384                      (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_HIMODE_MATH"
11387   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11388
11389 (define_insn "*ashrhi3_1_one_bit"
11390   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11391         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11392                      (match_operand:QI 2 "const1_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11395    && (TARGET_SHIFT1 || optimize_size)"
11396   "sar{w}\t%0"
11397   [(set_attr "type" "ishift")
11398    (set (attr "length") 
11399      (if_then_else (match_operand 0 "register_operand" "") 
11400         (const_string "2")
11401         (const_string "*")))])
11402
11403 (define_insn "*ashrhi3_1"
11404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11405         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11406                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11407    (clobber (reg:CC FLAGS_REG))]
11408   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11409   "@
11410    sar{w}\t{%2, %0|%0, %2}
11411    sar{w}\t{%b2, %0|%0, %b2}"
11412   [(set_attr "type" "ishift")
11413    (set_attr "mode" "HI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags.  We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashrhi3_one_bit_cmp"
11419   [(set (reg FLAGS_REG)
11420         (compare
11421           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11422                        (match_operand:QI 2 "const1_operand" ""))
11423           (const_int 0)))
11424    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11426   "ix86_match_ccmode (insn, CCGOCmode)
11427    && (TARGET_SHIFT1 || optimize_size)
11428    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11429   "sar{w}\t%0"
11430   [(set_attr "type" "ishift")
11431    (set (attr "length") 
11432      (if_then_else (match_operand 0 "register_operand" "") 
11433         (const_string "2")
11434         (const_string "*")))])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags.  We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*ashrhi3_cmp"
11440   [(set (reg FLAGS_REG)
11441         (compare
11442           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11443                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11444           (const_int 0)))
11445    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11446         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11447   "ix86_match_ccmode (insn, CCGOCmode)
11448    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11449   "sar{w}\t{%2, %0|%0, %2}"
11450   [(set_attr "type" "ishift")
11451    (set_attr "mode" "HI")])
11452
11453 (define_expand "ashrqi3"
11454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11455         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11456                      (match_operand:QI 2 "nonmemory_operand" "")))
11457    (clobber (reg:CC FLAGS_REG))]
11458   "TARGET_QIMODE_MATH"
11459   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11460
11461 (define_insn "*ashrqi3_1_one_bit"
11462   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11463         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464                      (match_operand:QI 2 "const1_operand" "")))
11465    (clobber (reg:CC FLAGS_REG))]
11466   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11467    && (TARGET_SHIFT1 || optimize_size)"
11468   "sar{b}\t%0"
11469   [(set_attr "type" "ishift")
11470    (set (attr "length") 
11471      (if_then_else (match_operand 0 "register_operand" "") 
11472         (const_string "2")
11473         (const_string "*")))])
11474
11475 (define_insn "*ashrqi3_1_one_bit_slp"
11476   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11477         (ashiftrt:QI (match_dup 0)
11478                      (match_operand:QI 1 "const1_operand" "")))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11481    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11482    && (TARGET_SHIFT1 || optimize_size)"
11483   "sar{b}\t%0"
11484   [(set_attr "type" "ishift1")
11485    (set (attr "length") 
11486      (if_then_else (match_operand 0 "register_operand" "") 
11487         (const_string "2")
11488         (const_string "*")))])
11489
11490 (define_insn "*ashrqi3_1"
11491   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11492         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11493                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11494    (clobber (reg:CC FLAGS_REG))]
11495   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11496   "@
11497    sar{b}\t{%2, %0|%0, %2}
11498    sar{b}\t{%b2, %0|%0, %b2}"
11499   [(set_attr "type" "ishift")
11500    (set_attr "mode" "QI")])
11501
11502 (define_insn "*ashrqi3_1_slp"
11503   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11504         (ashiftrt:QI (match_dup 0)
11505                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11508    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11509   "@
11510    sar{b}\t{%1, %0|%0, %1}
11511    sar{b}\t{%b1, %0|%0, %b1}"
11512   [(set_attr "type" "ishift1")
11513    (set_attr "mode" "QI")])
11514
11515 ;; This pattern can't accept a variable shift count, since shifts by
11516 ;; zero don't affect the flags.  We assume that shifts by constant
11517 ;; zero are optimized away.
11518 (define_insn "*ashrqi3_one_bit_cmp"
11519   [(set (reg FLAGS_REG)
11520         (compare
11521           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11522                        (match_operand:QI 2 "const1_operand" "I"))
11523           (const_int 0)))
11524    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11525         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11526   "ix86_match_ccmode (insn, CCGOCmode)
11527    && (TARGET_SHIFT1 || optimize_size)
11528    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11529   "sar{b}\t%0"
11530   [(set_attr "type" "ishift")
11531    (set (attr "length") 
11532      (if_then_else (match_operand 0 "register_operand" "") 
11533         (const_string "2")
11534         (const_string "*")))])
11535
11536 ;; This pattern can't accept a variable shift count, since shifts by
11537 ;; zero don't affect the flags.  We assume that shifts by constant
11538 ;; zero are optimized away.
11539 (define_insn "*ashrqi3_cmp"
11540   [(set (reg FLAGS_REG)
11541         (compare
11542           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11543                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11544           (const_int 0)))
11545    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11546         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11547   "ix86_match_ccmode (insn, CCGOCmode)
11548    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11549   "sar{b}\t{%2, %0|%0, %2}"
11550   [(set_attr "type" "ishift")
11551    (set_attr "mode" "QI")])
11552 \f
11553 ;; Logical shift instructions
11554
11555 ;; See comment above `ashldi3' about how this works.
11556
11557 (define_expand "lshrti3"
11558   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11559                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11560                                 (match_operand:QI 2 "nonmemory_operand" "")))
11561               (clobber (reg:CC FLAGS_REG))])]
11562   "TARGET_64BIT"
11563 {
11564   if (! immediate_operand (operands[2], QImode))
11565     {
11566       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11567       DONE;
11568     }
11569   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11570   DONE;
11571 })
11572
11573 (define_insn "lshrti3_1"
11574   [(set (match_operand:TI 0 "register_operand" "=r")
11575         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11576                      (match_operand:QI 2 "register_operand" "c")))
11577    (clobber (match_scratch:DI 3 "=&r"))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "TARGET_64BIT"
11580   "#"
11581   [(set_attr "type" "multi")])
11582
11583 (define_insn "*lshrti3_2"
11584   [(set (match_operand:TI 0 "register_operand" "=r")
11585         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11586                      (match_operand:QI 2 "immediate_operand" "O")))
11587    (clobber (reg:CC FLAGS_REG))]
11588   "TARGET_64BIT"
11589   "#"
11590   [(set_attr "type" "multi")])
11591
11592 (define_split 
11593   [(set (match_operand:TI 0 "register_operand" "")
11594         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595                      (match_operand:QI 2 "register_operand" "")))
11596    (clobber (match_scratch:DI 3 ""))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "TARGET_64BIT && reload_completed"
11599   [(const_int 0)]
11600   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11601
11602 (define_split 
11603   [(set (match_operand:TI 0 "register_operand" "")
11604         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11605                      (match_operand:QI 2 "immediate_operand" "")))
11606    (clobber (reg:CC FLAGS_REG))]
11607   "TARGET_64BIT && reload_completed"
11608   [(const_int 0)]
11609   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11610
11611 (define_expand "lshrdi3"
11612   [(set (match_operand:DI 0 "shiftdi_operand" "")
11613         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11614                      (match_operand:QI 2 "nonmemory_operand" "")))]
11615   ""
11616   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11617
11618 (define_insn "*lshrdi3_1_one_bit_rex64"
11619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11620         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11621                      (match_operand:QI 2 "const1_operand" "")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624    && (TARGET_SHIFT1 || optimize_size)"
11625   "shr{q}\t%0"
11626   [(set_attr "type" "ishift")
11627    (set (attr "length") 
11628      (if_then_else (match_operand:DI 0 "register_operand" "") 
11629         (const_string "2")
11630         (const_string "*")))])
11631
11632 (define_insn "*lshrdi3_1_rex64"
11633   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11634         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11635                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11638   "@
11639    shr{q}\t{%2, %0|%0, %2}
11640    shr{q}\t{%b2, %0|%0, %b2}"
11641   [(set_attr "type" "ishift")
11642    (set_attr "mode" "DI")])
11643
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags.  We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11648   [(set (reg FLAGS_REG)
11649         (compare
11650           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651                        (match_operand:QI 2 "const1_operand" ""))
11652           (const_int 0)))
11653    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11655   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11656    && (TARGET_SHIFT1 || optimize_size)
11657    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11658   "shr{q}\t%0"
11659   [(set_attr "type" "ishift")
11660    (set (attr "length") 
11661      (if_then_else (match_operand:DI 0 "register_operand" "") 
11662         (const_string "2")
11663         (const_string "*")))])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags.  We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrdi3_cmp_rex64"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const_int_operand" "e"))
11673           (const_int 0)))
11674    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11675         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678   "shr{q}\t{%2, %0|%0, %2}"
11679   [(set_attr "type" "ishift")
11680    (set_attr "mode" "DI")])
11681
11682 (define_insn "*lshrdi3_1"
11683   [(set (match_operand:DI 0 "register_operand" "=r")
11684         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11685                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "!TARGET_64BIT"
11688   "#"
11689   [(set_attr "type" "multi")])
11690
11691 ;; By default we don't ask for a scratch register, because when DImode
11692 ;; values are manipulated, registers are already at a premium.  But if
11693 ;; we have one handy, we won't turn it away.
11694 (define_peephole2
11695   [(match_scratch:SI 3 "r")
11696    (parallel [(set (match_operand:DI 0 "register_operand" "")
11697                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11698                                 (match_operand:QI 2 "nonmemory_operand" "")))
11699               (clobber (reg:CC FLAGS_REG))])
11700    (match_dup 3)]
11701   "!TARGET_64BIT && TARGET_CMOVE"
11702   [(const_int 0)]
11703   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11704
11705 (define_split 
11706   [(set (match_operand:DI 0 "register_operand" "")
11707         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11708                      (match_operand:QI 2 "nonmemory_operand" "")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11711                      ? flow2_completed : reload_completed)"
11712   [(const_int 0)]
11713   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11714
11715 (define_expand "lshrsi3"
11716   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11717         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11718                      (match_operand:QI 2 "nonmemory_operand" "")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   ""
11721   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11722
11723 (define_insn "*lshrsi3_1_one_bit"
11724   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11725         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11726                      (match_operand:QI 2 "const1_operand" "")))
11727    (clobber (reg:CC FLAGS_REG))]
11728   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11729    && (TARGET_SHIFT1 || optimize_size)"
11730   "shr{l}\t%0"
11731   [(set_attr "type" "ishift")
11732    (set (attr "length") 
11733      (if_then_else (match_operand:SI 0 "register_operand" "") 
11734         (const_string "2")
11735         (const_string "*")))])
11736
11737 (define_insn "*lshrsi3_1_one_bit_zext"
11738   [(set (match_operand:DI 0 "register_operand" "=r")
11739         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11740                      (match_operand:QI 2 "const1_operand" "")))
11741    (clobber (reg:CC FLAGS_REG))]
11742   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11743    && (TARGET_SHIFT1 || optimize_size)"
11744   "shr{l}\t%k0"
11745   [(set_attr "type" "ishift")
11746    (set_attr "length" "2")])
11747
11748 (define_insn "*lshrsi3_1"
11749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11754   "@
11755    shr{l}\t{%2, %0|%0, %2}
11756    shr{l}\t{%b2, %0|%0, %b2}"
11757   [(set_attr "type" "ishift")
11758    (set_attr "mode" "SI")])
11759
11760 (define_insn "*lshrsi3_1_zext"
11761   [(set (match_operand:DI 0 "register_operand" "=r,r")
11762         (zero_extend:DI
11763           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11764                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765    (clobber (reg:CC FLAGS_REG))]
11766   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11767   "@
11768    shr{l}\t{%2, %k0|%k0, %2}
11769    shr{l}\t{%b2, %k0|%k0, %b2}"
11770   [(set_attr "type" "ishift")
11771    (set_attr "mode" "SI")])
11772
11773 ;; This pattern can't accept a variable shift count, since shifts by
11774 ;; zero don't affect the flags.  We assume that shifts by constant
11775 ;; zero are optimized away.
11776 (define_insn "*lshrsi3_one_bit_cmp"
11777   [(set (reg FLAGS_REG)
11778         (compare
11779           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11780                        (match_operand:QI 2 "const1_operand" ""))
11781           (const_int 0)))
11782    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11784   "ix86_match_ccmode (insn, CCGOCmode)
11785    && (TARGET_SHIFT1 || optimize_size)
11786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11787   "shr{l}\t%0"
11788   [(set_attr "type" "ishift")
11789    (set (attr "length") 
11790      (if_then_else (match_operand:SI 0 "register_operand" "") 
11791         (const_string "2")
11792         (const_string "*")))])
11793
11794 (define_insn "*lshrsi3_cmp_one_bit_zext"
11795   [(set (reg FLAGS_REG)
11796         (compare
11797           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11798                        (match_operand:QI 2 "const1_operand" ""))
11799           (const_int 0)))
11800    (set (match_operand:DI 0 "register_operand" "=r")
11801         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11802   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11803    && (TARGET_SHIFT1 || optimize_size)
11804    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11805   "shr{l}\t%k0"
11806   [(set_attr "type" "ishift")
11807    (set_attr "length" "2")])
11808
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags.  We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*lshrsi3_cmp"
11813   [(set (reg FLAGS_REG)
11814         (compare
11815           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817           (const_int 0)))
11818    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11819         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11820   "ix86_match_ccmode (insn, CCGOCmode)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t{%2, %0|%0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "SI")])
11825
11826 (define_insn "*lshrsi3_cmp_zext"
11827   [(set (reg FLAGS_REG)
11828         (compare
11829           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11831           (const_int 0)))
11832    (set (match_operand:DI 0 "register_operand" "=r")
11833         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11834   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11835    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836   "shr{l}\t{%2, %k0|%k0, %2}"
11837   [(set_attr "type" "ishift")
11838    (set_attr "mode" "SI")])
11839
11840 (define_expand "lshrhi3"
11841   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843                      (match_operand:QI 2 "nonmemory_operand" "")))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "TARGET_HIMODE_MATH"
11846   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11847
11848 (define_insn "*lshrhi3_1_one_bit"
11849   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11851                      (match_operand:QI 2 "const1_operand" "")))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11854    && (TARGET_SHIFT1 || optimize_size)"
11855   "shr{w}\t%0"
11856   [(set_attr "type" "ishift")
11857    (set (attr "length") 
11858      (if_then_else (match_operand 0 "register_operand" "") 
11859         (const_string "2")
11860         (const_string "*")))])
11861
11862 (define_insn "*lshrhi3_1"
11863   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11864         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11865                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11868   "@
11869    shr{w}\t{%2, %0|%0, %2}
11870    shr{w}\t{%b2, %0|%0, %b2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "HI")])
11873
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags.  We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*lshrhi3_one_bit_cmp"
11878   [(set (reg FLAGS_REG)
11879         (compare
11880           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881                        (match_operand:QI 2 "const1_operand" ""))
11882           (const_int 0)))
11883    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11885   "ix86_match_ccmode (insn, CCGOCmode)
11886    && (TARGET_SHIFT1 || optimize_size)
11887    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11888   "shr{w}\t%0"
11889   [(set_attr "type" "ishift")
11890    (set (attr "length") 
11891      (if_then_else (match_operand:SI 0 "register_operand" "") 
11892         (const_string "2")
11893         (const_string "*")))])
11894
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags.  We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*lshrhi3_cmp"
11899   [(set (reg FLAGS_REG)
11900         (compare
11901           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11903           (const_int 0)))
11904    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11906   "ix86_match_ccmode (insn, CCGOCmode)
11907    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11908   "shr{w}\t{%2, %0|%0, %2}"
11909   [(set_attr "type" "ishift")
11910    (set_attr "mode" "HI")])
11911
11912 (define_expand "lshrqi3"
11913   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915                      (match_operand:QI 2 "nonmemory_operand" "")))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "TARGET_QIMODE_MATH"
11918   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11919
11920 (define_insn "*lshrqi3_1_one_bit"
11921   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923                      (match_operand:QI 2 "const1_operand" "")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11926    && (TARGET_SHIFT1 || optimize_size)"
11927   "shr{b}\t%0"
11928   [(set_attr "type" "ishift")
11929    (set (attr "length") 
11930      (if_then_else (match_operand 0 "register_operand" "") 
11931         (const_string "2")
11932         (const_string "*")))])
11933
11934 (define_insn "*lshrqi3_1_one_bit_slp"
11935   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11936         (lshiftrt:QI (match_dup 0)
11937                      (match_operand:QI 1 "const1_operand" "")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11940    && (TARGET_SHIFT1 || optimize_size)"
11941   "shr{b}\t%0"
11942   [(set_attr "type" "ishift1")
11943    (set (attr "length") 
11944      (if_then_else (match_operand 0 "register_operand" "") 
11945         (const_string "2")
11946         (const_string "*")))])
11947
11948 (define_insn "*lshrqi3_1"
11949   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11950         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11951                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11952    (clobber (reg:CC FLAGS_REG))]
11953   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11954   "@
11955    shr{b}\t{%2, %0|%0, %2}
11956    shr{b}\t{%b2, %0|%0, %b2}"
11957   [(set_attr "type" "ishift")
11958    (set_attr "mode" "QI")])
11959
11960 (define_insn "*lshrqi3_1_slp"
11961   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11962         (lshiftrt:QI (match_dup 0)
11963                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11966    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11967   "@
11968    shr{b}\t{%1, %0|%0, %1}
11969    shr{b}\t{%b1, %0|%0, %b1}"
11970   [(set_attr "type" "ishift1")
11971    (set_attr "mode" "QI")])
11972
11973 ;; This pattern can't accept a variable shift count, since shifts by
11974 ;; zero don't affect the flags.  We assume that shifts by constant
11975 ;; zero are optimized away.
11976 (define_insn "*lshrqi2_one_bit_cmp"
11977   [(set (reg FLAGS_REG)
11978         (compare
11979           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11980                        (match_operand:QI 2 "const1_operand" ""))
11981           (const_int 0)))
11982    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11983         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11984   "ix86_match_ccmode (insn, CCGOCmode)
11985    && (TARGET_SHIFT1 || optimize_size)
11986    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11987   "shr{b}\t%0"
11988   [(set_attr "type" "ishift")
11989    (set (attr "length") 
11990      (if_then_else (match_operand:SI 0 "register_operand" "") 
11991         (const_string "2")
11992         (const_string "*")))])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*lshrqi2_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12007   "shr{b}\t{%2, %0|%0, %2}"
12008   [(set_attr "type" "ishift")
12009    (set_attr "mode" "QI")])
12010 \f
12011 ;; Rotate instructions
12012
12013 (define_expand "rotldi3"
12014   [(set (match_operand:DI 0 "shiftdi_operand" "")
12015         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12016                    (match_operand:QI 2 "nonmemory_operand" "")))
12017    (clobber (reg:CC FLAGS_REG))]
12018  ""
12019 {
12020   if (TARGET_64BIT)
12021     {
12022       ix86_expand_binary_operator (ROTATE, DImode, operands);
12023       DONE;
12024     }
12025   if (!const_1_to_31_operand (operands[2], VOIDmode))
12026     FAIL;
12027   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12028   DONE;
12029 })
12030
12031 ;; Implement rotation using two double-precision shift instructions
12032 ;; and a scratch register.   
12033 (define_insn_and_split "ix86_rotldi3"
12034  [(set (match_operand:DI 0 "register_operand" "=r")
12035        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12036                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12037   (clobber (reg:CC FLAGS_REG))
12038   (clobber (match_scratch:SI 3 "=&r"))]
12039  "!TARGET_64BIT"
12040  "" 
12041  "&& reload_completed"
12042  [(set (match_dup 3) (match_dup 4))
12043   (parallel
12044    [(set (match_dup 4)
12045          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12046                  (lshiftrt:SI (match_dup 5)
12047                               (minus:QI (const_int 32) (match_dup 2)))))
12048     (clobber (reg:CC FLAGS_REG))])
12049   (parallel
12050    [(set (match_dup 5)
12051          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12052                  (lshiftrt:SI (match_dup 3)
12053                               (minus:QI (const_int 32) (match_dup 2)))))
12054     (clobber (reg:CC FLAGS_REG))])]
12055  "split_di (operands, 1, operands + 4, operands + 5);")
12056  
12057 (define_insn "*rotlsi3_1_one_bit_rex64"
12058   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                    (match_operand:QI 2 "const1_operand" "")))
12061    (clobber (reg:CC FLAGS_REG))]
12062   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12063    && (TARGET_SHIFT1 || optimize_size)"
12064   "rol{q}\t%0"
12065   [(set_attr "type" "rotate")
12066    (set (attr "length") 
12067      (if_then_else (match_operand:DI 0 "register_operand" "") 
12068         (const_string "2")
12069         (const_string "*")))])
12070
12071 (define_insn "*rotldi3_1_rex64"
12072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12073         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12074                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12077   "@
12078    rol{q}\t{%2, %0|%0, %2}
12079    rol{q}\t{%b2, %0|%0, %b2}"
12080   [(set_attr "type" "rotate")
12081    (set_attr "mode" "DI")])
12082
12083 (define_expand "rotlsi3"
12084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086                    (match_operand:QI 2 "nonmemory_operand" "")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   ""
12089   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12090
12091 (define_insn "*rotlsi3_1_one_bit"
12092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094                    (match_operand:QI 2 "const1_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12097    && (TARGET_SHIFT1 || optimize_size)"
12098   "rol{l}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:SI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12104
12105 (define_insn "*rotlsi3_1_one_bit_zext"
12106   [(set (match_operand:DI 0 "register_operand" "=r")
12107         (zero_extend:DI
12108           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12109                      (match_operand:QI 2 "const1_operand" ""))))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12112    && (TARGET_SHIFT1 || optimize_size)"
12113   "rol{l}\t%k0"
12114   [(set_attr "type" "rotate")
12115    (set_attr "length" "2")])
12116
12117 (define_insn "*rotlsi3_1"
12118   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12119         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12120                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12123   "@
12124    rol{l}\t{%2, %0|%0, %2}
12125    rol{l}\t{%b2, %0|%0, %b2}"
12126   [(set_attr "type" "rotate")
12127    (set_attr "mode" "SI")])
12128
12129 (define_insn "*rotlsi3_1_zext"
12130   [(set (match_operand:DI 0 "register_operand" "=r,r")
12131         (zero_extend:DI
12132           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12133                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12136   "@
12137    rol{l}\t{%2, %k0|%k0, %2}
12138    rol{l}\t{%b2, %k0|%k0, %b2}"
12139   [(set_attr "type" "rotate")
12140    (set_attr "mode" "SI")])
12141
12142 (define_expand "rotlhi3"
12143   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12144         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12145                    (match_operand:QI 2 "nonmemory_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "TARGET_HIMODE_MATH"
12148   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12149
12150 (define_insn "*rotlhi3_1_one_bit"
12151   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12152         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12153                    (match_operand:QI 2 "const1_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12156    && (TARGET_SHIFT1 || optimize_size)"
12157   "rol{w}\t%0"
12158   [(set_attr "type" "rotate")
12159    (set (attr "length") 
12160      (if_then_else (match_operand 0 "register_operand" "") 
12161         (const_string "2")
12162         (const_string "*")))])
12163
12164 (define_insn "*rotlhi3_1"
12165   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12166         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12167                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12170   "@
12171    rol{w}\t{%2, %0|%0, %2}
12172    rol{w}\t{%b2, %0|%0, %b2}"
12173   [(set_attr "type" "rotate")
12174    (set_attr "mode" "HI")])
12175
12176 (define_expand "rotlqi3"
12177   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12178         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12179                    (match_operand:QI 2 "nonmemory_operand" "")))
12180    (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_QIMODE_MATH"
12182   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12183
12184 (define_insn "*rotlqi3_1_one_bit_slp"
12185   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12186         (rotate:QI (match_dup 0)
12187                    (match_operand:QI 1 "const1_operand" "")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12190    && (TARGET_SHIFT1 || optimize_size)"
12191   "rol{b}\t%0"
12192   [(set_attr "type" "rotate1")
12193    (set (attr "length") 
12194      (if_then_else (match_operand 0 "register_operand" "") 
12195         (const_string "2")
12196         (const_string "*")))])
12197
12198 (define_insn "*rotlqi3_1_one_bit"
12199   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12200         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12201                    (match_operand:QI 2 "const1_operand" "")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12204    && (TARGET_SHIFT1 || optimize_size)"
12205   "rol{b}\t%0"
12206   [(set_attr "type" "rotate")
12207    (set (attr "length") 
12208      (if_then_else (match_operand 0 "register_operand" "") 
12209         (const_string "2")
12210         (const_string "*")))])
12211
12212 (define_insn "*rotlqi3_1_slp"
12213   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12214         (rotate:QI (match_dup 0)
12215                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12219   "@
12220    rol{b}\t{%1, %0|%0, %1}
12221    rol{b}\t{%b1, %0|%0, %b1}"
12222   [(set_attr "type" "rotate1")
12223    (set_attr "mode" "QI")])
12224
12225 (define_insn "*rotlqi3_1"
12226   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12227         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12228                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12229    (clobber (reg:CC FLAGS_REG))]
12230   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12231   "@
12232    rol{b}\t{%2, %0|%0, %2}
12233    rol{b}\t{%b2, %0|%0, %b2}"
12234   [(set_attr "type" "rotate")
12235    (set_attr "mode" "QI")])
12236
12237 (define_expand "rotrdi3"
12238   [(set (match_operand:DI 0 "shiftdi_operand" "")
12239         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12240                    (match_operand:QI 2 "nonmemory_operand" "")))
12241    (clobber (reg:CC FLAGS_REG))]
12242  ""
12243 {
12244   if (TARGET_64BIT)
12245     {
12246       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12247       DONE;
12248     }
12249   if (!const_1_to_31_operand (operands[2], VOIDmode))
12250     FAIL;
12251   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12252   DONE;
12253 })
12254   
12255 ;; Implement rotation using two double-precision shift instructions
12256 ;; and a scratch register.   
12257 (define_insn_and_split "ix86_rotrdi3"
12258  [(set (match_operand:DI 0 "register_operand" "=r")
12259        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12260                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12261   (clobber (reg:CC FLAGS_REG))
12262   (clobber (match_scratch:SI 3 "=&r"))]
12263  "!TARGET_64BIT"
12264  ""
12265  "&& reload_completed"
12266  [(set (match_dup 3) (match_dup 4))
12267   (parallel
12268    [(set (match_dup 4)
12269          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12270                  (ashift:SI (match_dup 5)
12271                             (minus:QI (const_int 32) (match_dup 2)))))
12272     (clobber (reg:CC FLAGS_REG))])
12273   (parallel
12274    [(set (match_dup 5)
12275          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12276                  (ashift:SI (match_dup 3)
12277                             (minus:QI (const_int 32) (match_dup 2)))))
12278     (clobber (reg:CC FLAGS_REG))])]
12279  "split_di (operands, 1, operands + 4, operands + 5);")
12280
12281 (define_insn "*rotrdi3_1_one_bit_rex64"
12282   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12283         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12284                      (match_operand:QI 2 "const1_operand" "")))
12285    (clobber (reg:CC FLAGS_REG))]
12286   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12287    && (TARGET_SHIFT1 || optimize_size)"
12288   "ror{q}\t%0"
12289   [(set_attr "type" "rotate")
12290    (set (attr "length") 
12291      (if_then_else (match_operand:DI 0 "register_operand" "") 
12292         (const_string "2")
12293         (const_string "*")))])
12294
12295 (define_insn "*rotrdi3_1_rex64"
12296   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12297         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12298                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12301   "@
12302    ror{q}\t{%2, %0|%0, %2}
12303    ror{q}\t{%b2, %0|%0, %b2}"
12304   [(set_attr "type" "rotate")
12305    (set_attr "mode" "DI")])
12306
12307 (define_expand "rotrsi3"
12308   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12309         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12310                      (match_operand:QI 2 "nonmemory_operand" "")))
12311    (clobber (reg:CC FLAGS_REG))]
12312   ""
12313   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12314
12315 (define_insn "*rotrsi3_1_one_bit"
12316   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12318                      (match_operand:QI 2 "const1_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12321    && (TARGET_SHIFT1 || optimize_size)"
12322   "ror{l}\t%0"
12323   [(set_attr "type" "rotate")
12324    (set (attr "length") 
12325      (if_then_else (match_operand:SI 0 "register_operand" "") 
12326         (const_string "2")
12327         (const_string "*")))])
12328
12329 (define_insn "*rotrsi3_1_one_bit_zext"
12330   [(set (match_operand:DI 0 "register_operand" "=r")
12331         (zero_extend:DI
12332           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12333                        (match_operand:QI 2 "const1_operand" ""))))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12336    && (TARGET_SHIFT1 || optimize_size)"
12337   "ror{l}\t%k0"
12338   [(set_attr "type" "rotate")
12339    (set (attr "length") 
12340      (if_then_else (match_operand:SI 0 "register_operand" "") 
12341         (const_string "2")
12342         (const_string "*")))])
12343
12344 (define_insn "*rotrsi3_1"
12345   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12350   "@
12351    ror{l}\t{%2, %0|%0, %2}
12352    ror{l}\t{%b2, %0|%0, %b2}"
12353   [(set_attr "type" "rotate")
12354    (set_attr "mode" "SI")])
12355
12356 (define_insn "*rotrsi3_1_zext"
12357   [(set (match_operand:DI 0 "register_operand" "=r,r")
12358         (zero_extend:DI
12359           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12360                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12363   "@
12364    ror{l}\t{%2, %k0|%k0, %2}
12365    ror{l}\t{%b2, %k0|%k0, %b2}"
12366   [(set_attr "type" "rotate")
12367    (set_attr "mode" "SI")])
12368
12369 (define_expand "rotrhi3"
12370   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372                      (match_operand:QI 2 "nonmemory_operand" "")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_HIMODE_MATH"
12375   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12376
12377 (define_insn "*rotrhi3_one_bit"
12378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380                      (match_operand:QI 2 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12383    && (TARGET_SHIFT1 || optimize_size)"
12384   "ror{w}\t%0"
12385   [(set_attr "type" "rotate")
12386    (set (attr "length") 
12387      (if_then_else (match_operand 0 "register_operand" "") 
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*rotrhi3"
12392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12397   "@
12398    ror{w}\t{%2, %0|%0, %2}
12399    ror{w}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "HI")])
12402
12403 (define_expand "rotrqi3"
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406                      (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_QIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12410
12411 (define_insn "*rotrqi3_1_one_bit"
12412   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12413         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12414                      (match_operand:QI 2 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{b}\t%0"
12419   [(set_attr "type" "rotate")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12424
12425 (define_insn "*rotrqi3_1_one_bit_slp"
12426   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12427         (rotatert:QI (match_dup 0)
12428                      (match_operand:QI 1 "const1_operand" "")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12431    && (TARGET_SHIFT1 || optimize_size)"
12432   "ror{b}\t%0"
12433   [(set_attr "type" "rotate1")
12434    (set (attr "length") 
12435      (if_then_else (match_operand 0 "register_operand" "") 
12436         (const_string "2")
12437         (const_string "*")))])
12438
12439 (define_insn "*rotrqi3_1"
12440   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12441         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12442                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12445   "@
12446    ror{b}\t{%2, %0|%0, %2}
12447    ror{b}\t{%b2, %0|%0, %b2}"
12448   [(set_attr "type" "rotate")
12449    (set_attr "mode" "QI")])
12450
12451 (define_insn "*rotrqi3_1_slp"
12452   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12453         (rotatert:QI (match_dup 0)
12454                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12455    (clobber (reg:CC FLAGS_REG))]
12456   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12457    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12458   "@
12459    ror{b}\t{%1, %0|%0, %1}
12460    ror{b}\t{%b1, %0|%0, %b1}"
12461   [(set_attr "type" "rotate1")
12462    (set_attr "mode" "QI")])
12463 \f
12464 ;; Bit set / bit test instructions
12465
12466 (define_expand "extv"
12467   [(set (match_operand:SI 0 "register_operand" "")
12468         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12469                          (match_operand:SI 2 "immediate_operand" "")
12470                          (match_operand:SI 3 "immediate_operand" "")))]
12471   ""
12472 {
12473   /* Handle extractions from %ah et al.  */
12474   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12475     FAIL;
12476
12477   /* From mips.md: extract_bit_field doesn't verify that our source
12478      matches the predicate, so check it again here.  */
12479   if (! ext_register_operand (operands[1], VOIDmode))
12480     FAIL;
12481 })
12482
12483 (define_expand "extzv"
12484   [(set (match_operand:SI 0 "register_operand" "")
12485         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12486                          (match_operand:SI 2 "immediate_operand" "")
12487                          (match_operand:SI 3 "immediate_operand" "")))]
12488   ""
12489 {
12490   /* Handle extractions from %ah et al.  */
12491   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12492     FAIL;
12493
12494   /* From mips.md: extract_bit_field doesn't verify that our source
12495      matches the predicate, so check it again here.  */
12496   if (! ext_register_operand (operands[1], VOIDmode))
12497     FAIL;
12498 })
12499
12500 (define_expand "insv"
12501   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12502                       (match_operand 1 "immediate_operand" "")
12503                       (match_operand 2 "immediate_operand" ""))
12504         (match_operand 3 "register_operand" ""))]
12505   ""
12506 {
12507   /* Handle extractions from %ah et al.  */
12508   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12509     FAIL;
12510
12511   /* From mips.md: insert_bit_field doesn't verify that our source
12512      matches the predicate, so check it again here.  */
12513   if (! ext_register_operand (operands[0], VOIDmode))
12514     FAIL;
12515
12516   if (TARGET_64BIT)
12517     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12518   else
12519     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12520
12521   DONE;
12522 })
12523
12524 ;; %%% bts, btr, btc, bt.
12525 ;; In general these instructions are *slow* when applied to memory,
12526 ;; since they enforce atomic operation.  When applied to registers,
12527 ;; it depends on the cpu implementation.  They're never faster than
12528 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12529 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12530 ;; within the instruction itself, so operating on bits in the high
12531 ;; 32-bits of a register becomes easier.
12532 ;;
12533 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12534 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12535 ;; negdf respectively, so they can never be disabled entirely.
12536
12537 (define_insn "*btsq"
12538   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12539                          (const_int 1)
12540                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12541         (const_int 1))
12542    (clobber (reg:CC FLAGS_REG))]
12543   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12544   "bts{q} %1,%0"
12545   [(set_attr "type" "alu1")])
12546
12547 (define_insn "*btrq"
12548   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12549                          (const_int 1)
12550                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12551         (const_int 0))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12554   "btr{q} %1,%0"
12555   [(set_attr "type" "alu1")])
12556
12557 (define_insn "*btcq"
12558   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12559                          (const_int 1)
12560                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12561         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12564   "btc{q} %1,%0"
12565   [(set_attr "type" "alu1")])
12566
12567 ;; Allow Nocona to avoid these instructions if a register is available.
12568
12569 (define_peephole2
12570   [(match_scratch:DI 2 "r")
12571    (parallel [(set (zero_extract:DI
12572                      (match_operand:DI 0 "register_operand" "")
12573                      (const_int 1)
12574                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12575                    (const_int 1))
12576               (clobber (reg:CC FLAGS_REG))])]
12577   "TARGET_64BIT && !TARGET_USE_BT"
12578   [(const_int 0)]
12579 {
12580   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12581   rtx op1;
12582
12583   if (HOST_BITS_PER_WIDE_INT >= 64)
12584     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12585   else if (i < HOST_BITS_PER_WIDE_INT)
12586     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12587   else
12588     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12589
12590   op1 = immed_double_const (lo, hi, DImode);
12591   if (i >= 31)
12592     {
12593       emit_move_insn (operands[2], op1);
12594       op1 = operands[2];
12595     }
12596
12597   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12598   DONE;
12599 })
12600
12601 (define_peephole2
12602   [(match_scratch:DI 2 "r")
12603    (parallel [(set (zero_extract:DI
12604                      (match_operand:DI 0 "register_operand" "")
12605                      (const_int 1)
12606                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12607                    (const_int 0))
12608               (clobber (reg:CC FLAGS_REG))])]
12609   "TARGET_64BIT && !TARGET_USE_BT"
12610   [(const_int 0)]
12611 {
12612   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12613   rtx op1;
12614
12615   if (HOST_BITS_PER_WIDE_INT >= 64)
12616     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12617   else if (i < HOST_BITS_PER_WIDE_INT)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else
12620     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12621
12622   op1 = immed_double_const (~lo, ~hi, DImode);
12623   if (i >= 32)
12624     {
12625       emit_move_insn (operands[2], op1);
12626       op1 = operands[2];
12627     }
12628
12629   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12630   DONE;
12631 })
12632
12633 (define_peephole2
12634   [(match_scratch:DI 2 "r")
12635    (parallel [(set (zero_extract:DI
12636                      (match_operand:DI 0 "register_operand" "")
12637                      (const_int 1)
12638                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12639               (not:DI (zero_extract:DI
12640                         (match_dup 0) (const_int 1) (match_dup 1))))
12641               (clobber (reg:CC FLAGS_REG))])]
12642   "TARGET_64BIT && !TARGET_USE_BT"
12643   [(const_int 0)]
12644 {
12645   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12646   rtx op1;
12647
12648   if (HOST_BITS_PER_WIDE_INT >= 64)
12649     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12650   else if (i < HOST_BITS_PER_WIDE_INT)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else
12653     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12654
12655   op1 = immed_double_const (lo, hi, DImode);
12656   if (i >= 31)
12657     {
12658       emit_move_insn (operands[2], op1);
12659       op1 = operands[2];
12660     }
12661
12662   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12663   DONE;
12664 })
12665 \f
12666 ;; Store-flag instructions.
12667
12668 ;; For all sCOND expanders, also expand the compare or test insn that
12669 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12670
12671 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12672 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12673 ;; way, which can later delete the movzx if only QImode is needed.
12674
12675 (define_expand "seq"
12676   [(set (match_operand:QI 0 "register_operand" "")
12677         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12678   ""
12679   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "sne"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sgt"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sgtu"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "slt"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sltu"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sge"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sgeu"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   ""
12721   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sle"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   ""
12727   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sleu"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   ""
12733   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sunordered"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   "TARGET_80387 || TARGET_SSE"
12739   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sordered"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387"
12745   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "suneq"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387 || TARGET_SSE"
12751   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "sunge"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sungt"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sunle"
12766   [(set (match_operand:QI 0 "register_operand" "")
12767         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768   "TARGET_80387 || TARGET_SSE"
12769   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sunlt"
12772   [(set (match_operand:QI 0 "register_operand" "")
12773         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774   "TARGET_80387 || TARGET_SSE"
12775   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12776
12777 (define_expand "sltgt"
12778   [(set (match_operand:QI 0 "register_operand" "")
12779         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780   "TARGET_80387 || TARGET_SSE"
12781   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12782
12783 (define_insn "*setcc_1"
12784   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12785         (match_operator:QI 1 "ix86_comparison_operator"
12786           [(reg FLAGS_REG) (const_int 0)]))]
12787   ""
12788   "set%C1\t%0"
12789   [(set_attr "type" "setcc")
12790    (set_attr "mode" "QI")])
12791
12792 (define_insn "*setcc_2"
12793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12794         (match_operator:QI 1 "ix86_comparison_operator"
12795           [(reg FLAGS_REG) (const_int 0)]))]
12796   ""
12797   "set%C1\t%0"
12798   [(set_attr "type" "setcc")
12799    (set_attr "mode" "QI")])
12800
12801 ;; In general it is not safe to assume too much about CCmode registers,
12802 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12803 ;; conditions this is safe on x86, so help combine not create
12804 ;;
12805 ;;      seta    %al
12806 ;;      testb   %al, %al
12807 ;;      sete    %al
12808
12809 (define_split 
12810   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12811         (ne:QI (match_operator 1 "ix86_comparison_operator"
12812                  [(reg FLAGS_REG) (const_int 0)])
12813             (const_int 0)))]
12814   ""
12815   [(set (match_dup 0) (match_dup 1))]
12816 {
12817   PUT_MODE (operands[1], QImode);
12818 })
12819
12820 (define_split 
12821   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12822         (ne:QI (match_operator 1 "ix86_comparison_operator"
12823                  [(reg FLAGS_REG) (const_int 0)])
12824             (const_int 0)))]
12825   ""
12826   [(set (match_dup 0) (match_dup 1))]
12827 {
12828   PUT_MODE (operands[1], QImode);
12829 })
12830
12831 (define_split 
12832   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833         (eq:QI (match_operator 1 "ix86_comparison_operator"
12834                  [(reg FLAGS_REG) (const_int 0)])
12835             (const_int 0)))]
12836   ""
12837   [(set (match_dup 0) (match_dup 1))]
12838 {
12839   rtx new_op1 = copy_rtx (operands[1]);
12840   operands[1] = new_op1;
12841   PUT_MODE (new_op1, QImode);
12842   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12843                                              GET_MODE (XEXP (new_op1, 0))));
12844
12845   /* Make sure that (a) the CCmode we have for the flags is strong
12846      enough for the reversed compare or (b) we have a valid FP compare.  */
12847   if (! ix86_comparison_operator (new_op1, VOIDmode))
12848     FAIL;
12849 })
12850
12851 (define_split 
12852   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12853         (eq:QI (match_operator 1 "ix86_comparison_operator"
12854                  [(reg FLAGS_REG) (const_int 0)])
12855             (const_int 0)))]
12856   ""
12857   [(set (match_dup 0) (match_dup 1))]
12858 {
12859   rtx new_op1 = copy_rtx (operands[1]);
12860   operands[1] = new_op1;
12861   PUT_MODE (new_op1, QImode);
12862   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12863                                              GET_MODE (XEXP (new_op1, 0))));
12864
12865   /* Make sure that (a) the CCmode we have for the flags is strong
12866      enough for the reversed compare or (b) we have a valid FP compare.  */
12867   if (! ix86_comparison_operator (new_op1, VOIDmode))
12868     FAIL;
12869 })
12870
12871 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12872 ;; subsequent logical operations are used to imitate conditional moves.
12873 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12874 ;; it directly.
12875
12876 (define_insn "*sse_setccsf"
12877   [(set (match_operand:SF 0 "register_operand" "=x")
12878         (match_operator:SF 1 "sse_comparison_operator"
12879           [(match_operand:SF 2 "register_operand" "0")
12880            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12881   "TARGET_SSE"
12882   "cmp%D1ss\t{%3, %0|%0, %3}"
12883   [(set_attr "type" "ssecmp")
12884    (set_attr "mode" "SF")])
12885
12886 (define_insn "*sse_setccdf"
12887   [(set (match_operand:DF 0 "register_operand" "=Y")
12888         (match_operator:DF 1 "sse_comparison_operator"
12889           [(match_operand:DF 2 "register_operand" "0")
12890            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12891   "TARGET_SSE2"
12892   "cmp%D1sd\t{%3, %0|%0, %3}"
12893   [(set_attr "type" "ssecmp")
12894    (set_attr "mode" "DF")])
12895 \f
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12898
12899 ;; For all bCOND expanders, also expand the compare or test insn that
12900 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12901
12902 (define_expand "beq"
12903   [(set (pc)
12904         (if_then_else (match_dup 1)
12905                       (label_ref (match_operand 0 "" ""))
12906                       (pc)))]
12907   ""
12908   "ix86_expand_branch (EQ, operands[0]); DONE;")
12909
12910 (define_expand "bne"
12911   [(set (pc)
12912         (if_then_else (match_dup 1)
12913                       (label_ref (match_operand 0 "" ""))
12914                       (pc)))]
12915   ""
12916   "ix86_expand_branch (NE, operands[0]); DONE;")
12917
12918 (define_expand "bgt"
12919   [(set (pc)
12920         (if_then_else (match_dup 1)
12921                       (label_ref (match_operand 0 "" ""))
12922                       (pc)))]
12923   ""
12924   "ix86_expand_branch (GT, operands[0]); DONE;")
12925
12926 (define_expand "bgtu"
12927   [(set (pc)
12928         (if_then_else (match_dup 1)
12929                       (label_ref (match_operand 0 "" ""))
12930                       (pc)))]
12931   ""
12932   "ix86_expand_branch (GTU, operands[0]); DONE;")
12933
12934 (define_expand "blt"
12935   [(set (pc)
12936         (if_then_else (match_dup 1)
12937                       (label_ref (match_operand 0 "" ""))
12938                       (pc)))]
12939   ""
12940   "ix86_expand_branch (LT, operands[0]); DONE;")
12941
12942 (define_expand "bltu"
12943   [(set (pc)
12944         (if_then_else (match_dup 1)
12945                       (label_ref (match_operand 0 "" ""))
12946                       (pc)))]
12947   ""
12948   "ix86_expand_branch (LTU, operands[0]); DONE;")
12949
12950 (define_expand "bge"
12951   [(set (pc)
12952         (if_then_else (match_dup 1)
12953                       (label_ref (match_operand 0 "" ""))
12954                       (pc)))]
12955   ""
12956   "ix86_expand_branch (GE, operands[0]); DONE;")
12957
12958 (define_expand "bgeu"
12959   [(set (pc)
12960         (if_then_else (match_dup 1)
12961                       (label_ref (match_operand 0 "" ""))
12962                       (pc)))]
12963   ""
12964   "ix86_expand_branch (GEU, operands[0]); DONE;")
12965
12966 (define_expand "ble"
12967   [(set (pc)
12968         (if_then_else (match_dup 1)
12969                       (label_ref (match_operand 0 "" ""))
12970                       (pc)))]
12971   ""
12972   "ix86_expand_branch (LE, operands[0]); DONE;")
12973
12974 (define_expand "bleu"
12975   [(set (pc)
12976         (if_then_else (match_dup 1)
12977                       (label_ref (match_operand 0 "" ""))
12978                       (pc)))]
12979   ""
12980   "ix86_expand_branch (LEU, operands[0]); DONE;")
12981
12982 (define_expand "bunordered"
12983   [(set (pc)
12984         (if_then_else (match_dup 1)
12985                       (label_ref (match_operand 0 "" ""))
12986                       (pc)))]
12987   "TARGET_80387 || TARGET_SSE_MATH"
12988   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12989
12990 (define_expand "bordered"
12991   [(set (pc)
12992         (if_then_else (match_dup 1)
12993                       (label_ref (match_operand 0 "" ""))
12994                       (pc)))]
12995   "TARGET_80387 || TARGET_SSE_MATH"
12996   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12997
12998 (define_expand "buneq"
12999   [(set (pc)
13000         (if_then_else (match_dup 1)
13001                       (label_ref (match_operand 0 "" ""))
13002                       (pc)))]
13003   "TARGET_80387 || TARGET_SSE_MATH"
13004   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13005
13006 (define_expand "bunge"
13007   [(set (pc)
13008         (if_then_else (match_dup 1)
13009                       (label_ref (match_operand 0 "" ""))
13010                       (pc)))]
13011   "TARGET_80387 || TARGET_SSE_MATH"
13012   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13013
13014 (define_expand "bungt"
13015   [(set (pc)
13016         (if_then_else (match_dup 1)
13017                       (label_ref (match_operand 0 "" ""))
13018                       (pc)))]
13019   "TARGET_80387 || TARGET_SSE_MATH"
13020   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13021
13022 (define_expand "bunle"
13023   [(set (pc)
13024         (if_then_else (match_dup 1)
13025                       (label_ref (match_operand 0 "" ""))
13026                       (pc)))]
13027   "TARGET_80387 || TARGET_SSE_MATH"
13028   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13029
13030 (define_expand "bunlt"
13031   [(set (pc)
13032         (if_then_else (match_dup 1)
13033                       (label_ref (match_operand 0 "" ""))
13034                       (pc)))]
13035   "TARGET_80387 || TARGET_SSE_MATH"
13036   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13037
13038 (define_expand "bltgt"
13039   [(set (pc)
13040         (if_then_else (match_dup 1)
13041                       (label_ref (match_operand 0 "" ""))
13042                       (pc)))]
13043   "TARGET_80387 || TARGET_SSE_MATH"
13044   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13045
13046 (define_insn "*jcc_1"
13047   [(set (pc)
13048         (if_then_else (match_operator 1 "ix86_comparison_operator"
13049                                       [(reg FLAGS_REG) (const_int 0)])
13050                       (label_ref (match_operand 0 "" ""))
13051                       (pc)))]
13052   ""
13053   "%+j%C1\t%l0"
13054   [(set_attr "type" "ibr")
13055    (set_attr "modrm" "0")
13056    (set (attr "length")
13057            (if_then_else (and (ge (minus (match_dup 0) (pc))
13058                                   (const_int -126))
13059                               (lt (minus (match_dup 0) (pc))
13060                                   (const_int 128)))
13061              (const_int 2)
13062              (const_int 6)))])
13063
13064 (define_insn "*jcc_2"
13065   [(set (pc)
13066         (if_then_else (match_operator 1 "ix86_comparison_operator"
13067                                       [(reg FLAGS_REG) (const_int 0)])
13068                       (pc)
13069                       (label_ref (match_operand 0 "" ""))))]
13070   ""
13071   "%+j%c1\t%l0"
13072   [(set_attr "type" "ibr")
13073    (set_attr "modrm" "0")
13074    (set (attr "length")
13075            (if_then_else (and (ge (minus (match_dup 0) (pc))
13076                                   (const_int -126))
13077                               (lt (minus (match_dup 0) (pc))
13078                                   (const_int 128)))
13079              (const_int 2)
13080              (const_int 6)))])
13081
13082 ;; In general it is not safe to assume too much about CCmode registers,
13083 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13084 ;; conditions this is safe on x86, so help combine not create
13085 ;;
13086 ;;      seta    %al
13087 ;;      testb   %al, %al
13088 ;;      je      Lfoo
13089
13090 (define_split 
13091   [(set (pc)
13092         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13093                                       [(reg FLAGS_REG) (const_int 0)])
13094                           (const_int 0))
13095                       (label_ref (match_operand 1 "" ""))
13096                       (pc)))]
13097   ""
13098   [(set (pc)
13099         (if_then_else (match_dup 0)
13100                       (label_ref (match_dup 1))
13101                       (pc)))]
13102 {
13103   PUT_MODE (operands[0], VOIDmode);
13104 })
13105   
13106 (define_split 
13107   [(set (pc)
13108         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13109                                       [(reg FLAGS_REG) (const_int 0)])
13110                           (const_int 0))
13111                       (label_ref (match_operand 1 "" ""))
13112                       (pc)))]
13113   ""
13114   [(set (pc)
13115         (if_then_else (match_dup 0)
13116                       (label_ref (match_dup 1))
13117                       (pc)))]
13118 {
13119   rtx new_op0 = copy_rtx (operands[0]);
13120   operands[0] = new_op0;
13121   PUT_MODE (new_op0, VOIDmode);
13122   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13123                                              GET_MODE (XEXP (new_op0, 0))));
13124
13125   /* Make sure that (a) the CCmode we have for the flags is strong
13126      enough for the reversed compare or (b) we have a valid FP compare.  */
13127   if (! ix86_comparison_operator (new_op0, VOIDmode))
13128     FAIL;
13129 })
13130
13131 ;; Define combination compare-and-branch fp compare instructions to use
13132 ;; during early optimization.  Splitting the operation apart early makes
13133 ;; for bad code when we want to reverse the operation.
13134
13135 (define_insn "*fp_jcc_1_mixed"
13136   [(set (pc)
13137         (if_then_else (match_operator 0 "comparison_operator"
13138                         [(match_operand 1 "register_operand" "f#x,x#f")
13139                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13140           (label_ref (match_operand 3 "" ""))
13141           (pc)))
13142    (clobber (reg:CCFP FPSR_REG))
13143    (clobber (reg:CCFP FLAGS_REG))]
13144   "TARGET_MIX_SSE_I387
13145    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13146    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13148   "#")
13149
13150 (define_insn "*fp_jcc_1_sse"
13151   [(set (pc)
13152         (if_then_else (match_operator 0 "comparison_operator"
13153                         [(match_operand 1 "register_operand" "x")
13154                          (match_operand 2 "nonimmediate_operand" "xm")])
13155           (label_ref (match_operand 3 "" ""))
13156           (pc)))
13157    (clobber (reg:CCFP FPSR_REG))
13158    (clobber (reg:CCFP FLAGS_REG))]
13159   "TARGET_SSE_MATH
13160    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13164
13165 (define_insn "*fp_jcc_1_387"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "register_operand" "f")])
13170           (label_ref (match_operand 3 "" ""))
13171           (pc)))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))]
13174   "TARGET_CMOVE && TARGET_80387
13175    && FLOAT_MODE_P (GET_MODE (operands[1]))
13176    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13177    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13178   "#")
13179
13180 (define_insn "*fp_jcc_2_mixed"
13181   [(set (pc)
13182         (if_then_else (match_operator 0 "comparison_operator"
13183                         [(match_operand 1 "register_operand" "f#x,x#f")
13184                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13185           (pc)
13186           (label_ref (match_operand 3 "" ""))))
13187    (clobber (reg:CCFP FPSR_REG))
13188    (clobber (reg:CCFP FLAGS_REG))]
13189   "TARGET_MIX_SSE_I387
13190    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13191    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13192    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13193   "#")
13194
13195 (define_insn "*fp_jcc_2_sse"
13196   [(set (pc)
13197         (if_then_else (match_operator 0 "comparison_operator"
13198                         [(match_operand 1 "register_operand" "x")
13199                          (match_operand 2 "nonimmediate_operand" "xm")])
13200           (pc)
13201           (label_ref (match_operand 3 "" ""))))
13202    (clobber (reg:CCFP FPSR_REG))
13203    (clobber (reg:CCFP FLAGS_REG))]
13204   "TARGET_SSE_MATH
13205    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208   "#")
13209
13210 (define_insn "*fp_jcc_2_387"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "register_operand" "f")])
13215           (pc)
13216           (label_ref (match_operand 3 "" ""))))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))]
13219   "TARGET_CMOVE && TARGET_80387
13220    && FLOAT_MODE_P (GET_MODE (operands[1]))
13221    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13222    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13223   "#")
13224
13225 (define_insn "*fp_jcc_3_387"
13226   [(set (pc)
13227         (if_then_else (match_operator 0 "comparison_operator"
13228                         [(match_operand 1 "register_operand" "f")
13229                          (match_operand 2 "nonimmediate_operand" "fm")])
13230           (label_ref (match_operand 3 "" ""))
13231           (pc)))
13232    (clobber (reg:CCFP FPSR_REG))
13233    (clobber (reg:CCFP FLAGS_REG))
13234    (clobber (match_scratch:HI 4 "=a"))]
13235   "TARGET_80387
13236    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13238    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13239    && SELECT_CC_MODE (GET_CODE (operands[0]),
13240                       operands[1], operands[2]) == CCFPmode
13241    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13242   "#")
13243
13244 (define_insn "*fp_jcc_4_387"
13245   [(set (pc)
13246         (if_then_else (match_operator 0 "comparison_operator"
13247                         [(match_operand 1 "register_operand" "f")
13248                          (match_operand 2 "nonimmediate_operand" "fm")])
13249           (pc)
13250           (label_ref (match_operand 3 "" ""))))
13251    (clobber (reg:CCFP FPSR_REG))
13252    (clobber (reg:CCFP FLAGS_REG))
13253    (clobber (match_scratch:HI 4 "=a"))]
13254   "TARGET_80387
13255    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13258    && SELECT_CC_MODE (GET_CODE (operands[0]),
13259                       operands[1], operands[2]) == CCFPmode
13260    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13261   "#")
13262
13263 (define_insn "*fp_jcc_5_387"
13264   [(set (pc)
13265         (if_then_else (match_operator 0 "comparison_operator"
13266                         [(match_operand 1 "register_operand" "f")
13267                          (match_operand 2 "register_operand" "f")])
13268           (label_ref (match_operand 3 "" ""))
13269           (pc)))
13270    (clobber (reg:CCFP FPSR_REG))
13271    (clobber (reg:CCFP FLAGS_REG))
13272    (clobber (match_scratch:HI 4 "=a"))]
13273   "TARGET_80387
13274    && FLOAT_MODE_P (GET_MODE (operands[1]))
13275    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13278
13279 (define_insn "*fp_jcc_6_387"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "register_operand" "f")])
13284           (pc)
13285           (label_ref (match_operand 3 "" ""))))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && FLOAT_MODE_P (GET_MODE (operands[1]))
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13293   "#")
13294
13295 (define_insn "*fp_jcc_7_387"
13296   [(set (pc)
13297         (if_then_else (match_operator 0 "comparison_operator"
13298                         [(match_operand 1 "register_operand" "f")
13299                          (match_operand 2 "const0_operand" "X")])
13300           (label_ref (match_operand 3 "" ""))
13301           (pc)))
13302    (clobber (reg:CCFP FPSR_REG))
13303    (clobber (reg:CCFP FLAGS_REG))
13304    (clobber (match_scratch:HI 4 "=a"))]
13305   "TARGET_80387
13306    && FLOAT_MODE_P (GET_MODE (operands[1]))
13307    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13308    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13309    && SELECT_CC_MODE (GET_CODE (operands[0]),
13310                       operands[1], operands[2]) == CCFPmode
13311    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312   "#")
13313
13314 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13315 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13316 ;; with a precedence over other operators and is always put in the first
13317 ;; place. Swap condition and operands to match ficom instruction.
13318
13319 (define_insn "*fp_jcc_8<mode>_387"
13320   [(set (pc)
13321         (if_then_else (match_operator 0 "comparison_operator"
13322                         [(match_operator 1 "float_operator"
13323                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13324                            (match_operand 3 "register_operand" "f,f")])
13325           (label_ref (match_operand 4 "" ""))
13326           (pc)))
13327    (clobber (reg:CCFP FPSR_REG))
13328    (clobber (reg:CCFP FLAGS_REG))
13329    (clobber (match_scratch:HI 5 "=a,a"))]
13330   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13331    && FLOAT_MODE_P (GET_MODE (operands[3]))
13332    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13333    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13334    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13335    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13336   "#")
13337
13338 (define_split
13339   [(set (pc)
13340         (if_then_else (match_operator 0 "comparison_operator"
13341                         [(match_operand 1 "register_operand" "")
13342                          (match_operand 2 "nonimmediate_operand" "")])
13343           (match_operand 3 "" "")
13344           (match_operand 4 "" "")))
13345    (clobber (reg:CCFP FPSR_REG))
13346    (clobber (reg:CCFP FLAGS_REG))]
13347   "reload_completed"
13348   [(const_int 0)]
13349 {
13350   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13352   DONE;
13353 })
13354
13355 (define_split
13356   [(set (pc)
13357         (if_then_else (match_operator 0 "comparison_operator"
13358                         [(match_operand 1 "register_operand" "")
13359                          (match_operand 2 "general_operand" "")])
13360           (match_operand 3 "" "")
13361           (match_operand 4 "" "")))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 5 "=a"))]
13365   "reload_completed"
13366   [(const_int 0)]
13367 {
13368   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13369                         operands[3], operands[4], operands[5], NULL_RTX);
13370   DONE;
13371 })
13372
13373 (define_split
13374   [(set (pc)
13375         (if_then_else (match_operator 0 "comparison_operator"
13376                         [(match_operator 1 "float_operator"
13377                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13378                            (match_operand 3 "register_operand" "")])
13379           (match_operand 4 "" "")
13380           (match_operand 5 "" "")))
13381    (clobber (reg:CCFP FPSR_REG))
13382    (clobber (reg:CCFP FLAGS_REG))
13383    (clobber (match_scratch:HI 6 "=a"))]
13384   "reload_completed"
13385   [(const_int 0)]
13386 {
13387   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13388   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13389                         operands[3], operands[7],
13390                         operands[4], operands[5], operands[6], NULL_RTX);
13391   DONE;
13392 })
13393
13394 ;; %%% Kill this when reload knows how to do it.
13395 (define_split
13396   [(set (pc)
13397         (if_then_else (match_operator 0 "comparison_operator"
13398                         [(match_operator 1 "float_operator"
13399                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13400                            (match_operand 3 "register_operand" "")])
13401           (match_operand 4 "" "")
13402           (match_operand 5 "" "")))
13403    (clobber (reg:CCFP FPSR_REG))
13404    (clobber (reg:CCFP FLAGS_REG))
13405    (clobber (match_scratch:HI 6 "=a"))]
13406   "reload_completed"
13407   [(const_int 0)]
13408 {
13409   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13410   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13411   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13412                         operands[3], operands[7],
13413                         operands[4], operands[5], operands[6], operands[2]);
13414   DONE;
13415 })
13416 \f
13417 ;; Unconditional and other jump instructions
13418
13419 (define_insn "jump"
13420   [(set (pc)
13421         (label_ref (match_operand 0 "" "")))]
13422   ""
13423   "jmp\t%l0"
13424   [(set_attr "type" "ibr")
13425    (set (attr "length")
13426            (if_then_else (and (ge (minus (match_dup 0) (pc))
13427                                   (const_int -126))
13428                               (lt (minus (match_dup 0) (pc))
13429                                   (const_int 128)))
13430              (const_int 2)
13431              (const_int 5)))
13432    (set_attr "modrm" "0")])
13433
13434 (define_expand "indirect_jump"
13435   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13436   ""
13437   "")
13438
13439 (define_insn "*indirect_jump"
13440   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13441   "!TARGET_64BIT"
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13445
13446 (define_insn "*indirect_jump_rtx64"
13447   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13448   "TARGET_64BIT"
13449   "jmp\t%A0"
13450   [(set_attr "type" "ibr")
13451    (set_attr "length_immediate" "0")])
13452
13453 (define_expand "tablejump"
13454   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13455               (use (label_ref (match_operand 1 "" "")))])]
13456   ""
13457 {
13458   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13459      relative.  Convert the relative address to an absolute address.  */
13460   if (flag_pic)
13461     {
13462       rtx op0, op1;
13463       enum rtx_code code;
13464
13465       if (TARGET_64BIT)
13466         {
13467           code = PLUS;
13468           op0 = operands[0];
13469           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13470         }
13471       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13472         {
13473           code = PLUS;
13474           op0 = operands[0];
13475           op1 = pic_offset_table_rtx;
13476         }
13477       else
13478         {
13479           code = MINUS;
13480           op0 = pic_offset_table_rtx;
13481           op1 = operands[0];
13482         }
13483
13484       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13485                                          OPTAB_DIRECT);
13486     }
13487 })
13488
13489 (define_insn "*tablejump_1"
13490   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13491    (use (label_ref (match_operand 1 "" "")))]
13492   "!TARGET_64BIT"
13493   "jmp\t%A0"
13494   [(set_attr "type" "ibr")
13495    (set_attr "length_immediate" "0")])
13496
13497 (define_insn "*tablejump_1_rtx64"
13498   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13499    (use (label_ref (match_operand 1 "" "")))]
13500   "TARGET_64BIT"
13501   "jmp\t%A0"
13502   [(set_attr "type" "ibr")
13503    (set_attr "length_immediate" "0")])
13504 \f
13505 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13506
13507 (define_peephole2
13508   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13509    (set (match_operand:QI 1 "register_operand" "")
13510         (match_operator:QI 2 "ix86_comparison_operator"
13511           [(reg FLAGS_REG) (const_int 0)]))
13512    (set (match_operand 3 "q_regs_operand" "")
13513         (zero_extend (match_dup 1)))]
13514   "(peep2_reg_dead_p (3, operands[1])
13515     || operands_match_p (operands[1], operands[3]))
13516    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13517   [(set (match_dup 4) (match_dup 0))
13518    (set (strict_low_part (match_dup 5))
13519         (match_dup 2))]
13520 {
13521   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13522   operands[5] = gen_lowpart (QImode, operands[3]);
13523   ix86_expand_clear (operands[3]);
13524 })
13525
13526 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13527
13528 (define_peephole2
13529   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13530    (set (match_operand:QI 1 "register_operand" "")
13531         (match_operator:QI 2 "ix86_comparison_operator"
13532           [(reg FLAGS_REG) (const_int 0)]))
13533    (parallel [(set (match_operand 3 "q_regs_operand" "")
13534                    (zero_extend (match_dup 1)))
13535               (clobber (reg:CC FLAGS_REG))])]
13536   "(peep2_reg_dead_p (3, operands[1])
13537     || operands_match_p (operands[1], operands[3]))
13538    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13539   [(set (match_dup 4) (match_dup 0))
13540    (set (strict_low_part (match_dup 5))
13541         (match_dup 2))]
13542 {
13543   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13544   operands[5] = gen_lowpart (QImode, operands[3]);
13545   ix86_expand_clear (operands[3]);
13546 })
13547 \f
13548 ;; Call instructions.
13549
13550 ;; The predicates normally associated with named expanders are not properly
13551 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13552 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13553
13554 ;; Call subroutine returning no value.
13555
13556 (define_expand "call_pop"
13557   [(parallel [(call (match_operand:QI 0 "" "")
13558                     (match_operand:SI 1 "" ""))
13559               (set (reg:SI SP_REG)
13560                    (plus:SI (reg:SI SP_REG)
13561                             (match_operand:SI 3 "" "")))])]
13562   "!TARGET_64BIT"
13563 {
13564   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13565   DONE;
13566 })
13567
13568 (define_insn "*call_pop_0"
13569   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13570          (match_operand:SI 1 "" ""))
13571    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13572                             (match_operand:SI 2 "immediate_operand" "")))]
13573   "!TARGET_64BIT"
13574 {
13575   if (SIBLING_CALL_P (insn))
13576     return "jmp\t%P0";
13577   else
13578     return "call\t%P0";
13579 }
13580   [(set_attr "type" "call")])
13581   
13582 (define_insn "*call_pop_1"
13583   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13584          (match_operand:SI 1 "" ""))
13585    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13586                             (match_operand:SI 2 "immediate_operand" "i")))]
13587   "!TARGET_64BIT"
13588 {
13589   if (constant_call_address_operand (operands[0], Pmode))
13590     {
13591       if (SIBLING_CALL_P (insn))
13592         return "jmp\t%P0";
13593       else
13594         return "call\t%P0";
13595     }
13596   if (SIBLING_CALL_P (insn))
13597     return "jmp\t%A0";
13598   else
13599     return "call\t%A0";
13600 }
13601   [(set_attr "type" "call")])
13602
13603 (define_expand "call"
13604   [(call (match_operand:QI 0 "" "")
13605          (match_operand 1 "" ""))
13606    (use (match_operand 2 "" ""))]
13607   ""
13608 {
13609   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13610   DONE;
13611 })
13612
13613 (define_expand "sibcall"
13614   [(call (match_operand:QI 0 "" "")
13615          (match_operand 1 "" ""))
13616    (use (match_operand 2 "" ""))]
13617   ""
13618 {
13619   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13620   DONE;
13621 })
13622
13623 (define_insn "*call_0"
13624   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13625          (match_operand 1 "" ""))]
13626   ""
13627 {
13628   if (SIBLING_CALL_P (insn))
13629     return "jmp\t%P0";
13630   else
13631     return "call\t%P0";
13632 }
13633   [(set_attr "type" "call")])
13634
13635 (define_insn "*call_1"
13636   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637          (match_operand 1 "" ""))]
13638   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13639 {
13640   if (constant_call_address_operand (operands[0], Pmode))
13641     return "call\t%P0";
13642   return "call\t%A0";
13643 }
13644   [(set_attr "type" "call")])
13645
13646 (define_insn "*sibcall_1"
13647   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13648          (match_operand 1 "" ""))]
13649   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13650 {
13651   if (constant_call_address_operand (operands[0], Pmode))
13652     return "jmp\t%P0";
13653   return "jmp\t%A0";
13654 }
13655   [(set_attr "type" "call")])
13656
13657 (define_insn "*call_1_rex64"
13658   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13659          (match_operand 1 "" ""))]
13660   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13661 {
13662   if (constant_call_address_operand (operands[0], Pmode))
13663     return "call\t%P0";
13664   return "call\t%A0";
13665 }
13666   [(set_attr "type" "call")])
13667
13668 (define_insn "*sibcall_1_rex64"
13669   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13670          (match_operand 1 "" ""))]
13671   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13672   "jmp\t%P0"
13673   [(set_attr "type" "call")])
13674
13675 (define_insn "*sibcall_1_rex64_v"
13676   [(call (mem:QI (reg:DI 40))
13677          (match_operand 0 "" ""))]
13678   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13679   "jmp\t*%%r11"
13680   [(set_attr "type" "call")])
13681
13682
13683 ;; Call subroutine, returning value in operand 0
13684
13685 (define_expand "call_value_pop"
13686   [(parallel [(set (match_operand 0 "" "")
13687                    (call (match_operand:QI 1 "" "")
13688                          (match_operand:SI 2 "" "")))
13689               (set (reg:SI SP_REG)
13690                    (plus:SI (reg:SI SP_REG)
13691                             (match_operand:SI 4 "" "")))])]
13692   "!TARGET_64BIT"
13693 {
13694   ix86_expand_call (operands[0], operands[1], operands[2],
13695                     operands[3], operands[4], 0);
13696   DONE;
13697 })
13698
13699 (define_expand "call_value"
13700   [(set (match_operand 0 "" "")
13701         (call (match_operand:QI 1 "" "")
13702               (match_operand:SI 2 "" "")))
13703    (use (match_operand:SI 3 "" ""))]
13704   ;; Operand 2 not used on the i386.
13705   ""
13706 {
13707   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13708   DONE;
13709 })
13710
13711 (define_expand "sibcall_value"
13712   [(set (match_operand 0 "" "")
13713         (call (match_operand:QI 1 "" "")
13714               (match_operand:SI 2 "" "")))
13715    (use (match_operand:SI 3 "" ""))]
13716   ;; Operand 2 not used on the i386.
13717   ""
13718 {
13719   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13720   DONE;
13721 })
13722
13723 ;; Call subroutine returning any type.
13724
13725 (define_expand "untyped_call"
13726   [(parallel [(call (match_operand 0 "" "")
13727                     (const_int 0))
13728               (match_operand 1 "" "")
13729               (match_operand 2 "" "")])]
13730   ""
13731 {
13732   int i;
13733
13734   /* In order to give reg-stack an easier job in validating two
13735      coprocessor registers as containing a possible return value,
13736      simply pretend the untyped call returns a complex long double
13737      value.  */
13738
13739   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13740                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13741                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13742                     NULL, 0);
13743
13744   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13745     {
13746       rtx set = XVECEXP (operands[2], 0, i);
13747       emit_move_insn (SET_DEST (set), SET_SRC (set));
13748     }
13749
13750   /* The optimizer does not know that the call sets the function value
13751      registers we stored in the result block.  We avoid problems by
13752      claiming that all hard registers are used and clobbered at this
13753      point.  */
13754   emit_insn (gen_blockage (const0_rtx));
13755
13756   DONE;
13757 })
13758 \f
13759 ;; Prologue and epilogue instructions
13760
13761 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13762 ;; all of memory.  This blocks insns from being moved across this point.
13763
13764 (define_insn "blockage"
13765   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13766   ""
13767   ""
13768   [(set_attr "length" "0")])
13769
13770 ;; Insn emitted into the body of a function to return from a function.
13771 ;; This is only done if the function's epilogue is known to be simple.
13772 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13773
13774 (define_expand "return"
13775   [(return)]
13776   "ix86_can_use_return_insn_p ()"
13777 {
13778   if (current_function_pops_args)
13779     {
13780       rtx popc = GEN_INT (current_function_pops_args);
13781       emit_jump_insn (gen_return_pop_internal (popc));
13782       DONE;
13783     }
13784 })
13785
13786 (define_insn "return_internal"
13787   [(return)]
13788   "reload_completed"
13789   "ret"
13790   [(set_attr "length" "1")
13791    (set_attr "length_immediate" "0")
13792    (set_attr "modrm" "0")])
13793
13794 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13795 ;; instruction Athlon and K8 have.
13796
13797 (define_insn "return_internal_long"
13798   [(return)
13799    (unspec [(const_int 0)] UNSPEC_REP)]
13800   "reload_completed"
13801   "rep {;} ret"
13802   [(set_attr "length" "1")
13803    (set_attr "length_immediate" "0")
13804    (set_attr "prefix_rep" "1")
13805    (set_attr "modrm" "0")])
13806
13807 (define_insn "return_pop_internal"
13808   [(return)
13809    (use (match_operand:SI 0 "const_int_operand" ""))]
13810   "reload_completed"
13811   "ret\t%0"
13812   [(set_attr "length" "3")
13813    (set_attr "length_immediate" "2")
13814    (set_attr "modrm" "0")])
13815
13816 (define_insn "return_indirect_internal"
13817   [(return)
13818    (use (match_operand:SI 0 "register_operand" "r"))]
13819   "reload_completed"
13820   "jmp\t%A0"
13821   [(set_attr "type" "ibr")
13822    (set_attr "length_immediate" "0")])
13823
13824 (define_insn "nop"
13825   [(const_int 0)]
13826   ""
13827   "nop"
13828   [(set_attr "length" "1")
13829    (set_attr "length_immediate" "0")
13830    (set_attr "modrm" "0")])
13831
13832 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13833 ;; branch prediction penalty for the third jump in a 16-byte
13834 ;; block on K8.
13835
13836 (define_insn "align"
13837   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13838   ""
13839 {
13840 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13841   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13842 #else
13843   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13844      The align insn is used to avoid 3 jump instructions in the row to improve
13845      branch prediction and the benefits hardly outweight the cost of extra 8
13846      nops on the average inserted by full alignment pseudo operation.  */
13847 #endif
13848   return "";
13849 }
13850   [(set_attr "length" "16")])
13851
13852 (define_expand "prologue"
13853   [(const_int 1)]
13854   ""
13855   "ix86_expand_prologue (); DONE;")
13856
13857 (define_insn "set_got"
13858   [(set (match_operand:SI 0 "register_operand" "=r")
13859         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13860    (clobber (reg:CC FLAGS_REG))]
13861   "!TARGET_64BIT"
13862   { return output_set_got (operands[0]); }
13863   [(set_attr "type" "multi")
13864    (set_attr "length" "12")])
13865
13866 (define_insn "set_got_rex64"
13867   [(set (match_operand:DI 0 "register_operand" "=r")
13868         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13869   "TARGET_64BIT"
13870   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13871   [(set_attr "type" "lea")
13872    (set_attr "length" "6")])
13873
13874 (define_expand "epilogue"
13875   [(const_int 1)]
13876   ""
13877   "ix86_expand_epilogue (1); DONE;")
13878
13879 (define_expand "sibcall_epilogue"
13880   [(const_int 1)]
13881   ""
13882   "ix86_expand_epilogue (0); DONE;")
13883
13884 (define_expand "eh_return"
13885   [(use (match_operand 0 "register_operand" ""))]
13886   ""
13887 {
13888   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13889
13890   /* Tricky bit: we write the address of the handler to which we will
13891      be returning into someone else's stack frame, one word below the
13892      stack address we wish to restore.  */
13893   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13894   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13895   tmp = gen_rtx_MEM (Pmode, tmp);
13896   emit_move_insn (tmp, ra);
13897
13898   if (Pmode == SImode)
13899     emit_jump_insn (gen_eh_return_si (sa));
13900   else
13901     emit_jump_insn (gen_eh_return_di (sa));
13902   emit_barrier ();
13903   DONE;
13904 })
13905
13906 (define_insn_and_split "eh_return_si"
13907   [(set (pc) 
13908         (unspec [(match_operand:SI 0 "register_operand" "c")]
13909                  UNSPEC_EH_RETURN))]
13910   "!TARGET_64BIT"
13911   "#"
13912   "reload_completed"
13913   [(const_int 1)]
13914   "ix86_expand_epilogue (2); DONE;")
13915
13916 (define_insn_and_split "eh_return_di"
13917   [(set (pc) 
13918         (unspec [(match_operand:DI 0 "register_operand" "c")]
13919                  UNSPEC_EH_RETURN))]
13920   "TARGET_64BIT"
13921   "#"
13922   "reload_completed"
13923   [(const_int 1)]
13924   "ix86_expand_epilogue (2); DONE;")
13925
13926 (define_insn "leave"
13927   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13928    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13929    (clobber (mem:BLK (scratch)))]
13930   "!TARGET_64BIT"
13931   "leave"
13932   [(set_attr "type" "leave")])
13933
13934 (define_insn "leave_rex64"
13935   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13936    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13937    (clobber (mem:BLK (scratch)))]
13938   "TARGET_64BIT"
13939   "leave"
13940   [(set_attr "type" "leave")])
13941 \f
13942 (define_expand "ffssi2"
13943   [(parallel
13944      [(set (match_operand:SI 0 "register_operand" "") 
13945            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13946       (clobber (match_scratch:SI 2 ""))
13947       (clobber (reg:CC FLAGS_REG))])]
13948   ""
13949   "")
13950
13951 (define_insn_and_split "*ffs_cmove"
13952   [(set (match_operand:SI 0 "register_operand" "=r") 
13953         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13954    (clobber (match_scratch:SI 2 "=&r"))
13955    (clobber (reg:CC FLAGS_REG))]
13956   "TARGET_CMOVE"
13957   "#"
13958   "&& reload_completed"
13959   [(set (match_dup 2) (const_int -1))
13960    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13961               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13962    (set (match_dup 0) (if_then_else:SI
13963                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13964                         (match_dup 2)
13965                         (match_dup 0)))
13966    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967               (clobber (reg:CC FLAGS_REG))])]
13968   "")
13969
13970 (define_insn_and_split "*ffs_no_cmove"
13971   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13972         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13973    (clobber (match_scratch:SI 2 "=&q"))
13974    (clobber (reg:CC FLAGS_REG))]
13975   ""
13976   "#"
13977   "reload_completed"
13978   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13979               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13980    (set (strict_low_part (match_dup 3))
13981         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13982    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13983               (clobber (reg:CC FLAGS_REG))])
13984    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13985               (clobber (reg:CC FLAGS_REG))])
13986    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13987               (clobber (reg:CC FLAGS_REG))])]
13988 {
13989   operands[3] = gen_lowpart (QImode, operands[2]);
13990   ix86_expand_clear (operands[2]);
13991 })
13992
13993 (define_insn "*ffssi_1"
13994   [(set (reg:CCZ FLAGS_REG)
13995         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13996                      (const_int 0)))
13997    (set (match_operand:SI 0 "register_operand" "=r")
13998         (ctz:SI (match_dup 1)))]
13999   ""
14000   "bsf{l}\t{%1, %0|%0, %1}"
14001   [(set_attr "prefix_0f" "1")])
14002
14003 (define_expand "ffsdi2"
14004   [(parallel
14005      [(set (match_operand:DI 0 "register_operand" "") 
14006            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14007       (clobber (match_scratch:DI 2 ""))
14008       (clobber (reg:CC FLAGS_REG))])]
14009   "TARGET_64BIT && TARGET_CMOVE"
14010   "")
14011
14012 (define_insn_and_split "*ffs_rex64"
14013   [(set (match_operand:DI 0 "register_operand" "=r") 
14014         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14015    (clobber (match_scratch:DI 2 "=&r"))
14016    (clobber (reg:CC FLAGS_REG))]
14017   "TARGET_64BIT && TARGET_CMOVE"
14018   "#"
14019   "&& reload_completed"
14020   [(set (match_dup 2) (const_int -1))
14021    (parallel [(set (reg:CCZ FLAGS_REG)
14022                    (compare:CCZ (match_dup 1) (const_int 0)))
14023               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14024    (set (match_dup 0) (if_then_else:DI
14025                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14026                         (match_dup 2)
14027                         (match_dup 0)))
14028    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14029               (clobber (reg:CC FLAGS_REG))])]
14030   "")
14031
14032 (define_insn "*ffsdi_1"
14033   [(set (reg:CCZ FLAGS_REG)
14034         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14035                      (const_int 0)))
14036    (set (match_operand:DI 0 "register_operand" "=r")
14037         (ctz:DI (match_dup 1)))]
14038   "TARGET_64BIT"
14039   "bsf{q}\t{%1, %0|%0, %1}"
14040   [(set_attr "prefix_0f" "1")])
14041
14042 (define_insn "ctzsi2"
14043   [(set (match_operand:SI 0 "register_operand" "=r")
14044         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14045    (clobber (reg:CC FLAGS_REG))]
14046   ""
14047   "bsf{l}\t{%1, %0|%0, %1}"
14048   [(set_attr "prefix_0f" "1")])
14049
14050 (define_insn "ctzdi2"
14051   [(set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14053    (clobber (reg:CC FLAGS_REG))]
14054   "TARGET_64BIT"
14055   "bsf{q}\t{%1, %0|%0, %1}"
14056   [(set_attr "prefix_0f" "1")])
14057
14058 (define_expand "clzsi2"
14059   [(parallel
14060      [(set (match_operand:SI 0 "register_operand" "")
14061            (minus:SI (const_int 31)
14062                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14063       (clobber (reg:CC FLAGS_REG))])
14064    (parallel
14065      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14066       (clobber (reg:CC FLAGS_REG))])]
14067   ""
14068   "")
14069
14070 (define_insn "*bsr"
14071   [(set (match_operand:SI 0 "register_operand" "=r")
14072         (minus:SI (const_int 31)
14073                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14074    (clobber (reg:CC FLAGS_REG))]
14075   ""
14076   "bsr{l}\t{%1, %0|%0, %1}"
14077   [(set_attr "prefix_0f" "1")])
14078
14079 (define_expand "clzdi2"
14080   [(parallel
14081      [(set (match_operand:DI 0 "register_operand" "")
14082            (minus:DI (const_int 63)
14083                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14084       (clobber (reg:CC FLAGS_REG))])
14085    (parallel
14086      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14087       (clobber (reg:CC FLAGS_REG))])]
14088   "TARGET_64BIT"
14089   "")
14090
14091 (define_insn "*bsr_rex64"
14092   [(set (match_operand:DI 0 "register_operand" "=r")
14093         (minus:DI (const_int 63)
14094                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14095    (clobber (reg:CC FLAGS_REG))]
14096   "TARGET_64BIT"
14097   "bsr{q}\t{%1, %0|%0, %1}"
14098   [(set_attr "prefix_0f" "1")])
14099 \f
14100 ;; Thread-local storage patterns for ELF.
14101 ;;
14102 ;; Note that these code sequences must appear exactly as shown
14103 ;; in order to allow linker relaxation.
14104
14105 (define_insn "*tls_global_dynamic_32_gnu"
14106   [(set (match_operand:SI 0 "register_operand" "=a")
14107         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14108                     (match_operand:SI 2 "tls_symbolic_operand" "")
14109                     (match_operand:SI 3 "call_insn_operand" "")]
14110                     UNSPEC_TLS_GD))
14111    (clobber (match_scratch:SI 4 "=d"))
14112    (clobber (match_scratch:SI 5 "=c"))
14113    (clobber (reg:CC FLAGS_REG))]
14114   "!TARGET_64BIT && TARGET_GNU_TLS"
14115   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14116   [(set_attr "type" "multi")
14117    (set_attr "length" "12")])
14118
14119 (define_insn "*tls_global_dynamic_32_sun"
14120   [(set (match_operand:SI 0 "register_operand" "=a")
14121         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14122                     (match_operand:SI 2 "tls_symbolic_operand" "")
14123                     (match_operand:SI 3 "call_insn_operand" "")]
14124                     UNSPEC_TLS_GD))
14125    (clobber (match_scratch:SI 4 "=d"))
14126    (clobber (match_scratch:SI 5 "=c"))
14127    (clobber (reg:CC FLAGS_REG))]
14128   "!TARGET_64BIT && TARGET_SUN_TLS"
14129   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14130         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "14")])
14133
14134 (define_expand "tls_global_dynamic_32"
14135   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14136                    (unspec:SI
14137                     [(match_dup 2)
14138                      (match_operand:SI 1 "tls_symbolic_operand" "")
14139                      (match_dup 3)]
14140                     UNSPEC_TLS_GD))
14141               (clobber (match_scratch:SI 4 ""))
14142               (clobber (match_scratch:SI 5 ""))
14143               (clobber (reg:CC FLAGS_REG))])]
14144   ""
14145 {
14146   if (flag_pic)
14147     operands[2] = pic_offset_table_rtx;
14148   else
14149     {
14150       operands[2] = gen_reg_rtx (Pmode);
14151       emit_insn (gen_set_got (operands[2]));
14152     }
14153   operands[3] = ix86_tls_get_addr ();
14154 })
14155
14156 (define_insn "*tls_global_dynamic_64"
14157   [(set (match_operand:DI 0 "register_operand" "=a")
14158         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14159                  (match_operand:DI 3 "" "")))
14160    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14161               UNSPEC_TLS_GD)]
14162   "TARGET_64BIT"
14163   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14164   [(set_attr "type" "multi")
14165    (set_attr "length" "16")])
14166
14167 (define_expand "tls_global_dynamic_64"
14168   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14169                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14170               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14171                          UNSPEC_TLS_GD)])]
14172   ""
14173 {
14174   operands[2] = ix86_tls_get_addr ();
14175 })
14176
14177 (define_insn "*tls_local_dynamic_base_32_gnu"
14178   [(set (match_operand:SI 0 "register_operand" "=a")
14179         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14180                     (match_operand:SI 2 "call_insn_operand" "")]
14181                    UNSPEC_TLS_LD_BASE))
14182    (clobber (match_scratch:SI 3 "=d"))
14183    (clobber (match_scratch:SI 4 "=c"))
14184    (clobber (reg:CC FLAGS_REG))]
14185   "!TARGET_64BIT && TARGET_GNU_TLS"
14186   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14187   [(set_attr "type" "multi")
14188    (set_attr "length" "11")])
14189
14190 (define_insn "*tls_local_dynamic_base_32_sun"
14191   [(set (match_operand:SI 0 "register_operand" "=a")
14192         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14193                     (match_operand:SI 2 "call_insn_operand" "")]
14194                    UNSPEC_TLS_LD_BASE))
14195    (clobber (match_scratch:SI 3 "=d"))
14196    (clobber (match_scratch:SI 4 "=c"))
14197    (clobber (reg:CC FLAGS_REG))]
14198   "!TARGET_64BIT && TARGET_SUN_TLS"
14199   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14200         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14201   [(set_attr "type" "multi")
14202    (set_attr "length" "13")])
14203
14204 (define_expand "tls_local_dynamic_base_32"
14205   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14206                    (unspec:SI [(match_dup 1) (match_dup 2)]
14207                               UNSPEC_TLS_LD_BASE))
14208               (clobber (match_scratch:SI 3 ""))
14209               (clobber (match_scratch:SI 4 ""))
14210               (clobber (reg:CC FLAGS_REG))])]
14211   ""
14212 {
14213   if (flag_pic)
14214     operands[1] = pic_offset_table_rtx;
14215   else
14216     {
14217       operands[1] = gen_reg_rtx (Pmode);
14218       emit_insn (gen_set_got (operands[1]));
14219     }
14220   operands[2] = ix86_tls_get_addr ();
14221 })
14222
14223 (define_insn "*tls_local_dynamic_base_64"
14224   [(set (match_operand:DI 0 "register_operand" "=a")
14225         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14226                  (match_operand:DI 2 "" "")))
14227    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14228   "TARGET_64BIT"
14229   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14230   [(set_attr "type" "multi")
14231    (set_attr "length" "12")])
14232
14233 (define_expand "tls_local_dynamic_base_64"
14234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14235                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14236               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14237   ""
14238 {
14239   operands[1] = ix86_tls_get_addr ();
14240 })
14241
14242 ;; Local dynamic of a single variable is a lose.  Show combine how
14243 ;; to convert that back to global dynamic.
14244
14245 (define_insn_and_split "*tls_local_dynamic_32_once"
14246   [(set (match_operand:SI 0 "register_operand" "=a")
14247         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14248                              (match_operand:SI 2 "call_insn_operand" "")]
14249                             UNSPEC_TLS_LD_BASE)
14250                  (const:SI (unspec:SI
14251                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14252                             UNSPEC_DTPOFF))))
14253    (clobber (match_scratch:SI 4 "=d"))
14254    (clobber (match_scratch:SI 5 "=c"))
14255    (clobber (reg:CC FLAGS_REG))]
14256   ""
14257   "#"
14258   ""
14259   [(parallel [(set (match_dup 0)
14260                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14261                               UNSPEC_TLS_GD))
14262               (clobber (match_dup 4))
14263               (clobber (match_dup 5))
14264               (clobber (reg:CC FLAGS_REG))])]
14265   "")
14266
14267 ;; Load and add the thread base pointer from %gs:0.
14268
14269 (define_insn "*load_tp_si"
14270   [(set (match_operand:SI 0 "register_operand" "=r")
14271         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14272   "!TARGET_64BIT"
14273   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14274   [(set_attr "type" "imov")
14275    (set_attr "modrm" "0")
14276    (set_attr "length" "7")
14277    (set_attr "memory" "load")
14278    (set_attr "imm_disp" "false")])
14279
14280 (define_insn "*add_tp_si"
14281   [(set (match_operand:SI 0 "register_operand" "=r")
14282         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14283                  (match_operand:SI 1 "register_operand" "0")))
14284    (clobber (reg:CC FLAGS_REG))]
14285   "!TARGET_64BIT"
14286   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14287   [(set_attr "type" "alu")
14288    (set_attr "modrm" "0")
14289    (set_attr "length" "7")
14290    (set_attr "memory" "load")
14291    (set_attr "imm_disp" "false")])
14292
14293 (define_insn "*load_tp_di"
14294   [(set (match_operand:DI 0 "register_operand" "=r")
14295         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14296   "TARGET_64BIT"
14297   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14298   [(set_attr "type" "imov")
14299    (set_attr "modrm" "0")
14300    (set_attr "length" "7")
14301    (set_attr "memory" "load")
14302    (set_attr "imm_disp" "false")])
14303
14304 (define_insn "*add_tp_di"
14305   [(set (match_operand:DI 0 "register_operand" "=r")
14306         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14307                  (match_operand:DI 1 "register_operand" "0")))
14308    (clobber (reg:CC FLAGS_REG))]
14309   "TARGET_64BIT"
14310   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14311   [(set_attr "type" "alu")
14312    (set_attr "modrm" "0")
14313    (set_attr "length" "7")
14314    (set_attr "memory" "load")
14315    (set_attr "imm_disp" "false")])
14316 \f
14317 ;; These patterns match the binary 387 instructions for addM3, subM3,
14318 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14319 ;; SFmode.  The first is the normal insn, the second the same insn but
14320 ;; with one operand a conversion, and the third the same insn but with
14321 ;; the other operand a conversion.  The conversion may be SFmode or
14322 ;; SImode if the target mode DFmode, but only SImode if the target mode
14323 ;; is SFmode.
14324
14325 ;; Gcc is slightly more smart about handling normal two address instructions
14326 ;; so use special patterns for add and mull.
14327
14328 (define_insn "*fop_sf_comm_mixed"
14329   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14330         (match_operator:SF 3 "binary_fp_operator"
14331                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14332                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14333   "TARGET_MIX_SSE_I387
14334    && COMMUTATIVE_ARITH_P (operands[3])
14335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (if_then_else (eq_attr "alternative" "1")
14339            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14340               (const_string "ssemul")
14341               (const_string "sseadd"))
14342            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14343               (const_string "fmul")
14344               (const_string "fop"))))
14345    (set_attr "mode" "SF")])
14346
14347 (define_insn "*fop_sf_comm_sse"
14348   [(set (match_operand:SF 0 "register_operand" "=x")
14349         (match_operator:SF 3 "binary_fp_operator"
14350                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14351                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14352   "TARGET_SSE_MATH
14353    && COMMUTATIVE_ARITH_P (operands[3])
14354    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14355   "* return output_387_binary_op (insn, operands);"
14356   [(set (attr "type") 
14357         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14358            (const_string "ssemul")
14359            (const_string "sseadd")))
14360    (set_attr "mode" "SF")])
14361
14362 (define_insn "*fop_sf_comm_i387"
14363   [(set (match_operand:SF 0 "register_operand" "=f")
14364         (match_operator:SF 3 "binary_fp_operator"
14365                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14366                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14367   "TARGET_80387
14368    && COMMUTATIVE_ARITH_P (operands[3])
14369    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14370   "* return output_387_binary_op (insn, operands);"
14371   [(set (attr "type") 
14372         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14373            (const_string "fmul")
14374            (const_string "fop")))
14375    (set_attr "mode" "SF")])
14376
14377 (define_insn "*fop_sf_1_mixed"
14378   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14379         (match_operator:SF 3 "binary_fp_operator"
14380                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14381                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14382   "TARGET_MIX_SSE_I387
14383    && !COMMUTATIVE_ARITH_P (operands[3])
14384    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14385   "* return output_387_binary_op (insn, operands);"
14386   [(set (attr "type") 
14387         (cond [(and (eq_attr "alternative" "2")
14388                     (match_operand:SF 3 "mult_operator" ""))
14389                  (const_string "ssemul")
14390                (and (eq_attr "alternative" "2")
14391                     (match_operand:SF 3 "div_operator" ""))
14392                  (const_string "ssediv")
14393                (eq_attr "alternative" "2")
14394                  (const_string "sseadd")
14395                (match_operand:SF 3 "mult_operator" "") 
14396                  (const_string "fmul")
14397                (match_operand:SF 3 "div_operator" "") 
14398                  (const_string "fdiv")
14399               ]
14400               (const_string "fop")))
14401    (set_attr "mode" "SF")])
14402
14403 (define_insn "*fop_sf_1_sse"
14404   [(set (match_operand:SF 0 "register_operand" "=x")
14405         (match_operator:SF 3 "binary_fp_operator"
14406                         [(match_operand:SF 1 "register_operand" "0")
14407                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14408   "TARGET_SSE_MATH
14409    && !COMMUTATIVE_ARITH_P (operands[3])"
14410   "* return output_387_binary_op (insn, operands);"
14411   [(set (attr "type") 
14412         (cond [(match_operand:SF 3 "mult_operator" "")
14413                  (const_string "ssemul")
14414                (match_operand:SF 3 "div_operator" "")
14415                  (const_string "ssediv")
14416               ]
14417               (const_string "sseadd")))
14418    (set_attr "mode" "SF")])
14419
14420 ;; This pattern is not fully shadowed by the pattern above.
14421 (define_insn "*fop_sf_1_i387"
14422   [(set (match_operand:SF 0 "register_operand" "=f,f")
14423         (match_operator:SF 3 "binary_fp_operator"
14424                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14425                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14426   "TARGET_80387 && !TARGET_SSE_MATH
14427    && !COMMUTATIVE_ARITH_P (operands[3])
14428    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14429   "* return output_387_binary_op (insn, operands);"
14430   [(set (attr "type") 
14431         (cond [(match_operand:SF 3 "mult_operator" "") 
14432                  (const_string "fmul")
14433                (match_operand:SF 3 "div_operator" "") 
14434                  (const_string "fdiv")
14435               ]
14436               (const_string "fop")))
14437    (set_attr "mode" "SF")])
14438
14439 ;; ??? Add SSE splitters for these!
14440 (define_insn "*fop_sf_2<mode>_i387"
14441   [(set (match_operand:SF 0 "register_operand" "=f,f")
14442         (match_operator:SF 3 "binary_fp_operator"
14443           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14444            (match_operand:SF 2 "register_operand" "0,0")]))]
14445   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14446   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (cond [(match_operand:SF 3 "mult_operator" "") 
14449                  (const_string "fmul")
14450                (match_operand:SF 3 "div_operator" "") 
14451                  (const_string "fdiv")
14452               ]
14453               (const_string "fop")))
14454    (set_attr "fp_int_src" "true")
14455    (set_attr "mode" "<MODE>")])
14456
14457 (define_insn "*fop_sf_3<mode>_i387"
14458   [(set (match_operand:SF 0 "register_operand" "=f,f")
14459         (match_operator:SF 3 "binary_fp_operator"
14460           [(match_operand:SF 1 "register_operand" "0,0")
14461            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14462   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14463   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14464   [(set (attr "type") 
14465         (cond [(match_operand:SF 3 "mult_operator" "") 
14466                  (const_string "fmul")
14467                (match_operand:SF 3 "div_operator" "") 
14468                  (const_string "fdiv")
14469               ]
14470               (const_string "fop")))
14471    (set_attr "fp_int_src" "true")
14472    (set_attr "mode" "<MODE>")])
14473
14474 (define_insn "*fop_df_comm_mixed"
14475   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14480    && COMMUTATIVE_ARITH_P (operands[3])
14481    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (if_then_else (eq_attr "alternative" "1")
14485            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14486               (const_string "ssemul")
14487               (const_string "sseadd"))
14488            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14489               (const_string "fmul")
14490               (const_string "fop"))))
14491    (set_attr "mode" "DF")])
14492
14493 (define_insn "*fop_df_comm_sse"
14494   [(set (match_operand:DF 0 "register_operand" "=Y")
14495         (match_operator:DF 3 "binary_fp_operator"
14496                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498   "TARGET_SSE2 && TARGET_SSE_MATH
14499    && COMMUTATIVE_ARITH_P (operands[3])
14500    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501   "* return output_387_binary_op (insn, operands);"
14502   [(set (attr "type") 
14503         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14504            (const_string "ssemul")
14505            (const_string "sseadd")))
14506    (set_attr "mode" "DF")])
14507
14508 (define_insn "*fop_df_comm_i387"
14509   [(set (match_operand:DF 0 "register_operand" "=f")
14510         (match_operator:DF 3 "binary_fp_operator"
14511                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14512                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14513   "TARGET_80387
14514    && COMMUTATIVE_ARITH_P (operands[3])
14515    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516   "* return output_387_binary_op (insn, operands);"
14517   [(set (attr "type") 
14518         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14519            (const_string "fmul")
14520            (const_string "fop")))
14521    (set_attr "mode" "DF")])
14522
14523 (define_insn "*fop_df_1_mixed"
14524   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14525         (match_operator:DF 3 "binary_fp_operator"
14526                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14527                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14528   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14529    && !COMMUTATIVE_ARITH_P (operands[3])
14530    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531   "* return output_387_binary_op (insn, operands);"
14532   [(set (attr "type") 
14533         (cond [(and (eq_attr "alternative" "2")
14534                     (match_operand:SF 3 "mult_operator" ""))
14535                  (const_string "ssemul")
14536                (and (eq_attr "alternative" "2")
14537                     (match_operand:SF 3 "div_operator" ""))
14538                  (const_string "ssediv")
14539                (eq_attr "alternative" "2")
14540                  (const_string "sseadd")
14541                (match_operand:DF 3 "mult_operator" "") 
14542                  (const_string "fmul")
14543                (match_operand:DF 3 "div_operator" "") 
14544                  (const_string "fdiv")
14545               ]
14546               (const_string "fop")))
14547    (set_attr "mode" "DF")])
14548
14549 (define_insn "*fop_df_1_sse"
14550   [(set (match_operand:DF 0 "register_operand" "=Y")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "register_operand" "0")
14553                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14554   "TARGET_SSE2 && TARGET_SSE_MATH
14555    && !COMMUTATIVE_ARITH_P (operands[3])"
14556   "* return output_387_binary_op (insn, operands);"
14557   [(set_attr "mode" "DF")
14558    (set (attr "type") 
14559         (cond [(match_operand:SF 3 "mult_operator" "")
14560                  (const_string "ssemul")
14561                (match_operand:SF 3 "div_operator" "")
14562                  (const_string "ssediv")
14563               ]
14564               (const_string "sseadd")))])
14565
14566 ;; This pattern is not fully shadowed by the pattern above.
14567 (define_insn "*fop_df_1_i387"
14568   [(set (match_operand:DF 0 "register_operand" "=f,f")
14569         (match_operator:DF 3 "binary_fp_operator"
14570                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14571                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14572   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14573    && !COMMUTATIVE_ARITH_P (operands[3])
14574    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14575   "* return output_387_binary_op (insn, operands);"
14576   [(set (attr "type") 
14577         (cond [(match_operand:DF 3 "mult_operator" "") 
14578                  (const_string "fmul")
14579                (match_operand:DF 3 "div_operator" "")
14580                  (const_string "fdiv")
14581               ]
14582               (const_string "fop")))
14583    (set_attr "mode" "DF")])
14584
14585 ;; ??? Add SSE splitters for these!
14586 (define_insn "*fop_df_2<mode>_i387"
14587   [(set (match_operand:DF 0 "register_operand" "=f,f")
14588         (match_operator:DF 3 "binary_fp_operator"
14589            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14590             (match_operand:DF 2 "register_operand" "0,0")]))]
14591   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14592    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594   [(set (attr "type") 
14595         (cond [(match_operand:DF 3 "mult_operator" "") 
14596                  (const_string "fmul")
14597                (match_operand:DF 3 "div_operator" "") 
14598                  (const_string "fdiv")
14599               ]
14600               (const_string "fop")))
14601    (set_attr "fp_int_src" "true")
14602    (set_attr "mode" "<MODE>")])
14603
14604 (define_insn "*fop_df_3<mode>_i387"
14605   [(set (match_operand:DF 0 "register_operand" "=f,f")
14606         (match_operator:DF 3 "binary_fp_operator"
14607            [(match_operand:DF 1 "register_operand" "0,0")
14608             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14609   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14610    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14611   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14612   [(set (attr "type") 
14613         (cond [(match_operand:DF 3 "mult_operator" "") 
14614                  (const_string "fmul")
14615                (match_operand:DF 3 "div_operator" "") 
14616                  (const_string "fdiv")
14617               ]
14618               (const_string "fop")))
14619    (set_attr "fp_int_src" "true")
14620    (set_attr "mode" "<MODE>")])
14621
14622 (define_insn "*fop_df_4_i387"
14623   [(set (match_operand:DF 0 "register_operand" "=f,f")
14624         (match_operator:DF 3 "binary_fp_operator"
14625            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14626             (match_operand:DF 2 "register_operand" "0,f")]))]
14627   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14628    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14629   "* return output_387_binary_op (insn, operands);"
14630   [(set (attr "type") 
14631         (cond [(match_operand:DF 3 "mult_operator" "") 
14632                  (const_string "fmul")
14633                (match_operand:DF 3 "div_operator" "") 
14634                  (const_string "fdiv")
14635               ]
14636               (const_string "fop")))
14637    (set_attr "mode" "SF")])
14638
14639 (define_insn "*fop_df_5_i387"
14640   [(set (match_operand:DF 0 "register_operand" "=f,f")
14641         (match_operator:DF 3 "binary_fp_operator"
14642           [(match_operand:DF 1 "register_operand" "0,f")
14643            (float_extend:DF
14644             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14645   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14646   "* return output_387_binary_op (insn, operands);"
14647   [(set (attr "type") 
14648         (cond [(match_operand:DF 3 "mult_operator" "") 
14649                  (const_string "fmul")
14650                (match_operand:DF 3 "div_operator" "") 
14651                  (const_string "fdiv")
14652               ]
14653               (const_string "fop")))
14654    (set_attr "mode" "SF")])
14655
14656 (define_insn "*fop_df_6_i387"
14657   [(set (match_operand:DF 0 "register_operand" "=f,f")
14658         (match_operator:DF 3 "binary_fp_operator"
14659           [(float_extend:DF
14660             (match_operand:SF 1 "register_operand" "0,f"))
14661            (float_extend:DF
14662             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14663   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14664   "* return output_387_binary_op (insn, operands);"
14665   [(set (attr "type") 
14666         (cond [(match_operand:DF 3 "mult_operator" "") 
14667                  (const_string "fmul")
14668                (match_operand:DF 3 "div_operator" "") 
14669                  (const_string "fdiv")
14670               ]
14671               (const_string "fop")))
14672    (set_attr "mode" "SF")])
14673
14674 (define_insn "*fop_xf_comm_i387"
14675   [(set (match_operand:XF 0 "register_operand" "=f")
14676         (match_operator:XF 3 "binary_fp_operator"
14677                         [(match_operand:XF 1 "register_operand" "%0")
14678                          (match_operand:XF 2 "register_operand" "f")]))]
14679   "TARGET_80387
14680    && COMMUTATIVE_ARITH_P (operands[3])"
14681   "* return output_387_binary_op (insn, operands);"
14682   [(set (attr "type") 
14683         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14684            (const_string "fmul")
14685            (const_string "fop")))
14686    (set_attr "mode" "XF")])
14687
14688 (define_insn "*fop_xf_1_i387"
14689   [(set (match_operand:XF 0 "register_operand" "=f,f")
14690         (match_operator:XF 3 "binary_fp_operator"
14691                         [(match_operand:XF 1 "register_operand" "0,f")
14692                          (match_operand:XF 2 "register_operand" "f,0")]))]
14693   "TARGET_80387
14694    && !COMMUTATIVE_ARITH_P (operands[3])"
14695   "* return output_387_binary_op (insn, operands);"
14696   [(set (attr "type") 
14697         (cond [(match_operand:XF 3 "mult_operator" "") 
14698                  (const_string "fmul")
14699                (match_operand:XF 3 "div_operator" "") 
14700                  (const_string "fdiv")
14701               ]
14702               (const_string "fop")))
14703    (set_attr "mode" "XF")])
14704
14705 (define_insn "*fop_xf_2<mode>_i387"
14706   [(set (match_operand:XF 0 "register_operand" "=f,f")
14707         (match_operator:XF 3 "binary_fp_operator"
14708            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14709             (match_operand:XF 2 "register_operand" "0,0")]))]
14710   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14711   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14712   [(set (attr "type") 
14713         (cond [(match_operand:XF 3 "mult_operator" "") 
14714                  (const_string "fmul")
14715                (match_operand:XF 3 "div_operator" "") 
14716                  (const_string "fdiv")
14717               ]
14718               (const_string "fop")))
14719    (set_attr "fp_int_src" "true")
14720    (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "*fop_xf_3<mode>_i387"
14723   [(set (match_operand:XF 0 "register_operand" "=f,f")
14724         (match_operator:XF 3 "binary_fp_operator"
14725           [(match_operand:XF 1 "register_operand" "0,0")
14726            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14727   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14728   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14729   [(set (attr "type") 
14730         (cond [(match_operand:XF 3 "mult_operator" "") 
14731                  (const_string "fmul")
14732                (match_operand:XF 3 "div_operator" "") 
14733                  (const_string "fdiv")
14734               ]
14735               (const_string "fop")))
14736    (set_attr "fp_int_src" "true")
14737    (set_attr "mode" "<MODE>")])
14738
14739 (define_insn "*fop_xf_4_i387"
14740   [(set (match_operand:XF 0 "register_operand" "=f,f")
14741         (match_operator:XF 3 "binary_fp_operator"
14742            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14743             (match_operand:XF 2 "register_operand" "0,f")]))]
14744   "TARGET_80387"
14745   "* return output_387_binary_op (insn, operands);"
14746   [(set (attr "type") 
14747         (cond [(match_operand:XF 3 "mult_operator" "") 
14748                  (const_string "fmul")
14749                (match_operand:XF 3 "div_operator" "") 
14750                  (const_string "fdiv")
14751               ]
14752               (const_string "fop")))
14753    (set_attr "mode" "SF")])
14754
14755 (define_insn "*fop_xf_5_i387"
14756   [(set (match_operand:XF 0 "register_operand" "=f,f")
14757         (match_operator:XF 3 "binary_fp_operator"
14758           [(match_operand:XF 1 "register_operand" "0,f")
14759            (float_extend:XF
14760             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14761   "TARGET_80387"
14762   "* return output_387_binary_op (insn, operands);"
14763   [(set (attr "type") 
14764         (cond [(match_operand:XF 3 "mult_operator" "") 
14765                  (const_string "fmul")
14766                (match_operand:XF 3 "div_operator" "") 
14767                  (const_string "fdiv")
14768               ]
14769               (const_string "fop")))
14770    (set_attr "mode" "SF")])
14771
14772 (define_insn "*fop_xf_6_i387"
14773   [(set (match_operand:XF 0 "register_operand" "=f,f")
14774         (match_operator:XF 3 "binary_fp_operator"
14775           [(float_extend:XF
14776             (match_operand 1 "register_operand" "0,f"))
14777            (float_extend:XF
14778             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14779   "TARGET_80387"
14780   "* return output_387_binary_op (insn, operands);"
14781   [(set (attr "type") 
14782         (cond [(match_operand:XF 3 "mult_operator" "") 
14783                  (const_string "fmul")
14784                (match_operand:XF 3 "div_operator" "") 
14785                  (const_string "fdiv")
14786               ]
14787               (const_string "fop")))
14788    (set_attr "mode" "SF")])
14789
14790 (define_split
14791   [(set (match_operand 0 "register_operand" "")
14792         (match_operator 3 "binary_fp_operator"
14793            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14794             (match_operand 2 "register_operand" "")]))]
14795   "TARGET_80387 && reload_completed
14796    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14797   [(const_int 0)]
14798
14799   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14800   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14801   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14802                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14803                                           GET_MODE (operands[3]),
14804                                           operands[4],
14805                                           operands[2])));
14806   ix86_free_from_memory (GET_MODE (operands[1]));
14807   DONE;
14808 })
14809
14810 (define_split
14811   [(set (match_operand 0 "register_operand" "")
14812         (match_operator 3 "binary_fp_operator"
14813            [(match_operand 1 "register_operand" "")
14814             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14815   "TARGET_80387 && reload_completed
14816    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14817   [(const_int 0)]
14818 {
14819   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14820   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14821   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14822                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14823                                           GET_MODE (operands[3]),
14824                                           operands[1],
14825                                           operands[4])));
14826   ix86_free_from_memory (GET_MODE (operands[2]));
14827   DONE;
14828 })
14829 \f
14830 ;; FPU special functions.
14831
14832 (define_expand "sqrtsf2"
14833   [(set (match_operand:SF 0 "register_operand" "")
14834         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14835   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14836 {
14837   if (!TARGET_SSE_MATH)
14838     operands[1] = force_reg (SFmode, operands[1]);
14839 })
14840
14841 (define_insn "*sqrtsf2_mixed"
14842   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14843         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14844   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14845   "@
14846    fsqrt
14847    sqrtss\t{%1, %0|%0, %1}"
14848   [(set_attr "type" "fpspc,sse")
14849    (set_attr "mode" "SF,SF")
14850    (set_attr "athlon_decode" "direct,*")])
14851
14852 (define_insn "*sqrtsf2_sse"
14853   [(set (match_operand:SF 0 "register_operand" "=x")
14854         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14855   "TARGET_SSE_MATH"
14856   "sqrtss\t{%1, %0|%0, %1}"
14857   [(set_attr "type" "sse")
14858    (set_attr "mode" "SF")
14859    (set_attr "athlon_decode" "*")])
14860
14861 (define_insn "*sqrtsf2_i387"
14862   [(set (match_operand:SF 0 "register_operand" "=f")
14863         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14864   "TARGET_USE_FANCY_MATH_387"
14865   "fsqrt"
14866   [(set_attr "type" "fpspc")
14867    (set_attr "mode" "SF")
14868    (set_attr "athlon_decode" "direct")])
14869
14870 (define_expand "sqrtdf2"
14871   [(set (match_operand:DF 0 "register_operand" "")
14872         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14873   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14874 {
14875   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14876     operands[1] = force_reg (DFmode, operands[1]);
14877 })
14878
14879 (define_insn "*sqrtdf2_mixed"
14880   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14881         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14882   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14883   "@
14884    fsqrt
14885    sqrtsd\t{%1, %0|%0, %1}"
14886   [(set_attr "type" "fpspc,sse")
14887    (set_attr "mode" "DF,DF")
14888    (set_attr "athlon_decode" "direct,*")])
14889
14890 (define_insn "*sqrtdf2_sse"
14891   [(set (match_operand:DF 0 "register_operand" "=Y")
14892         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14893   "TARGET_SSE2 && TARGET_SSE_MATH"
14894   "sqrtsd\t{%1, %0|%0, %1}"
14895   [(set_attr "type" "sse")
14896    (set_attr "mode" "DF")
14897    (set_attr "athlon_decode" "*")])
14898
14899 (define_insn "*sqrtdf2_i387"
14900   [(set (match_operand:DF 0 "register_operand" "=f")
14901         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14902   "TARGET_USE_FANCY_MATH_387"
14903   "fsqrt"
14904   [(set_attr "type" "fpspc")
14905    (set_attr "mode" "DF")
14906    (set_attr "athlon_decode" "direct")])
14907
14908 (define_insn "*sqrtextendsfdf2_i387"
14909   [(set (match_operand:DF 0 "register_operand" "=f")
14910         (sqrt:DF (float_extend:DF
14911                   (match_operand:SF 1 "register_operand" "0"))))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14914   "fsqrt"
14915   [(set_attr "type" "fpspc")
14916    (set_attr "mode" "DF")
14917    (set_attr "athlon_decode" "direct")])
14918
14919 (define_insn "sqrtxf2"
14920   [(set (match_operand:XF 0 "register_operand" "=f")
14921         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14922   "TARGET_USE_FANCY_MATH_387 
14923    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14924   "fsqrt"
14925   [(set_attr "type" "fpspc")
14926    (set_attr "mode" "XF")
14927    (set_attr "athlon_decode" "direct")])
14928
14929 (define_insn "*sqrtextendsfxf2_i387"
14930   [(set (match_operand:XF 0 "register_operand" "=f")
14931         (sqrt:XF (float_extend:XF
14932                   (match_operand:SF 1 "register_operand" "0"))))]
14933   "TARGET_USE_FANCY_MATH_387"
14934   "fsqrt"
14935   [(set_attr "type" "fpspc")
14936    (set_attr "mode" "XF")
14937    (set_attr "athlon_decode" "direct")])
14938
14939 (define_insn "*sqrtextenddfxf2_i387"
14940   [(set (match_operand:XF 0 "register_operand" "=f")
14941         (sqrt:XF (float_extend:XF
14942                   (match_operand:DF 1 "register_operand" "0"))))]
14943   "TARGET_USE_FANCY_MATH_387"
14944   "fsqrt"
14945   [(set_attr "type" "fpspc")
14946    (set_attr "mode" "XF")
14947    (set_attr "athlon_decode" "direct")])
14948
14949 (define_insn "fpremxf4"
14950   [(set (match_operand:XF 0 "register_operand" "=f")
14951         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14952                     (match_operand:XF 3 "register_operand" "1")]
14953                    UNSPEC_FPREM_F))
14954    (set (match_operand:XF 1 "register_operand" "=u")
14955         (unspec:XF [(match_dup 2) (match_dup 3)]
14956                    UNSPEC_FPREM_U))
14957    (set (reg:CCFP FPSR_REG)
14958         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961   "fprem"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "XF")])
14964
14965 (define_expand "fmodsf3"
14966   [(use (match_operand:SF 0 "register_operand" ""))
14967    (use (match_operand:SF 1 "register_operand" ""))
14968    (use (match_operand:SF 2 "register_operand" ""))]
14969   "TARGET_USE_FANCY_MATH_387
14970    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14971    && flag_unsafe_math_optimizations"
14972 {
14973   rtx label = gen_label_rtx ();
14974
14975   rtx op1 = gen_reg_rtx (XFmode);
14976   rtx op2 = gen_reg_rtx (XFmode);
14977
14978   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14979   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14980
14981   emit_label (label);
14982
14983   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14984   ix86_emit_fp_unordered_jump (label);
14985
14986   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14987   DONE;
14988 })
14989
14990 (define_expand "fmoddf3"
14991   [(use (match_operand:DF 0 "register_operand" ""))
14992    (use (match_operand:DF 1 "register_operand" ""))
14993    (use (match_operand:DF 2 "register_operand" ""))]
14994   "TARGET_USE_FANCY_MATH_387
14995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14996    && flag_unsafe_math_optimizations"
14997 {
14998   rtx label = gen_label_rtx ();
14999
15000   rtx op1 = gen_reg_rtx (XFmode);
15001   rtx op2 = gen_reg_rtx (XFmode);
15002
15003   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15004   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15005
15006   emit_label (label);
15007
15008   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15009   ix86_emit_fp_unordered_jump (label);
15010
15011   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15012   DONE;
15013 })
15014
15015 (define_expand "fmodxf3"
15016   [(use (match_operand:XF 0 "register_operand" ""))
15017    (use (match_operand:XF 1 "register_operand" ""))
15018    (use (match_operand:XF 2 "register_operand" ""))]
15019   "TARGET_USE_FANCY_MATH_387
15020    && flag_unsafe_math_optimizations"
15021 {
15022   rtx label = gen_label_rtx ();
15023
15024   emit_label (label);
15025
15026   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15027                            operands[1], operands[2]));
15028   ix86_emit_fp_unordered_jump (label);
15029
15030   emit_move_insn (operands[0], operands[1]);
15031   DONE;
15032 })
15033
15034 (define_insn "fprem1xf4"
15035   [(set (match_operand:XF 0 "register_operand" "=f")
15036         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15037                     (match_operand:XF 3 "register_operand" "1")]
15038                    UNSPEC_FPREM1_F))
15039    (set (match_operand:XF 1 "register_operand" "=u")
15040         (unspec:XF [(match_dup 2) (match_dup 3)]
15041                    UNSPEC_FPREM1_U))
15042    (set (reg:CCFP FPSR_REG)
15043         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15044   "TARGET_USE_FANCY_MATH_387
15045    && flag_unsafe_math_optimizations"
15046   "fprem1"
15047   [(set_attr "type" "fpspc")
15048    (set_attr "mode" "XF")])
15049
15050 (define_expand "dremsf3"
15051   [(use (match_operand:SF 0 "register_operand" ""))
15052    (use (match_operand:SF 1 "register_operand" ""))
15053    (use (match_operand:SF 2 "register_operand" ""))]
15054   "TARGET_USE_FANCY_MATH_387
15055    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15057 {
15058   rtx label = gen_label_rtx ();
15059
15060   rtx op1 = gen_reg_rtx (XFmode);
15061   rtx op2 = gen_reg_rtx (XFmode);
15062
15063   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15064   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15065
15066   emit_label (label);
15067
15068   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15069   ix86_emit_fp_unordered_jump (label);
15070
15071   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15072   DONE;
15073 })
15074
15075 (define_expand "dremdf3"
15076   [(use (match_operand:DF 0 "register_operand" ""))
15077    (use (match_operand:DF 1 "register_operand" ""))
15078    (use (match_operand:DF 2 "register_operand" ""))]
15079   "TARGET_USE_FANCY_MATH_387
15080    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15081    && flag_unsafe_math_optimizations"
15082 {
15083   rtx label = gen_label_rtx ();
15084
15085   rtx op1 = gen_reg_rtx (XFmode);
15086   rtx op2 = gen_reg_rtx (XFmode);
15087
15088   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15089   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15090
15091   emit_label (label);
15092
15093   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15094   ix86_emit_fp_unordered_jump (label);
15095
15096   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15097   DONE;
15098 })
15099
15100 (define_expand "dremxf3"
15101   [(use (match_operand:XF 0 "register_operand" ""))
15102    (use (match_operand:XF 1 "register_operand" ""))
15103    (use (match_operand:XF 2 "register_operand" ""))]
15104   "TARGET_USE_FANCY_MATH_387
15105    && flag_unsafe_math_optimizations"
15106 {
15107   rtx label = gen_label_rtx ();
15108
15109   emit_label (label);
15110
15111   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15112                             operands[1], operands[2]));
15113   ix86_emit_fp_unordered_jump (label);
15114
15115   emit_move_insn (operands[0], operands[1]);
15116   DONE;
15117 })
15118
15119 (define_insn "*sindf2"
15120   [(set (match_operand:DF 0 "register_operand" "=f")
15121         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15124    && flag_unsafe_math_optimizations"
15125   "fsin"
15126   [(set_attr "type" "fpspc")
15127    (set_attr "mode" "DF")])
15128
15129 (define_insn "*sinsf2"
15130   [(set (match_operand:SF 0 "register_operand" "=f")
15131         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15132   "TARGET_USE_FANCY_MATH_387
15133    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "SF")])
15138
15139 (define_insn "*sinextendsfdf2"
15140   [(set (match_operand:DF 0 "register_operand" "=f")
15141         (unspec:DF [(float_extend:DF
15142                      (match_operand:SF 1 "register_operand" "0"))]
15143                    UNSPEC_SIN))]
15144   "TARGET_USE_FANCY_MATH_387
15145    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15146    && flag_unsafe_math_optimizations"
15147   "fsin"
15148   [(set_attr "type" "fpspc")
15149    (set_attr "mode" "DF")])
15150
15151 (define_insn "*sinxf2"
15152   [(set (match_operand:XF 0 "register_operand" "=f")
15153         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15154   "TARGET_USE_FANCY_MATH_387
15155    && flag_unsafe_math_optimizations"
15156   "fsin"
15157   [(set_attr "type" "fpspc")
15158    (set_attr "mode" "XF")])
15159
15160 (define_insn "*cosdf2"
15161   [(set (match_operand:DF 0 "register_operand" "=f")
15162         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15165    && flag_unsafe_math_optimizations"
15166   "fcos"
15167   [(set_attr "type" "fpspc")
15168    (set_attr "mode" "DF")])
15169
15170 (define_insn "*cossf2"
15171   [(set (match_operand:SF 0 "register_operand" "=f")
15172         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15175    && flag_unsafe_math_optimizations"
15176   "fcos"
15177   [(set_attr "type" "fpspc")
15178    (set_attr "mode" "SF")])
15179
15180 (define_insn "*cosextendsfdf2"
15181   [(set (match_operand:DF 0 "register_operand" "=f")
15182         (unspec:DF [(float_extend:DF
15183                      (match_operand:SF 1 "register_operand" "0"))]
15184                    UNSPEC_COS))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15187    && flag_unsafe_math_optimizations"
15188   "fcos"
15189   [(set_attr "type" "fpspc")
15190    (set_attr "mode" "DF")])
15191
15192 (define_insn "*cosxf2"
15193   [(set (match_operand:XF 0 "register_operand" "=f")
15194         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15195   "TARGET_USE_FANCY_MATH_387
15196    && flag_unsafe_math_optimizations"
15197   "fcos"
15198   [(set_attr "type" "fpspc")
15199    (set_attr "mode" "XF")])
15200
15201 ;; With sincos pattern defined, sin and cos builtin function will be
15202 ;; expanded to sincos pattern with one of its outputs left unused. 
15203 ;; Cse pass  will detected, if two sincos patterns can be combined,
15204 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15205 ;; depending on the unused output.
15206
15207 (define_insn "sincosdf3"
15208   [(set (match_operand:DF 0 "register_operand" "=f")
15209         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15210                    UNSPEC_SINCOS_COS))
15211    (set (match_operand:DF 1 "register_operand" "=u")
15212         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15213   "TARGET_USE_FANCY_MATH_387
15214    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15215    && flag_unsafe_math_optimizations"
15216   "fsincos"
15217   [(set_attr "type" "fpspc")
15218    (set_attr "mode" "DF")])
15219
15220 (define_split
15221   [(set (match_operand:DF 0 "register_operand" "")
15222         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15223                    UNSPEC_SINCOS_COS))
15224    (set (match_operand:DF 1 "register_operand" "")
15225         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15226   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15227    && !reload_completed && !reload_in_progress"
15228   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15229   "")
15230
15231 (define_split
15232   [(set (match_operand:DF 0 "register_operand" "")
15233         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234                    UNSPEC_SINCOS_COS))
15235    (set (match_operand:DF 1 "register_operand" "")
15236         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15238    && !reload_completed && !reload_in_progress"
15239   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15240   "")
15241
15242 (define_insn "sincossf3"
15243   [(set (match_operand:SF 0 "register_operand" "=f")
15244         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15245                    UNSPEC_SINCOS_COS))
15246    (set (match_operand:SF 1 "register_operand" "=u")
15247         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248   "TARGET_USE_FANCY_MATH_387
15249    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15250    && flag_unsafe_math_optimizations"
15251   "fsincos"
15252   [(set_attr "type" "fpspc")
15253    (set_attr "mode" "SF")])
15254
15255 (define_split
15256   [(set (match_operand:SF 0 "register_operand" "")
15257         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15258                    UNSPEC_SINCOS_COS))
15259    (set (match_operand:SF 1 "register_operand" "")
15260         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15261   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15262    && !reload_completed && !reload_in_progress"
15263   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15264   "")
15265
15266 (define_split
15267   [(set (match_operand:SF 0 "register_operand" "")
15268         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15269                    UNSPEC_SINCOS_COS))
15270    (set (match_operand:SF 1 "register_operand" "")
15271         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15272   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15273    && !reload_completed && !reload_in_progress"
15274   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15275   "")
15276
15277 (define_insn "*sincosextendsfdf3"
15278   [(set (match_operand:DF 0 "register_operand" "=f")
15279         (unspec:DF [(float_extend:DF
15280                      (match_operand:SF 2 "register_operand" "0"))]
15281                    UNSPEC_SINCOS_COS))
15282    (set (match_operand:DF 1 "register_operand" "=u")
15283         (unspec:DF [(float_extend:DF
15284                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15285   "TARGET_USE_FANCY_MATH_387
15286    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15287    && flag_unsafe_math_optimizations"
15288   "fsincos"
15289   [(set_attr "type" "fpspc")
15290    (set_attr "mode" "DF")])
15291
15292 (define_split
15293   [(set (match_operand:DF 0 "register_operand" "")
15294         (unspec:DF [(float_extend:DF
15295                      (match_operand:SF 2 "register_operand" ""))]
15296                    UNSPEC_SINCOS_COS))
15297    (set (match_operand:DF 1 "register_operand" "")
15298         (unspec:DF [(float_extend:DF
15299                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15300   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15301    && !reload_completed && !reload_in_progress"
15302   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15303                                    (match_dup 2))] UNSPEC_SIN))]
15304   "")
15305
15306 (define_split
15307   [(set (match_operand:DF 0 "register_operand" "")
15308         (unspec:DF [(float_extend:DF
15309                      (match_operand:SF 2 "register_operand" ""))]
15310                    UNSPEC_SINCOS_COS))
15311    (set (match_operand:DF 1 "register_operand" "")
15312         (unspec:DF [(float_extend:DF
15313                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15314   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15315    && !reload_completed && !reload_in_progress"
15316   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15317                                    (match_dup 2))] UNSPEC_COS))]
15318   "")
15319
15320 (define_insn "sincosxf3"
15321   [(set (match_operand:XF 0 "register_operand" "=f")
15322         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15323                    UNSPEC_SINCOS_COS))
15324    (set (match_operand:XF 1 "register_operand" "=u")
15325         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15326   "TARGET_USE_FANCY_MATH_387
15327    && flag_unsafe_math_optimizations"
15328   "fsincos"
15329   [(set_attr "type" "fpspc")
15330    (set_attr "mode" "XF")])
15331
15332 (define_split
15333   [(set (match_operand:XF 0 "register_operand" "")
15334         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15335                    UNSPEC_SINCOS_COS))
15336    (set (match_operand:XF 1 "register_operand" "")
15337         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15338   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15339    && !reload_completed && !reload_in_progress"
15340   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15341   "")
15342
15343 (define_split
15344   [(set (match_operand:XF 0 "register_operand" "")
15345         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15346                    UNSPEC_SINCOS_COS))
15347    (set (match_operand:XF 1 "register_operand" "")
15348         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15349   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15350    && !reload_completed && !reload_in_progress"
15351   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15352   "")
15353
15354 (define_insn "*tandf3_1"
15355   [(set (match_operand:DF 0 "register_operand" "=f")
15356         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15357                    UNSPEC_TAN_ONE))
15358    (set (match_operand:DF 1 "register_operand" "=u")
15359         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15360   "TARGET_USE_FANCY_MATH_387
15361    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations"
15363   "fptan"
15364   [(set_attr "type" "fpspc")
15365    (set_attr "mode" "DF")])
15366
15367 ;; optimize sequence: fptan
15368 ;;                    fstp    %st(0)
15369 ;;                    fld1
15370 ;; into fptan insn.
15371
15372 (define_peephole2
15373   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15374                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15375                              UNSPEC_TAN_ONE))
15376              (set (match_operand:DF 1 "register_operand" "")
15377                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15378    (set (match_dup 0)
15379         (match_operand:DF 3 "immediate_operand" ""))]
15380   "standard_80387_constant_p (operands[3]) == 2"
15381   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15382              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15383   "")
15384
15385 (define_expand "tandf2"
15386   [(parallel [(set (match_dup 2)
15387                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15388                               UNSPEC_TAN_ONE))
15389               (set (match_operand:DF 0 "register_operand" "")
15390                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15391   "TARGET_USE_FANCY_MATH_387
15392    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15393    && flag_unsafe_math_optimizations"
15394 {
15395   operands[2] = gen_reg_rtx (DFmode);
15396 })
15397
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406    && flag_unsafe_math_optimizations"
15407   "fptan"
15408   [(set_attr "type" "fpspc")
15409    (set_attr "mode" "SF")])
15410
15411 ;; optimize sequence: fptan
15412 ;;                    fstp    %st(0)
15413 ;;                    fld1
15414 ;; into fptan insn.
15415
15416 (define_peephole2
15417   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15418                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15419                              UNSPEC_TAN_ONE))
15420              (set (match_operand:SF 1 "register_operand" "")
15421                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15422    (set (match_dup 0)
15423         (match_operand:SF 3 "immediate_operand" ""))]
15424   "standard_80387_constant_p (operands[3]) == 2"
15425   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15426              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15427   "")
15428
15429 (define_expand "tansf2"
15430   [(parallel [(set (match_dup 2)
15431                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15432                               UNSPEC_TAN_ONE))
15433               (set (match_operand:SF 0 "register_operand" "")
15434                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15435   "TARGET_USE_FANCY_MATH_387
15436    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15437    && flag_unsafe_math_optimizations"
15438 {
15439   operands[2] = gen_reg_rtx (SFmode);
15440 })
15441
15442 (define_insn "*tanxf3_1"
15443   [(set (match_operand:XF 0 "register_operand" "=f")
15444         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15445                    UNSPEC_TAN_ONE))
15446    (set (match_operand:XF 1 "register_operand" "=u")
15447         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15448   "TARGET_USE_FANCY_MATH_387
15449    && flag_unsafe_math_optimizations"
15450   "fptan"
15451   [(set_attr "type" "fpspc")
15452    (set_attr "mode" "XF")])
15453
15454 ;; optimize sequence: fptan
15455 ;;                    fstp    %st(0)
15456 ;;                    fld1
15457 ;; into fptan insn.
15458
15459 (define_peephole2
15460   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15461                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15462                              UNSPEC_TAN_ONE))
15463              (set (match_operand:XF 1 "register_operand" "")
15464                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15465    (set (match_dup 0)
15466         (match_operand:XF 3 "immediate_operand" ""))]
15467   "standard_80387_constant_p (operands[3]) == 2"
15468   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15469              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15470   "")
15471
15472 (define_expand "tanxf2"
15473   [(parallel [(set (match_dup 2)
15474                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15475                               UNSPEC_TAN_ONE))
15476               (set (match_operand:XF 0 "register_operand" "")
15477                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations"
15480 {
15481   operands[2] = gen_reg_rtx (XFmode);
15482 })
15483
15484 (define_insn "atan2df3_1"
15485   [(set (match_operand:DF 0 "register_operand" "=f")
15486         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15487                     (match_operand:DF 1 "register_operand" "u")]
15488                    UNSPEC_FPATAN))
15489    (clobber (match_scratch:DF 3 "=1"))]
15490   "TARGET_USE_FANCY_MATH_387
15491    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15492    && flag_unsafe_math_optimizations"
15493   "fpatan"
15494   [(set_attr "type" "fpspc")
15495    (set_attr "mode" "DF")])
15496
15497 (define_expand "atan2df3"
15498   [(use (match_operand:DF 0 "register_operand" ""))
15499    (use (match_operand:DF 2 "register_operand" ""))
15500    (use (match_operand:DF 1 "register_operand" ""))]
15501   "TARGET_USE_FANCY_MATH_387
15502    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15503    && flag_unsafe_math_optimizations"
15504 {
15505   rtx copy = gen_reg_rtx (DFmode);
15506   emit_move_insn (copy, operands[1]);
15507   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15508   DONE;
15509 })
15510
15511 (define_expand "atandf2"
15512   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15513                    (unspec:DF [(match_dup 2)
15514                                (match_operand:DF 1 "register_operand" "")]
15515                     UNSPEC_FPATAN))
15516               (clobber (match_scratch:DF 3 ""))])]
15517   "TARGET_USE_FANCY_MATH_387
15518    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15519    && flag_unsafe_math_optimizations"
15520 {
15521   operands[2] = gen_reg_rtx (DFmode);
15522   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15523 })
15524
15525 (define_insn "atan2sf3_1"
15526   [(set (match_operand:SF 0 "register_operand" "=f")
15527         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15528                     (match_operand:SF 1 "register_operand" "u")]
15529                    UNSPEC_FPATAN))
15530    (clobber (match_scratch:SF 3 "=1"))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15533    && flag_unsafe_math_optimizations"
15534   "fpatan"
15535   [(set_attr "type" "fpspc")
15536    (set_attr "mode" "SF")])
15537
15538 (define_expand "atan2sf3"
15539   [(use (match_operand:SF 0 "register_operand" ""))
15540    (use (match_operand:SF 2 "register_operand" ""))
15541    (use (match_operand:SF 1 "register_operand" ""))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15544    && flag_unsafe_math_optimizations"
15545 {
15546   rtx copy = gen_reg_rtx (SFmode);
15547   emit_move_insn (copy, operands[1]);
15548   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15549   DONE;
15550 })
15551
15552 (define_expand "atansf2"
15553   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15554                    (unspec:SF [(match_dup 2)
15555                                (match_operand:SF 1 "register_operand" "")]
15556                     UNSPEC_FPATAN))
15557               (clobber (match_scratch:SF 3 ""))])]
15558   "TARGET_USE_FANCY_MATH_387
15559    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15560    && flag_unsafe_math_optimizations"
15561 {
15562   operands[2] = gen_reg_rtx (SFmode);
15563   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15564 })
15565
15566 (define_insn "atan2xf3_1"
15567   [(set (match_operand:XF 0 "register_operand" "=f")
15568         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15569                     (match_operand:XF 1 "register_operand" "u")]
15570                    UNSPEC_FPATAN))
15571    (clobber (match_scratch:XF 3 "=1"))]
15572   "TARGET_USE_FANCY_MATH_387
15573    && flag_unsafe_math_optimizations"
15574   "fpatan"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")])
15577
15578 (define_expand "atan2xf3"
15579   [(use (match_operand:XF 0 "register_operand" ""))
15580    (use (match_operand:XF 2 "register_operand" ""))
15581    (use (match_operand:XF 1 "register_operand" ""))]
15582   "TARGET_USE_FANCY_MATH_387
15583    && flag_unsafe_math_optimizations"
15584 {
15585   rtx copy = gen_reg_rtx (XFmode);
15586   emit_move_insn (copy, operands[1]);
15587   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15588   DONE;
15589 })
15590
15591 (define_expand "atanxf2"
15592   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15593                    (unspec:XF [(match_dup 2)
15594                                (match_operand:XF 1 "register_operand" "")]
15595                     UNSPEC_FPATAN))
15596               (clobber (match_scratch:XF 3 ""))])]
15597   "TARGET_USE_FANCY_MATH_387
15598    && flag_unsafe_math_optimizations"
15599 {
15600   operands[2] = gen_reg_rtx (XFmode);
15601   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15602 })
15603
15604 (define_expand "asindf2"
15605   [(set (match_dup 2)
15606         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15607    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15608    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15609    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15610    (parallel [(set (match_dup 7)
15611                    (unspec:XF [(match_dup 6) (match_dup 2)]
15612                               UNSPEC_FPATAN))
15613               (clobber (match_scratch:XF 8 ""))])
15614    (set (match_operand:DF 0 "register_operand" "")
15615         (float_truncate:DF (match_dup 7)))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15618    && flag_unsafe_math_optimizations"
15619 {
15620   int i;
15621
15622   for (i=2; i<8; i++)
15623     operands[i] = gen_reg_rtx (XFmode);
15624
15625   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15626 })
15627
15628 (define_expand "asinsf2"
15629   [(set (match_dup 2)
15630         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15631    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15632    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15633    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15634    (parallel [(set (match_dup 7)
15635                    (unspec:XF [(match_dup 6) (match_dup 2)]
15636                               UNSPEC_FPATAN))
15637               (clobber (match_scratch:XF 8 ""))])
15638    (set (match_operand:SF 0 "register_operand" "")
15639         (float_truncate:SF (match_dup 7)))]
15640   "TARGET_USE_FANCY_MATH_387
15641    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15642    && flag_unsafe_math_optimizations"
15643 {
15644   int i;
15645
15646   for (i=2; i<8; i++)
15647     operands[i] = gen_reg_rtx (XFmode);
15648
15649   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15650 })
15651
15652 (define_expand "asinxf2"
15653   [(set (match_dup 2)
15654         (mult:XF (match_operand:XF 1 "register_operand" "")
15655                  (match_dup 1)))
15656    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15657    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15658    (parallel [(set (match_operand:XF 0 "register_operand" "")
15659                    (unspec:XF [(match_dup 5) (match_dup 1)]
15660                               UNSPEC_FPATAN))
15661               (clobber (match_scratch:XF 6 ""))])]
15662   "TARGET_USE_FANCY_MATH_387
15663    && flag_unsafe_math_optimizations"
15664 {
15665   int i;
15666
15667   for (i=2; i<6; i++)
15668     operands[i] = gen_reg_rtx (XFmode);
15669
15670   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15671 })
15672
15673 (define_expand "acosdf2"
15674   [(set (match_dup 2)
15675         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15676    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15677    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15678    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15679    (parallel [(set (match_dup 7)
15680                    (unspec:XF [(match_dup 2) (match_dup 6)]
15681                               UNSPEC_FPATAN))
15682               (clobber (match_scratch:XF 8 ""))])
15683    (set (match_operand:DF 0 "register_operand" "")
15684         (float_truncate:DF (match_dup 7)))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15687    && flag_unsafe_math_optimizations"
15688 {
15689   int i;
15690
15691   for (i=2; i<8; i++)
15692     operands[i] = gen_reg_rtx (XFmode);
15693
15694   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15695 })
15696
15697 (define_expand "acossf2"
15698   [(set (match_dup 2)
15699         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15700    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15701    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15702    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15703    (parallel [(set (match_dup 7)
15704                    (unspec:XF [(match_dup 2) (match_dup 6)]
15705                               UNSPEC_FPATAN))
15706               (clobber (match_scratch:XF 8 ""))])
15707    (set (match_operand:SF 0 "register_operand" "")
15708         (float_truncate:SF (match_dup 7)))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15712 {
15713   int i;
15714
15715   for (i=2; i<8; i++)
15716     operands[i] = gen_reg_rtx (XFmode);
15717
15718   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15719 })
15720
15721 (define_expand "acosxf2"
15722   [(set (match_dup 2)
15723         (mult:XF (match_operand:XF 1 "register_operand" "")
15724                  (match_dup 1)))
15725    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15726    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15727    (parallel [(set (match_operand:XF 0 "register_operand" "")
15728                    (unspec:XF [(match_dup 1) (match_dup 5)]
15729                               UNSPEC_FPATAN))
15730               (clobber (match_scratch:XF 6 ""))])]
15731   "TARGET_USE_FANCY_MATH_387
15732    && flag_unsafe_math_optimizations"
15733 {
15734   int i;
15735
15736   for (i=2; i<6; i++)
15737     operands[i] = gen_reg_rtx (XFmode);
15738
15739   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15740 })
15741
15742 (define_insn "fyl2x_xf3"
15743   [(set (match_operand:XF 0 "register_operand" "=f")
15744         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745                     (match_operand:XF 1 "register_operand" "u")]
15746                    UNSPEC_FYL2X))
15747    (clobber (match_scratch:XF 3 "=1"))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && flag_unsafe_math_optimizations"
15750   "fyl2x"
15751   [(set_attr "type" "fpspc")
15752    (set_attr "mode" "XF")])
15753
15754 (define_expand "logsf2"
15755   [(set (match_dup 2)
15756         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15757    (parallel [(set (match_dup 4)
15758                    (unspec:XF [(match_dup 2)
15759                                (match_dup 3)] UNSPEC_FYL2X))
15760               (clobber (match_scratch:XF 5 ""))])
15761    (set (match_operand:SF 0 "register_operand" "")
15762         (float_truncate:SF (match_dup 4)))]
15763   "TARGET_USE_FANCY_MATH_387
15764    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15765    && flag_unsafe_math_optimizations"
15766 {
15767   rtx temp;
15768
15769   operands[2] = gen_reg_rtx (XFmode);
15770   operands[3] = gen_reg_rtx (XFmode);
15771   operands[4] = gen_reg_rtx (XFmode);
15772
15773   temp = standard_80387_constant_rtx (4); /* fldln2 */
15774   emit_move_insn (operands[3], temp);
15775 })
15776
15777 (define_expand "logdf2"
15778   [(set (match_dup 2)
15779         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15780    (parallel [(set (match_dup 4)
15781                    (unspec:XF [(match_dup 2)
15782                                (match_dup 3)] UNSPEC_FYL2X))
15783               (clobber (match_scratch:XF 5 ""))])
15784    (set (match_operand:DF 0 "register_operand" "")
15785         (float_truncate:DF (match_dup 4)))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15788    && flag_unsafe_math_optimizations"
15789 {
15790   rtx temp;
15791
15792   operands[2] = gen_reg_rtx (XFmode);
15793   operands[3] = gen_reg_rtx (XFmode);
15794   operands[4] = gen_reg_rtx (XFmode);
15795
15796   temp = standard_80387_constant_rtx (4); /* fldln2 */
15797   emit_move_insn (operands[3], temp);
15798 })
15799
15800 (define_expand "logxf2"
15801   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15803                                (match_dup 2)] UNSPEC_FYL2X))
15804               (clobber (match_scratch:XF 3 ""))])]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15807 {
15808   rtx temp;
15809
15810   operands[2] = gen_reg_rtx (XFmode);
15811   temp = standard_80387_constant_rtx (4); /* fldln2 */
15812   emit_move_insn (operands[2], temp);
15813 })
15814
15815 (define_expand "log10sf2"
15816   [(set (match_dup 2)
15817         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15818    (parallel [(set (match_dup 4)
15819                    (unspec:XF [(match_dup 2)
15820                                (match_dup 3)] UNSPEC_FYL2X))
15821               (clobber (match_scratch:XF 5 ""))])
15822    (set (match_operand:SF 0 "register_operand" "")
15823         (float_truncate:SF (match_dup 4)))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15826    && flag_unsafe_math_optimizations"
15827 {
15828   rtx temp;
15829
15830   operands[2] = gen_reg_rtx (XFmode);
15831   operands[3] = gen_reg_rtx (XFmode);
15832   operands[4] = gen_reg_rtx (XFmode);
15833
15834   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15835   emit_move_insn (operands[3], temp);
15836 })
15837
15838 (define_expand "log10df2"
15839   [(set (match_dup 2)
15840         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15841    (parallel [(set (match_dup 4)
15842                    (unspec:XF [(match_dup 2)
15843                                (match_dup 3)] UNSPEC_FYL2X))
15844               (clobber (match_scratch:XF 5 ""))])
15845    (set (match_operand:DF 0 "register_operand" "")
15846         (float_truncate:DF (match_dup 4)))]
15847   "TARGET_USE_FANCY_MATH_387
15848    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15849    && flag_unsafe_math_optimizations"
15850 {
15851   rtx temp;
15852
15853   operands[2] = gen_reg_rtx (XFmode);
15854   operands[3] = gen_reg_rtx (XFmode);
15855   operands[4] = gen_reg_rtx (XFmode);
15856
15857   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15858   emit_move_insn (operands[3], temp);
15859 })
15860
15861 (define_expand "log10xf2"
15862   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15863                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15864                                (match_dup 2)] UNSPEC_FYL2X))
15865               (clobber (match_scratch:XF 3 ""))])]
15866   "TARGET_USE_FANCY_MATH_387
15867    && flag_unsafe_math_optimizations"
15868 {
15869   rtx temp;
15870
15871   operands[2] = gen_reg_rtx (XFmode);
15872   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15873   emit_move_insn (operands[2], temp);
15874 })
15875
15876 (define_expand "log2sf2"
15877   [(set (match_dup 2)
15878         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879    (parallel [(set (match_dup 4)
15880                    (unspec:XF [(match_dup 2)
15881                                (match_dup 3)] UNSPEC_FYL2X))
15882               (clobber (match_scratch:XF 5 ""))])
15883    (set (match_operand:SF 0 "register_operand" "")
15884         (float_truncate:SF (match_dup 4)))]
15885   "TARGET_USE_FANCY_MATH_387
15886    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887    && flag_unsafe_math_optimizations"
15888 {
15889   operands[2] = gen_reg_rtx (XFmode);
15890   operands[3] = gen_reg_rtx (XFmode);
15891   operands[4] = gen_reg_rtx (XFmode);
15892
15893   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15894 })
15895
15896 (define_expand "log2df2"
15897   [(set (match_dup 2)
15898         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15899    (parallel [(set (match_dup 4)
15900                    (unspec:XF [(match_dup 2)
15901                                (match_dup 3)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 5 ""))])
15903    (set (match_operand:DF 0 "register_operand" "")
15904         (float_truncate:DF (match_dup 4)))]
15905   "TARGET_USE_FANCY_MATH_387
15906    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15907    && flag_unsafe_math_optimizations"
15908 {
15909   operands[2] = gen_reg_rtx (XFmode);
15910   operands[3] = gen_reg_rtx (XFmode);
15911   operands[4] = gen_reg_rtx (XFmode);
15912
15913   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15914 })
15915
15916 (define_expand "log2xf2"
15917   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15918                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15919                                (match_dup 2)] UNSPEC_FYL2X))
15920               (clobber (match_scratch:XF 3 ""))])]
15921   "TARGET_USE_FANCY_MATH_387
15922    && flag_unsafe_math_optimizations"
15923 {
15924   operands[2] = gen_reg_rtx (XFmode);
15925   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15926 })
15927
15928 (define_insn "fyl2xp1_xf3"
15929   [(set (match_operand:XF 0 "register_operand" "=f")
15930         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15931                     (match_operand:XF 1 "register_operand" "u")]
15932                    UNSPEC_FYL2XP1))
15933    (clobber (match_scratch:XF 3 "=1"))]
15934   "TARGET_USE_FANCY_MATH_387
15935    && flag_unsafe_math_optimizations"
15936   "fyl2xp1"
15937   [(set_attr "type" "fpspc")
15938    (set_attr "mode" "XF")])
15939
15940 (define_expand "log1psf2"
15941   [(use (match_operand:SF 0 "register_operand" ""))
15942    (use (match_operand:SF 1 "register_operand" ""))]
15943   "TARGET_USE_FANCY_MATH_387
15944    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945    && flag_unsafe_math_optimizations"
15946 {
15947   rtx op0 = gen_reg_rtx (XFmode);
15948   rtx op1 = gen_reg_rtx (XFmode);
15949
15950   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15951   ix86_emit_i387_log1p (op0, op1);
15952   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15953   DONE;
15954 })
15955
15956 (define_expand "log1pdf2"
15957   [(use (match_operand:DF 0 "register_operand" ""))
15958    (use (match_operand:DF 1 "register_operand" ""))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15961    && flag_unsafe_math_optimizations"
15962 {
15963   rtx op0 = gen_reg_rtx (XFmode);
15964   rtx op1 = gen_reg_rtx (XFmode);
15965
15966   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15967   ix86_emit_i387_log1p (op0, op1);
15968   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15969   DONE;
15970 })
15971
15972 (define_expand "log1pxf2"
15973   [(use (match_operand:XF 0 "register_operand" ""))
15974    (use (match_operand:XF 1 "register_operand" ""))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && flag_unsafe_math_optimizations"
15977 {
15978   ix86_emit_i387_log1p (operands[0], operands[1]);
15979   DONE;
15980 })
15981
15982 (define_insn "*fxtractxf3"
15983   [(set (match_operand:XF 0 "register_operand" "=f")
15984         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15985                    UNSPEC_XTRACT_FRACT))
15986    (set (match_operand:XF 1 "register_operand" "=u")
15987         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15988   "TARGET_USE_FANCY_MATH_387
15989    && flag_unsafe_math_optimizations"
15990   "fxtract"
15991   [(set_attr "type" "fpspc")
15992    (set_attr "mode" "XF")])
15993
15994 (define_expand "logbsf2"
15995   [(set (match_dup 2)
15996         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15997    (parallel [(set (match_dup 3)
15998                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15999               (set (match_dup 4)
16000                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16001    (set (match_operand:SF 0 "register_operand" "")
16002         (float_truncate:SF (match_dup 4)))]
16003   "TARGET_USE_FANCY_MATH_387
16004    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16006 {
16007   operands[2] = gen_reg_rtx (XFmode);
16008   operands[3] = gen_reg_rtx (XFmode);
16009   operands[4] = gen_reg_rtx (XFmode);
16010 })
16011
16012 (define_expand "logbdf2"
16013   [(set (match_dup 2)
16014         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16015    (parallel [(set (match_dup 3)
16016                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16017               (set (match_dup 4)
16018                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16019    (set (match_operand:DF 0 "register_operand" "")
16020         (float_truncate:DF (match_dup 4)))]
16021   "TARGET_USE_FANCY_MATH_387
16022    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16023    && flag_unsafe_math_optimizations"
16024 {
16025   operands[2] = gen_reg_rtx (XFmode);
16026   operands[3] = gen_reg_rtx (XFmode);
16027   operands[4] = gen_reg_rtx (XFmode);
16028 })
16029
16030 (define_expand "logbxf2"
16031   [(parallel [(set (match_dup 2)
16032                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16033                               UNSPEC_XTRACT_FRACT))
16034               (set (match_operand:XF 0 "register_operand" "")
16035                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16036   "TARGET_USE_FANCY_MATH_387
16037    && flag_unsafe_math_optimizations"
16038 {
16039   operands[2] = gen_reg_rtx (XFmode);
16040 })
16041
16042 (define_expand "ilogbsi2"
16043   [(parallel [(set (match_dup 2)
16044                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16045                               UNSPEC_XTRACT_FRACT))
16046               (set (match_operand:XF 3 "register_operand" "")
16047                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16048    (parallel [(set (match_operand:SI 0 "register_operand" "")
16049                    (fix:SI (match_dup 3)))
16050               (clobber (reg:CC FLAGS_REG))])]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054 {
16055   operands[2] = gen_reg_rtx (XFmode);
16056   operands[3] = gen_reg_rtx (XFmode);
16057 })
16058
16059 (define_insn "*f2xm1xf2"
16060   [(set (match_operand:XF 0 "register_operand" "=f")
16061         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16062          UNSPEC_F2XM1))]
16063   "TARGET_USE_FANCY_MATH_387
16064    && flag_unsafe_math_optimizations"
16065   "f2xm1"
16066   [(set_attr "type" "fpspc")
16067    (set_attr "mode" "XF")])
16068
16069 (define_insn "*fscalexf4"
16070   [(set (match_operand:XF 0 "register_operand" "=f")
16071         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16072                     (match_operand:XF 3 "register_operand" "1")]
16073                    UNSPEC_FSCALE_FRACT))
16074    (set (match_operand:XF 1 "register_operand" "=u")
16075         (unspec:XF [(match_dup 2) (match_dup 3)]
16076                    UNSPEC_FSCALE_EXP))]
16077   "TARGET_USE_FANCY_MATH_387
16078    && flag_unsafe_math_optimizations"
16079   "fscale"
16080   [(set_attr "type" "fpspc")
16081    (set_attr "mode" "XF")])
16082
16083 (define_expand "expsf2"
16084   [(set (match_dup 2)
16085         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16086    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16087    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16088    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16089    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16090    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16091    (parallel [(set (match_dup 10)
16092                    (unspec:XF [(match_dup 9) (match_dup 5)]
16093                               UNSPEC_FSCALE_FRACT))
16094               (set (match_dup 11)
16095                    (unspec:XF [(match_dup 9) (match_dup 5)]
16096                               UNSPEC_FSCALE_EXP))])
16097    (set (match_operand:SF 0 "register_operand" "")
16098         (float_truncate:SF (match_dup 10)))]
16099   "TARGET_USE_FANCY_MATH_387
16100    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16101    && flag_unsafe_math_optimizations"
16102 {
16103   rtx temp;
16104   int i;
16105
16106   for (i=2; i<12; i++)
16107     operands[i] = gen_reg_rtx (XFmode);
16108   temp = standard_80387_constant_rtx (5); /* fldl2e */
16109   emit_move_insn (operands[3], temp);
16110   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16111 })
16112
16113 (define_expand "expdf2"
16114   [(set (match_dup 2)
16115         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121    (parallel [(set (match_dup 10)
16122                    (unspec:XF [(match_dup 9) (match_dup 5)]
16123                               UNSPEC_FSCALE_FRACT))
16124               (set (match_dup 11)
16125                    (unspec:XF [(match_dup 9) (match_dup 5)]
16126                               UNSPEC_FSCALE_EXP))])
16127    (set (match_operand:DF 0 "register_operand" "")
16128         (float_truncate:DF (match_dup 10)))]
16129   "TARGET_USE_FANCY_MATH_387
16130    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16131    && flag_unsafe_math_optimizations"
16132 {
16133   rtx temp;
16134   int i;
16135
16136   for (i=2; i<12; i++)
16137     operands[i] = gen_reg_rtx (XFmode);
16138   temp = standard_80387_constant_rtx (5); /* fldl2e */
16139   emit_move_insn (operands[3], temp);
16140   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16141 })
16142
16143 (define_expand "expxf2"
16144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16145                                (match_dup 2)))
16146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16148    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16149    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16150    (parallel [(set (match_operand:XF 0 "register_operand" "")
16151                    (unspec:XF [(match_dup 8) (match_dup 4)]
16152                               UNSPEC_FSCALE_FRACT))
16153               (set (match_dup 9)
16154                    (unspec:XF [(match_dup 8) (match_dup 4)]
16155                               UNSPEC_FSCALE_EXP))])]
16156   "TARGET_USE_FANCY_MATH_387
16157    && flag_unsafe_math_optimizations"
16158 {
16159   rtx temp;
16160   int i;
16161
16162   for (i=2; i<10; i++)
16163     operands[i] = gen_reg_rtx (XFmode);
16164   temp = standard_80387_constant_rtx (5); /* fldl2e */
16165   emit_move_insn (operands[2], temp);
16166   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16167 })
16168
16169 (define_expand "exp10sf2"
16170   [(set (match_dup 2)
16171         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16172    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16173    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16174    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16175    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16176    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16177    (parallel [(set (match_dup 10)
16178                    (unspec:XF [(match_dup 9) (match_dup 5)]
16179                               UNSPEC_FSCALE_FRACT))
16180               (set (match_dup 11)
16181                    (unspec:XF [(match_dup 9) (match_dup 5)]
16182                               UNSPEC_FSCALE_EXP))])
16183    (set (match_operand:SF 0 "register_operand" "")
16184         (float_truncate:SF (match_dup 10)))]
16185   "TARGET_USE_FANCY_MATH_387
16186    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16187    && flag_unsafe_math_optimizations"
16188 {
16189   rtx temp;
16190   int i;
16191
16192   for (i=2; i<12; i++)
16193     operands[i] = gen_reg_rtx (XFmode);
16194   temp = standard_80387_constant_rtx (6); /* fldl2t */
16195   emit_move_insn (operands[3], temp);
16196   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16197 })
16198
16199 (define_expand "exp10df2"
16200   [(set (match_dup 2)
16201         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16202    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16203    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16204    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16205    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16206    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16207    (parallel [(set (match_dup 10)
16208                    (unspec:XF [(match_dup 9) (match_dup 5)]
16209                               UNSPEC_FSCALE_FRACT))
16210               (set (match_dup 11)
16211                    (unspec:XF [(match_dup 9) (match_dup 5)]
16212                               UNSPEC_FSCALE_EXP))])
16213    (set (match_operand:DF 0 "register_operand" "")
16214         (float_truncate:DF (match_dup 10)))]
16215   "TARGET_USE_FANCY_MATH_387
16216    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16217    && flag_unsafe_math_optimizations"
16218 {
16219   rtx temp;
16220   int i;
16221
16222   for (i=2; i<12; i++)
16223     operands[i] = gen_reg_rtx (XFmode);
16224   temp = standard_80387_constant_rtx (6); /* fldl2t */
16225   emit_move_insn (operands[3], temp);
16226   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16227 })
16228
16229 (define_expand "exp10xf2"
16230   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16231                                (match_dup 2)))
16232    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236    (parallel [(set (match_operand:XF 0 "register_operand" "")
16237                    (unspec:XF [(match_dup 8) (match_dup 4)]
16238                               UNSPEC_FSCALE_FRACT))
16239               (set (match_dup 9)
16240                    (unspec:XF [(match_dup 8) (match_dup 4)]
16241                               UNSPEC_FSCALE_EXP))])]
16242   "TARGET_USE_FANCY_MATH_387
16243    && flag_unsafe_math_optimizations"
16244 {
16245   rtx temp;
16246   int i;
16247
16248   for (i=2; i<10; i++)
16249     operands[i] = gen_reg_rtx (XFmode);
16250   temp = standard_80387_constant_rtx (6); /* fldl2t */
16251   emit_move_insn (operands[2], temp);
16252   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16253 })
16254
16255 (define_expand "exp2sf2"
16256   [(set (match_dup 2)
16257         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16258    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16259    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16260    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16261    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16262    (parallel [(set (match_dup 8)
16263                    (unspec:XF [(match_dup 7) (match_dup 3)]
16264                               UNSPEC_FSCALE_FRACT))
16265               (set (match_dup 9)
16266                    (unspec:XF [(match_dup 7) (match_dup 3)]
16267                               UNSPEC_FSCALE_EXP))])
16268    (set (match_operand:SF 0 "register_operand" "")
16269         (float_truncate:SF (match_dup 8)))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16272    && flag_unsafe_math_optimizations"
16273 {
16274   int i;
16275
16276   for (i=2; i<10; i++)
16277     operands[i] = gen_reg_rtx (XFmode);
16278   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16279 })
16280
16281 (define_expand "exp2df2"
16282   [(set (match_dup 2)
16283         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16284    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16285    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16286    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16287    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16288    (parallel [(set (match_dup 8)
16289                    (unspec:XF [(match_dup 7) (match_dup 3)]
16290                               UNSPEC_FSCALE_FRACT))
16291               (set (match_dup 9)
16292                    (unspec:XF [(match_dup 7) (match_dup 3)]
16293                               UNSPEC_FSCALE_EXP))])
16294    (set (match_operand:DF 0 "register_operand" "")
16295         (float_truncate:DF (match_dup 8)))]
16296   "TARGET_USE_FANCY_MATH_387
16297    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298    && flag_unsafe_math_optimizations"
16299 {
16300   int i;
16301
16302   for (i=2; i<10; i++)
16303     operands[i] = gen_reg_rtx (XFmode);
16304   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16305 })
16306
16307 (define_expand "exp2xf2"
16308   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16309    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16310    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16311    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16312    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16313    (parallel [(set (match_operand:XF 0 "register_operand" "")
16314                    (unspec:XF [(match_dup 7) (match_dup 3)]
16315                               UNSPEC_FSCALE_FRACT))
16316               (set (match_dup 8)
16317                    (unspec:XF [(match_dup 7) (match_dup 3)]
16318                               UNSPEC_FSCALE_EXP))])]
16319   "TARGET_USE_FANCY_MATH_387
16320    && flag_unsafe_math_optimizations"
16321 {
16322   int i;
16323
16324   for (i=2; i<9; i++)
16325     operands[i] = gen_reg_rtx (XFmode);
16326   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16327 })
16328
16329 (define_expand "expm1df2"
16330   [(set (match_dup 2)
16331         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16332    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16333    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16334    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16335    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16336    (parallel [(set (match_dup 8)
16337                    (unspec:XF [(match_dup 7) (match_dup 5)]
16338                               UNSPEC_FSCALE_FRACT))
16339                    (set (match_dup 9)
16340                    (unspec:XF [(match_dup 7) (match_dup 5)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (parallel [(set (match_dup 11)
16343                    (unspec:XF [(match_dup 10) (match_dup 9)]
16344                               UNSPEC_FSCALE_FRACT))
16345               (set (match_dup 12)
16346                    (unspec:XF [(match_dup 10) (match_dup 9)]
16347                               UNSPEC_FSCALE_EXP))])
16348    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16349    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16350    (set (match_operand:DF 0 "register_operand" "")
16351         (float_truncate:DF (match_dup 14)))]
16352   "TARGET_USE_FANCY_MATH_387
16353    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16354    && flag_unsafe_math_optimizations"
16355 {
16356   rtx temp;
16357   int i;
16358
16359   for (i=2; i<15; i++)
16360     operands[i] = gen_reg_rtx (XFmode);
16361   temp = standard_80387_constant_rtx (5); /* fldl2e */
16362   emit_move_insn (operands[3], temp);
16363   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16364 })
16365
16366 (define_expand "expm1sf2"
16367   [(set (match_dup 2)
16368         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16369    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16370    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16371    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16372    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16373    (parallel [(set (match_dup 8)
16374                    (unspec:XF [(match_dup 7) (match_dup 5)]
16375                               UNSPEC_FSCALE_FRACT))
16376                    (set (match_dup 9)
16377                    (unspec:XF [(match_dup 7) (match_dup 5)]
16378                               UNSPEC_FSCALE_EXP))])
16379    (parallel [(set (match_dup 11)
16380                    (unspec:XF [(match_dup 10) (match_dup 9)]
16381                               UNSPEC_FSCALE_FRACT))
16382               (set (match_dup 12)
16383                    (unspec:XF [(match_dup 10) (match_dup 9)]
16384                               UNSPEC_FSCALE_EXP))])
16385    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16386    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16387    (set (match_operand:SF 0 "register_operand" "")
16388         (float_truncate:SF (match_dup 14)))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391    && flag_unsafe_math_optimizations"
16392 {
16393   rtx temp;
16394   int i;
16395
16396   for (i=2; i<15; i++)
16397     operands[i] = gen_reg_rtx (XFmode);
16398   temp = standard_80387_constant_rtx (5); /* fldl2e */
16399   emit_move_insn (operands[3], temp);
16400   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16401 })
16402
16403 (define_expand "expm1xf2"
16404   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16405                                (match_dup 2)))
16406    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16407    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16408    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16409    (parallel [(set (match_dup 7)
16410                    (unspec:XF [(match_dup 6) (match_dup 4)]
16411                               UNSPEC_FSCALE_FRACT))
16412                    (set (match_dup 8)
16413                    (unspec:XF [(match_dup 6) (match_dup 4)]
16414                               UNSPEC_FSCALE_EXP))])
16415    (parallel [(set (match_dup 10)
16416                    (unspec:XF [(match_dup 9) (match_dup 8)]
16417                               UNSPEC_FSCALE_FRACT))
16418               (set (match_dup 11)
16419                    (unspec:XF [(match_dup 9) (match_dup 8)]
16420                               UNSPEC_FSCALE_EXP))])
16421    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16422    (set (match_operand:XF 0 "register_operand" "")
16423         (plus:XF (match_dup 12) (match_dup 7)))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && flag_unsafe_math_optimizations"
16426 {
16427   rtx temp;
16428   int i;
16429
16430   for (i=2; i<13; i++)
16431     operands[i] = gen_reg_rtx (XFmode);
16432   temp = standard_80387_constant_rtx (5); /* fldl2e */
16433   emit_move_insn (operands[2], temp);
16434   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16435 })
16436
16437 (define_expand "ldexpdf3"
16438   [(set (match_dup 3)
16439         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16440    (set (match_dup 4)
16441         (float:XF (match_operand:SI 2 "register_operand" "")))
16442    (parallel [(set (match_dup 5)
16443                    (unspec:XF [(match_dup 3) (match_dup 4)]
16444                               UNSPEC_FSCALE_FRACT))
16445               (set (match_dup 6)
16446                    (unspec:XF [(match_dup 3) (match_dup 4)]
16447                               UNSPEC_FSCALE_EXP))])
16448    (set (match_operand:DF 0 "register_operand" "")
16449         (float_truncate:DF (match_dup 5)))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16452    && flag_unsafe_math_optimizations"
16453 {
16454   int i;
16455
16456   for (i=3; i<7; i++)
16457     operands[i] = gen_reg_rtx (XFmode);
16458 })
16459
16460 (define_expand "ldexpsf3"
16461   [(set (match_dup 3)
16462         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16463    (set (match_dup 4)
16464         (float:XF (match_operand:SI 2 "register_operand" "")))
16465    (parallel [(set (match_dup 5)
16466                    (unspec:XF [(match_dup 3) (match_dup 4)]
16467                               UNSPEC_FSCALE_FRACT))
16468               (set (match_dup 6)
16469                    (unspec:XF [(match_dup 3) (match_dup 4)]
16470                               UNSPEC_FSCALE_EXP))])
16471    (set (match_operand:SF 0 "register_operand" "")
16472         (float_truncate:SF (match_dup 5)))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16476 {
16477   int i;
16478
16479   for (i=3; i<7; i++)
16480     operands[i] = gen_reg_rtx (XFmode);
16481 })
16482
16483 (define_expand "ldexpxf3"
16484   [(set (match_dup 3)
16485         (float:XF (match_operand:SI 2 "register_operand" "")))
16486    (parallel [(set (match_operand:XF 0 " register_operand" "")
16487                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16488                                (match_dup 3)]
16489                               UNSPEC_FSCALE_FRACT))
16490               (set (match_dup 4)
16491                    (unspec:XF [(match_dup 1) (match_dup 3)]
16492                               UNSPEC_FSCALE_EXP))])]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations"
16495 {
16496   int i;
16497
16498   for (i=3; i<5; i++)
16499     operands[i] = gen_reg_rtx (XFmode);
16500 })
16501 \f
16502
16503 (define_insn "frndintxf2"
16504   [(set (match_operand:XF 0 "register_operand" "=f")
16505         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16506          UNSPEC_FRNDINT))]
16507   "TARGET_USE_FANCY_MATH_387
16508    && flag_unsafe_math_optimizations"
16509   "frndint"
16510   [(set_attr "type" "fpspc")
16511    (set_attr "mode" "XF")])
16512
16513 (define_expand "rintdf2"
16514   [(use (match_operand:DF 0 "register_operand" ""))
16515    (use (match_operand:DF 1 "register_operand" ""))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518    && flag_unsafe_math_optimizations"
16519 {
16520   rtx op0 = gen_reg_rtx (XFmode);
16521   rtx op1 = gen_reg_rtx (XFmode);
16522
16523   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16524   emit_insn (gen_frndintxf2 (op0, op1));
16525
16526   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16527   DONE;
16528 })
16529
16530 (define_expand "rintsf2"
16531   [(use (match_operand:SF 0 "register_operand" ""))
16532    (use (match_operand:SF 1 "register_operand" ""))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16535    && flag_unsafe_math_optimizations"
16536 {
16537   rtx op0 = gen_reg_rtx (XFmode);
16538   rtx op1 = gen_reg_rtx (XFmode);
16539
16540   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16541   emit_insn (gen_frndintxf2 (op0, op1));
16542
16543   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16544   DONE;
16545 })
16546
16547 (define_expand "rintxf2"
16548   [(use (match_operand:XF 0 "register_operand" ""))
16549    (use (match_operand:XF 1 "register_operand" ""))]
16550   "TARGET_USE_FANCY_MATH_387
16551    && flag_unsafe_math_optimizations"
16552 {
16553   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16554   DONE;
16555 })
16556
16557 (define_insn_and_split "*fistdi2_1"
16558   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16559         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16560          UNSPEC_FIST))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && flag_unsafe_math_optimizations
16563    && !(reload_completed || reload_in_progress)"
16564   "#"
16565   "&& 1"
16566   [(const_int 0)]
16567 {
16568   if (memory_operand (operands[0], VOIDmode))
16569     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16570   else
16571     {
16572       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16573       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16574                                          operands[2]));
16575     }
16576   DONE;
16577 }
16578   [(set_attr "type" "fpspc")
16579    (set_attr "mode" "DI")])
16580
16581 (define_insn "fistdi2"
16582   [(set (match_operand:DI 0 "memory_operand" "=m")
16583         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16584          UNSPEC_FIST))
16585    (clobber (match_scratch:XF 2 "=&1f"))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations"
16588   "* return output_fix_trunc (insn, operands, 0);"
16589   [(set_attr "type" "fpspc")
16590    (set_attr "mode" "DI")])
16591
16592 (define_insn "fistdi2_with_temp"
16593   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16594         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16595          UNSPEC_FIST))
16596    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16597    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && flag_unsafe_math_optimizations"
16600   "#"
16601   [(set_attr "type" "fpspc")
16602    (set_attr "mode" "DI")])
16603
16604 (define_split 
16605   [(set (match_operand:DI 0 "register_operand" "")
16606         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16607          UNSPEC_FIST))
16608    (clobber (match_operand:DI 2 "memory_operand" ""))
16609    (clobber (match_scratch 3 ""))]
16610   "reload_completed"
16611   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16612               (clobber (match_dup 3))])
16613    (set (match_dup 0) (match_dup 2))]
16614   "")
16615
16616 (define_split 
16617   [(set (match_operand:DI 0 "memory_operand" "")
16618         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16619          UNSPEC_FIST))
16620    (clobber (match_operand:DI 2 "memory_operand" ""))
16621    (clobber (match_scratch 3 ""))]
16622   "reload_completed"
16623   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16624               (clobber (match_dup 3))])]
16625   "")
16626
16627 (define_insn_and_split "*fist<mode>2_1"
16628   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16629         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16630          UNSPEC_FIST))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && flag_unsafe_math_optimizations
16633    && !(reload_completed || reload_in_progress)"
16634   "#"
16635   "&& 1"
16636   [(const_int 0)]
16637 {
16638   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16639   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16640                                         operands[2]));
16641   DONE;
16642 }
16643   [(set_attr "type" "fpspc")
16644    (set_attr "mode" "<MODE>")])
16645
16646 (define_insn "fist<mode>2"
16647   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16648         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16649          UNSPEC_FIST))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && flag_unsafe_math_optimizations"
16652   "* return output_fix_trunc (insn, operands, 0);"
16653   [(set_attr "type" "fpspc")
16654    (set_attr "mode" "<MODE>")])
16655
16656 (define_insn "fist<mode>2_with_temp"
16657   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16658         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16659          UNSPEC_FIST))
16660    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663   "#"
16664   [(set_attr "type" "fpspc")
16665    (set_attr "mode" "<MODE>")])
16666
16667 (define_split 
16668   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16669         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16670          UNSPEC_FIST))
16671    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16672   "reload_completed"
16673   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16674                        UNSPEC_FIST))
16675    (set (match_dup 0) (match_dup 2))]
16676   "")
16677
16678 (define_split 
16679   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16681          UNSPEC_FIST))
16682    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16683   "reload_completed"
16684   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16685                        UNSPEC_FIST))]
16686   "")
16687
16688 (define_expand "lrint<mode>2"
16689   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16690         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16691          UNSPEC_FIST))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16694    && flag_unsafe_math_optimizations"
16695   "")
16696
16697 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16698 (define_insn_and_split "frndintxf2_floor"
16699   [(set (match_operand:XF 0 "register_operand" "=f")
16700         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16701          UNSPEC_FRNDINT_FLOOR))
16702    (clobber (reg:CC FLAGS_REG))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && flag_unsafe_math_optimizations
16705    && !(reload_completed || reload_in_progress)"
16706   "#"
16707   "&& 1"
16708   [(const_int 0)]
16709 {
16710   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16711
16712   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16713   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16714
16715   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16716                                         operands[2], operands[3]));
16717   DONE;
16718 }
16719   [(set_attr "type" "frndint")
16720    (set_attr "i387_cw" "floor")
16721    (set_attr "mode" "XF")])
16722
16723 (define_insn "frndintxf2_floor_i387"
16724   [(set (match_operand:XF 0 "register_operand" "=f")
16725         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16726          UNSPEC_FRNDINT_FLOOR))
16727    (use (match_operand:HI 2 "memory_operand" "m"))
16728    (use (match_operand:HI 3 "memory_operand" "m"))]
16729   "TARGET_USE_FANCY_MATH_387
16730    && flag_unsafe_math_optimizations"
16731   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16732   [(set_attr "type" "frndint")
16733    (set_attr "i387_cw" "floor")
16734    (set_attr "mode" "XF")])
16735
16736 (define_expand "floorxf2"
16737   [(use (match_operand:XF 0 "register_operand" ""))
16738    (use (match_operand:XF 1 "register_operand" ""))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations"
16741 {
16742   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16743   DONE;
16744 })
16745
16746 (define_expand "floordf2"
16747   [(use (match_operand:DF 0 "register_operand" ""))
16748    (use (match_operand:DF 1 "register_operand" ""))]
16749   "TARGET_USE_FANCY_MATH_387
16750    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16751    && flag_unsafe_math_optimizations"
16752 {
16753   rtx op0 = gen_reg_rtx (XFmode);
16754   rtx op1 = gen_reg_rtx (XFmode);
16755
16756   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16757   emit_insn (gen_frndintxf2_floor (op0, op1));
16758
16759   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16760   DONE;
16761 })
16762
16763 (define_expand "floorsf2"
16764   [(use (match_operand:SF 0 "register_operand" ""))
16765    (use (match_operand:SF 1 "register_operand" ""))]
16766   "TARGET_USE_FANCY_MATH_387
16767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16768    && flag_unsafe_math_optimizations"
16769 {
16770   rtx op0 = gen_reg_rtx (XFmode);
16771   rtx op1 = gen_reg_rtx (XFmode);
16772
16773   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16774   emit_insn (gen_frndintxf2_floor (op0, op1));
16775
16776   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16777   DONE;
16778 })
16779
16780 (define_insn_and_split "*fist<mode>2_floor_1"
16781   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16782         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16783          UNSPEC_FIST_FLOOR))
16784    (clobber (reg:CC FLAGS_REG))]
16785   "TARGET_USE_FANCY_MATH_387
16786    && flag_unsafe_math_optimizations
16787    && !(reload_completed || reload_in_progress)"
16788   "#"
16789   "&& 1"
16790   [(const_int 0)]
16791 {
16792   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16793
16794   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16795   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16796   if (memory_operand (operands[0], VOIDmode))
16797     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16798                                       operands[2], operands[3]));
16799   else
16800     {
16801       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16802       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16803                                                   operands[2], operands[3],
16804                                                   operands[4]));
16805     }
16806   DONE;
16807 }
16808   [(set_attr "type" "fistp")
16809    (set_attr "i387_cw" "floor")
16810    (set_attr "mode" "<MODE>")])
16811
16812 (define_insn "fistdi2_floor"
16813   [(set (match_operand:DI 0 "memory_operand" "=m")
16814         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16815          UNSPEC_FIST_FLOOR))
16816    (use (match_operand:HI 2 "memory_operand" "m"))
16817    (use (match_operand:HI 3 "memory_operand" "m"))
16818    (clobber (match_scratch:XF 4 "=&1f"))]
16819   "TARGET_USE_FANCY_MATH_387
16820    && flag_unsafe_math_optimizations"
16821   "* return output_fix_trunc (insn, operands, 0);"
16822   [(set_attr "type" "fistp")
16823    (set_attr "i387_cw" "floor")
16824    (set_attr "mode" "DI")])
16825
16826 (define_insn "fistdi2_floor_with_temp"
16827   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16828         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16829          UNSPEC_FIST_FLOOR))
16830    (use (match_operand:HI 2 "memory_operand" "m,m"))
16831    (use (match_operand:HI 3 "memory_operand" "m,m"))
16832    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16833    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16834   "TARGET_USE_FANCY_MATH_387
16835    && flag_unsafe_math_optimizations"
16836   "#"
16837   [(set_attr "type" "fistp")
16838    (set_attr "i387_cw" "floor")
16839    (set_attr "mode" "DI")])
16840
16841 (define_split 
16842   [(set (match_operand:DI 0 "register_operand" "")
16843         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16844          UNSPEC_FIST_FLOOR))
16845    (use (match_operand:HI 2 "memory_operand" ""))
16846    (use (match_operand:HI 3 "memory_operand" ""))
16847    (clobber (match_operand:DI 4 "memory_operand" ""))
16848    (clobber (match_scratch 5 ""))]
16849   "reload_completed"
16850   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16851               (use (match_dup 2))
16852               (use (match_dup 3))
16853               (clobber (match_dup 5))])
16854    (set (match_dup 0) (match_dup 4))]
16855   "")
16856
16857 (define_split 
16858   [(set (match_operand:DI 0 "memory_operand" "")
16859         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16860          UNSPEC_FIST_FLOOR))
16861    (use (match_operand:HI 2 "memory_operand" ""))
16862    (use (match_operand:HI 3 "memory_operand" ""))
16863    (clobber (match_operand:DI 4 "memory_operand" ""))
16864    (clobber (match_scratch 5 ""))]
16865   "reload_completed"
16866   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16867               (use (match_dup 2))
16868               (use (match_dup 3))
16869               (clobber (match_dup 5))])]
16870   "")
16871
16872 (define_insn "fist<mode>2_floor"
16873   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16874         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16875          UNSPEC_FIST_FLOOR))
16876    (use (match_operand:HI 2 "memory_operand" "m"))
16877    (use (match_operand:HI 3 "memory_operand" "m"))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && flag_unsafe_math_optimizations"
16880   "* return output_fix_trunc (insn, operands, 0);"
16881   [(set_attr "type" "fistp")
16882    (set_attr "i387_cw" "floor")
16883    (set_attr "mode" "<MODE>")])
16884
16885 (define_insn "fist<mode>2_floor_with_temp"
16886   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16887         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16888          UNSPEC_FIST_FLOOR))
16889    (use (match_operand:HI 2 "memory_operand" "m,m"))
16890    (use (match_operand:HI 3 "memory_operand" "m,m"))
16891    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16892   "TARGET_USE_FANCY_MATH_387
16893    && flag_unsafe_math_optimizations"
16894   "#"
16895   [(set_attr "type" "fistp")
16896    (set_attr "i387_cw" "floor")
16897    (set_attr "mode" "<MODE>")])
16898
16899 (define_split 
16900   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16901         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16902          UNSPEC_FIST_FLOOR))
16903    (use (match_operand:HI 2 "memory_operand" ""))
16904    (use (match_operand:HI 3 "memory_operand" ""))
16905    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16906   "reload_completed"
16907   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16908                                   UNSPEC_FIST_FLOOR))
16909               (use (match_dup 2))
16910               (use (match_dup 3))])
16911    (set (match_dup 0) (match_dup 4))]
16912   "")
16913
16914 (define_split 
16915   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16916         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16917          UNSPEC_FIST_FLOOR))
16918    (use (match_operand:HI 2 "memory_operand" ""))
16919    (use (match_operand:HI 3 "memory_operand" ""))
16920    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16921   "reload_completed"
16922   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16923                                   UNSPEC_FIST_FLOOR))
16924               (use (match_dup 2))
16925               (use (match_dup 3))])]
16926   "")
16927
16928 (define_expand "lfloor<mode>2"
16929   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16930                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16931                     UNSPEC_FIST_FLOOR))
16932               (clobber (reg:CC FLAGS_REG))])]
16933   "TARGET_USE_FANCY_MATH_387
16934    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16935    && flag_unsafe_math_optimizations"
16936   "")
16937
16938 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16939 (define_insn_and_split "frndintxf2_ceil"
16940   [(set (match_operand:XF 0 "register_operand" "=f")
16941         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16942          UNSPEC_FRNDINT_CEIL))
16943    (clobber (reg:CC FLAGS_REG))]
16944   "TARGET_USE_FANCY_MATH_387
16945    && flag_unsafe_math_optimizations
16946    && !(reload_completed || reload_in_progress)"
16947   "#"
16948   "&& 1"
16949   [(const_int 0)]
16950 {
16951   ix86_optimize_mode_switching[I387_CEIL] = 1;
16952
16953   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16954   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16955
16956   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16957                                        operands[2], operands[3]));
16958   DONE;
16959 }
16960   [(set_attr "type" "frndint")
16961    (set_attr "i387_cw" "ceil")
16962    (set_attr "mode" "XF")])
16963
16964 (define_insn "frndintxf2_ceil_i387"
16965   [(set (match_operand:XF 0 "register_operand" "=f")
16966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16967          UNSPEC_FRNDINT_CEIL))
16968    (use (match_operand:HI 2 "memory_operand" "m"))
16969    (use (match_operand:HI 3 "memory_operand" "m"))]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations"
16972   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16973   [(set_attr "type" "frndint")
16974    (set_attr "i387_cw" "ceil")
16975    (set_attr "mode" "XF")])
16976
16977 (define_expand "ceilxf2"
16978   [(use (match_operand:XF 0 "register_operand" ""))
16979    (use (match_operand:XF 1 "register_operand" ""))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && flag_unsafe_math_optimizations"
16982 {
16983   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16984   DONE;
16985 })
16986
16987 (define_expand "ceildf2"
16988   [(use (match_operand:DF 0 "register_operand" ""))
16989    (use (match_operand:DF 1 "register_operand" ""))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16992    && flag_unsafe_math_optimizations"
16993 {
16994   rtx op0 = gen_reg_rtx (XFmode);
16995   rtx op1 = gen_reg_rtx (XFmode);
16996
16997   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16998   emit_insn (gen_frndintxf2_ceil (op0, op1));
16999
17000   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17001   DONE;
17002 })
17003
17004 (define_expand "ceilsf2"
17005   [(use (match_operand:SF 0 "register_operand" ""))
17006    (use (match_operand:SF 1 "register_operand" ""))]
17007   "TARGET_USE_FANCY_MATH_387
17008    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17009    && flag_unsafe_math_optimizations"
17010 {
17011   rtx op0 = gen_reg_rtx (XFmode);
17012   rtx op1 = gen_reg_rtx (XFmode);
17013
17014   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17015   emit_insn (gen_frndintxf2_ceil (op0, op1));
17016
17017   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17018   DONE;
17019 })
17020
17021 (define_insn_and_split "*fist<mode>2_ceil_1"
17022   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17023         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17024          UNSPEC_FIST_CEIL))
17025    (clobber (reg:CC FLAGS_REG))]
17026   "TARGET_USE_FANCY_MATH_387
17027    && flag_unsafe_math_optimizations
17028    && !(reload_completed || reload_in_progress)"
17029   "#"
17030   "&& 1"
17031   [(const_int 0)]
17032 {
17033   ix86_optimize_mode_switching[I387_CEIL] = 1;
17034
17035   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17036   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17037   if (memory_operand (operands[0], VOIDmode))
17038     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17039                                      operands[2], operands[3]));
17040   else
17041     {
17042       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17043       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17044                                                  operands[2], operands[3],
17045                                                  operands[4]));
17046     }
17047   DONE;
17048 }
17049   [(set_attr "type" "fistp")
17050    (set_attr "i387_cw" "ceil")
17051    (set_attr "mode" "<MODE>")])
17052
17053 (define_insn "fistdi2_ceil"
17054   [(set (match_operand:DI 0 "memory_operand" "=m")
17055         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17056          UNSPEC_FIST_CEIL))
17057    (use (match_operand:HI 2 "memory_operand" "m"))
17058    (use (match_operand:HI 3 "memory_operand" "m"))
17059    (clobber (match_scratch:XF 4 "=&1f"))]
17060   "TARGET_USE_FANCY_MATH_387
17061    && flag_unsafe_math_optimizations"
17062   "* return output_fix_trunc (insn, operands, 0);"
17063   [(set_attr "type" "fistp")
17064    (set_attr "i387_cw" "ceil")
17065    (set_attr "mode" "DI")])
17066
17067 (define_insn "fistdi2_ceil_with_temp"
17068   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17069         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17070          UNSPEC_FIST_CEIL))
17071    (use (match_operand:HI 2 "memory_operand" "m,m"))
17072    (use (match_operand:HI 3 "memory_operand" "m,m"))
17073    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17074    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17075   "TARGET_USE_FANCY_MATH_387
17076    && flag_unsafe_math_optimizations"
17077   "#"
17078   [(set_attr "type" "fistp")
17079    (set_attr "i387_cw" "ceil")
17080    (set_attr "mode" "DI")])
17081
17082 (define_split 
17083   [(set (match_operand:DI 0 "register_operand" "")
17084         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17085          UNSPEC_FIST_CEIL))
17086    (use (match_operand:HI 2 "memory_operand" ""))
17087    (use (match_operand:HI 3 "memory_operand" ""))
17088    (clobber (match_operand:DI 4 "memory_operand" ""))
17089    (clobber (match_scratch 5 ""))]
17090   "reload_completed"
17091   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17092               (use (match_dup 2))
17093               (use (match_dup 3))
17094               (clobber (match_dup 5))])
17095    (set (match_dup 0) (match_dup 4))]
17096   "")
17097
17098 (define_split 
17099   [(set (match_operand:DI 0 "memory_operand" "")
17100         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17101          UNSPEC_FIST_CEIL))
17102    (use (match_operand:HI 2 "memory_operand" ""))
17103    (use (match_operand:HI 3 "memory_operand" ""))
17104    (clobber (match_operand:DI 4 "memory_operand" ""))
17105    (clobber (match_scratch 5 ""))]
17106   "reload_completed"
17107   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17108               (use (match_dup 2))
17109               (use (match_dup 3))
17110               (clobber (match_dup 5))])]
17111   "")
17112
17113 (define_insn "fist<mode>2_ceil"
17114   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17115         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17116          UNSPEC_FIST_CEIL))
17117    (use (match_operand:HI 2 "memory_operand" "m"))
17118    (use (match_operand:HI 3 "memory_operand" "m"))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && flag_unsafe_math_optimizations"
17121   "* return output_fix_trunc (insn, operands, 0);"
17122   [(set_attr "type" "fistp")
17123    (set_attr "i387_cw" "ceil")
17124    (set_attr "mode" "<MODE>")])
17125
17126 (define_insn "fist<mode>2_ceil_with_temp"
17127   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17128         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17129          UNSPEC_FIST_CEIL))
17130    (use (match_operand:HI 2 "memory_operand" "m,m"))
17131    (use (match_operand:HI 3 "memory_operand" "m,m"))
17132    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135   "#"
17136   [(set_attr "type" "fistp")
17137    (set_attr "i387_cw" "ceil")
17138    (set_attr "mode" "<MODE>")])
17139
17140 (define_split 
17141   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17142         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17143          UNSPEC_FIST_CEIL))
17144    (use (match_operand:HI 2 "memory_operand" ""))
17145    (use (match_operand:HI 3 "memory_operand" ""))
17146    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17147   "reload_completed"
17148   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17149                                   UNSPEC_FIST_CEIL))
17150               (use (match_dup 2))
17151               (use (match_dup 3))])
17152    (set (match_dup 0) (match_dup 4))]
17153   "")
17154
17155 (define_split 
17156   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17157         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17158          UNSPEC_FIST_CEIL))
17159    (use (match_operand:HI 2 "memory_operand" ""))
17160    (use (match_operand:HI 3 "memory_operand" ""))
17161    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17162   "reload_completed"
17163   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17164                                   UNSPEC_FIST_CEIL))
17165               (use (match_dup 2))
17166               (use (match_dup 3))])]
17167   "")
17168
17169 (define_expand "lceil<mode>2"
17170   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17171                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17172                     UNSPEC_FIST_CEIL))
17173               (clobber (reg:CC FLAGS_REG))])]
17174   "TARGET_USE_FANCY_MATH_387
17175    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17176    && flag_unsafe_math_optimizations"
17177   "")
17178
17179 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17180 (define_insn_and_split "frndintxf2_trunc"
17181   [(set (match_operand:XF 0 "register_operand" "=f")
17182         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17183          UNSPEC_FRNDINT_TRUNC))
17184    (clobber (reg:CC FLAGS_REG))]
17185   "TARGET_USE_FANCY_MATH_387
17186    && flag_unsafe_math_optimizations
17187    && !(reload_completed || reload_in_progress)"
17188   "#"
17189   "&& 1"
17190   [(const_int 0)]
17191 {
17192   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17193
17194   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17195   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17196
17197   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17198                                         operands[2], operands[3]));
17199   DONE;
17200 }
17201   [(set_attr "type" "frndint")
17202    (set_attr "i387_cw" "trunc")
17203    (set_attr "mode" "XF")])
17204
17205 (define_insn "frndintxf2_trunc_i387"
17206   [(set (match_operand:XF 0 "register_operand" "=f")
17207         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208          UNSPEC_FRNDINT_TRUNC))
17209    (use (match_operand:HI 2 "memory_operand" "m"))
17210    (use (match_operand:HI 3 "memory_operand" "m"))]
17211   "TARGET_USE_FANCY_MATH_387
17212    && flag_unsafe_math_optimizations"
17213   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17214   [(set_attr "type" "frndint")
17215    (set_attr "i387_cw" "trunc")
17216    (set_attr "mode" "XF")])
17217
17218 (define_expand "btruncxf2"
17219   [(use (match_operand:XF 0 "register_operand" ""))
17220    (use (match_operand:XF 1 "register_operand" ""))]
17221   "TARGET_USE_FANCY_MATH_387
17222    && flag_unsafe_math_optimizations"
17223 {
17224   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17225   DONE;
17226 })
17227
17228 (define_expand "btruncdf2"
17229   [(use (match_operand:DF 0 "register_operand" ""))
17230    (use (match_operand:DF 1 "register_operand" ""))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17233    && flag_unsafe_math_optimizations"
17234 {
17235   rtx op0 = gen_reg_rtx (XFmode);
17236   rtx op1 = gen_reg_rtx (XFmode);
17237
17238   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17239   emit_insn (gen_frndintxf2_trunc (op0, op1));
17240
17241   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17242   DONE;
17243 })
17244
17245 (define_expand "btruncsf2"
17246   [(use (match_operand:SF 0 "register_operand" ""))
17247    (use (match_operand:SF 1 "register_operand" ""))]
17248   "TARGET_USE_FANCY_MATH_387
17249    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17250    && flag_unsafe_math_optimizations"
17251 {
17252   rtx op0 = gen_reg_rtx (XFmode);
17253   rtx op1 = gen_reg_rtx (XFmode);
17254
17255   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17256   emit_insn (gen_frndintxf2_trunc (op0, op1));
17257
17258   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17259   DONE;
17260 })
17261
17262 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17263 (define_insn_and_split "frndintxf2_mask_pm"
17264   [(set (match_operand:XF 0 "register_operand" "=f")
17265         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17266          UNSPEC_FRNDINT_MASK_PM))
17267    (clobber (reg:CC FLAGS_REG))]
17268   "TARGET_USE_FANCY_MATH_387
17269    && flag_unsafe_math_optimizations
17270    && !(reload_completed || reload_in_progress)"
17271   "#"
17272   "&& 1"
17273   [(const_int 0)]
17274 {
17275   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17276
17277   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17278   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17279
17280   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17281                                           operands[2], operands[3]));
17282   DONE;
17283 }
17284   [(set_attr "type" "frndint")
17285    (set_attr "i387_cw" "mask_pm")
17286    (set_attr "mode" "XF")])
17287
17288 (define_insn "frndintxf2_mask_pm_i387"
17289   [(set (match_operand:XF 0 "register_operand" "=f")
17290         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17291          UNSPEC_FRNDINT_MASK_PM))
17292    (use (match_operand:HI 2 "memory_operand" "m"))
17293    (use (match_operand:HI 3 "memory_operand" "m"))]
17294   "TARGET_USE_FANCY_MATH_387
17295    && flag_unsafe_math_optimizations"
17296   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17297   [(set_attr "type" "frndint")
17298    (set_attr "i387_cw" "mask_pm")
17299    (set_attr "mode" "XF")])
17300
17301 (define_expand "nearbyintxf2"
17302   [(use (match_operand:XF 0 "register_operand" ""))
17303    (use (match_operand:XF 1 "register_operand" ""))]
17304   "TARGET_USE_FANCY_MATH_387
17305    && flag_unsafe_math_optimizations"
17306 {
17307   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17308
17309   DONE;
17310 })
17311
17312 (define_expand "nearbyintdf2"
17313   [(use (match_operand:DF 0 "register_operand" ""))
17314    (use (match_operand:DF 1 "register_operand" ""))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17317    && flag_unsafe_math_optimizations"
17318 {
17319   rtx op0 = gen_reg_rtx (XFmode);
17320   rtx op1 = gen_reg_rtx (XFmode);
17321
17322   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17323   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17324
17325   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17326   DONE;
17327 })
17328
17329 (define_expand "nearbyintsf2"
17330   [(use (match_operand:SF 0 "register_operand" ""))
17331    (use (match_operand:SF 1 "register_operand" ""))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334    && flag_unsafe_math_optimizations"
17335 {
17336   rtx op0 = gen_reg_rtx (XFmode);
17337   rtx op1 = gen_reg_rtx (XFmode);
17338
17339   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17340   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17341
17342   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17343   DONE;
17344 })
17345
17346 \f
17347 ;; Block operation instructions
17348
17349 (define_insn "cld"
17350  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17351  ""
17352  "cld"
17353   [(set_attr "type" "cld")])
17354
17355 (define_expand "movmemsi"
17356   [(use (match_operand:BLK 0 "memory_operand" ""))
17357    (use (match_operand:BLK 1 "memory_operand" ""))
17358    (use (match_operand:SI 2 "nonmemory_operand" ""))
17359    (use (match_operand:SI 3 "const_int_operand" ""))]
17360   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17361 {
17362  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17363    DONE;
17364  else
17365    FAIL;
17366 })
17367
17368 (define_expand "movmemdi"
17369   [(use (match_operand:BLK 0 "memory_operand" ""))
17370    (use (match_operand:BLK 1 "memory_operand" ""))
17371    (use (match_operand:DI 2 "nonmemory_operand" ""))
17372    (use (match_operand:DI 3 "const_int_operand" ""))]
17373   "TARGET_64BIT"
17374 {
17375  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17376    DONE;
17377  else
17378    FAIL;
17379 })
17380
17381 ;; Most CPUs don't like single string operations
17382 ;; Handle this case here to simplify previous expander.
17383
17384 (define_expand "strmov"
17385   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17386    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17387    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17388               (clobber (reg:CC FLAGS_REG))])
17389    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17390               (clobber (reg:CC FLAGS_REG))])]
17391   ""
17392 {
17393   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17394
17395   /* If .md ever supports :P for Pmode, these can be directly
17396      in the pattern above.  */
17397   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17398   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17399
17400   if (TARGET_SINGLE_STRINGOP || optimize_size)
17401     {
17402       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17403                                       operands[2], operands[3],
17404                                       operands[5], operands[6]));
17405       DONE;
17406     }
17407
17408   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17409 })
17410
17411 (define_expand "strmov_singleop"
17412   [(parallel [(set (match_operand 1 "memory_operand" "")
17413                    (match_operand 3 "memory_operand" ""))
17414               (set (match_operand 0 "register_operand" "")
17415                    (match_operand 4 "" ""))
17416               (set (match_operand 2 "register_operand" "")
17417                    (match_operand 5 "" ""))
17418               (use (reg:SI DIRFLAG_REG))])]
17419   "TARGET_SINGLE_STRINGOP || optimize_size"
17420   "")
17421
17422 (define_insn "*strmovdi_rex_1"
17423   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17424         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17425    (set (match_operand:DI 0 "register_operand" "=D")
17426         (plus:DI (match_dup 2)
17427                  (const_int 8)))
17428    (set (match_operand:DI 1 "register_operand" "=S")
17429         (plus:DI (match_dup 3)
17430                  (const_int 8)))
17431    (use (reg:SI DIRFLAG_REG))]
17432   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17433   "movsq"
17434   [(set_attr "type" "str")
17435    (set_attr "mode" "DI")
17436    (set_attr "memory" "both")])
17437
17438 (define_insn "*strmovsi_1"
17439   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17440         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17441    (set (match_operand:SI 0 "register_operand" "=D")
17442         (plus:SI (match_dup 2)
17443                  (const_int 4)))
17444    (set (match_operand:SI 1 "register_operand" "=S")
17445         (plus:SI (match_dup 3)
17446                  (const_int 4)))
17447    (use (reg:SI DIRFLAG_REG))]
17448   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17449   "{movsl|movsd}"
17450   [(set_attr "type" "str")
17451    (set_attr "mode" "SI")
17452    (set_attr "memory" "both")])
17453
17454 (define_insn "*strmovsi_rex_1"
17455   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17456         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17457    (set (match_operand:DI 0 "register_operand" "=D")
17458         (plus:DI (match_dup 2)
17459                  (const_int 4)))
17460    (set (match_operand:DI 1 "register_operand" "=S")
17461         (plus:DI (match_dup 3)
17462                  (const_int 4)))
17463    (use (reg:SI DIRFLAG_REG))]
17464   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17465   "{movsl|movsd}"
17466   [(set_attr "type" "str")
17467    (set_attr "mode" "SI")
17468    (set_attr "memory" "both")])
17469
17470 (define_insn "*strmovhi_1"
17471   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17472         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17473    (set (match_operand:SI 0 "register_operand" "=D")
17474         (plus:SI (match_dup 2)
17475                  (const_int 2)))
17476    (set (match_operand:SI 1 "register_operand" "=S")
17477         (plus:SI (match_dup 3)
17478                  (const_int 2)))
17479    (use (reg:SI DIRFLAG_REG))]
17480   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17481   "movsw"
17482   [(set_attr "type" "str")
17483    (set_attr "memory" "both")
17484    (set_attr "mode" "HI")])
17485
17486 (define_insn "*strmovhi_rex_1"
17487   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17488         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17489    (set (match_operand:DI 0 "register_operand" "=D")
17490         (plus:DI (match_dup 2)
17491                  (const_int 2)))
17492    (set (match_operand:DI 1 "register_operand" "=S")
17493         (plus:DI (match_dup 3)
17494                  (const_int 2)))
17495    (use (reg:SI DIRFLAG_REG))]
17496   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17497   "movsw"
17498   [(set_attr "type" "str")
17499    (set_attr "memory" "both")
17500    (set_attr "mode" "HI")])
17501
17502 (define_insn "*strmovqi_1"
17503   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17504         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17505    (set (match_operand:SI 0 "register_operand" "=D")
17506         (plus:SI (match_dup 2)
17507                  (const_int 1)))
17508    (set (match_operand:SI 1 "register_operand" "=S")
17509         (plus:SI (match_dup 3)
17510                  (const_int 1)))
17511    (use (reg:SI DIRFLAG_REG))]
17512   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17513   "movsb"
17514   [(set_attr "type" "str")
17515    (set_attr "memory" "both")
17516    (set_attr "mode" "QI")])
17517
17518 (define_insn "*strmovqi_rex_1"
17519   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17520         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17521    (set (match_operand:DI 0 "register_operand" "=D")
17522         (plus:DI (match_dup 2)
17523                  (const_int 1)))
17524    (set (match_operand:DI 1 "register_operand" "=S")
17525         (plus:DI (match_dup 3)
17526                  (const_int 1)))
17527    (use (reg:SI DIRFLAG_REG))]
17528   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17529   "movsb"
17530   [(set_attr "type" "str")
17531    (set_attr "memory" "both")
17532    (set_attr "mode" "QI")])
17533
17534 (define_expand "rep_mov"
17535   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17536               (set (match_operand 0 "register_operand" "")
17537                    (match_operand 5 "" ""))
17538               (set (match_operand 2 "register_operand" "")
17539                    (match_operand 6 "" ""))
17540               (set (match_operand 1 "memory_operand" "")
17541                    (match_operand 3 "memory_operand" ""))
17542               (use (match_dup 4))
17543               (use (reg:SI DIRFLAG_REG))])]
17544   ""
17545   "")
17546
17547 (define_insn "*rep_movdi_rex64"
17548   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17549    (set (match_operand:DI 0 "register_operand" "=D") 
17550         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17551                             (const_int 3))
17552                  (match_operand:DI 3 "register_operand" "0")))
17553    (set (match_operand:DI 1 "register_operand" "=S") 
17554         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17555                  (match_operand:DI 4 "register_operand" "1")))
17556    (set (mem:BLK (match_dup 3))
17557         (mem:BLK (match_dup 4)))
17558    (use (match_dup 5))
17559    (use (reg:SI DIRFLAG_REG))]
17560   "TARGET_64BIT"
17561   "{rep\;movsq|rep movsq}"
17562   [(set_attr "type" "str")
17563    (set_attr "prefix_rep" "1")
17564    (set_attr "memory" "both")
17565    (set_attr "mode" "DI")])
17566
17567 (define_insn "*rep_movsi"
17568   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17569    (set (match_operand:SI 0 "register_operand" "=D") 
17570         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17571                             (const_int 2))
17572                  (match_operand:SI 3 "register_operand" "0")))
17573    (set (match_operand:SI 1 "register_operand" "=S") 
17574         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17575                  (match_operand:SI 4 "register_operand" "1")))
17576    (set (mem:BLK (match_dup 3))
17577         (mem:BLK (match_dup 4)))
17578    (use (match_dup 5))
17579    (use (reg:SI DIRFLAG_REG))]
17580   "!TARGET_64BIT"
17581   "{rep\;movsl|rep movsd}"
17582   [(set_attr "type" "str")
17583    (set_attr "prefix_rep" "1")
17584    (set_attr "memory" "both")
17585    (set_attr "mode" "SI")])
17586
17587 (define_insn "*rep_movsi_rex64"
17588   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17589    (set (match_operand:DI 0 "register_operand" "=D") 
17590         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17591                             (const_int 2))
17592                  (match_operand:DI 3 "register_operand" "0")))
17593    (set (match_operand:DI 1 "register_operand" "=S") 
17594         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17595                  (match_operand:DI 4 "register_operand" "1")))
17596    (set (mem:BLK (match_dup 3))
17597         (mem:BLK (match_dup 4)))
17598    (use (match_dup 5))
17599    (use (reg:SI DIRFLAG_REG))]
17600   "TARGET_64BIT"
17601   "{rep\;movsl|rep movsd}"
17602   [(set_attr "type" "str")
17603    (set_attr "prefix_rep" "1")
17604    (set_attr "memory" "both")
17605    (set_attr "mode" "SI")])
17606
17607 (define_insn "*rep_movqi"
17608   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17609    (set (match_operand:SI 0 "register_operand" "=D") 
17610         (plus:SI (match_operand:SI 3 "register_operand" "0")
17611                  (match_operand:SI 5 "register_operand" "2")))
17612    (set (match_operand:SI 1 "register_operand" "=S") 
17613         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17614    (set (mem:BLK (match_dup 3))
17615         (mem:BLK (match_dup 4)))
17616    (use (match_dup 5))
17617    (use (reg:SI DIRFLAG_REG))]
17618   "!TARGET_64BIT"
17619   "{rep\;movsb|rep movsb}"
17620   [(set_attr "type" "str")
17621    (set_attr "prefix_rep" "1")
17622    (set_attr "memory" "both")
17623    (set_attr "mode" "SI")])
17624
17625 (define_insn "*rep_movqi_rex64"
17626   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17627    (set (match_operand:DI 0 "register_operand" "=D") 
17628         (plus:DI (match_operand:DI 3 "register_operand" "0")
17629                  (match_operand:DI 5 "register_operand" "2")))
17630    (set (match_operand:DI 1 "register_operand" "=S") 
17631         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17632    (set (mem:BLK (match_dup 3))
17633         (mem:BLK (match_dup 4)))
17634    (use (match_dup 5))
17635    (use (reg:SI DIRFLAG_REG))]
17636   "TARGET_64BIT"
17637   "{rep\;movsb|rep movsb}"
17638   [(set_attr "type" "str")
17639    (set_attr "prefix_rep" "1")
17640    (set_attr "memory" "both")
17641    (set_attr "mode" "SI")])
17642
17643 (define_expand "setmemsi"
17644    [(use (match_operand:BLK 0 "memory_operand" ""))
17645     (use (match_operand:SI 1 "nonmemory_operand" ""))
17646     (use (match_operand 2 "const_int_operand" ""))
17647     (use (match_operand 3 "const_int_operand" ""))]
17648   ""
17649 {
17650  /* If value to set is not zero, use the library routine.  */
17651  if (operands[2] != const0_rtx)
17652    FAIL;
17653
17654  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17655    DONE;
17656  else
17657    FAIL;
17658 })
17659
17660 (define_expand "setmemdi"
17661    [(use (match_operand:BLK 0 "memory_operand" ""))
17662     (use (match_operand:DI 1 "nonmemory_operand" ""))
17663     (use (match_operand 2 "const_int_operand" ""))
17664     (use (match_operand 3 "const_int_operand" ""))]
17665   "TARGET_64BIT"
17666 {
17667  /* If value to set is not zero, use the library routine.  */
17668  if (operands[2] != const0_rtx)
17669    FAIL;
17670
17671  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17672    DONE;
17673  else
17674    FAIL;
17675 })
17676
17677 ;; Most CPUs don't like single string operations
17678 ;; Handle this case here to simplify previous expander.
17679
17680 (define_expand "strset"
17681   [(set (match_operand 1 "memory_operand" "")
17682         (match_operand 2 "register_operand" ""))
17683    (parallel [(set (match_operand 0 "register_operand" "")
17684                    (match_dup 3))
17685               (clobber (reg:CC FLAGS_REG))])]
17686   ""
17687 {
17688   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17689     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17690
17691   /* If .md ever supports :P for Pmode, this can be directly
17692      in the pattern above.  */
17693   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17694                               GEN_INT (GET_MODE_SIZE (GET_MODE
17695                                                       (operands[2]))));
17696   if (TARGET_SINGLE_STRINGOP || optimize_size)
17697     {
17698       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17699                                       operands[3]));
17700       DONE;
17701     }
17702 })
17703
17704 (define_expand "strset_singleop"
17705   [(parallel [(set (match_operand 1 "memory_operand" "")
17706                    (match_operand 2 "register_operand" ""))
17707               (set (match_operand 0 "register_operand" "")
17708                    (match_operand 3 "" ""))
17709               (use (reg:SI DIRFLAG_REG))])]
17710   "TARGET_SINGLE_STRINGOP || optimize_size"
17711   "")
17712
17713 (define_insn "*strsetdi_rex_1"
17714   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17715         (match_operand:DI 2 "register_operand" "a"))
17716    (set (match_operand:DI 0 "register_operand" "=D")
17717         (plus:DI (match_dup 1)
17718                  (const_int 8)))
17719    (use (reg:SI DIRFLAG_REG))]
17720   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17721   "stosq"
17722   [(set_attr "type" "str")
17723    (set_attr "memory" "store")
17724    (set_attr "mode" "DI")])
17725
17726 (define_insn "*strsetsi_1"
17727   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17728         (match_operand:SI 2 "register_operand" "a"))
17729    (set (match_operand:SI 0 "register_operand" "=D")
17730         (plus:SI (match_dup 1)
17731                  (const_int 4)))
17732    (use (reg:SI DIRFLAG_REG))]
17733   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17734   "{stosl|stosd}"
17735   [(set_attr "type" "str")
17736    (set_attr "memory" "store")
17737    (set_attr "mode" "SI")])
17738
17739 (define_insn "*strsetsi_rex_1"
17740   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17741         (match_operand:SI 2 "register_operand" "a"))
17742    (set (match_operand:DI 0 "register_operand" "=D")
17743         (plus:DI (match_dup 1)
17744                  (const_int 4)))
17745    (use (reg:SI DIRFLAG_REG))]
17746   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17747   "{stosl|stosd}"
17748   [(set_attr "type" "str")
17749    (set_attr "memory" "store")
17750    (set_attr "mode" "SI")])
17751
17752 (define_insn "*strsethi_1"
17753   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17754         (match_operand:HI 2 "register_operand" "a"))
17755    (set (match_operand:SI 0 "register_operand" "=D")
17756         (plus:SI (match_dup 1)
17757                  (const_int 2)))
17758    (use (reg:SI DIRFLAG_REG))]
17759   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17760   "stosw"
17761   [(set_attr "type" "str")
17762    (set_attr "memory" "store")
17763    (set_attr "mode" "HI")])
17764
17765 (define_insn "*strsethi_rex_1"
17766   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17767         (match_operand:HI 2 "register_operand" "a"))
17768    (set (match_operand:DI 0 "register_operand" "=D")
17769         (plus:DI (match_dup 1)
17770                  (const_int 2)))
17771    (use (reg:SI DIRFLAG_REG))]
17772   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17773   "stosw"
17774   [(set_attr "type" "str")
17775    (set_attr "memory" "store")
17776    (set_attr "mode" "HI")])
17777
17778 (define_insn "*strsetqi_1"
17779   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17780         (match_operand:QI 2 "register_operand" "a"))
17781    (set (match_operand:SI 0 "register_operand" "=D")
17782         (plus:SI (match_dup 1)
17783                  (const_int 1)))
17784    (use (reg:SI DIRFLAG_REG))]
17785   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17786   "stosb"
17787   [(set_attr "type" "str")
17788    (set_attr "memory" "store")
17789    (set_attr "mode" "QI")])
17790
17791 (define_insn "*strsetqi_rex_1"
17792   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17793         (match_operand:QI 2 "register_operand" "a"))
17794    (set (match_operand:DI 0 "register_operand" "=D")
17795         (plus:DI (match_dup 1)
17796                  (const_int 1)))
17797    (use (reg:SI DIRFLAG_REG))]
17798   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17799   "stosb"
17800   [(set_attr "type" "str")
17801    (set_attr "memory" "store")
17802    (set_attr "mode" "QI")])
17803
17804 (define_expand "rep_stos"
17805   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17806               (set (match_operand 0 "register_operand" "")
17807                    (match_operand 4 "" ""))
17808               (set (match_operand 2 "memory_operand" "") (const_int 0))
17809               (use (match_operand 3 "register_operand" ""))
17810               (use (match_dup 1))
17811               (use (reg:SI DIRFLAG_REG))])]
17812   ""
17813   "")
17814
17815 (define_insn "*rep_stosdi_rex64"
17816   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17817    (set (match_operand:DI 0 "register_operand" "=D") 
17818         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17819                             (const_int 3))
17820                  (match_operand:DI 3 "register_operand" "0")))
17821    (set (mem:BLK (match_dup 3))
17822         (const_int 0))
17823    (use (match_operand:DI 2 "register_operand" "a"))
17824    (use (match_dup 4))
17825    (use (reg:SI DIRFLAG_REG))]
17826   "TARGET_64BIT"
17827   "{rep\;stosq|rep stosq}"
17828   [(set_attr "type" "str")
17829    (set_attr "prefix_rep" "1")
17830    (set_attr "memory" "store")
17831    (set_attr "mode" "DI")])
17832
17833 (define_insn "*rep_stossi"
17834   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17835    (set (match_operand:SI 0 "register_operand" "=D") 
17836         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17837                             (const_int 2))
17838                  (match_operand:SI 3 "register_operand" "0")))
17839    (set (mem:BLK (match_dup 3))
17840         (const_int 0))
17841    (use (match_operand:SI 2 "register_operand" "a"))
17842    (use (match_dup 4))
17843    (use (reg:SI DIRFLAG_REG))]
17844   "!TARGET_64BIT"
17845   "{rep\;stosl|rep stosd}"
17846   [(set_attr "type" "str")
17847    (set_attr "prefix_rep" "1")
17848    (set_attr "memory" "store")
17849    (set_attr "mode" "SI")])
17850
17851 (define_insn "*rep_stossi_rex64"
17852   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17853    (set (match_operand:DI 0 "register_operand" "=D") 
17854         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17855                             (const_int 2))
17856                  (match_operand:DI 3 "register_operand" "0")))
17857    (set (mem:BLK (match_dup 3))
17858         (const_int 0))
17859    (use (match_operand:SI 2 "register_operand" "a"))
17860    (use (match_dup 4))
17861    (use (reg:SI DIRFLAG_REG))]
17862   "TARGET_64BIT"
17863   "{rep\;stosl|rep stosd}"
17864   [(set_attr "type" "str")
17865    (set_attr "prefix_rep" "1")
17866    (set_attr "memory" "store")
17867    (set_attr "mode" "SI")])
17868
17869 (define_insn "*rep_stosqi"
17870   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17871    (set (match_operand:SI 0 "register_operand" "=D") 
17872         (plus:SI (match_operand:SI 3 "register_operand" "0")
17873                  (match_operand:SI 4 "register_operand" "1")))
17874    (set (mem:BLK (match_dup 3))
17875         (const_int 0))
17876    (use (match_operand:QI 2 "register_operand" "a"))
17877    (use (match_dup 4))
17878    (use (reg:SI DIRFLAG_REG))]
17879   "!TARGET_64BIT"
17880   "{rep\;stosb|rep stosb}"
17881   [(set_attr "type" "str")
17882    (set_attr "prefix_rep" "1")
17883    (set_attr "memory" "store")
17884    (set_attr "mode" "QI")])
17885
17886 (define_insn "*rep_stosqi_rex64"
17887   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17888    (set (match_operand:DI 0 "register_operand" "=D") 
17889         (plus:DI (match_operand:DI 3 "register_operand" "0")
17890                  (match_operand:DI 4 "register_operand" "1")))
17891    (set (mem:BLK (match_dup 3))
17892         (const_int 0))
17893    (use (match_operand:QI 2 "register_operand" "a"))
17894    (use (match_dup 4))
17895    (use (reg:SI DIRFLAG_REG))]
17896   "TARGET_64BIT"
17897   "{rep\;stosb|rep stosb}"
17898   [(set_attr "type" "str")
17899    (set_attr "prefix_rep" "1")
17900    (set_attr "memory" "store")
17901    (set_attr "mode" "QI")])
17902
17903 (define_expand "cmpstrnsi"
17904   [(set (match_operand:SI 0 "register_operand" "")
17905         (compare:SI (match_operand:BLK 1 "general_operand" "")
17906                     (match_operand:BLK 2 "general_operand" "")))
17907    (use (match_operand 3 "general_operand" ""))
17908    (use (match_operand 4 "immediate_operand" ""))]
17909   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17910 {
17911   rtx addr1, addr2, out, outlow, count, countreg, align;
17912
17913   /* Can't use this if the user has appropriated esi or edi.  */
17914   if (global_regs[4] || global_regs[5])
17915     FAIL;
17916
17917   out = operands[0];
17918   if (GET_CODE (out) != REG)
17919     out = gen_reg_rtx (SImode);
17920
17921   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17922   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17923   if (addr1 != XEXP (operands[1], 0))
17924     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17925   if (addr2 != XEXP (operands[2], 0))
17926     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17927
17928   count = operands[3];
17929   countreg = ix86_zero_extend_to_Pmode (count);
17930
17931   /* %%% Iff we are testing strict equality, we can use known alignment
17932      to good advantage.  This may be possible with combine, particularly
17933      once cc0 is dead.  */
17934   align = operands[4];
17935
17936   emit_insn (gen_cld ());
17937   if (GET_CODE (count) == CONST_INT)
17938     {
17939       if (INTVAL (count) == 0)
17940         {
17941           emit_move_insn (operands[0], const0_rtx);
17942           DONE;
17943         }
17944       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17945                                      operands[1], operands[2]));
17946     }
17947   else
17948     {
17949       if (TARGET_64BIT)
17950         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17951       else
17952         emit_insn (gen_cmpsi_1 (countreg, countreg));
17953       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17954                                   operands[1], operands[2]));
17955     }
17956
17957   outlow = gen_lowpart (QImode, out);
17958   emit_insn (gen_cmpintqi (outlow));
17959   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17960
17961   if (operands[0] != out)
17962     emit_move_insn (operands[0], out);
17963
17964   DONE;
17965 })
17966
17967 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17968
17969 (define_expand "cmpintqi"
17970   [(set (match_dup 1)
17971         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17972    (set (match_dup 2)
17973         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17974    (parallel [(set (match_operand:QI 0 "register_operand" "")
17975                    (minus:QI (match_dup 1)
17976                              (match_dup 2)))
17977               (clobber (reg:CC FLAGS_REG))])]
17978   ""
17979   "operands[1] = gen_reg_rtx (QImode);
17980    operands[2] = gen_reg_rtx (QImode);")
17981
17982 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17983 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17984
17985 (define_expand "cmpstrnqi_nz_1"
17986   [(parallel [(set (reg:CC FLAGS_REG)
17987                    (compare:CC (match_operand 4 "memory_operand" "")
17988                                (match_operand 5 "memory_operand" "")))
17989               (use (match_operand 2 "register_operand" ""))
17990               (use (match_operand:SI 3 "immediate_operand" ""))
17991               (use (reg:SI DIRFLAG_REG))
17992               (clobber (match_operand 0 "register_operand" ""))
17993               (clobber (match_operand 1 "register_operand" ""))
17994               (clobber (match_dup 2))])]
17995   ""
17996   "")
17997
17998 (define_insn "*cmpstrnqi_nz_1"
17999   [(set (reg:CC FLAGS_REG)
18000         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18001                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18002    (use (match_operand:SI 6 "register_operand" "2"))
18003    (use (match_operand:SI 3 "immediate_operand" "i"))
18004    (use (reg:SI DIRFLAG_REG))
18005    (clobber (match_operand:SI 0 "register_operand" "=S"))
18006    (clobber (match_operand:SI 1 "register_operand" "=D"))
18007    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18008   "!TARGET_64BIT"
18009   "repz{\;| }cmpsb"
18010   [(set_attr "type" "str")
18011    (set_attr "mode" "QI")
18012    (set_attr "prefix_rep" "1")])
18013
18014 (define_insn "*cmpstrnqi_nz_rex_1"
18015   [(set (reg:CC FLAGS_REG)
18016         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18017                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18018    (use (match_operand:DI 6 "register_operand" "2"))
18019    (use (match_operand:SI 3 "immediate_operand" "i"))
18020    (use (reg:SI DIRFLAG_REG))
18021    (clobber (match_operand:DI 0 "register_operand" "=S"))
18022    (clobber (match_operand:DI 1 "register_operand" "=D"))
18023    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18024   "TARGET_64BIT"
18025   "repz{\;| }cmpsb"
18026   [(set_attr "type" "str")
18027    (set_attr "mode" "QI")
18028    (set_attr "prefix_rep" "1")])
18029
18030 ;; The same, but the count is not known to not be zero.
18031
18032 (define_expand "cmpstrnqi_1"
18033   [(parallel [(set (reg:CC FLAGS_REG)
18034                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18035                                      (const_int 0))
18036                   (compare:CC (match_operand 4 "memory_operand" "")
18037                               (match_operand 5 "memory_operand" ""))
18038                   (const_int 0)))
18039               (use (match_operand:SI 3 "immediate_operand" ""))
18040               (use (reg:CC FLAGS_REG))
18041               (use (reg:SI DIRFLAG_REG))
18042               (clobber (match_operand 0 "register_operand" ""))
18043               (clobber (match_operand 1 "register_operand" ""))
18044               (clobber (match_dup 2))])]
18045   ""
18046   "")
18047
18048 (define_insn "*cmpstrnqi_1"
18049   [(set (reg:CC FLAGS_REG)
18050         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18051                              (const_int 0))
18052           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18053                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18054           (const_int 0)))
18055    (use (match_operand:SI 3 "immediate_operand" "i"))
18056    (use (reg:CC FLAGS_REG))
18057    (use (reg:SI DIRFLAG_REG))
18058    (clobber (match_operand:SI 0 "register_operand" "=S"))
18059    (clobber (match_operand:SI 1 "register_operand" "=D"))
18060    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18061   "!TARGET_64BIT"
18062   "repz{\;| }cmpsb"
18063   [(set_attr "type" "str")
18064    (set_attr "mode" "QI")
18065    (set_attr "prefix_rep" "1")])
18066
18067 (define_insn "*cmpstrnqi_rex_1"
18068   [(set (reg:CC FLAGS_REG)
18069         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18070                              (const_int 0))
18071           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18072                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18073           (const_int 0)))
18074    (use (match_operand:SI 3 "immediate_operand" "i"))
18075    (use (reg:CC FLAGS_REG))
18076    (use (reg:SI DIRFLAG_REG))
18077    (clobber (match_operand:DI 0 "register_operand" "=S"))
18078    (clobber (match_operand:DI 1 "register_operand" "=D"))
18079    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18080   "TARGET_64BIT"
18081   "repz{\;| }cmpsb"
18082   [(set_attr "type" "str")
18083    (set_attr "mode" "QI")
18084    (set_attr "prefix_rep" "1")])
18085
18086 (define_expand "strlensi"
18087   [(set (match_operand:SI 0 "register_operand" "")
18088         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18089                     (match_operand:QI 2 "immediate_operand" "")
18090                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18091   ""
18092 {
18093  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18094    DONE;
18095  else
18096    FAIL;
18097 })
18098
18099 (define_expand "strlendi"
18100   [(set (match_operand:DI 0 "register_operand" "")
18101         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18102                     (match_operand:QI 2 "immediate_operand" "")
18103                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18104   ""
18105 {
18106  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18107    DONE;
18108  else
18109    FAIL;
18110 })
18111
18112 (define_expand "strlenqi_1"
18113   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18114               (use (reg:SI DIRFLAG_REG))
18115               (clobber (match_operand 1 "register_operand" ""))
18116               (clobber (reg:CC FLAGS_REG))])]
18117   ""
18118   "")
18119
18120 (define_insn "*strlenqi_1"
18121   [(set (match_operand:SI 0 "register_operand" "=&c")
18122         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18123                     (match_operand:QI 2 "register_operand" "a")
18124                     (match_operand:SI 3 "immediate_operand" "i")
18125                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18126    (use (reg:SI DIRFLAG_REG))
18127    (clobber (match_operand:SI 1 "register_operand" "=D"))
18128    (clobber (reg:CC FLAGS_REG))]
18129   "!TARGET_64BIT"
18130   "repnz{\;| }scasb"
18131   [(set_attr "type" "str")
18132    (set_attr "mode" "QI")
18133    (set_attr "prefix_rep" "1")])
18134
18135 (define_insn "*strlenqi_rex_1"
18136   [(set (match_operand:DI 0 "register_operand" "=&c")
18137         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18138                     (match_operand:QI 2 "register_operand" "a")
18139                     (match_operand:DI 3 "immediate_operand" "i")
18140                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18141    (use (reg:SI DIRFLAG_REG))
18142    (clobber (match_operand:DI 1 "register_operand" "=D"))
18143    (clobber (reg:CC FLAGS_REG))]
18144   "TARGET_64BIT"
18145   "repnz{\;| }scasb"
18146   [(set_attr "type" "str")
18147    (set_attr "mode" "QI")
18148    (set_attr "prefix_rep" "1")])
18149
18150 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18151 ;; handled in combine, but it is not currently up to the task.
18152 ;; When used for their truth value, the cmpstrn* expanders generate
18153 ;; code like this:
18154 ;;
18155 ;;   repz cmpsb
18156 ;;   seta       %al
18157 ;;   setb       %dl
18158 ;;   cmpb       %al, %dl
18159 ;;   jcc        label
18160 ;;
18161 ;; The intermediate three instructions are unnecessary.
18162
18163 ;; This one handles cmpstrn*_nz_1...
18164 (define_peephole2
18165   [(parallel[
18166      (set (reg:CC FLAGS_REG)
18167           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18168                       (mem:BLK (match_operand 5 "register_operand" ""))))
18169      (use (match_operand 6 "register_operand" ""))
18170      (use (match_operand:SI 3 "immediate_operand" ""))
18171      (use (reg:SI DIRFLAG_REG))
18172      (clobber (match_operand 0 "register_operand" ""))
18173      (clobber (match_operand 1 "register_operand" ""))
18174      (clobber (match_operand 2 "register_operand" ""))])
18175    (set (match_operand:QI 7 "register_operand" "")
18176         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18177    (set (match_operand:QI 8 "register_operand" "")
18178         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18179    (set (reg FLAGS_REG)
18180         (compare (match_dup 7) (match_dup 8)))
18181   ]
18182   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18183   [(parallel[
18184      (set (reg:CC FLAGS_REG)
18185           (compare:CC (mem:BLK (match_dup 4))
18186                       (mem:BLK (match_dup 5))))
18187      (use (match_dup 6))
18188      (use (match_dup 3))
18189      (use (reg:SI DIRFLAG_REG))
18190      (clobber (match_dup 0))
18191      (clobber (match_dup 1))
18192      (clobber (match_dup 2))])]
18193   "")
18194
18195 ;; ...and this one handles cmpstrn*_1.
18196 (define_peephole2
18197   [(parallel[
18198      (set (reg:CC FLAGS_REG)
18199           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18200                                (const_int 0))
18201             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18202                         (mem:BLK (match_operand 5 "register_operand" "")))
18203             (const_int 0)))
18204      (use (match_operand:SI 3 "immediate_operand" ""))
18205      (use (reg:CC FLAGS_REG))
18206      (use (reg:SI DIRFLAG_REG))
18207      (clobber (match_operand 0 "register_operand" ""))
18208      (clobber (match_operand 1 "register_operand" ""))
18209      (clobber (match_operand 2 "register_operand" ""))])
18210    (set (match_operand:QI 7 "register_operand" "")
18211         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18212    (set (match_operand:QI 8 "register_operand" "")
18213         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18214    (set (reg FLAGS_REG)
18215         (compare (match_dup 7) (match_dup 8)))
18216   ]
18217   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18218   [(parallel[
18219      (set (reg:CC FLAGS_REG)
18220           (if_then_else:CC (ne (match_dup 6)
18221                                (const_int 0))
18222             (compare:CC (mem:BLK (match_dup 4))
18223                         (mem:BLK (match_dup 5)))
18224             (const_int 0)))
18225      (use (match_dup 3))
18226      (use (reg:CC FLAGS_REG))
18227      (use (reg:SI DIRFLAG_REG))
18228      (clobber (match_dup 0))
18229      (clobber (match_dup 1))
18230      (clobber (match_dup 2))])]
18231   "")
18232
18233
18234 \f
18235 ;; Conditional move instructions.
18236
18237 (define_expand "movdicc"
18238   [(set (match_operand:DI 0 "register_operand" "")
18239         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18240                          (match_operand:DI 2 "general_operand" "")
18241                          (match_operand:DI 3 "general_operand" "")))]
18242   "TARGET_64BIT"
18243   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18244
18245 (define_insn "x86_movdicc_0_m1_rex64"
18246   [(set (match_operand:DI 0 "register_operand" "=r")
18247         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18248           (const_int -1)
18249           (const_int 0)))
18250    (clobber (reg:CC FLAGS_REG))]
18251   "TARGET_64BIT"
18252   "sbb{q}\t%0, %0"
18253   ; Since we don't have the proper number of operands for an alu insn,
18254   ; fill in all the blanks.
18255   [(set_attr "type" "alu")
18256    (set_attr "pent_pair" "pu")
18257    (set_attr "memory" "none")
18258    (set_attr "imm_disp" "false")
18259    (set_attr "mode" "DI")
18260    (set_attr "length_immediate" "0")])
18261
18262 (define_insn "*movdicc_c_rex64"
18263   [(set (match_operand:DI 0 "register_operand" "=r,r")
18264         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18265                                 [(reg FLAGS_REG) (const_int 0)])
18266                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18267                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18268   "TARGET_64BIT && TARGET_CMOVE
18269    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18270   "@
18271    cmov%O2%C1\t{%2, %0|%0, %2}
18272    cmov%O2%c1\t{%3, %0|%0, %3}"
18273   [(set_attr "type" "icmov")
18274    (set_attr "mode" "DI")])
18275
18276 (define_expand "movsicc"
18277   [(set (match_operand:SI 0 "register_operand" "")
18278         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18279                          (match_operand:SI 2 "general_operand" "")
18280                          (match_operand:SI 3 "general_operand" "")))]
18281   ""
18282   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18283
18284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18286 ;; So just document what we're doing explicitly.
18287
18288 (define_insn "x86_movsicc_0_m1"
18289   [(set (match_operand:SI 0 "register_operand" "=r")
18290         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18291           (const_int -1)
18292           (const_int 0)))
18293    (clobber (reg:CC FLAGS_REG))]
18294   ""
18295   "sbb{l}\t%0, %0"
18296   ; Since we don't have the proper number of operands for an alu insn,
18297   ; fill in all the blanks.
18298   [(set_attr "type" "alu")
18299    (set_attr "pent_pair" "pu")
18300    (set_attr "memory" "none")
18301    (set_attr "imm_disp" "false")
18302    (set_attr "mode" "SI")
18303    (set_attr "length_immediate" "0")])
18304
18305 (define_insn "*movsicc_noc"
18306   [(set (match_operand:SI 0 "register_operand" "=r,r")
18307         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18308                                 [(reg FLAGS_REG) (const_int 0)])
18309                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18310                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18311   "TARGET_CMOVE
18312    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18313   "@
18314    cmov%O2%C1\t{%2, %0|%0, %2}
18315    cmov%O2%c1\t{%3, %0|%0, %3}"
18316   [(set_attr "type" "icmov")
18317    (set_attr "mode" "SI")])
18318
18319 (define_expand "movhicc"
18320   [(set (match_operand:HI 0 "register_operand" "")
18321         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18322                          (match_operand:HI 2 "general_operand" "")
18323                          (match_operand:HI 3 "general_operand" "")))]
18324   "TARGET_HIMODE_MATH"
18325   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18326
18327 (define_insn "*movhicc_noc"
18328   [(set (match_operand:HI 0 "register_operand" "=r,r")
18329         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18330                                 [(reg FLAGS_REG) (const_int 0)])
18331                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18332                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18333   "TARGET_CMOVE
18334    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18335   "@
18336    cmov%O2%C1\t{%2, %0|%0, %2}
18337    cmov%O2%c1\t{%3, %0|%0, %3}"
18338   [(set_attr "type" "icmov")
18339    (set_attr "mode" "HI")])
18340
18341 (define_expand "movqicc"
18342   [(set (match_operand:QI 0 "register_operand" "")
18343         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18344                          (match_operand:QI 2 "general_operand" "")
18345                          (match_operand:QI 3 "general_operand" "")))]
18346   "TARGET_QIMODE_MATH"
18347   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18348
18349 (define_insn_and_split "*movqicc_noc"
18350   [(set (match_operand:QI 0 "register_operand" "=r,r")
18351         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18352                                 [(match_operand 4 "flags_reg_operand" "")
18353                                  (const_int 0)])
18354                       (match_operand:QI 2 "register_operand" "r,0")
18355                       (match_operand:QI 3 "register_operand" "0,r")))]
18356   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18357   "#"
18358   "&& reload_completed"
18359   [(set (match_dup 0)
18360         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18361                       (match_dup 2)
18362                       (match_dup 3)))]
18363   "operands[0] = gen_lowpart (SImode, operands[0]);
18364    operands[2] = gen_lowpart (SImode, operands[2]);
18365    operands[3] = gen_lowpart (SImode, operands[3]);"
18366   [(set_attr "type" "icmov")
18367    (set_attr "mode" "SI")])
18368
18369 (define_expand "movsfcc"
18370   [(set (match_operand:SF 0 "register_operand" "")
18371         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18372                          (match_operand:SF 2 "register_operand" "")
18373                          (match_operand:SF 3 "register_operand" "")))]
18374   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18375   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18376
18377 (define_insn "*movsfcc_1_387"
18378   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18379         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18380                                 [(reg FLAGS_REG) (const_int 0)])
18381                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18382                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18383   "TARGET_80387 && TARGET_CMOVE
18384    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18385   "@
18386    fcmov%F1\t{%2, %0|%0, %2}
18387    fcmov%f1\t{%3, %0|%0, %3}
18388    cmov%O2%C1\t{%2, %0|%0, %2}
18389    cmov%O2%c1\t{%3, %0|%0, %3}"
18390   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18391    (set_attr "mode" "SF,SF,SI,SI")])
18392
18393 (define_expand "movdfcc"
18394   [(set (match_operand:DF 0 "register_operand" "")
18395         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18396                          (match_operand:DF 2 "register_operand" "")
18397                          (match_operand:DF 3 "register_operand" "")))]
18398   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18399   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18400
18401 (define_insn "*movdfcc_1"
18402   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18403         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18404                                 [(reg FLAGS_REG) (const_int 0)])
18405                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18406                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18407   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18408    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18409   "@
18410    fcmov%F1\t{%2, %0|%0, %2}
18411    fcmov%f1\t{%3, %0|%0, %3}
18412    #
18413    #"
18414   [(set_attr "type" "fcmov,fcmov,multi,multi")
18415    (set_attr "mode" "DF")])
18416
18417 (define_insn "*movdfcc_1_rex64"
18418   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18419         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18420                                 [(reg FLAGS_REG) (const_int 0)])
18421                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18422                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18423   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18424    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18425   "@
18426    fcmov%F1\t{%2, %0|%0, %2}
18427    fcmov%f1\t{%3, %0|%0, %3}
18428    cmov%O2%C1\t{%2, %0|%0, %2}
18429    cmov%O2%c1\t{%3, %0|%0, %3}"
18430   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18431    (set_attr "mode" "DF")])
18432
18433 (define_split
18434   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18435         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18436                                 [(match_operand 4 "flags_reg_operand" "")
18437                                  (const_int 0)])
18438                       (match_operand:DF 2 "nonimmediate_operand" "")
18439                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18440   "!TARGET_64BIT && reload_completed"
18441   [(set (match_dup 2)
18442         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18443                       (match_dup 5)
18444                       (match_dup 7)))
18445    (set (match_dup 3)
18446         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18447                       (match_dup 6)
18448                       (match_dup 8)))]
18449   "split_di (operands+2, 1, operands+5, operands+6);
18450    split_di (operands+3, 1, operands+7, operands+8);
18451    split_di (operands, 1, operands+2, operands+3);")
18452
18453 (define_expand "movxfcc"
18454   [(set (match_operand:XF 0 "register_operand" "")
18455         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18456                          (match_operand:XF 2 "register_operand" "")
18457                          (match_operand:XF 3 "register_operand" "")))]
18458   "TARGET_80387 && TARGET_CMOVE"
18459   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18460
18461 (define_insn "*movxfcc_1"
18462   [(set (match_operand:XF 0 "register_operand" "=f,f")
18463         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18464                                 [(reg FLAGS_REG) (const_int 0)])
18465                       (match_operand:XF 2 "register_operand" "f,0")
18466                       (match_operand:XF 3 "register_operand" "0,f")))]
18467   "TARGET_80387 && TARGET_CMOVE"
18468   "@
18469    fcmov%F1\t{%2, %0|%0, %2}
18470    fcmov%f1\t{%3, %0|%0, %3}"
18471   [(set_attr "type" "fcmov")
18472    (set_attr "mode" "XF")])
18473
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18478
18479 (define_insn "sminsf3"
18480   [(set (match_operand:SF 0 "register_operand" "=x")
18481         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18482                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18483   "TARGET_SSE_MATH"
18484   "minss\t{%2, %0|%0, %2}"
18485   [(set_attr "type" "sseadd")
18486    (set_attr "mode" "SF")])
18487
18488 (define_insn "smaxsf3"
18489   [(set (match_operand:SF 0 "register_operand" "=x")
18490         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18491                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18492   "TARGET_SSE_MATH"
18493   "maxss\t{%2, %0|%0, %2}"
18494   [(set_attr "type" "sseadd")
18495    (set_attr "mode" "SF")])
18496
18497 (define_insn "smindf3"
18498   [(set (match_operand:DF 0 "register_operand" "=x")
18499         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18500                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18501   "TARGET_SSE2 && TARGET_SSE_MATH"
18502   "minsd\t{%2, %0|%0, %2}"
18503   [(set_attr "type" "sseadd")
18504    (set_attr "mode" "DF")])
18505
18506 (define_insn "smaxdf3"
18507   [(set (match_operand:DF 0 "register_operand" "=x")
18508         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18509                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18510   "TARGET_SSE2 && TARGET_SSE_MATH"
18511   "maxsd\t{%2, %0|%0, %2}"
18512   [(set_attr "type" "sseadd")
18513    (set_attr "mode" "DF")])
18514
18515 ;; These versions of the min/max patterns implement exactly the operations
18516 ;;   min = (op1 < op2 ? op1 : op2)
18517 ;;   max = (!(op1 < op2) ? op1 : op2)
18518 ;; Their operands are not commutative, and thus they may be used in the
18519 ;; presence of -0.0 and NaN.
18520
18521 (define_insn "*ieee_sminsf3"
18522   [(set (match_operand:SF 0 "register_operand" "=x")
18523         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18524                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18525                    UNSPEC_IEEE_MIN))]
18526   "TARGET_SSE_MATH"
18527   "minss\t{%2, %0|%0, %2}"
18528   [(set_attr "type" "sseadd")
18529    (set_attr "mode" "SF")])
18530
18531 (define_insn "*ieee_smaxsf3"
18532   [(set (match_operand:SF 0 "register_operand" "=x")
18533         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18534                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18535                    UNSPEC_IEEE_MAX))]
18536   "TARGET_SSE_MATH"
18537   "maxss\t{%2, %0|%0, %2}"
18538   [(set_attr "type" "sseadd")
18539    (set_attr "mode" "SF")])
18540
18541 (define_insn "*ieee_smindf3"
18542   [(set (match_operand:DF 0 "register_operand" "=x")
18543         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18544                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18545                    UNSPEC_IEEE_MIN))]
18546   "TARGET_SSE2 && TARGET_SSE_MATH"
18547   "minsd\t{%2, %0|%0, %2}"
18548   [(set_attr "type" "sseadd")
18549    (set_attr "mode" "DF")])
18550
18551 (define_insn "*ieee_smaxdf3"
18552   [(set (match_operand:DF 0 "register_operand" "=x")
18553         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18554                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18555                    UNSPEC_IEEE_MAX))]
18556   "TARGET_SSE2 && TARGET_SSE_MATH"
18557   "maxsd\t{%2, %0|%0, %2}"
18558   [(set_attr "type" "sseadd")
18559    (set_attr "mode" "DF")])
18560
18561 ;; Conditional addition patterns
18562 (define_expand "addqicc"
18563   [(match_operand:QI 0 "register_operand" "")
18564    (match_operand 1 "comparison_operator" "")
18565    (match_operand:QI 2 "register_operand" "")
18566    (match_operand:QI 3 "const_int_operand" "")]
18567   ""
18568   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18569
18570 (define_expand "addhicc"
18571   [(match_operand:HI 0 "register_operand" "")
18572    (match_operand 1 "comparison_operator" "")
18573    (match_operand:HI 2 "register_operand" "")
18574    (match_operand:HI 3 "const_int_operand" "")]
18575   ""
18576   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18577
18578 (define_expand "addsicc"
18579   [(match_operand:SI 0 "register_operand" "")
18580    (match_operand 1 "comparison_operator" "")
18581    (match_operand:SI 2 "register_operand" "")
18582    (match_operand:SI 3 "const_int_operand" "")]
18583   ""
18584   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18585
18586 (define_expand "adddicc"
18587   [(match_operand:DI 0 "register_operand" "")
18588    (match_operand 1 "comparison_operator" "")
18589    (match_operand:DI 2 "register_operand" "")
18590    (match_operand:DI 3 "const_int_operand" "")]
18591   "TARGET_64BIT"
18592   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18593
18594 \f
18595 ;; Misc patterns (?)
18596
18597 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18598 ;; Otherwise there will be nothing to keep
18599 ;; 
18600 ;; [(set (reg ebp) (reg esp))]
18601 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18602 ;;  (clobber (eflags)]
18603 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18604 ;;
18605 ;; in proper program order.
18606 (define_insn "pro_epilogue_adjust_stack_1"
18607   [(set (match_operand:SI 0 "register_operand" "=r,r")
18608         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18609                  (match_operand:SI 2 "immediate_operand" "i,i")))
18610    (clobber (reg:CC FLAGS_REG))
18611    (clobber (mem:BLK (scratch)))]
18612   "!TARGET_64BIT"
18613 {
18614   switch (get_attr_type (insn))
18615     {
18616     case TYPE_IMOV:
18617       return "mov{l}\t{%1, %0|%0, %1}";
18618
18619     case TYPE_ALU:
18620       if (GET_CODE (operands[2]) == CONST_INT
18621           && (INTVAL (operands[2]) == 128
18622               || (INTVAL (operands[2]) < 0
18623                   && INTVAL (operands[2]) != -128)))
18624         {
18625           operands[2] = GEN_INT (-INTVAL (operands[2]));
18626           return "sub{l}\t{%2, %0|%0, %2}";
18627         }
18628       return "add{l}\t{%2, %0|%0, %2}";
18629
18630     case TYPE_LEA:
18631       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18632       return "lea{l}\t{%a2, %0|%0, %a2}";
18633
18634     default:
18635       gcc_unreachable ();
18636     }
18637 }
18638   [(set (attr "type")
18639         (cond [(eq_attr "alternative" "0")
18640                  (const_string "alu")
18641                (match_operand:SI 2 "const0_operand" "")
18642                  (const_string "imov")
18643               ]
18644               (const_string "lea")))
18645    (set_attr "mode" "SI")])
18646
18647 (define_insn "pro_epilogue_adjust_stack_rex64"
18648   [(set (match_operand:DI 0 "register_operand" "=r,r")
18649         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18650                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18651    (clobber (reg:CC FLAGS_REG))
18652    (clobber (mem:BLK (scratch)))]
18653   "TARGET_64BIT"
18654 {
18655   switch (get_attr_type (insn))
18656     {
18657     case TYPE_IMOV:
18658       return "mov{q}\t{%1, %0|%0, %1}";
18659
18660     case TYPE_ALU:
18661       if (GET_CODE (operands[2]) == CONST_INT
18662           /* Avoid overflows.  */
18663           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18664           && (INTVAL (operands[2]) == 128
18665               || (INTVAL (operands[2]) < 0
18666                   && INTVAL (operands[2]) != -128)))
18667         {
18668           operands[2] = GEN_INT (-INTVAL (operands[2]));
18669           return "sub{q}\t{%2, %0|%0, %2}";
18670         }
18671       return "add{q}\t{%2, %0|%0, %2}";
18672
18673     case TYPE_LEA:
18674       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18675       return "lea{q}\t{%a2, %0|%0, %a2}";
18676
18677     default:
18678       gcc_unreachable ();
18679     }
18680 }
18681   [(set (attr "type")
18682         (cond [(eq_attr "alternative" "0")
18683                  (const_string "alu")
18684                (match_operand:DI 2 "const0_operand" "")
18685                  (const_string "imov")
18686               ]
18687               (const_string "lea")))
18688    (set_attr "mode" "DI")])
18689
18690 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18691   [(set (match_operand:DI 0 "register_operand" "=r,r")
18692         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18693                  (match_operand:DI 3 "immediate_operand" "i,i")))
18694    (use (match_operand:DI 2 "register_operand" "r,r"))
18695    (clobber (reg:CC FLAGS_REG))
18696    (clobber (mem:BLK (scratch)))]
18697   "TARGET_64BIT"
18698 {
18699   switch (get_attr_type (insn))
18700     {
18701     case TYPE_ALU:
18702       return "add{q}\t{%2, %0|%0, %2}";
18703
18704     case TYPE_LEA:
18705       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18706       return "lea{q}\t{%a2, %0|%0, %a2}";
18707
18708     default:
18709       gcc_unreachable ();
18710     }
18711 }
18712   [(set_attr "type" "alu,lea")
18713    (set_attr "mode" "DI")])
18714
18715 (define_expand "allocate_stack_worker"
18716   [(match_operand:SI 0 "register_operand" "")]
18717   "TARGET_STACK_PROBE"
18718 {
18719   if (reload_completed)
18720     {
18721       if (TARGET_64BIT)
18722         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18723       else
18724         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18725     }
18726   else
18727     {
18728       if (TARGET_64BIT)
18729         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18730       else
18731         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18732     }
18733   DONE;
18734 })
18735
18736 (define_insn "allocate_stack_worker_1"
18737   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18738     UNSPECV_STACK_PROBE)
18739    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18740    (clobber (match_scratch:SI 1 "=0"))
18741    (clobber (reg:CC FLAGS_REG))]
18742   "!TARGET_64BIT && TARGET_STACK_PROBE"
18743   "call\t__alloca"
18744   [(set_attr "type" "multi")
18745    (set_attr "length" "5")])
18746
18747 (define_expand "allocate_stack_worker_postreload"
18748   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18749                                     UNSPECV_STACK_PROBE)
18750               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18751               (clobber (match_dup 0))
18752               (clobber (reg:CC FLAGS_REG))])]
18753   ""
18754   "")
18755
18756 (define_insn "allocate_stack_worker_rex64"
18757   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18758     UNSPECV_STACK_PROBE)
18759    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18760    (clobber (match_scratch:DI 1 "=0"))
18761    (clobber (reg:CC FLAGS_REG))]
18762   "TARGET_64BIT && TARGET_STACK_PROBE"
18763   "call\t__alloca"
18764   [(set_attr "type" "multi")
18765    (set_attr "length" "5")])
18766
18767 (define_expand "allocate_stack_worker_rex64_postreload"
18768   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18769                                     UNSPECV_STACK_PROBE)
18770               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18771               (clobber (match_dup 0))
18772               (clobber (reg:CC FLAGS_REG))])]
18773   ""
18774   "")
18775
18776 (define_expand "allocate_stack"
18777   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18778                    (minus:SI (reg:SI SP_REG)
18779                              (match_operand:SI 1 "general_operand" "")))
18780               (clobber (reg:CC FLAGS_REG))])
18781    (parallel [(set (reg:SI SP_REG)
18782                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18783               (clobber (reg:CC FLAGS_REG))])]
18784   "TARGET_STACK_PROBE"
18785 {
18786 #ifdef CHECK_STACK_LIMIT
18787   if (GET_CODE (operands[1]) == CONST_INT
18788       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18789     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18790                            operands[1]));
18791   else 
18792 #endif
18793     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18794                                                             operands[1])));
18795
18796   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18797   DONE;
18798 })
18799
18800 (define_expand "builtin_setjmp_receiver"
18801   [(label_ref (match_operand 0 "" ""))]
18802   "!TARGET_64BIT && flag_pic"
18803 {
18804   emit_insn (gen_set_got (pic_offset_table_rtx));
18805   DONE;
18806 })
18807 \f
18808 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18809
18810 (define_split
18811   [(set (match_operand 0 "register_operand" "")
18812         (match_operator 3 "promotable_binary_operator"
18813            [(match_operand 1 "register_operand" "")
18814             (match_operand 2 "aligned_operand" "")]))
18815    (clobber (reg:CC FLAGS_REG))]
18816   "! TARGET_PARTIAL_REG_STALL && reload_completed
18817    && ((GET_MODE (operands[0]) == HImode 
18818         && ((!optimize_size && !TARGET_FAST_PREFIX)
18819             || GET_CODE (operands[2]) != CONST_INT
18820             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18821        || (GET_MODE (operands[0]) == QImode 
18822            && (TARGET_PROMOTE_QImode || optimize_size)))"
18823   [(parallel [(set (match_dup 0)
18824                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18825               (clobber (reg:CC FLAGS_REG))])]
18826   "operands[0] = gen_lowpart (SImode, operands[0]);
18827    operands[1] = gen_lowpart (SImode, operands[1]);
18828    if (GET_CODE (operands[3]) != ASHIFT)
18829      operands[2] = gen_lowpart (SImode, operands[2]);
18830    PUT_MODE (operands[3], SImode);")
18831
18832 ; Promote the QImode tests, as i386 has encoding of the AND
18833 ; instruction with 32-bit sign-extended immediate and thus the
18834 ; instruction size is unchanged, except in the %eax case for
18835 ; which it is increased by one byte, hence the ! optimize_size.
18836 (define_split
18837   [(set (match_operand 0 "flags_reg_operand" "")
18838         (match_operator 2 "compare_operator"
18839           [(and (match_operand 3 "aligned_operand" "")
18840                 (match_operand 4 "const_int_operand" ""))
18841            (const_int 0)]))
18842    (set (match_operand 1 "register_operand" "")
18843         (and (match_dup 3) (match_dup 4)))]
18844   "! TARGET_PARTIAL_REG_STALL && reload_completed
18845    /* Ensure that the operand will remain sign-extended immediate.  */
18846    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18847    && ! optimize_size
18848    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18849        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18850   [(parallel [(set (match_dup 0)
18851                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18852                                     (const_int 0)]))
18853               (set (match_dup 1)
18854                    (and:SI (match_dup 3) (match_dup 4)))])]
18855 {
18856   operands[4]
18857     = gen_int_mode (INTVAL (operands[4])
18858                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18859   operands[1] = gen_lowpart (SImode, operands[1]);
18860   operands[3] = gen_lowpart (SImode, operands[3]);
18861 })
18862
18863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18864 ; the TEST instruction with 32-bit sign-extended immediate and thus
18865 ; the instruction size would at least double, which is not what we
18866 ; want even with ! optimize_size.
18867 (define_split
18868   [(set (match_operand 0 "flags_reg_operand" "")
18869         (match_operator 1 "compare_operator"
18870           [(and (match_operand:HI 2 "aligned_operand" "")
18871                 (match_operand:HI 3 "const_int_operand" ""))
18872            (const_int 0)]))]
18873   "! TARGET_PARTIAL_REG_STALL && reload_completed
18874    /* Ensure that the operand will remain sign-extended immediate.  */
18875    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18876    && ! TARGET_FAST_PREFIX
18877    && ! optimize_size"
18878   [(set (match_dup 0)
18879         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18880                          (const_int 0)]))]
18881 {
18882   operands[3]
18883     = gen_int_mode (INTVAL (operands[3])
18884                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18885   operands[2] = gen_lowpart (SImode, operands[2]);
18886 })
18887
18888 (define_split
18889   [(set (match_operand 0 "register_operand" "")
18890         (neg (match_operand 1 "register_operand" "")))
18891    (clobber (reg:CC FLAGS_REG))]
18892   "! TARGET_PARTIAL_REG_STALL && reload_completed
18893    && (GET_MODE (operands[0]) == HImode
18894        || (GET_MODE (operands[0]) == QImode 
18895            && (TARGET_PROMOTE_QImode || optimize_size)))"
18896   [(parallel [(set (match_dup 0)
18897                    (neg:SI (match_dup 1)))
18898               (clobber (reg:CC FLAGS_REG))])]
18899   "operands[0] = gen_lowpart (SImode, operands[0]);
18900    operands[1] = gen_lowpart (SImode, operands[1]);")
18901
18902 (define_split
18903   [(set (match_operand 0 "register_operand" "")
18904         (not (match_operand 1 "register_operand" "")))]
18905   "! TARGET_PARTIAL_REG_STALL && reload_completed
18906    && (GET_MODE (operands[0]) == HImode
18907        || (GET_MODE (operands[0]) == QImode 
18908            && (TARGET_PROMOTE_QImode || optimize_size)))"
18909   [(set (match_dup 0)
18910         (not:SI (match_dup 1)))]
18911   "operands[0] = gen_lowpart (SImode, operands[0]);
18912    operands[1] = gen_lowpart (SImode, operands[1]);")
18913
18914 (define_split 
18915   [(set (match_operand 0 "register_operand" "")
18916         (if_then_else (match_operator 1 "comparison_operator" 
18917                                 [(reg FLAGS_REG) (const_int 0)])
18918                       (match_operand 2 "register_operand" "")
18919                       (match_operand 3 "register_operand" "")))]
18920   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18921    && (GET_MODE (operands[0]) == HImode
18922        || (GET_MODE (operands[0]) == QImode 
18923            && (TARGET_PROMOTE_QImode || optimize_size)))"
18924   [(set (match_dup 0)
18925         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18926   "operands[0] = gen_lowpart (SImode, operands[0]);
18927    operands[2] = gen_lowpart (SImode, operands[2]);
18928    operands[3] = gen_lowpart (SImode, operands[3]);")
18929                         
18930 \f
18931 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18932 ;; transform a complex memory operation into two memory to register operations.
18933
18934 ;; Don't push memory operands
18935 (define_peephole2
18936   [(set (match_operand:SI 0 "push_operand" "")
18937         (match_operand:SI 1 "memory_operand" ""))
18938    (match_scratch:SI 2 "r")]
18939   "!optimize_size && !TARGET_PUSH_MEMORY
18940    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18941   [(set (match_dup 2) (match_dup 1))
18942    (set (match_dup 0) (match_dup 2))]
18943   "")
18944
18945 (define_peephole2
18946   [(set (match_operand:DI 0 "push_operand" "")
18947         (match_operand:DI 1 "memory_operand" ""))
18948    (match_scratch:DI 2 "r")]
18949   "!optimize_size && !TARGET_PUSH_MEMORY
18950    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18951   [(set (match_dup 2) (match_dup 1))
18952    (set (match_dup 0) (match_dup 2))]
18953   "")
18954
18955 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18956 ;; SImode pushes.
18957 (define_peephole2
18958   [(set (match_operand:SF 0 "push_operand" "")
18959         (match_operand:SF 1 "memory_operand" ""))
18960    (match_scratch:SF 2 "r")]
18961   "!optimize_size && !TARGET_PUSH_MEMORY
18962    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963   [(set (match_dup 2) (match_dup 1))
18964    (set (match_dup 0) (match_dup 2))]
18965   "")
18966
18967 (define_peephole2
18968   [(set (match_operand:HI 0 "push_operand" "")
18969         (match_operand:HI 1 "memory_operand" ""))
18970    (match_scratch:HI 2 "r")]
18971   "!optimize_size && !TARGET_PUSH_MEMORY
18972    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18973   [(set (match_dup 2) (match_dup 1))
18974    (set (match_dup 0) (match_dup 2))]
18975   "")
18976
18977 (define_peephole2
18978   [(set (match_operand:QI 0 "push_operand" "")
18979         (match_operand:QI 1 "memory_operand" ""))
18980    (match_scratch:QI 2 "q")]
18981   "!optimize_size && !TARGET_PUSH_MEMORY
18982    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18983   [(set (match_dup 2) (match_dup 1))
18984    (set (match_dup 0) (match_dup 2))]
18985   "")
18986
18987 ;; Don't move an immediate directly to memory when the instruction
18988 ;; gets too big.
18989 (define_peephole2
18990   [(match_scratch:SI 1 "r")
18991    (set (match_operand:SI 0 "memory_operand" "")
18992         (const_int 0))]
18993   "! optimize_size
18994    && ! TARGET_USE_MOV0
18995    && TARGET_SPLIT_LONG_MOVES
18996    && get_attr_length (insn) >= ix86_cost->large_insn
18997    && peep2_regno_dead_p (0, FLAGS_REG)"
18998   [(parallel [(set (match_dup 1) (const_int 0))
18999               (clobber (reg:CC FLAGS_REG))])
19000    (set (match_dup 0) (match_dup 1))]
19001   "")
19002
19003 (define_peephole2
19004   [(match_scratch:HI 1 "r")
19005    (set (match_operand:HI 0 "memory_operand" "")
19006         (const_int 0))]
19007   "! optimize_size
19008    && ! TARGET_USE_MOV0
19009    && TARGET_SPLIT_LONG_MOVES
19010    && get_attr_length (insn) >= ix86_cost->large_insn
19011    && peep2_regno_dead_p (0, FLAGS_REG)"
19012   [(parallel [(set (match_dup 2) (const_int 0))
19013               (clobber (reg:CC FLAGS_REG))])
19014    (set (match_dup 0) (match_dup 1))]
19015   "operands[2] = gen_lowpart (SImode, operands[1]);")
19016
19017 (define_peephole2
19018   [(match_scratch:QI 1 "q")
19019    (set (match_operand:QI 0 "memory_operand" "")
19020         (const_int 0))]
19021   "! optimize_size
19022    && ! TARGET_USE_MOV0
19023    && TARGET_SPLIT_LONG_MOVES
19024    && get_attr_length (insn) >= ix86_cost->large_insn
19025    && peep2_regno_dead_p (0, FLAGS_REG)"
19026   [(parallel [(set (match_dup 2) (const_int 0))
19027               (clobber (reg:CC FLAGS_REG))])
19028    (set (match_dup 0) (match_dup 1))]
19029   "operands[2] = gen_lowpart (SImode, operands[1]);")
19030
19031 (define_peephole2
19032   [(match_scratch:SI 2 "r")
19033    (set (match_operand:SI 0 "memory_operand" "")
19034         (match_operand:SI 1 "immediate_operand" ""))]
19035   "! optimize_size
19036    && get_attr_length (insn) >= ix86_cost->large_insn
19037    && TARGET_SPLIT_LONG_MOVES"
19038   [(set (match_dup 2) (match_dup 1))
19039    (set (match_dup 0) (match_dup 2))]
19040   "")
19041
19042 (define_peephole2
19043   [(match_scratch:HI 2 "r")
19044    (set (match_operand:HI 0 "memory_operand" "")
19045         (match_operand:HI 1 "immediate_operand" ""))]
19046   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19047   && TARGET_SPLIT_LONG_MOVES"
19048   [(set (match_dup 2) (match_dup 1))
19049    (set (match_dup 0) (match_dup 2))]
19050   "")
19051
19052 (define_peephole2
19053   [(match_scratch:QI 2 "q")
19054    (set (match_operand:QI 0 "memory_operand" "")
19055         (match_operand:QI 1 "immediate_operand" ""))]
19056   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19057   && TARGET_SPLIT_LONG_MOVES"
19058   [(set (match_dup 2) (match_dup 1))
19059    (set (match_dup 0) (match_dup 2))]
19060   "")
19061
19062 ;; Don't compare memory with zero, load and use a test instead.
19063 (define_peephole2
19064   [(set (match_operand 0 "flags_reg_operand" "")
19065         (match_operator 1 "compare_operator"
19066           [(match_operand:SI 2 "memory_operand" "")
19067            (const_int 0)]))
19068    (match_scratch:SI 3 "r")]
19069   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19070   [(set (match_dup 3) (match_dup 2))
19071    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19072   "")
19073
19074 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19075 ;; Don't split NOTs with a displacement operand, because resulting XOR
19076 ;; will not be pairable anyway.
19077 ;;
19078 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19079 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19080 ;; so this split helps here as well.
19081 ;;
19082 ;; Note: Can't do this as a regular split because we can't get proper
19083 ;; lifetime information then.
19084
19085 (define_peephole2
19086   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19087         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19088   "!optimize_size
19089    && peep2_regno_dead_p (0, FLAGS_REG)
19090    && ((TARGET_PENTIUM 
19091         && (GET_CODE (operands[0]) != MEM
19092             || !memory_displacement_operand (operands[0], SImode)))
19093        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19094   [(parallel [(set (match_dup 0)
19095                    (xor:SI (match_dup 1) (const_int -1)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "")
19098
19099 (define_peephole2
19100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19101         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19102   "!optimize_size
19103    && peep2_regno_dead_p (0, FLAGS_REG)
19104    && ((TARGET_PENTIUM 
19105         && (GET_CODE (operands[0]) != MEM
19106             || !memory_displacement_operand (operands[0], HImode)))
19107        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19108   [(parallel [(set (match_dup 0)
19109                    (xor:HI (match_dup 1) (const_int -1)))
19110               (clobber (reg:CC FLAGS_REG))])]
19111   "")
19112
19113 (define_peephole2
19114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19115         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19116   "!optimize_size
19117    && peep2_regno_dead_p (0, FLAGS_REG)
19118    && ((TARGET_PENTIUM 
19119         && (GET_CODE (operands[0]) != MEM
19120             || !memory_displacement_operand (operands[0], QImode)))
19121        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19122   [(parallel [(set (match_dup 0)
19123                    (xor:QI (match_dup 1) (const_int -1)))
19124               (clobber (reg:CC FLAGS_REG))])]
19125   "")
19126
19127 ;; Non pairable "test imm, reg" instructions can be translated to
19128 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19129 ;; byte opcode instead of two, have a short form for byte operands),
19130 ;; so do it for other CPUs as well.  Given that the value was dead,
19131 ;; this should not create any new dependencies.  Pass on the sub-word
19132 ;; versions if we're concerned about partial register stalls.
19133
19134 (define_peephole2
19135   [(set (match_operand 0 "flags_reg_operand" "")
19136         (match_operator 1 "compare_operator"
19137           [(and:SI (match_operand:SI 2 "register_operand" "")
19138                    (match_operand:SI 3 "immediate_operand" ""))
19139            (const_int 0)]))]
19140   "ix86_match_ccmode (insn, CCNOmode)
19141    && (true_regnum (operands[2]) != 0
19142        || (GET_CODE (operands[3]) == CONST_INT
19143            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19144    && peep2_reg_dead_p (1, operands[2])"
19145   [(parallel
19146      [(set (match_dup 0)
19147            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19148                             (const_int 0)]))
19149       (set (match_dup 2)
19150            (and:SI (match_dup 2) (match_dup 3)))])]
19151   "")
19152
19153 ;; We don't need to handle HImode case, because it will be promoted to SImode
19154 ;; on ! TARGET_PARTIAL_REG_STALL
19155
19156 (define_peephole2
19157   [(set (match_operand 0 "flags_reg_operand" "")
19158         (match_operator 1 "compare_operator"
19159           [(and:QI (match_operand:QI 2 "register_operand" "")
19160                    (match_operand:QI 3 "immediate_operand" ""))
19161            (const_int 0)]))]
19162   "! TARGET_PARTIAL_REG_STALL
19163    && ix86_match_ccmode (insn, CCNOmode)
19164    && true_regnum (operands[2]) != 0
19165    && peep2_reg_dead_p (1, operands[2])"
19166   [(parallel
19167      [(set (match_dup 0)
19168            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19169                             (const_int 0)]))
19170       (set (match_dup 2)
19171            (and:QI (match_dup 2) (match_dup 3)))])]
19172   "")
19173
19174 (define_peephole2
19175   [(set (match_operand 0 "flags_reg_operand" "")
19176         (match_operator 1 "compare_operator"
19177           [(and:SI
19178              (zero_extract:SI
19179                (match_operand 2 "ext_register_operand" "")
19180                (const_int 8)
19181                (const_int 8))
19182              (match_operand 3 "const_int_operand" ""))
19183            (const_int 0)]))]
19184   "! TARGET_PARTIAL_REG_STALL
19185    && ix86_match_ccmode (insn, CCNOmode)
19186    && true_regnum (operands[2]) != 0
19187    && peep2_reg_dead_p (1, operands[2])"
19188   [(parallel [(set (match_dup 0)
19189                    (match_op_dup 1
19190                      [(and:SI
19191                         (zero_extract:SI
19192                           (match_dup 2)
19193                           (const_int 8)
19194                           (const_int 8))
19195                         (match_dup 3))
19196                       (const_int 0)]))
19197               (set (zero_extract:SI (match_dup 2)
19198                                     (const_int 8)
19199                                     (const_int 8))
19200                    (and:SI 
19201                      (zero_extract:SI
19202                        (match_dup 2)
19203                        (const_int 8)
19204                        (const_int 8))
19205                      (match_dup 3)))])]
19206   "")
19207
19208 ;; Don't do logical operations with memory inputs.
19209 (define_peephole2
19210   [(match_scratch:SI 2 "r")
19211    (parallel [(set (match_operand:SI 0 "register_operand" "")
19212                    (match_operator:SI 3 "arith_or_logical_operator"
19213                      [(match_dup 0)
19214                       (match_operand:SI 1 "memory_operand" "")]))
19215               (clobber (reg:CC FLAGS_REG))])]
19216   "! optimize_size && ! TARGET_READ_MODIFY"
19217   [(set (match_dup 2) (match_dup 1))
19218    (parallel [(set (match_dup 0)
19219                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   "")
19222
19223 (define_peephole2
19224   [(match_scratch:SI 2 "r")
19225    (parallel [(set (match_operand:SI 0 "register_operand" "")
19226                    (match_operator:SI 3 "arith_or_logical_operator"
19227                      [(match_operand:SI 1 "memory_operand" "")
19228                       (match_dup 0)]))
19229               (clobber (reg:CC FLAGS_REG))])]
19230   "! optimize_size && ! TARGET_READ_MODIFY"
19231   [(set (match_dup 2) (match_dup 1))
19232    (parallel [(set (match_dup 0)
19233                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19234               (clobber (reg:CC FLAGS_REG))])]
19235   "")
19236
19237 ; Don't do logical operations with memory outputs
19238 ;
19239 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19240 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19241 ; the same decoder scheduling characteristics as the original.
19242
19243 (define_peephole2
19244   [(match_scratch:SI 2 "r")
19245    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19246                    (match_operator:SI 3 "arith_or_logical_operator"
19247                      [(match_dup 0)
19248                       (match_operand:SI 1 "nonmemory_operand" "")]))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19251   [(set (match_dup 2) (match_dup 0))
19252    (parallel [(set (match_dup 2)
19253                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19254               (clobber (reg:CC FLAGS_REG))])
19255    (set (match_dup 0) (match_dup 2))]
19256   "")
19257
19258 (define_peephole2
19259   [(match_scratch:SI 2 "r")
19260    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19261                    (match_operator:SI 3 "arith_or_logical_operator"
19262                      [(match_operand:SI 1 "nonmemory_operand" "")
19263                       (match_dup 0)]))
19264               (clobber (reg:CC FLAGS_REG))])]
19265   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19266   [(set (match_dup 2) (match_dup 0))
19267    (parallel [(set (match_dup 2)
19268                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19269               (clobber (reg:CC FLAGS_REG))])
19270    (set (match_dup 0) (match_dup 2))]
19271   "")
19272
19273 ;; Attempt to always use XOR for zeroing registers.
19274 (define_peephole2
19275   [(set (match_operand 0 "register_operand" "")
19276         (match_operand 1 "const0_operand" ""))]
19277   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19278    && (! TARGET_USE_MOV0 || optimize_size)
19279    && GENERAL_REG_P (operands[0])
19280    && peep2_regno_dead_p (0, FLAGS_REG)"
19281   [(parallel [(set (match_dup 0) (const_int 0))
19282               (clobber (reg:CC FLAGS_REG))])]
19283 {
19284   operands[0] = gen_lowpart (word_mode, operands[0]);
19285 })
19286
19287 (define_peephole2
19288   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19289         (const_int 0))]
19290   "(GET_MODE (operands[0]) == QImode
19291     || GET_MODE (operands[0]) == HImode)
19292    && (! TARGET_USE_MOV0 || optimize_size)
19293    && peep2_regno_dead_p (0, FLAGS_REG)"
19294   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19295               (clobber (reg:CC FLAGS_REG))])])
19296
19297 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19298 (define_peephole2
19299   [(set (match_operand 0 "register_operand" "")
19300         (const_int -1))]
19301   "(GET_MODE (operands[0]) == HImode
19302     || GET_MODE (operands[0]) == SImode 
19303     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19304    && (optimize_size || TARGET_PENTIUM)
19305    && peep2_regno_dead_p (0, FLAGS_REG)"
19306   [(parallel [(set (match_dup 0) (const_int -1))
19307               (clobber (reg:CC FLAGS_REG))])]
19308   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19309                               operands[0]);")
19310
19311 ;; Attempt to convert simple leas to adds. These can be created by
19312 ;; move expanders.
19313 (define_peephole2
19314   [(set (match_operand:SI 0 "register_operand" "")
19315         (plus:SI (match_dup 0)
19316                  (match_operand:SI 1 "nonmemory_operand" "")))]
19317   "peep2_regno_dead_p (0, FLAGS_REG)"
19318   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19319               (clobber (reg:CC FLAGS_REG))])]
19320   "")
19321
19322 (define_peephole2
19323   [(set (match_operand:SI 0 "register_operand" "")
19324         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19325                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19326   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19327   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19328               (clobber (reg:CC FLAGS_REG))])]
19329   "operands[2] = gen_lowpart (SImode, operands[2]);")
19330
19331 (define_peephole2
19332   [(set (match_operand:DI 0 "register_operand" "")
19333         (plus:DI (match_dup 0)
19334                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19335   "peep2_regno_dead_p (0, FLAGS_REG)"
19336   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19337               (clobber (reg:CC FLAGS_REG))])]
19338   "")
19339
19340 (define_peephole2
19341   [(set (match_operand:SI 0 "register_operand" "")
19342         (mult:SI (match_dup 0)
19343                  (match_operand:SI 1 "const_int_operand" "")))]
19344   "exact_log2 (INTVAL (operands[1])) >= 0
19345    && peep2_regno_dead_p (0, FLAGS_REG)"
19346   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19347               (clobber (reg:CC FLAGS_REG))])]
19348   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19349
19350 (define_peephole2
19351   [(set (match_operand:DI 0 "register_operand" "")
19352         (mult:DI (match_dup 0)
19353                  (match_operand:DI 1 "const_int_operand" "")))]
19354   "exact_log2 (INTVAL (operands[1])) >= 0
19355    && peep2_regno_dead_p (0, FLAGS_REG)"
19356   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19357               (clobber (reg:CC FLAGS_REG))])]
19358   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19359
19360 (define_peephole2
19361   [(set (match_operand:SI 0 "register_operand" "")
19362         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19363                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19364   "exact_log2 (INTVAL (operands[2])) >= 0
19365    && REGNO (operands[0]) == REGNO (operands[1])
19366    && peep2_regno_dead_p (0, FLAGS_REG)"
19367   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19368               (clobber (reg:CC FLAGS_REG))])]
19369   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19370
19371 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19372 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19373 ;; many CPUs it is also faster, since special hardware to avoid esp
19374 ;; dependencies is present.
19375
19376 ;; While some of these conversions may be done using splitters, we use peepholes
19377 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19378
19379 ;; Convert prologue esp subtractions to push.
19380 ;; We need register to push.  In order to keep verify_flow_info happy we have
19381 ;; two choices
19382 ;; - use scratch and clobber it in order to avoid dependencies
19383 ;; - use already live register
19384 ;; We can't use the second way right now, since there is no reliable way how to
19385 ;; verify that given register is live.  First choice will also most likely in
19386 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19387 ;; call clobbered registers are dead.  We may want to use base pointer as an
19388 ;; alternative when no register is available later.
19389
19390 (define_peephole2
19391   [(match_scratch:SI 0 "r")
19392    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19393               (clobber (reg:CC FLAGS_REG))
19394               (clobber (mem:BLK (scratch)))])]
19395   "optimize_size || !TARGET_SUB_ESP_4"
19396   [(clobber (match_dup 0))
19397    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19398               (clobber (mem:BLK (scratch)))])])
19399
19400 (define_peephole2
19401   [(match_scratch:SI 0 "r")
19402    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19403               (clobber (reg:CC FLAGS_REG))
19404               (clobber (mem:BLK (scratch)))])]
19405   "optimize_size || !TARGET_SUB_ESP_8"
19406   [(clobber (match_dup 0))
19407    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19408    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19409               (clobber (mem:BLK (scratch)))])])
19410
19411 ;; Convert esp subtractions to push.
19412 (define_peephole2
19413   [(match_scratch:SI 0 "r")
19414    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19415               (clobber (reg:CC FLAGS_REG))])]
19416   "optimize_size || !TARGET_SUB_ESP_4"
19417   [(clobber (match_dup 0))
19418    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19419
19420 (define_peephole2
19421   [(match_scratch:SI 0 "r")
19422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19423               (clobber (reg:CC FLAGS_REG))])]
19424   "optimize_size || !TARGET_SUB_ESP_8"
19425   [(clobber (match_dup 0))
19426    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19427    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19428
19429 ;; Convert epilogue deallocator to pop.
19430 (define_peephole2
19431   [(match_scratch:SI 0 "r")
19432    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19433               (clobber (reg:CC FLAGS_REG))
19434               (clobber (mem:BLK (scratch)))])]
19435   "optimize_size || !TARGET_ADD_ESP_4"
19436   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19437               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19438               (clobber (mem:BLK (scratch)))])]
19439   "")
19440
19441 ;; Two pops case is tricky, since pop causes dependency on destination register.
19442 ;; We use two registers if available.
19443 (define_peephole2
19444   [(match_scratch:SI 0 "r")
19445    (match_scratch:SI 1 "r")
19446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447               (clobber (reg:CC FLAGS_REG))
19448               (clobber (mem:BLK (scratch)))])]
19449   "optimize_size || !TARGET_ADD_ESP_8"
19450   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452               (clobber (mem:BLK (scratch)))])
19453    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19455   "")
19456
19457 (define_peephole2
19458   [(match_scratch:SI 0 "r")
19459    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460               (clobber (reg:CC FLAGS_REG))
19461               (clobber (mem:BLK (scratch)))])]
19462   "optimize_size"
19463   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465               (clobber (mem:BLK (scratch)))])
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   "")
19469
19470 ;; Convert esp additions to pop.
19471 (define_peephole2
19472   [(match_scratch:SI 0 "r")
19473    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19474               (clobber (reg:CC FLAGS_REG))])]
19475   ""
19476   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19477               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19478   "")
19479
19480 ;; Two pops case is tricky, since pop causes dependency on destination register.
19481 ;; We use two registers if available.
19482 (define_peephole2
19483   [(match_scratch:SI 0 "r")
19484    (match_scratch:SI 1 "r")
19485    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   ""
19488   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19490    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19491               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19492   "")
19493
19494 (define_peephole2
19495   [(match_scratch:SI 0 "r")
19496    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19497               (clobber (reg:CC FLAGS_REG))])]
19498   "optimize_size"
19499   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19500               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19501    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19502               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19503   "")
19504 \f
19505 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19506 ;; required and register dies.  Similarly for 128 to plus -128.
19507 (define_peephole2
19508   [(set (match_operand 0 "flags_reg_operand" "")
19509         (match_operator 1 "compare_operator"
19510           [(match_operand 2 "register_operand" "")
19511            (match_operand 3 "const_int_operand" "")]))]
19512   "(INTVAL (operands[3]) == -1
19513     || INTVAL (operands[3]) == 1
19514     || INTVAL (operands[3]) == 128)
19515    && ix86_match_ccmode (insn, CCGCmode)
19516    && peep2_reg_dead_p (1, operands[2])"
19517   [(parallel [(set (match_dup 0)
19518                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19519               (clobber (match_dup 2))])]
19520   "")
19521 \f
19522 (define_peephole2
19523   [(match_scratch:DI 0 "r")
19524    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19525               (clobber (reg:CC FLAGS_REG))
19526               (clobber (mem:BLK (scratch)))])]
19527   "optimize_size || !TARGET_SUB_ESP_4"
19528   [(clobber (match_dup 0))
19529    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19530               (clobber (mem:BLK (scratch)))])])
19531
19532 (define_peephole2
19533   [(match_scratch:DI 0 "r")
19534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19535               (clobber (reg:CC FLAGS_REG))
19536               (clobber (mem:BLK (scratch)))])]
19537   "optimize_size || !TARGET_SUB_ESP_8"
19538   [(clobber (match_dup 0))
19539    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19540    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19541               (clobber (mem:BLK (scratch)))])])
19542
19543 ;; Convert esp subtractions to push.
19544 (define_peephole2
19545   [(match_scratch:DI 0 "r")
19546    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19547               (clobber (reg:CC FLAGS_REG))])]
19548   "optimize_size || !TARGET_SUB_ESP_4"
19549   [(clobber (match_dup 0))
19550    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19551
19552 (define_peephole2
19553   [(match_scratch:DI 0 "r")
19554    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19555               (clobber (reg:CC FLAGS_REG))])]
19556   "optimize_size || !TARGET_SUB_ESP_8"
19557   [(clobber (match_dup 0))
19558    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19559    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19560
19561 ;; Convert epilogue deallocator to pop.
19562 (define_peephole2
19563   [(match_scratch:DI 0 "r")
19564    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19565               (clobber (reg:CC FLAGS_REG))
19566               (clobber (mem:BLK (scratch)))])]
19567   "optimize_size || !TARGET_ADD_ESP_4"
19568   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19569               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19570               (clobber (mem:BLK (scratch)))])]
19571   "")
19572
19573 ;; Two pops case is tricky, since pop causes dependency on destination register.
19574 ;; We use two registers if available.
19575 (define_peephole2
19576   [(match_scratch:DI 0 "r")
19577    (match_scratch:DI 1 "r")
19578    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19579               (clobber (reg:CC FLAGS_REG))
19580               (clobber (mem:BLK (scratch)))])]
19581   "optimize_size || !TARGET_ADD_ESP_8"
19582   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19583               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19584               (clobber (mem:BLK (scratch)))])
19585    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19586               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19587   "")
19588
19589 (define_peephole2
19590   [(match_scratch:DI 0 "r")
19591    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19592               (clobber (reg:CC FLAGS_REG))
19593               (clobber (mem:BLK (scratch)))])]
19594   "optimize_size"
19595   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19596               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19597               (clobber (mem:BLK (scratch)))])
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   "")
19601
19602 ;; Convert esp additions to pop.
19603 (define_peephole2
19604   [(match_scratch:DI 0 "r")
19605    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19606               (clobber (reg:CC FLAGS_REG))])]
19607   ""
19608   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19609               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19610   "")
19611
19612 ;; Two pops case is tricky, since pop causes dependency on destination register.
19613 ;; We use two registers if available.
19614 (define_peephole2
19615   [(match_scratch:DI 0 "r")
19616    (match_scratch:DI 1 "r")
19617    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19618               (clobber (reg:CC FLAGS_REG))])]
19619   ""
19620   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19621               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19622    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19623               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19624   "")
19625
19626 (define_peephole2
19627   [(match_scratch:DI 0 "r")
19628    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19629               (clobber (reg:CC FLAGS_REG))])]
19630   "optimize_size"
19631   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19633    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19634               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19635   "")
19636 \f
19637 ;; Convert imul by three, five and nine into lea
19638 (define_peephole2
19639   [(parallel
19640     [(set (match_operand:SI 0 "register_operand" "")
19641           (mult:SI (match_operand:SI 1 "register_operand" "")
19642                    (match_operand:SI 2 "const_int_operand" "")))
19643      (clobber (reg:CC FLAGS_REG))])]
19644   "INTVAL (operands[2]) == 3
19645    || INTVAL (operands[2]) == 5
19646    || INTVAL (operands[2]) == 9"
19647   [(set (match_dup 0)
19648         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19649                  (match_dup 1)))]
19650   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19651
19652 (define_peephole2
19653   [(parallel
19654     [(set (match_operand:SI 0 "register_operand" "")
19655           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19656                    (match_operand:SI 2 "const_int_operand" "")))
19657      (clobber (reg:CC FLAGS_REG))])]
19658   "!optimize_size 
19659    && (INTVAL (operands[2]) == 3
19660        || INTVAL (operands[2]) == 5
19661        || INTVAL (operands[2]) == 9)"
19662   [(set (match_dup 0) (match_dup 1))
19663    (set (match_dup 0)
19664         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19665                  (match_dup 0)))]
19666   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19667
19668 (define_peephole2
19669   [(parallel
19670     [(set (match_operand:DI 0 "register_operand" "")
19671           (mult:DI (match_operand:DI 1 "register_operand" "")
19672                    (match_operand:DI 2 "const_int_operand" "")))
19673      (clobber (reg:CC FLAGS_REG))])]
19674   "TARGET_64BIT
19675    && (INTVAL (operands[2]) == 3
19676        || INTVAL (operands[2]) == 5
19677        || INTVAL (operands[2]) == 9)"
19678   [(set (match_dup 0)
19679         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19680                  (match_dup 1)))]
19681   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19682
19683 (define_peephole2
19684   [(parallel
19685     [(set (match_operand:DI 0 "register_operand" "")
19686           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19687                    (match_operand:DI 2 "const_int_operand" "")))
19688      (clobber (reg:CC FLAGS_REG))])]
19689   "TARGET_64BIT
19690    && !optimize_size 
19691    && (INTVAL (operands[2]) == 3
19692        || INTVAL (operands[2]) == 5
19693        || INTVAL (operands[2]) == 9)"
19694   [(set (match_dup 0) (match_dup 1))
19695    (set (match_dup 0)
19696         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19697                  (match_dup 0)))]
19698   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19699
19700 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19701 ;; imul $32bit_imm, reg, reg is direct decoded.
19702 (define_peephole2
19703   [(match_scratch:DI 3 "r")
19704    (parallel [(set (match_operand:DI 0 "register_operand" "")
19705                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19706                             (match_operand:DI 2 "immediate_operand" "")))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   "TARGET_K8 && !optimize_size
19709    && (GET_CODE (operands[2]) != CONST_INT
19710        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19711   [(set (match_dup 3) (match_dup 1))
19712    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19713               (clobber (reg:CC FLAGS_REG))])]
19714 "")
19715
19716 (define_peephole2
19717   [(match_scratch:SI 3 "r")
19718    (parallel [(set (match_operand:SI 0 "register_operand" "")
19719                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19720                             (match_operand:SI 2 "immediate_operand" "")))
19721               (clobber (reg:CC FLAGS_REG))])]
19722   "TARGET_K8 && !optimize_size
19723    && (GET_CODE (operands[2]) != CONST_INT
19724        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19725   [(set (match_dup 3) (match_dup 1))
19726    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19727               (clobber (reg:CC FLAGS_REG))])]
19728 "")
19729
19730 (define_peephole2
19731   [(match_scratch:SI 3 "r")
19732    (parallel [(set (match_operand:DI 0 "register_operand" "")
19733                    (zero_extend:DI
19734                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19735                               (match_operand:SI 2 "immediate_operand" ""))))
19736               (clobber (reg:CC FLAGS_REG))])]
19737   "TARGET_K8 && !optimize_size
19738    && (GET_CODE (operands[2]) != CONST_INT
19739        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19740   [(set (match_dup 3) (match_dup 1))
19741    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19742               (clobber (reg:CC FLAGS_REG))])]
19743 "")
19744
19745 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19746 ;; Convert it into imul reg, reg
19747 ;; It would be better to force assembler to encode instruction using long
19748 ;; immediate, but there is apparently no way to do so.
19749 (define_peephole2
19750   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19751                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19752                             (match_operand:DI 2 "const_int_operand" "")))
19753               (clobber (reg:CC FLAGS_REG))])
19754    (match_scratch:DI 3 "r")]
19755   "TARGET_K8 && !optimize_size
19756    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19757   [(set (match_dup 3) (match_dup 2))
19758    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19759               (clobber (reg:CC FLAGS_REG))])]
19760 {
19761   if (!rtx_equal_p (operands[0], operands[1]))
19762     emit_move_insn (operands[0], operands[1]);
19763 })
19764
19765 (define_peephole2
19766   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19767                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19768                             (match_operand:SI 2 "const_int_operand" "")))
19769               (clobber (reg:CC FLAGS_REG))])
19770    (match_scratch:SI 3 "r")]
19771   "TARGET_K8 && !optimize_size
19772    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19773   [(set (match_dup 3) (match_dup 2))
19774    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19775               (clobber (reg:CC FLAGS_REG))])]
19776 {
19777   if (!rtx_equal_p (operands[0], operands[1]))
19778     emit_move_insn (operands[0], operands[1]);
19779 })
19780
19781 (define_peephole2
19782   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19783                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19784                             (match_operand:HI 2 "immediate_operand" "")))
19785               (clobber (reg:CC FLAGS_REG))])
19786    (match_scratch:HI 3 "r")]
19787   "TARGET_K8 && !optimize_size"
19788   [(set (match_dup 3) (match_dup 2))
19789    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19790               (clobber (reg:CC FLAGS_REG))])]
19791 {
19792   if (!rtx_equal_p (operands[0], operands[1]))
19793     emit_move_insn (operands[0], operands[1]);
19794 })
19795
19796 ;; After splitting up read-modify operations, array accesses with memory
19797 ;; operands might end up in form:
19798 ;;  sall    $2, %eax
19799 ;;  movl    4(%esp), %edx
19800 ;;  addl    %edx, %eax
19801 ;; instead of pre-splitting:
19802 ;;  sall    $2, %eax
19803 ;;  addl    4(%esp), %eax
19804 ;; Turn it into:
19805 ;;  movl    4(%esp), %edx
19806 ;;  leal    (%edx,%eax,4), %eax
19807
19808 (define_peephole2
19809   [(parallel [(set (match_operand 0 "register_operand" "")
19810                    (ashift (match_operand 1 "register_operand" "")
19811                            (match_operand 2 "const_int_operand" "")))
19812                (clobber (reg:CC FLAGS_REG))])
19813    (set (match_operand 3 "register_operand")
19814         (match_operand 4 "x86_64_general_operand" ""))
19815    (parallel [(set (match_operand 5 "register_operand" "")
19816                    (plus (match_operand 6 "register_operand" "")
19817                          (match_operand 7 "register_operand" "")))
19818                    (clobber (reg:CC FLAGS_REG))])]
19819   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19820    /* Validate MODE for lea.  */
19821    && ((!TARGET_PARTIAL_REG_STALL
19822         && (GET_MODE (operands[0]) == QImode
19823             || GET_MODE (operands[0]) == HImode))
19824        || GET_MODE (operands[0]) == SImode 
19825        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826    /* We reorder load and the shift.  */
19827    && !rtx_equal_p (operands[1], operands[3])
19828    && !reg_overlap_mentioned_p (operands[0], operands[4])
19829    /* Last PLUS must consist of operand 0 and 3.  */
19830    && !rtx_equal_p (operands[0], operands[3])
19831    && (rtx_equal_p (operands[3], operands[6])
19832        || rtx_equal_p (operands[3], operands[7]))
19833    && (rtx_equal_p (operands[0], operands[6])
19834        || rtx_equal_p (operands[0], operands[7]))
19835    /* The intermediate operand 0 must die or be same as output.  */
19836    && (rtx_equal_p (operands[0], operands[5])
19837        || peep2_reg_dead_p (3, operands[0]))"
19838   [(set (match_dup 3) (match_dup 4))
19839    (set (match_dup 0) (match_dup 1))]
19840 {
19841   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19842   int scale = 1 << INTVAL (operands[2]);
19843   rtx index = gen_lowpart (Pmode, operands[1]);
19844   rtx base = gen_lowpart (Pmode, operands[3]);
19845   rtx dest = gen_lowpart (mode, operands[5]);
19846
19847   operands[1] = gen_rtx_PLUS (Pmode, base,
19848                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19849   if (mode != Pmode)
19850     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19851   operands[0] = dest;
19852 })
19853 \f
19854 ;; Call-value patterns last so that the wildcard operand does not
19855 ;; disrupt insn-recog's switch tables.
19856
19857 (define_insn "*call_value_pop_0"
19858   [(set (match_operand 0 "" "")
19859         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19860               (match_operand:SI 2 "" "")))
19861    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19862                             (match_operand:SI 3 "immediate_operand" "")))]
19863   "!TARGET_64BIT"
19864 {
19865   if (SIBLING_CALL_P (insn))
19866     return "jmp\t%P1";
19867   else
19868     return "call\t%P1";
19869 }
19870   [(set_attr "type" "callv")])
19871
19872 (define_insn "*call_value_pop_1"
19873   [(set (match_operand 0 "" "")
19874         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19875               (match_operand:SI 2 "" "")))
19876    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19877                             (match_operand:SI 3 "immediate_operand" "i")))]
19878   "!TARGET_64BIT"
19879 {
19880   if (constant_call_address_operand (operands[1], Pmode))
19881     {
19882       if (SIBLING_CALL_P (insn))
19883         return "jmp\t%P1";
19884       else
19885         return "call\t%P1";
19886     }
19887   if (SIBLING_CALL_P (insn))
19888     return "jmp\t%A1";
19889   else
19890     return "call\t%A1";
19891 }
19892   [(set_attr "type" "callv")])
19893
19894 (define_insn "*call_value_0"
19895   [(set (match_operand 0 "" "")
19896         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19897               (match_operand:SI 2 "" "")))]
19898   "!TARGET_64BIT"
19899 {
19900   if (SIBLING_CALL_P (insn))
19901     return "jmp\t%P1";
19902   else
19903     return "call\t%P1";
19904 }
19905   [(set_attr "type" "callv")])
19906
19907 (define_insn "*call_value_0_rex64"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910               (match_operand:DI 2 "const_int_operand" "")))]
19911   "TARGET_64BIT"
19912 {
19913   if (SIBLING_CALL_P (insn))
19914     return "jmp\t%P1";
19915   else
19916     return "call\t%P1";
19917 }
19918   [(set_attr "type" "callv")])
19919
19920 (define_insn "*call_value_1"
19921   [(set (match_operand 0 "" "")
19922         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19923               (match_operand:SI 2 "" "")))]
19924   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19925 {
19926   if (constant_call_address_operand (operands[1], Pmode))
19927     return "call\t%P1";
19928   return "call\t%A1";
19929 }
19930   [(set_attr "type" "callv")])
19931
19932 (define_insn "*sibcall_value_1"
19933   [(set (match_operand 0 "" "")
19934         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19935               (match_operand:SI 2 "" "")))]
19936   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19937 {
19938   if (constant_call_address_operand (operands[1], Pmode))
19939     return "jmp\t%P1";
19940   return "jmp\t%A1";
19941 }
19942   [(set_attr "type" "callv")])
19943
19944 (define_insn "*call_value_1_rex64"
19945   [(set (match_operand 0 "" "")
19946         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19947               (match_operand:DI 2 "" "")))]
19948   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19949 {
19950   if (constant_call_address_operand (operands[1], Pmode))
19951     return "call\t%P1";
19952   return "call\t%A1";
19953 }
19954   [(set_attr "type" "callv")])
19955
19956 (define_insn "*sibcall_value_1_rex64"
19957   [(set (match_operand 0 "" "")
19958         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19959               (match_operand:DI 2 "" "")))]
19960   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19961   "jmp\t%P1"
19962   [(set_attr "type" "callv")])
19963
19964 (define_insn "*sibcall_value_1_rex64_v"
19965   [(set (match_operand 0 "" "")
19966         (call (mem:QI (reg:DI 40))
19967               (match_operand:DI 1 "" "")))]
19968   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19969   "jmp\t*%%r11"
19970   [(set_attr "type" "callv")])
19971 \f
19972 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19973 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19974 ;; caught for use by garbage collectors and the like.  Using an insn that
19975 ;; maps to SIGILL makes it more likely the program will rightfully die.
19976 ;; Keeping with tradition, "6" is in honor of #UD.
19977 (define_insn "trap"
19978   [(trap_if (const_int 1) (const_int 6))]
19979   ""
19980   ".word\t0x0b0f"
19981   [(set_attr "length" "2")])
19982
19983 (define_expand "sse_prologue_save"
19984   [(parallel [(set (match_operand:BLK 0 "" "")
19985                    (unspec:BLK [(reg:DI 21)
19986                                 (reg:DI 22)
19987                                 (reg:DI 23)
19988                                 (reg:DI 24)
19989                                 (reg:DI 25)
19990                                 (reg:DI 26)
19991                                 (reg:DI 27)
19992                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19993               (use (match_operand:DI 1 "register_operand" ""))
19994               (use (match_operand:DI 2 "immediate_operand" ""))
19995               (use (label_ref:DI (match_operand 3 "" "")))])]
19996   "TARGET_64BIT"
19997   "")
19998
19999 (define_insn "*sse_prologue_save_insn"
20000   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20001                           (match_operand:DI 4 "const_int_operand" "n")))
20002         (unspec:BLK [(reg:DI 21)
20003                      (reg:DI 22)
20004                      (reg:DI 23)
20005                      (reg:DI 24)
20006                      (reg:DI 25)
20007                      (reg:DI 26)
20008                      (reg:DI 27)
20009                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20010    (use (match_operand:DI 1 "register_operand" "r"))
20011    (use (match_operand:DI 2 "const_int_operand" "i"))
20012    (use (label_ref:DI (match_operand 3 "" "X")))]
20013   "TARGET_64BIT
20014    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20015    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20016   "*
20017 {
20018   int i;
20019   operands[0] = gen_rtx_MEM (Pmode,
20020                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20021   output_asm_insn (\"jmp\\t%A1\", operands);
20022   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20023     {
20024       operands[4] = adjust_address (operands[0], DImode, i*16);
20025       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20026       PUT_MODE (operands[4], TImode);
20027       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20028         output_asm_insn (\"rex\", operands);
20029       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20030     }
20031   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20032                              CODE_LABEL_NUMBER (operands[3]));
20033   RET;
20034 }
20035   "
20036   [(set_attr "type" "other")
20037    (set_attr "length_immediate" "0")
20038    (set_attr "length_address" "0")
20039    (set_attr "length" "135")
20040    (set_attr "memory" "store")
20041    (set_attr "modrm" "0")
20042    (set_attr "mode" "DI")])
20043
20044 (define_expand "prefetch"
20045   [(prefetch (match_operand 0 "address_operand" "")
20046              (match_operand:SI 1 "const_int_operand" "")
20047              (match_operand:SI 2 "const_int_operand" ""))]
20048   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20049 {
20050   int rw = INTVAL (operands[1]);
20051   int locality = INTVAL (operands[2]);
20052
20053   gcc_assert (rw == 0 || rw == 1);
20054   gcc_assert (locality >= 0 && locality <= 3);
20055   gcc_assert (GET_MODE (operands[0]) == Pmode
20056               || GET_MODE (operands[0]) == VOIDmode);
20057
20058   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20059      supported by SSE counterpart or the SSE prefetch is not available
20060      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20061      of locality.  */
20062   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20063     operands[2] = GEN_INT (3);
20064   else
20065     operands[1] = const0_rtx;
20066 })
20067
20068 (define_insn "*prefetch_sse"
20069   [(prefetch (match_operand:SI 0 "address_operand" "p")
20070              (const_int 0)
20071              (match_operand:SI 1 "const_int_operand" ""))]
20072   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20073 {
20074   static const char * const patterns[4] = {
20075    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20076   };
20077
20078   int locality = INTVAL (operands[1]);
20079   gcc_assert (locality >= 0 && locality <= 3);
20080
20081   return patterns[locality];  
20082 }
20083   [(set_attr "type" "sse")
20084    (set_attr "memory" "none")])
20085
20086 (define_insn "*prefetch_sse_rex"
20087   [(prefetch (match_operand:DI 0 "address_operand" "p")
20088              (const_int 0)
20089              (match_operand:SI 1 "const_int_operand" ""))]
20090   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20091 {
20092   static const char * const patterns[4] = {
20093    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20094   };
20095
20096   int locality = INTVAL (operands[1]);
20097   gcc_assert (locality >= 0 && locality <= 3);
20098
20099   return patterns[locality];  
20100 }
20101   [(set_attr "type" "sse")
20102    (set_attr "memory" "none")])
20103
20104 (define_insn "*prefetch_3dnow"
20105   [(prefetch (match_operand:SI 0 "address_operand" "p")
20106              (match_operand:SI 1 "const_int_operand" "n")
20107              (const_int 3))]
20108   "TARGET_3DNOW && !TARGET_64BIT"
20109 {
20110   if (INTVAL (operands[1]) == 0)
20111     return "prefetch\t%a0";
20112   else
20113     return "prefetchw\t%a0";
20114 }
20115   [(set_attr "type" "mmx")
20116    (set_attr "memory" "none")])
20117
20118 (define_insn "*prefetch_3dnow_rex"
20119   [(prefetch (match_operand:DI 0 "address_operand" "p")
20120              (match_operand:SI 1 "const_int_operand" "n")
20121              (const_int 3))]
20122   "TARGET_3DNOW && TARGET_64BIT"
20123 {
20124   if (INTVAL (operands[1]) == 0)
20125     return "prefetch\t%a0";
20126   else
20127     return "prefetchw\t%a0";
20128 }
20129   [(set_attr "type" "mmx")
20130    (set_attr "memory" "none")])
20131
20132 (define_expand "stack_protect_set"
20133   [(match_operand 0 "memory_operand" "")
20134    (match_operand 1 "memory_operand" "")]
20135   ""
20136 {
20137 #ifdef TARGET_THREAD_SSP_OFFSET
20138   if (TARGET_64BIT)
20139     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20140                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20141   else
20142     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20143                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20144 #else
20145   if (TARGET_64BIT)
20146     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20147   else
20148     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20149 #endif
20150   DONE;
20151 })
20152
20153 (define_insn "stack_protect_set_si"
20154   [(set (match_operand:SI 0 "memory_operand" "=m")
20155         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20156    (set (match_scratch:SI 2 "=&r") (const_int 0))
20157    (clobber (reg:CC FLAGS_REG))]
20158   ""
20159   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20160   [(set_attr "type" "multi")])
20161
20162 (define_insn "stack_protect_set_di"
20163   [(set (match_operand:DI 0 "memory_operand" "=m")
20164         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20165    (set (match_scratch:DI 2 "=&r") (const_int 0))
20166    (clobber (reg:CC FLAGS_REG))]
20167   "TARGET_64BIT"
20168   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20169   [(set_attr "type" "multi")])
20170
20171 (define_insn "stack_tls_protect_set_si"
20172   [(set (match_operand:SI 0 "memory_operand" "=m")
20173         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20174    (set (match_scratch:SI 2 "=&r") (const_int 0))
20175    (clobber (reg:CC FLAGS_REG))]
20176   ""
20177   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20178   [(set_attr "type" "multi")])
20179
20180 (define_insn "stack_tls_protect_set_di"
20181   [(set (match_operand:DI 0 "memory_operand" "=m")
20182         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20183    (set (match_scratch:DI 2 "=&r") (const_int 0))
20184    (clobber (reg:CC FLAGS_REG))]
20185   "TARGET_64BIT"
20186   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20187   [(set_attr "type" "multi")])
20188
20189 (define_expand "stack_protect_test"
20190   [(match_operand 0 "memory_operand" "")
20191    (match_operand 1 "memory_operand" "")
20192    (match_operand 2 "" "")]
20193   ""
20194 {
20195   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20196   ix86_compare_op0 = operands[0];
20197   ix86_compare_op1 = operands[1];
20198   ix86_compare_emitted = flags;
20199
20200 #ifdef TARGET_THREAD_SSP_OFFSET
20201   if (TARGET_64BIT)
20202     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20203                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20204   else
20205     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20206                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20207 #else
20208   if (TARGET_64BIT)
20209     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20210   else
20211     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20212 #endif
20213   emit_jump_insn (gen_beq (operands[2]));
20214   DONE;
20215 })
20216
20217 (define_insn "stack_protect_test_si"
20218   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20219         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20220                      (match_operand:SI 2 "memory_operand" "m")]
20221                     UNSPEC_SP_TEST))
20222    (clobber (match_scratch:SI 3 "=&r"))]
20223   ""
20224   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20225   [(set_attr "type" "multi")])
20226
20227 (define_insn "stack_protect_test_di"
20228   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20229         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20230                      (match_operand:DI 2 "memory_operand" "m")]
20231                     UNSPEC_SP_TEST))
20232    (clobber (match_scratch:DI 3 "=&r"))]
20233   "TARGET_64BIT"
20234   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20235   [(set_attr "type" "multi")])
20236
20237 (define_insn "stack_tls_protect_test_si"
20238   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20239         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20240                      (match_operand:SI 2 "const_int_operand" "i")]
20241                     UNSPEC_SP_TLS_TEST))
20242    (clobber (match_scratch:SI 3 "=r"))]
20243   ""
20244   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20245   [(set_attr "type" "multi")])
20246
20247 (define_insn "stack_tls_protect_test_di"
20248   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20249         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20250                      (match_operand:DI 2 "const_int_operand" "i")]
20251                     UNSPEC_SP_TLS_TEST))
20252    (clobber (match_scratch:DI 3 "=r"))]
20253   "TARGET_64BIT"
20254   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20255   [(set_attr "type" "multi")])
20256
20257 (include "sse.md")
20258 (include "mmx.md")
20259 (include "sync.md")