OSDN Git Service

PR debug/25023
[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               (ior (and (match_operand 0 "register_operand" "")
318                         (match_operand 1 "immediate_operand" ""))
319                    (ior (and (match_operand 0 "ax_reg_operand" "")
320                              (match_operand 1 "memory_displacement_only_operand" ""))
321                         (and (match_operand 0 "memory_displacement_only_operand" "")
322                              (match_operand 1 "ax_reg_operand" "")))))
323            (const_int 0)
324          (and (eq_attr "type" "call")
325               (match_operand 0 "constant_call_address_operand" ""))
326              (const_int 0)
327          (and (eq_attr "type" "callv")
328               (match_operand 1 "constant_call_address_operand" ""))
329              (const_int 0)
330          ]
331          (const_int 1)))
332
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
336 ;; other insns.
337 (define_attr "length" ""
338   (cond [(eq_attr "type" "other,multi,fistp,frndint")
339            (const_int 16)
340          (eq_attr "type" "fcmp")
341            (const_int 4)
342          (eq_attr "unit" "i387")
343            (plus (const_int 2)
344                  (plus (attr "prefix_data16")
345                        (attr "length_address")))]
346          (plus (plus (attr "modrm")
347                      (plus (attr "prefix_0f")
348                            (plus (attr "prefix_rex")
349                                  (const_int 1))))
350                (plus (attr "prefix_rep")
351                      (plus (attr "prefix_data16")
352                            (plus (attr "length_immediate")
353                                  (attr "length_address")))))))
354
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
358
359 (define_attr "memory" "none,load,store,both,unknown"
360   (cond [(eq_attr "type" "other,multi,str")
361            (const_string "unknown")
362          (eq_attr "type" "lea,fcmov,fpspc,cld")
363            (const_string "none")
364          (eq_attr "type" "fistp,leave")
365            (const_string "both")
366          (eq_attr "type" "frndint")
367            (const_string "load")
368          (eq_attr "type" "push")
369            (if_then_else (match_operand 1 "memory_operand" "")
370              (const_string "both")
371              (const_string "store"))
372          (eq_attr "type" "pop")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "both")
375              (const_string "load"))
376          (eq_attr "type" "setcc")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "store")
379              (const_string "none"))
380          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381            (if_then_else (ior (match_operand 0 "memory_operand" "")
382                               (match_operand 1 "memory_operand" ""))
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "ibr")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "load")
388              (const_string "none"))
389          (eq_attr "type" "call")
390            (if_then_else (match_operand 0 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (eq_attr "type" "callv")
394            (if_then_else (match_operand 1 "constant_call_address_operand" "")
395              (const_string "none")
396              (const_string "load"))
397          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398               (match_operand 1 "memory_operand" ""))
399            (const_string "both")
400          (and (match_operand 0 "memory_operand" "")
401               (match_operand 1 "memory_operand" ""))
402            (const_string "both")
403          (match_operand 0 "memory_operand" "")
404            (const_string "store")
405          (match_operand 1 "memory_operand" "")
406            (const_string "load")
407          (and (eq_attr "type"
408                  "!alu1,negnot,ishift1,
409                    imov,imovx,icmp,test,
410                    fmov,fcmp,fsgn,
411                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412                    mmx,mmxmov,mmxcmp,mmxcvt")
413               (match_operand 2 "memory_operand" ""))
414            (const_string "load")
415          (and (eq_attr "type" "icmov")
416               (match_operand 3 "memory_operand" ""))
417            (const_string "load")
418         ]
419         (const_string "none")))
420
421 ;; Indicates if an instruction has both an immediate and a displacement.
422
423 (define_attr "imm_disp" "false,true,unknown"
424   (cond [(eq_attr "type" "other,multi")
425            (const_string "unknown")
426          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 1 "immediate_operand" "")))
429            (const_string "true")
430          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431               (and (match_operand 0 "memory_displacement_operand" "")
432                    (match_operand 2 "immediate_operand" "")))
433            (const_string "true")
434         ]
435         (const_string "false")))
436
437 ;; Indicates if an FP operation has an integer source.
438
439 (define_attr "fp_int_src" "false,true"
440   (const_string "false"))
441
442 ;; Defines rounding mode of an FP operation.
443
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445   (const_string "any"))
446
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449   [(set_attr "length" "128")
450    (set_attr "type" "multi")])
451
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
454  
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
457
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
460
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
463  
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
466
467 \f
468 ;; Scheduling descriptions
469
470 (include "pentium.md")
471 (include "ppro.md")
472 (include "k6.md")
473 (include "athlon.md")
474
475 \f
476 ;; Operand and operator predicates
477
478 (include "predicates.md")
479
480 \f
481 ;; Compare instructions.
482
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
486
487 (define_expand "cmpti"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490                     (match_operand:TI 1 "x86_64_general_operand" "")))]
491   "TARGET_64BIT"
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (TImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpdi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503                     (match_operand:DI 1 "x86_64_general_operand" "")))]
504   ""
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (DImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_expand "cmpsi"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516                     (match_operand:SI 1 "general_operand" "")))]
517   ""
518 {
519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520     operands[0] = force_reg (SImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmphi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529                     (match_operand:HI 1 "general_operand" "")))]
530   ""
531 {
532   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533     operands[0] = force_reg (HImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpqi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542                     (match_operand:QI 1 "general_operand" "")))]
543   "TARGET_QIMODE_MATH"
544 {
545   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546     operands[0] = force_reg (QImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_insn "cmpdi_ccno_1_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:DI 1 "const0_operand" "n,n")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{q}\t{%0, %0|%0, %0}
559    cmp{q}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "DI")])
563
564 (define_insn "*cmpdi_minus_1_rex64"
565   [(set (reg FLAGS_REG)
566         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
568                  (const_int 0)))]
569   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "DI")])
573
574 (define_expand "cmpdi_1_rex64"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577                     (match_operand:DI 1 "general_operand" "")))]
578   "TARGET_64BIT"
579   "")
580
581 (define_insn "cmpdi_1_insn_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586   "cmp{q}\t{%1, %0|%0, %1}"
587   [(set_attr "type" "icmp")
588    (set_attr "mode" "DI")])
589
590
591 (define_insn "*cmpsi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:SI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{l}\t{%0, %0|%0, %0}
598    cmp{l}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "SI")])
602
603 (define_insn "*cmpsi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:SI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "SI")])
612
613 (define_expand "cmpsi_1"
614   [(set (reg:CC FLAGS_REG)
615         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616                     (match_operand:SI 1 "general_operand" "ri,mr")))]
617   ""
618   "")
619
620 (define_insn "*cmpsi_1_insn"
621   [(set (reg FLAGS_REG)
622         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                  (match_operand:SI 1 "general_operand" "ri,mr")))]
624   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625     && ix86_match_ccmode (insn, CCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_insn "*cmphi_ccno_1"
631   [(set (reg FLAGS_REG)
632         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633                  (match_operand:HI 1 "const0_operand" "n,n")))]
634   "ix86_match_ccmode (insn, CCNOmode)"
635   "@
636    test{w}\t{%0, %0|%0, %0}
637    cmp{w}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "test,icmp")
639    (set_attr "length_immediate" "0,1")
640    (set_attr "mode" "HI")])
641
642 (define_insn "*cmphi_minus_1"
643   [(set (reg FLAGS_REG)
644         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645                            (match_operand:HI 1 "general_operand" "ri,mr"))
646                  (const_int 0)))]
647   "ix86_match_ccmode (insn, CCGOCmode)"
648   "cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "icmp")
650    (set_attr "mode" "HI")])
651
652 (define_insn "*cmphi_1"
653   [(set (reg FLAGS_REG)
654         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655                  (match_operand:HI 1 "general_operand" "ri,mr")))]
656   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657    && ix86_match_ccmode (insn, CCmode)"
658   "cmp{w}\t{%1, %0|%0, %1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "HI")])
661
662 (define_insn "*cmpqi_ccno_1"
663   [(set (reg FLAGS_REG)
664         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665                  (match_operand:QI 1 "const0_operand" "n,n")))]
666   "ix86_match_ccmode (insn, CCNOmode)"
667   "@
668    test{b}\t{%0, %0|%0, %0}
669    cmp{b}\t{$0, %0|%0, 0}"
670   [(set_attr "type" "test,icmp")
671    (set_attr "length_immediate" "0,1")
672    (set_attr "mode" "QI")])
673
674 (define_insn "*cmpqi_1"
675   [(set (reg FLAGS_REG)
676         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677                  (match_operand:QI 1 "general_operand" "qi,mq")))]
678   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679     && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%1, %0|%0, %1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_minus_1"
685   [(set (reg FLAGS_REG)
686         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687                            (match_operand:QI 1 "general_operand" "qi,mq"))
688                  (const_int 0)))]
689   "ix86_match_ccmode (insn, CCGOCmode)"
690   "cmp{b}\t{%1, %0|%0, %1}"
691   [(set_attr "type" "icmp")
692    (set_attr "mode" "QI")])
693
694 (define_insn "*cmpqi_ext_1"
695   [(set (reg FLAGS_REG)
696         (compare
697           (match_operand:QI 0 "general_operand" "Qm")
698           (subreg:QI
699             (zero_extract:SI
700               (match_operand 1 "ext_register_operand" "Q")
701               (const_int 8)
702               (const_int 8)) 0)))]
703   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704   "cmp{b}\t{%h1, %0|%0, %h1}"
705   [(set_attr "type" "icmp")
706    (set_attr "mode" "QI")])
707
708 (define_insn "*cmpqi_ext_1_rex64"
709   [(set (reg FLAGS_REG)
710         (compare
711           (match_operand:QI 0 "register_operand" "Q")
712           (subreg:QI
713             (zero_extract:SI
714               (match_operand 1 "ext_register_operand" "Q")
715               (const_int 8)
716               (const_int 8)) 0)))]
717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718   "cmp{b}\t{%h1, %0|%0, %h1}"
719   [(set_attr "type" "icmp")
720    (set_attr "mode" "QI")])
721
722 (define_insn "*cmpqi_ext_2"
723   [(set (reg FLAGS_REG)
724         (compare
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 0 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)
730           (match_operand:QI 1 "const0_operand" "n")))]
731   "ix86_match_ccmode (insn, CCNOmode)"
732   "test{b}\t%h0, %h0"
733   [(set_attr "type" "test")
734    (set_attr "length_immediate" "0")
735    (set_attr "mode" "QI")])
736
737 (define_expand "cmpqi_ext_3"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC
740           (subreg:QI
741             (zero_extract:SI
742               (match_operand 0 "ext_register_operand" "")
743               (const_int 8)
744               (const_int 8)) 0)
745           (match_operand:QI 1 "general_operand" "")))]
746   ""
747   "")
748
749 (define_insn "cmpqi_ext_3_insn"
750   [(set (reg FLAGS_REG)
751         (compare
752           (subreg:QI
753             (zero_extract:SI
754               (match_operand 0 "ext_register_operand" "Q")
755               (const_int 8)
756               (const_int 8)) 0)
757           (match_operand:QI 1 "general_operand" "Qmn")))]
758   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759   "cmp{b}\t{%1, %h0|%h0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "QI")])
762
763 (define_insn "cmpqi_ext_3_insn_rex64"
764   [(set (reg FLAGS_REG)
765         (compare
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773   "cmp{b}\t{%1, %h0|%h0, %1}"
774   [(set_attr "type" "icmp")
775    (set_attr "mode" "QI")])
776
777 (define_insn "*cmpqi_ext_4"
778   [(set (reg FLAGS_REG)
779         (compare
780           (subreg:QI
781             (zero_extract:SI
782               (match_operand 0 "ext_register_operand" "Q")
783               (const_int 8)
784               (const_int 8)) 0)
785           (subreg:QI
786             (zero_extract:SI
787               (match_operand 1 "ext_register_operand" "Q")
788               (const_int 8)
789               (const_int 8)) 0)))]
790   "ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%h1, %h0|%h0, %h1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares.  Which is what
798 ;; the old patterns did, but with many more of them.
799
800 (define_expand "cmpxf"
801   [(set (reg:CC FLAGS_REG)
802         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803                     (match_operand:XF 1 "nonmemory_operand" "")))]
804   "TARGET_80387"
805 {
806   ix86_compare_op0 = operands[0];
807   ix86_compare_op1 = operands[1];
808   DONE;
809 })
810
811 (define_expand "cmpdf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
816 {
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
820 })
821
822 (define_expand "cmpsf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || TARGET_SSE_MATH"
827 {
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
831 })
832
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
835 ;;
836 ;; CCFPmode     compare with exceptions
837 ;; CCFPUmode    compare with no exceptions
838
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
841
842 (define_insn "*cmpfp_0"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand 1 "register_operand" "f")
847              (match_operand 2 "const0_operand" "X"))]
848         UNSPEC_FNSTSW))]
849   "TARGET_80387
850    && FLOAT_MODE_P (GET_MODE (operands[1]))
851    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
855    (set (attr "mode")
856      (cond [(match_operand:SF 1 "" "")
857               (const_string "SF")
858             (match_operand:DF 1 "" "")
859               (const_string "DF")
860            ]
861            (const_string "XF")))])
862
863 (define_insn "*cmpfp_sf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:SF 1 "register_operand" "f")
868              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "unit" "i387")
874    (set_attr "mode" "SF")])
875
876 (define_insn "*cmpfp_df"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFP
880              (match_operand:DF 1 "register_operand" "f")
881              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387"
884   "* return output_fp_compare (insn, operands, 0, 0);"
885   [(set_attr "type" "multi")
886    (set_attr "unit" "i387")
887    (set_attr "mode" "DF")])
888
889 (define_insn "*cmpfp_xf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:XF 1 "register_operand" "f")
894              (match_operand:XF 2 "register_operand" "f"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "XF")])
901
902 (define_insn "*cmpfp_u"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 0, 1);"
913   [(set_attr "type" "multi")
914    (set_attr "unit" "i387")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
922
923 (define_insn "*cmpfp_<mode>"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFP
927              (match_operand 1 "register_operand" "f")
928              (match_operator 3 "float_operator"
929                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
930           UNSPEC_FNSTSW))]
931   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932    && FLOAT_MODE_P (GET_MODE (operands[1]))
933    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934   "* return output_fp_compare (insn, operands, 0, 0);"
935   [(set_attr "type" "multi")
936    (set_attr "unit" "i387")
937    (set_attr "fp_int_src" "true")
938    (set_attr "mode" "<MODE>")])
939
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
942
943 (define_insn "x86_fnstsw_1"
944   [(set (match_operand:HI 0 "register_operand" "=a")
945         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
946   "TARGET_80387"
947   "fnstsw\t%0"
948   [(set_attr "length" "2")
949    (set_attr "mode" "SI")
950    (set_attr "unit" "i387")])
951
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
954
955 (define_insn "x86_sahf_1"
956   [(set (reg:CC FLAGS_REG)
957         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
958   "!TARGET_64BIT"
959   "sahf"
960   [(set_attr "length" "1")
961    (set_attr "athlon_decode" "vector")
962    (set_attr "mode" "SI")])
963
964 ;; Pentium Pro can do steps 1 through 3 in one go.
965
966 (define_insn "*cmpfp_i_mixed"
967   [(set (reg:CCFP FLAGS_REG)
968         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
970   "TARGET_MIX_SSE_I387
971    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973   "* return output_fp_compare (insn, operands, 1, 0);"
974   [(set_attr "type" "fcmp,ssecomi")
975    (set (attr "mode")
976      (if_then_else (match_operand:SF 1 "" "")
977         (const_string "SF")
978         (const_string "DF")))
979    (set_attr "athlon_decode" "vector")])
980
981 (define_insn "*cmpfp_i_sse"
982   [(set (reg:CCFP FLAGS_REG)
983         (compare:CCFP (match_operand 0 "register_operand" "x")
984                       (match_operand 1 "nonimmediate_operand" "xm")))]
985   "TARGET_SSE_MATH
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 0);"
989   [(set_attr "type" "ssecomi")
990    (set (attr "mode")
991      (if_then_else (match_operand:SF 1 "" "")
992         (const_string "SF")
993         (const_string "DF")))
994    (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_i_i387"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP (match_operand 0 "register_operand" "f")
999                       (match_operand 1 "register_operand" "f")))]
1000   "TARGET_80387 && TARGET_CMOVE
1001    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002    && FLOAT_MODE_P (GET_MODE (operands[0]))
1003    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004   "* return output_fp_compare (insn, operands, 1, 0);"
1005   [(set_attr "type" "fcmp")
1006    (set (attr "mode")
1007      (cond [(match_operand:SF 1 "" "")
1008               (const_string "SF")
1009             (match_operand:DF 1 "" "")
1010               (const_string "DF")
1011            ]
1012            (const_string "XF")))
1013    (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_iu_mixed"
1016   [(set (reg:CCFPU FLAGS_REG)
1017         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019   "TARGET_MIX_SSE_I387
1020    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 1);"
1023   [(set_attr "type" "fcmp,ssecomi")
1024    (set (attr "mode")
1025      (if_then_else (match_operand:SF 1 "" "")
1026         (const_string "SF")
1027         (const_string "DF")))
1028    (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_iu_sse"
1031   [(set (reg:CCFPU FLAGS_REG)
1032         (compare:CCFPU (match_operand 0 "register_operand" "x")
1033                        (match_operand 1 "nonimmediate_operand" "xm")))]
1034   "TARGET_SSE_MATH
1035    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037   "* return output_fp_compare (insn, operands, 1, 1);"
1038   [(set_attr "type" "ssecomi")
1039    (set (attr "mode")
1040      (if_then_else (match_operand:SF 1 "" "")
1041         (const_string "SF")
1042         (const_string "DF")))
1043    (set_attr "athlon_decode" "vector")])
1044
1045 (define_insn "*cmpfp_iu_387"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f")
1048                        (match_operand 1 "register_operand" "f")))]
1049   "TARGET_80387 && TARGET_CMOVE
1050    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051    && FLOAT_MODE_P (GET_MODE (operands[0]))
1052    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053   "* return output_fp_compare (insn, operands, 1, 1);"
1054   [(set_attr "type" "fcmp")
1055    (set (attr "mode")
1056      (cond [(match_operand:SF 1 "" "")
1057               (const_string "SF")
1058             (match_operand:DF 1 "" "")
1059               (const_string "DF")
1060            ]
1061            (const_string "XF")))
1062    (set_attr "athlon_decode" "vector")])
1063 \f
1064 ;; Move instructions.
1065
1066 ;; General case of fullword move.
1067
1068 (define_expand "movsi"
1069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070         (match_operand:SI 1 "general_operand" ""))]
1071   ""
1072   "ix86_expand_move (SImode, operands); DONE;")
1073
1074 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1075 ;; general_operand.
1076 ;;
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1082
1083 (define_insn "*pushsi2"
1084   [(set (match_operand:SI 0 "push_operand" "=<")
1085         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1086   "!TARGET_64BIT"
1087   "push{l}\t%1"
1088   [(set_attr "type" "push")
1089    (set_attr "mode" "SI")])
1090
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093   [(set (match_operand:SI 0 "push_operand" "=X")
1094         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1095   "TARGET_64BIT"
1096   "push{q}\t%q1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1099
1100 (define_insn "*pushsi2_prologue"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103    (clobber (mem:BLK (scratch)))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 (define_insn "*popsi1_epilogue"
1110   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111         (mem:SI (reg:SI SP_REG)))
1112    (set (reg:SI SP_REG)
1113         (plus:SI (reg:SI SP_REG) (const_int 4)))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "pop{l}\t%0"
1117   [(set_attr "type" "pop")
1118    (set_attr "mode" "SI")])
1119
1120 (define_insn "popsi1"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1125   "!TARGET_64BIT"
1126   "pop{l}\t%0"
1127   [(set_attr "type" "pop")
1128    (set_attr "mode" "SI")])
1129
1130 (define_insn "*movsi_xor"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (match_operand:SI 1 "const0_operand" "i"))
1133    (clobber (reg:CC FLAGS_REG))]
1134   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135   "xor{l}\t{%0, %0|%0, %0}"
1136   [(set_attr "type" "alu1")
1137    (set_attr "mode" "SI")
1138    (set_attr "length_immediate" "0")])
1139  
1140 (define_insn "*movsi_or"
1141   [(set (match_operand:SI 0 "register_operand" "=r")
1142         (match_operand:SI 1 "immediate_operand" "i"))
1143    (clobber (reg:CC FLAGS_REG))]
1144   "reload_completed
1145    && operands[1] == constm1_rtx
1146    && (TARGET_PENTIUM || optimize_size)"
1147 {
1148   operands[1] = constm1_rtx;
1149   return "or{l}\t{%1, %0|%0, %1}";
1150 }
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "1")])
1154
1155 (define_insn "*movsi_1"
1156   [(set (match_operand:SI 0 "nonimmediate_operand"
1157                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158         (match_operand:SI 1 "general_operand"
1159                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1160   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1161 {
1162   switch (get_attr_type (insn))
1163     {
1164     case TYPE_SSELOG1:
1165       if (get_attr_mode (insn) == MODE_TI)
1166         return "pxor\t%0, %0";
1167       return "xorps\t%0, %0";
1168
1169     case TYPE_SSEMOV:
1170       switch (get_attr_mode (insn))
1171         {
1172         case MODE_TI:
1173           return "movdqa\t{%1, %0|%0, %1}";
1174         case MODE_V4SF:
1175           return "movaps\t{%1, %0|%0, %1}";
1176         case MODE_SI:
1177           return "movd\t{%1, %0|%0, %1}";
1178         case MODE_SF:
1179           return "movss\t{%1, %0|%0, %1}";
1180         default:
1181           gcc_unreachable ();
1182         }
1183
1184     case TYPE_MMXADD:
1185       return "pxor\t%0, %0";
1186
1187     case TYPE_MMXMOV:
1188       if (get_attr_mode (insn) == MODE_DI)
1189         return "movq\t{%1, %0|%0, %1}";
1190       return "movd\t{%1, %0|%0, %1}";
1191
1192     case TYPE_LEA:
1193       return "lea{l}\t{%1, %0|%0, %1}";
1194
1195     default:
1196       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197       return "mov{l}\t{%1, %0|%0, %1}";
1198     }
1199 }
1200   [(set (attr "type")
1201      (cond [(eq_attr "alternative" "2")
1202               (const_string "mmxadd")
1203             (eq_attr "alternative" "3,4,5")
1204               (const_string "mmxmov")
1205             (eq_attr "alternative" "6")
1206               (const_string "sselog1")
1207             (eq_attr "alternative" "7,8,9,10,11")
1208               (const_string "ssemov")
1209             (match_operand:DI 1 "pic_32bit_operand" "")
1210               (const_string "lea")
1211            ]
1212            (const_string "imov")))
1213    (set (attr "mode")
1214      (cond [(eq_attr "alternative" "2,3")
1215               (const_string "DI")
1216             (eq_attr "alternative" "6,7")
1217               (if_then_else
1218                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219                 (const_string "V4SF")
1220                 (const_string "TI"))
1221             (and (eq_attr "alternative" "8,9,10,11")
1222                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1223               (const_string "SF")
1224            ]
1225            (const_string "SI")))])
1226
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1234   "@
1235    movabs{l}\t{%1, %P0|%P0, %1}
1236    mov{l}\t{%1, %a0|%a0, %1}"
1237   [(set_attr "type" "imov")
1238    (set_attr "modrm" "0,*")
1239    (set_attr "length_address" "8,0")
1240    (set_attr "length_immediate" "0,*")
1241    (set_attr "memory" "store")
1242    (set_attr "mode" "SI")])
1243
1244 (define_insn "*movabssi_2_rex64"
1245   [(set (match_operand:SI 0 "register_operand" "=a,r")
1246         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1248   "@
1249    movabs{l}\t{%P1, %0|%0, %P1}
1250    mov{l}\t{%a1, %0|%0, %a1}"
1251   [(set_attr "type" "imov")
1252    (set_attr "modrm" "0,*")
1253    (set_attr "length_address" "8,0")
1254    (set_attr "length_immediate" "0")
1255    (set_attr "memory" "load")
1256    (set_attr "mode" "SI")])
1257
1258 (define_insn "*swapsi"
1259   [(set (match_operand:SI 0 "register_operand" "+r")
1260         (match_operand:SI 1 "register_operand" "+r"))
1261    (set (match_dup 1)
1262         (match_dup 0))]
1263   ""
1264   "xchg{l}\t%1, %0"
1265   [(set_attr "type" "imov")
1266    (set_attr "mode" "SI")
1267    (set_attr "pent_pair" "np")
1268    (set_attr "athlon_decode" "vector")])
1269
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=X")
1278         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1279   "!TARGET_64BIT"
1280   "push{l}\t%k1"
1281   [(set_attr "type" "push")
1282    (set_attr "mode" "SI")])
1283
1284 ;; For 64BIT abi we always round up to 8 bytes.
1285 (define_insn "*pushhi2_rex64"
1286   [(set (match_operand:HI 0 "push_operand" "=X")
1287         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1288   "TARGET_64BIT"
1289   "push{q}\t%q1"
1290   [(set_attr "type" "push")
1291    (set_attr "mode" "DI")])
1292
1293 (define_insn "*movhi_1"
1294   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1295         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1296   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1297 {
1298   switch (get_attr_type (insn))
1299     {
1300     case TYPE_IMOVX:
1301       /* movzwl is faster than movw on p2 due to partial word stalls,
1302          though not as fast as an aligned movl.  */
1303       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1304     default:
1305       if (get_attr_mode (insn) == MODE_SI)
1306         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1307       else
1308         return "mov{w}\t{%1, %0|%0, %1}";
1309     }
1310 }
1311   [(set (attr "type")
1312      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1313               (const_string "imov")
1314             (and (eq_attr "alternative" "0")
1315                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316                           (const_int 0))
1317                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1318                           (const_int 0))))
1319               (const_string "imov")
1320             (and (eq_attr "alternative" "1,2")
1321                  (match_operand:HI 1 "aligned_operand" ""))
1322               (const_string "imov")
1323             (and (ne (symbol_ref "TARGET_MOVX")
1324                      (const_int 0))
1325                  (eq_attr "alternative" "0,2"))
1326               (const_string "imovx")
1327            ]
1328            (const_string "imov")))
1329     (set (attr "mode")
1330       (cond [(eq_attr "type" "imovx")
1331                (const_string "SI")
1332              (and (eq_attr "alternative" "1,2")
1333                   (match_operand:HI 1 "aligned_operand" ""))
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "0")
1336                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337                            (const_int 0))
1338                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1339                            (const_int 0))))
1340                (const_string "SI")
1341             ]
1342             (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351   "@
1352    movabs{w}\t{%1, %P0|%P0, %1}
1353    mov{w}\t{%1, %a0|%a0, %1}"
1354   [(set_attr "type" "imov")
1355    (set_attr "modrm" "0,*")
1356    (set_attr "length_address" "8,0")
1357    (set_attr "length_immediate" "0,*")
1358    (set_attr "memory" "store")
1359    (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362   [(set (match_operand:HI 0 "register_operand" "=a,r")
1363         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365   "@
1366    movabs{w}\t{%P1, %0|%0, %P1}
1367    mov{w}\t{%a1, %0|%0, %a1}"
1368   [(set_attr "type" "imov")
1369    (set_attr "modrm" "0,*")
1370    (set_attr "length_address" "8,0")
1371    (set_attr "length_immediate" "0")
1372    (set_attr "memory" "load")
1373    (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376   [(set (match_operand:HI 0 "register_operand" "+r")
1377         (match_operand:HI 1 "register_operand" "+r"))
1378    (set (match_dup 1)
1379         (match_dup 0))]
1380   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1381   "xchg{l}\t%k1, %k0"
1382   [(set_attr "type" "imov")
1383    (set_attr "mode" "SI")
1384    (set_attr "pent_pair" "np")
1385    (set_attr "athlon_decode" "vector")])
1386
1387 (define_insn "*swaphi_2"
1388   [(set (match_operand:HI 0 "register_operand" "+r")
1389         (match_operand:HI 1 "register_operand" "+r"))
1390    (set (match_dup 1)
1391         (match_dup 0))]
1392   "TARGET_PARTIAL_REG_STALL"
1393   "xchg{w}\t%1, %0"
1394   [(set_attr "type" "imov")
1395    (set_attr "mode" "HI")
1396    (set_attr "pent_pair" "np")
1397    (set_attr "athlon_decode" "vector")])
1398
1399 (define_expand "movstricthi"
1400   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1401         (match_operand:HI 1 "general_operand" ""))]
1402   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1403 {
1404   /* Don't generate memory->memory moves, go through a register */
1405   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1406     operands[1] = force_reg (HImode, operands[1]);
1407 })
1408
1409 (define_insn "*movstricthi_1"
1410   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1411         (match_operand:HI 1 "general_operand" "rn,m"))]
1412   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1413    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1414   "mov{w}\t{%1, %0|%0, %1}"
1415   [(set_attr "type" "imov")
1416    (set_attr "mode" "HI")])
1417
1418 (define_insn "*movstricthi_xor"
1419   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1420         (match_operand:HI 1 "const0_operand" "i"))
1421    (clobber (reg:CC FLAGS_REG))]
1422   "reload_completed
1423    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1424   "xor{w}\t{%0, %0|%0, %0}"
1425   [(set_attr "type" "alu1")
1426    (set_attr "mode" "HI")
1427    (set_attr "length_immediate" "0")])
1428
1429 (define_expand "movqi"
1430   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1431         (match_operand:QI 1 "general_operand" ""))]
1432   ""
1433   "ix86_expand_move (QImode, operands); DONE;")
1434
1435 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1436 ;; "push a byte".  But actually we use pushl, which has the effect
1437 ;; of rounding the amount pushed up to a word.
1438
1439 (define_insn "*pushqi2"
1440   [(set (match_operand:QI 0 "push_operand" "=X")
1441         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1442   "!TARGET_64BIT"
1443   "push{l}\t%k1"
1444   [(set_attr "type" "push")
1445    (set_attr "mode" "SI")])
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" "DI")])
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,qm,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 [(and (eq_attr "alternative" "5")
1485                  (not (match_operand:QI 1 "aligned_operand" "")))
1486               (const_string "imovx")
1487             (ne (symbol_ref "optimize_size") (const_int 0))
1488               (const_string "imov")
1489             (and (eq_attr "alternative" "3")
1490                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491                           (const_int 0))
1492                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1493                           (const_int 0))))
1494               (const_string "imov")
1495             (eq_attr "alternative" "3,5")
1496               (const_string "imovx")
1497             (and (ne (symbol_ref "TARGET_MOVX")
1498                      (const_int 0))
1499                  (eq_attr "alternative" "2"))
1500               (const_string "imovx")
1501            ]
1502            (const_string "imov")))
1503    (set (attr "mode")
1504       (cond [(eq_attr "alternative" "3,4,5")
1505                (const_string "SI")
1506              (eq_attr "alternative" "6")
1507                (const_string "QI")
1508              (eq_attr "type" "imovx")
1509                (const_string "SI")
1510              (and (eq_attr "type" "imov")
1511                   (and (eq_attr "alternative" "0,1")
1512                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513                            (const_int 0))))
1514                (const_string "SI")
1515              ;; Avoid partial register stalls when not using QImode arithmetic
1516              (and (eq_attr "type" "imov")
1517                   (and (eq_attr "alternative" "0,1")
1518                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                 (const_int 0))
1520                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1521                                 (const_int 0)))))
1522                (const_string "SI")
1523            ]
1524            (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527   [(parallel [(match_operand:QI 0 "" "=m")
1528               (match_operand:QI 1 "register_operand" "r")
1529               (match_operand:QI 2 "register_operand" "=&q")])]
1530   ""
1531 {
1532   rtx op0, op1, op2;
1533   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1536   if (! q_regs_operand (op1, QImode))
1537     {
1538       emit_insn (gen_movqi (op2, op1));
1539       op1 = op2;
1540     }
1541   emit_insn (gen_movqi (op0, op1));
1542   DONE;
1543 })
1544
1545 (define_insn "*swapqi_1"
1546   [(set (match_operand:QI 0 "register_operand" "+r")
1547         (match_operand:QI 1 "register_operand" "+r"))
1548    (set (match_dup 1)
1549         (match_dup 0))]
1550   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551   "xchg{l}\t%k1, %k0"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "SI")
1554    (set_attr "pent_pair" "np")
1555    (set_attr "athlon_decode" "vector")])
1556
1557 (define_insn "*swapqi_2"
1558   [(set (match_operand:QI 0 "register_operand" "+q")
1559         (match_operand:QI 1 "register_operand" "+q"))
1560    (set (match_dup 1)
1561         (match_dup 0))]
1562   "TARGET_PARTIAL_REG_STALL"
1563   "xchg{b}\t%1, %0"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "QI")
1566    (set_attr "pent_pair" "np")
1567    (set_attr "athlon_decode" "vector")])
1568
1569 (define_expand "movstrictqi"
1570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1571         (match_operand:QI 1 "general_operand" ""))]
1572   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1573 {
1574   /* Don't generate memory->memory moves, go through a register.  */
1575   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1576     operands[1] = force_reg (QImode, operands[1]);
1577 })
1578
1579 (define_insn "*movstrictqi_1"
1580   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1581         (match_operand:QI 1 "general_operand" "*qn,m"))]
1582   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1583    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1584   "mov{b}\t{%1, %0|%0, %1}"
1585   [(set_attr "type" "imov")
1586    (set_attr "mode" "QI")])
1587
1588 (define_insn "*movstrictqi_xor"
1589   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1590         (match_operand:QI 1 "const0_operand" "i"))
1591    (clobber (reg:CC FLAGS_REG))]
1592   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1593   "xor{b}\t{%0, %0|%0, %0}"
1594   [(set_attr "type" "alu1")
1595    (set_attr "mode" "QI")
1596    (set_attr "length_immediate" "0")])
1597
1598 (define_insn "*movsi_extv_1"
1599   [(set (match_operand:SI 0 "register_operand" "=R")
1600         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1601                          (const_int 8)
1602                          (const_int 8)))]
1603   ""
1604   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1605   [(set_attr "type" "imovx")
1606    (set_attr "mode" "SI")])
1607
1608 (define_insn "*movhi_extv_1"
1609   [(set (match_operand:HI 0 "register_operand" "=R")
1610         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1611                          (const_int 8)
1612                          (const_int 8)))]
1613   ""
1614   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1615   [(set_attr "type" "imovx")
1616    (set_attr "mode" "SI")])
1617
1618 (define_insn "*movqi_extv_1"
1619   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1620         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1621                          (const_int 8)
1622                          (const_int 8)))]
1623   "!TARGET_64BIT"
1624 {
1625   switch (get_attr_type (insn))
1626     {
1627     case TYPE_IMOVX:
1628       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1629     default:
1630       return "mov{b}\t{%h1, %0|%0, %h1}";
1631     }
1632 }
1633   [(set (attr "type")
1634      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1635                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1636                              (ne (symbol_ref "TARGET_MOVX")
1637                                  (const_int 0))))
1638         (const_string "imovx")
1639         (const_string "imov")))
1640    (set (attr "mode")
1641      (if_then_else (eq_attr "type" "imovx")
1642         (const_string "SI")
1643         (const_string "QI")))])
1644
1645 (define_insn "*movqi_extv_1_rex64"
1646   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1647         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1648                          (const_int 8)
1649                          (const_int 8)))]
1650   "TARGET_64BIT"
1651 {
1652   switch (get_attr_type (insn))
1653     {
1654     case TYPE_IMOVX:
1655       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1656     default:
1657       return "mov{b}\t{%h1, %0|%0, %h1}";
1658     }
1659 }
1660   [(set (attr "type")
1661      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1662                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1663                              (ne (symbol_ref "TARGET_MOVX")
1664                                  (const_int 0))))
1665         (const_string "imovx")
1666         (const_string "imov")))
1667    (set (attr "mode")
1668      (if_then_else (eq_attr "type" "imovx")
1669         (const_string "SI")
1670         (const_string "QI")))])
1671
1672 ;; Stores and loads of ax to arbitrary constant address.
1673 ;; We fake an second form of instruction to force reload to load address
1674 ;; into register when rax is not available
1675 (define_insn "*movabsqi_1_rex64"
1676   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1677         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1678   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1679   "@
1680    movabs{b}\t{%1, %P0|%P0, %1}
1681    mov{b}\t{%1, %a0|%a0, %1}"
1682   [(set_attr "type" "imov")
1683    (set_attr "modrm" "0,*")
1684    (set_attr "length_address" "8,0")
1685    (set_attr "length_immediate" "0,*")
1686    (set_attr "memory" "store")
1687    (set_attr "mode" "QI")])
1688
1689 (define_insn "*movabsqi_2_rex64"
1690   [(set (match_operand:QI 0 "register_operand" "=a,r")
1691         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1692   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1693   "@
1694    movabs{b}\t{%P1, %0|%0, %P1}
1695    mov{b}\t{%a1, %0|%0, %a1}"
1696   [(set_attr "type" "imov")
1697    (set_attr "modrm" "0,*")
1698    (set_attr "length_address" "8,0")
1699    (set_attr "length_immediate" "0")
1700    (set_attr "memory" "load")
1701    (set_attr "mode" "QI")])
1702
1703 (define_insn "*movdi_extzv_1"
1704   [(set (match_operand:DI 0 "register_operand" "=R")
1705         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1706                          (const_int 8)
1707                          (const_int 8)))]
1708   "TARGET_64BIT"
1709   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1710   [(set_attr "type" "imovx")
1711    (set_attr "mode" "DI")])
1712
1713 (define_insn "*movsi_extzv_1"
1714   [(set (match_operand:SI 0 "register_operand" "=R")
1715         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1716                          (const_int 8)
1717                          (const_int 8)))]
1718   ""
1719   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1720   [(set_attr "type" "imovx")
1721    (set_attr "mode" "SI")])
1722
1723 (define_insn "*movqi_extzv_2"
1724   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1725         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1726                                     (const_int 8)
1727                                     (const_int 8)) 0))]
1728   "!TARGET_64BIT"
1729 {
1730   switch (get_attr_type (insn))
1731     {
1732     case TYPE_IMOVX:
1733       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1734     default:
1735       return "mov{b}\t{%h1, %0|%0, %h1}";
1736     }
1737 }
1738   [(set (attr "type")
1739      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1740                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1741                              (ne (symbol_ref "TARGET_MOVX")
1742                                  (const_int 0))))
1743         (const_string "imovx")
1744         (const_string "imov")))
1745    (set (attr "mode")
1746      (if_then_else (eq_attr "type" "imovx")
1747         (const_string "SI")
1748         (const_string "QI")))])
1749
1750 (define_insn "*movqi_extzv_2_rex64"
1751   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1752         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1753                                     (const_int 8)
1754                                     (const_int 8)) 0))]
1755   "TARGET_64BIT"
1756 {
1757   switch (get_attr_type (insn))
1758     {
1759     case TYPE_IMOVX:
1760       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1761     default:
1762       return "mov{b}\t{%h1, %0|%0, %h1}";
1763     }
1764 }
1765   [(set (attr "type")
1766      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1767                         (ne (symbol_ref "TARGET_MOVX")
1768                             (const_int 0)))
1769         (const_string "imovx")
1770         (const_string "imov")))
1771    (set (attr "mode")
1772      (if_then_else (eq_attr "type" "imovx")
1773         (const_string "SI")
1774         (const_string "QI")))])
1775
1776 (define_insn "movsi_insv_1"
1777   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778                          (const_int 8)
1779                          (const_int 8))
1780         (match_operand:SI 1 "general_operand" "Qmn"))]
1781   "!TARGET_64BIT"
1782   "mov{b}\t{%b1, %h0|%h0, %b1}"
1783   [(set_attr "type" "imov")
1784    (set_attr "mode" "QI")])
1785
1786 (define_insn "movdi_insv_1_rex64"
1787   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1788                          (const_int 8)
1789                          (const_int 8))
1790         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1791   "TARGET_64BIT"
1792   "mov{b}\t{%b1, %h0|%h0, %b1}"
1793   [(set_attr "type" "imov")
1794    (set_attr "mode" "QI")])
1795
1796 (define_insn "*movqi_insv_2"
1797   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1798                          (const_int 8)
1799                          (const_int 8))
1800         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1801                      (const_int 8)))]
1802   ""
1803   "mov{b}\t{%h1, %h0|%h0, %h1}"
1804   [(set_attr "type" "imov")
1805    (set_attr "mode" "QI")])
1806
1807 (define_expand "movdi"
1808   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1809         (match_operand:DI 1 "general_operand" ""))]
1810   ""
1811   "ix86_expand_move (DImode, operands); DONE;")
1812
1813 (define_insn "*pushdi"
1814   [(set (match_operand:DI 0 "push_operand" "=<")
1815         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1816   "!TARGET_64BIT"
1817   "#")
1818
1819 (define_insn "*pushdi2_rex64"
1820   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1821         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1822   "TARGET_64BIT"
1823   "@
1824    push{q}\t%1
1825    #"
1826   [(set_attr "type" "push,multi")
1827    (set_attr "mode" "DI")])
1828
1829 ;; Convert impossible pushes of immediate to existing instructions.
1830 ;; First try to get scratch register and go through it.  In case this
1831 ;; fails, push sign extended lower part first and then overwrite
1832 ;; upper part by 32bit move.
1833 (define_peephole2
1834   [(match_scratch:DI 2 "r")
1835    (set (match_operand:DI 0 "push_operand" "")
1836         (match_operand:DI 1 "immediate_operand" ""))]
1837   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838    && !x86_64_immediate_operand (operands[1], DImode)"
1839   [(set (match_dup 2) (match_dup 1))
1840    (set (match_dup 0) (match_dup 2))]
1841   "")
1842
1843 ;; We need to define this as both peepholer and splitter for case
1844 ;; peephole2 pass is not run.
1845 ;; "&& 1" is needed to keep it from matching the previous pattern.
1846 (define_peephole2
1847   [(set (match_operand:DI 0 "push_operand" "")
1848         (match_operand:DI 1 "immediate_operand" ""))]
1849   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1851   [(set (match_dup 0) (match_dup 1))
1852    (set (match_dup 2) (match_dup 3))]
1853   "split_di (operands + 1, 1, operands + 2, operands + 3);
1854    operands[1] = gen_lowpart (DImode, operands[2]);
1855    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856                                                     GEN_INT (4)));
1857   ")
1858
1859 (define_split
1860   [(set (match_operand:DI 0 "push_operand" "")
1861         (match_operand:DI 1 "immediate_operand" ""))]
1862   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1863                     ? flow2_completed : reload_completed)
1864    && !symbolic_operand (operands[1], DImode)
1865    && !x86_64_immediate_operand (operands[1], DImode)"
1866   [(set (match_dup 0) (match_dup 1))
1867    (set (match_dup 2) (match_dup 3))]
1868   "split_di (operands + 1, 1, operands + 2, operands + 3);
1869    operands[1] = gen_lowpart (DImode, operands[2]);
1870    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871                                                     GEN_INT (4)));
1872   ")
1873
1874 (define_insn "*pushdi2_prologue_rex64"
1875   [(set (match_operand:DI 0 "push_operand" "=<")
1876         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1877    (clobber (mem:BLK (scratch)))]
1878   "TARGET_64BIT"
1879   "push{q}\t%1"
1880   [(set_attr "type" "push")
1881    (set_attr "mode" "DI")])
1882
1883 (define_insn "*popdi1_epilogue_rex64"
1884   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1885         (mem:DI (reg:DI SP_REG)))
1886    (set (reg:DI SP_REG)
1887         (plus:DI (reg:DI SP_REG) (const_int 8)))
1888    (clobber (mem:BLK (scratch)))]
1889   "TARGET_64BIT"
1890   "pop{q}\t%0"
1891   [(set_attr "type" "pop")
1892    (set_attr "mode" "DI")])
1893
1894 (define_insn "popdi1"
1895   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1896         (mem:DI (reg:DI SP_REG)))
1897    (set (reg:DI SP_REG)
1898         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1899   "TARGET_64BIT"
1900   "pop{q}\t%0"
1901   [(set_attr "type" "pop")
1902    (set_attr "mode" "DI")])
1903
1904 (define_insn "*movdi_xor_rex64"
1905   [(set (match_operand:DI 0 "register_operand" "=r")
1906         (match_operand:DI 1 "const0_operand" "i"))
1907    (clobber (reg:CC FLAGS_REG))]
1908   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1909    && reload_completed"
1910   "xor{l}\t{%k0, %k0|%k0, %k0}"
1911   [(set_attr "type" "alu1")
1912    (set_attr "mode" "SI")
1913    (set_attr "length_immediate" "0")])
1914
1915 (define_insn "*movdi_or_rex64"
1916   [(set (match_operand:DI 0 "register_operand" "=r")
1917         (match_operand:DI 1 "const_int_operand" "i"))
1918    (clobber (reg:CC FLAGS_REG))]
1919   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1920    && reload_completed
1921    && operands[1] == constm1_rtx"
1922 {
1923   operands[1] = constm1_rtx;
1924   return "or{q}\t{%1, %0|%0, %1}";
1925 }
1926   [(set_attr "type" "alu1")
1927    (set_attr "mode" "DI")
1928    (set_attr "length_immediate" "1")])
1929
1930 (define_insn "*movdi_2"
1931   [(set (match_operand:DI 0 "nonimmediate_operand"
1932                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1933         (match_operand:DI 1 "general_operand"
1934                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1935   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936   "@
1937    #
1938    #
1939    pxor\t%0, %0
1940    movq\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    pxor\t%0, %0
1943    movq\t{%1, %0|%0, %1}
1944    movdqa\t{%1, %0|%0, %1}
1945    movq\t{%1, %0|%0, %1}
1946    xorps\t%0, %0
1947    movlps\t{%1, %0|%0, %1}
1948    movaps\t{%1, %0|%0, %1}
1949    movlps\t{%1, %0|%0, %1}"
1950   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1951    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1952
1953 (define_split
1954   [(set (match_operand:DI 0 "push_operand" "")
1955         (match_operand:DI 1 "general_operand" ""))]
1956   "!TARGET_64BIT && reload_completed
1957    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1958   [(const_int 0)]
1959   "ix86_split_long_move (operands); DONE;")
1960
1961 ;; %%% This multiword shite has got to go.
1962 (define_split
1963   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964         (match_operand:DI 1 "general_operand" ""))]
1965   "!TARGET_64BIT && reload_completed
1966    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1968   [(const_int 0)]
1969   "ix86_split_long_move (operands); DONE;")
1970
1971 (define_insn "*movdi_1_rex64"
1972   [(set (match_operand:DI 0 "nonimmediate_operand"
1973                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1974         (match_operand:DI 1 "general_operand"
1975                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1976   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1977 {
1978   switch (get_attr_type (insn))
1979     {
1980     case TYPE_SSECVT:
1981       if (which_alternative == 13)
1982         return "movq2dq\t{%1, %0|%0, %1}";
1983       else
1984         return "movdq2q\t{%1, %0|%0, %1}";
1985     case TYPE_SSEMOV:
1986       if (get_attr_mode (insn) == MODE_TI)
1987           return "movdqa\t{%1, %0|%0, %1}";
1988       /* FALLTHRU */
1989     case TYPE_MMXMOV:
1990       /* Moves from and into integer register is done using movd opcode with
1991          REX prefix.  */
1992       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993           return "movd\t{%1, %0|%0, %1}";
1994       return "movq\t{%1, %0|%0, %1}";
1995     case TYPE_SSELOG1:
1996     case TYPE_MMXADD:
1997       return "pxor\t%0, %0";
1998     case TYPE_MULTI:
1999       return "#";
2000     case TYPE_LEA:
2001       return "lea{q}\t{%a1, %0|%0, %a1}";
2002     default:
2003       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2004       if (get_attr_mode (insn) == MODE_SI)
2005         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2006       else if (which_alternative == 2)
2007         return "movabs{q}\t{%1, %0|%0, %1}";
2008       else
2009         return "mov{q}\t{%1, %0|%0, %1}";
2010     }
2011 }
2012   [(set (attr "type")
2013      (cond [(eq_attr "alternative" "5")
2014               (const_string "mmxadd")
2015             (eq_attr "alternative" "6,7,8")
2016               (const_string "mmxmov")
2017             (eq_attr "alternative" "9")
2018               (const_string "sselog1")
2019             (eq_attr "alternative" "10,11,12")
2020               (const_string "ssemov")
2021             (eq_attr "alternative" "13,14")
2022               (const_string "ssecvt")
2023             (eq_attr "alternative" "4")
2024               (const_string "multi")
2025             (match_operand:DI 1 "pic_32bit_operand" "")
2026               (const_string "lea")
2027            ]
2028            (const_string "imov")))
2029    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2030    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2031    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2032
2033 ;; Stores and loads of ax to arbitrary constant address.
2034 ;; We fake an second form of instruction to force reload to load address
2035 ;; into register when rax is not available
2036 (define_insn "*movabsdi_1_rex64"
2037   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2038         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2039   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2040   "@
2041    movabs{q}\t{%1, %P0|%P0, %1}
2042    mov{q}\t{%1, %a0|%a0, %1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "modrm" "0,*")
2045    (set_attr "length_address" "8,0")
2046    (set_attr "length_immediate" "0,*")
2047    (set_attr "memory" "store")
2048    (set_attr "mode" "DI")])
2049
2050 (define_insn "*movabsdi_2_rex64"
2051   [(set (match_operand:DI 0 "register_operand" "=a,r")
2052         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2053   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2054   "@
2055    movabs{q}\t{%P1, %0|%0, %P1}
2056    mov{q}\t{%a1, %0|%0, %a1}"
2057   [(set_attr "type" "imov")
2058    (set_attr "modrm" "0,*")
2059    (set_attr "length_address" "8,0")
2060    (set_attr "length_immediate" "0")
2061    (set_attr "memory" "load")
2062    (set_attr "mode" "DI")])
2063
2064 ;; Convert impossible stores of immediate to existing instructions.
2065 ;; First try to get scratch register and go through it.  In case this
2066 ;; fails, move by 32bit parts.
2067 (define_peephole2
2068   [(match_scratch:DI 2 "r")
2069    (set (match_operand:DI 0 "memory_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072    && !x86_64_immediate_operand (operands[1], DImode)"
2073   [(set (match_dup 2) (match_dup 1))
2074    (set (match_dup 0) (match_dup 2))]
2075   "")
2076
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 (define_peephole2
2081   [(set (match_operand:DI 0 "memory_operand" "")
2082         (match_operand:DI 1 "immediate_operand" ""))]
2083   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_split
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2093                     ? flow2_completed : reload_completed)
2094    && !symbolic_operand (operands[1], DImode)
2095    && !x86_64_immediate_operand (operands[1], DImode)"
2096   [(set (match_dup 2) (match_dup 3))
2097    (set (match_dup 4) (match_dup 5))]
2098   "split_di (operands, 2, operands + 2, operands + 4);")
2099
2100 (define_insn "*swapdi_rex64"
2101   [(set (match_operand:DI 0 "register_operand" "+r")
2102         (match_operand:DI 1 "register_operand" "+r"))
2103    (set (match_dup 1)
2104         (match_dup 0))]
2105   "TARGET_64BIT"
2106   "xchg{q}\t%1, %0"
2107   [(set_attr "type" "imov")
2108    (set_attr "mode" "DI")
2109    (set_attr "pent_pair" "np")
2110    (set_attr "athlon_decode" "vector")])
2111
2112 (define_expand "movti"
2113   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2114         (match_operand:TI 1 "nonimmediate_operand" ""))]
2115   "TARGET_SSE || TARGET_64BIT"
2116 {
2117   if (TARGET_64BIT)
2118     ix86_expand_move (TImode, operands);
2119   else
2120     ix86_expand_vector_move (TImode, operands);
2121   DONE;
2122 })
2123
2124 (define_insn "*movti_internal"
2125   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2126         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2127   "TARGET_SSE && !TARGET_64BIT
2128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2129 {
2130   switch (which_alternative)
2131     {
2132     case 0:
2133       if (get_attr_mode (insn) == MODE_V4SF)
2134         return "xorps\t%0, %0";
2135       else
2136         return "pxor\t%0, %0";
2137     case 1:
2138     case 2:
2139       if (get_attr_mode (insn) == MODE_V4SF)
2140         return "movaps\t{%1, %0|%0, %1}";
2141       else
2142         return "movdqa\t{%1, %0|%0, %1}";
2143     default:
2144       gcc_unreachable ();
2145     }
2146 }
2147   [(set_attr "type" "sselog1,ssemov,ssemov")
2148    (set (attr "mode")
2149         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2150                     (ne (symbol_ref "optimize_size") (const_int 0)))
2151                  (const_string "V4SF")
2152                (and (eq_attr "alternative" "2")
2153                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2154                         (const_int 0)))
2155                  (const_string "V4SF")]
2156               (const_string "TI")))])
2157
2158 (define_insn "*movti_rex64"
2159   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2160         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2161   "TARGET_64BIT
2162    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163 {
2164   switch (which_alternative)
2165     {
2166     case 0:
2167     case 1:
2168       return "#";
2169     case 2:
2170       if (get_attr_mode (insn) == MODE_V4SF)
2171         return "xorps\t%0, %0";
2172       else
2173         return "pxor\t%0, %0";
2174     case 3:
2175     case 4:
2176       if (get_attr_mode (insn) == MODE_V4SF)
2177         return "movaps\t{%1, %0|%0, %1}";
2178       else
2179         return "movdqa\t{%1, %0|%0, %1}";
2180     default:
2181       gcc_unreachable ();
2182     }
2183 }
2184   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2185    (set (attr "mode")
2186         (cond [(eq_attr "alternative" "2,3")
2187                  (if_then_else
2188                    (ne (symbol_ref "optimize_size")
2189                        (const_int 0))
2190                    (const_string "V4SF")
2191                    (const_string "TI"))
2192                (eq_attr "alternative" "4")
2193                  (if_then_else
2194                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2195                             (const_int 0))
2196                         (ne (symbol_ref "optimize_size")
2197                             (const_int 0)))
2198                    (const_string "V4SF")
2199                    (const_string "TI"))]
2200                (const_string "DI")))])
2201
2202 (define_split
2203   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2204         (match_operand:TI 1 "general_operand" ""))]
2205   "reload_completed && !SSE_REG_P (operands[0])
2206    && !SSE_REG_P (operands[1])"
2207   [(const_int 0)]
2208   "ix86_split_long_move (operands); DONE;")
2209
2210 (define_expand "movsf"
2211   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2212         (match_operand:SF 1 "general_operand" ""))]
2213   ""
2214   "ix86_expand_move (SFmode, operands); DONE;")
2215
2216 (define_insn "*pushsf"
2217   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2218         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2219   "!TARGET_64BIT"
2220 {
2221   /* Anything else should be already split before reg-stack.  */
2222   gcc_assert (which_alternative == 1);
2223   return "push{l}\t%1";
2224 }
2225   [(set_attr "type" "multi,push,multi")
2226    (set_attr "unit" "i387,*,*")
2227    (set_attr "mode" "SF,SI,SF")])
2228
2229 (define_insn "*pushsf_rex64"
2230   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2231         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2232   "TARGET_64BIT"
2233 {
2234   /* Anything else should be already split before reg-stack.  */
2235   gcc_assert (which_alternative == 1);
2236   return "push{q}\t%q1";
2237 }
2238   [(set_attr "type" "multi,push,multi")
2239    (set_attr "unit" "i387,*,*")
2240    (set_attr "mode" "SF,DI,SF")])
2241
2242 (define_split
2243   [(set (match_operand:SF 0 "push_operand" "")
2244         (match_operand:SF 1 "memory_operand" ""))]
2245   "reload_completed
2246    && GET_CODE (operands[1]) == MEM
2247    && constant_pool_reference_p (operands[1])"
2248   [(set (match_dup 0)
2249         (match_dup 1))]
2250   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2251
2252
2253 ;; %%% Kill this when call knows how to work this out.
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "any_fp_register_operand" ""))]
2257   "!TARGET_64BIT"
2258   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2259    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2260
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2266    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2267
2268 (define_insn "*movsf_1"
2269   [(set (match_operand:SF 0 "nonimmediate_operand"
2270           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2271         (match_operand:SF 1 "general_operand"
2272           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2273   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2274    && (reload_in_progress || reload_completed
2275        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2276        || GET_CODE (operands[1]) != CONST_DOUBLE
2277        || memory_operand (operands[0], SFmode))" 
2278 {
2279   switch (which_alternative)
2280     {
2281     case 0:
2282       return output_387_reg_move (insn, operands);
2283
2284     case 1:
2285       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286         return "fstp%z0\t%y0";
2287       else
2288         return "fst%z0\t%y0";
2289
2290     case 2:
2291       return standard_80387_constant_opcode (operands[1]);
2292
2293     case 3:
2294     case 4:
2295       return "mov{l}\t{%1, %0|%0, %1}";
2296     case 5:
2297       if (get_attr_mode (insn) == MODE_TI)
2298         return "pxor\t%0, %0";
2299       else
2300         return "xorps\t%0, %0";
2301     case 6:
2302       if (get_attr_mode (insn) == MODE_V4SF)
2303         return "movaps\t{%1, %0|%0, %1}";
2304       else
2305         return "movss\t{%1, %0|%0, %1}";
2306     case 7:
2307     case 8:
2308       return "movss\t{%1, %0|%0, %1}";
2309
2310     case 9:
2311     case 10:
2312       return "movd\t{%1, %0|%0, %1}";
2313
2314     case 11:
2315       return "movq\t{%1, %0|%0, %1}";
2316
2317     default:
2318       gcc_unreachable ();
2319     }
2320 }
2321   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2322    (set (attr "mode")
2323         (cond [(eq_attr "alternative" "3,4,9,10")
2324                  (const_string "SI")
2325                (eq_attr "alternative" "5")
2326                  (if_then_else
2327                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2328                                  (const_int 0))
2329                              (ne (symbol_ref "TARGET_SSE2")
2330                                  (const_int 0)))
2331                         (eq (symbol_ref "optimize_size")
2332                             (const_int 0)))
2333                    (const_string "TI")
2334                    (const_string "V4SF"))
2335                /* For architectures resolving dependencies on
2336                   whole SSE registers use APS move to break dependency
2337                   chains, otherwise use short move to avoid extra work. 
2338
2339                   Do the same for architectures resolving dependencies on
2340                   the parts.  While in DF mode it is better to always handle
2341                   just register parts, the SF mode is different due to lack
2342                   of instructions to load just part of the register.  It is
2343                   better to maintain the whole registers in single format
2344                   to avoid problems on using packed logical operations.  */
2345                (eq_attr "alternative" "6")
2346                  (if_then_else
2347                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2348                             (const_int 0))
2349                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2350                             (const_int 0)))
2351                    (const_string "V4SF")
2352                    (const_string "SF"))
2353                (eq_attr "alternative" "11")
2354                  (const_string "DI")]
2355                (const_string "SF")))])
2356
2357 (define_insn "*swapsf"
2358   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2359         (match_operand:SF 1 "fp_register_operand" "+f"))
2360    (set (match_dup 1)
2361         (match_dup 0))]
2362   "reload_completed || TARGET_80387"
2363 {
2364   if (STACK_TOP_P (operands[0]))
2365     return "fxch\t%1";
2366   else
2367     return "fxch\t%0";
2368 }
2369   [(set_attr "type" "fxch")
2370    (set_attr "mode" "SF")])
2371
2372 (define_expand "movdf"
2373   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2374         (match_operand:DF 1 "general_operand" ""))]
2375   ""
2376   "ix86_expand_move (DFmode, operands); DONE;")
2377
2378 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2379 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2380 ;; On the average, pushdf using integers can be still shorter.  Allow this
2381 ;; pattern for optimize_size too.
2382
2383 (define_insn "*pushdf_nointeger"
2384   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2385         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2386   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2387 {
2388   /* This insn should be already split before reg-stack.  */
2389   gcc_unreachable ();
2390 }
2391   [(set_attr "type" "multi")
2392    (set_attr "unit" "i387,*,*,*")
2393    (set_attr "mode" "DF,SI,SI,DF")])
2394
2395 (define_insn "*pushdf_integer"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2398   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   gcc_unreachable ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "unit" "i387,*,*")
2405    (set_attr "mode" "DF,SI,DF")])
2406
2407 ;; %%% Kill this when call knows how to work this out.
2408 (define_split
2409   [(set (match_operand:DF 0 "push_operand" "")
2410         (match_operand:DF 1 "any_fp_register_operand" ""))]
2411   "!TARGET_64BIT && reload_completed"
2412   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2413    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2414   "")
2415
2416 (define_split
2417   [(set (match_operand:DF 0 "push_operand" "")
2418         (match_operand:DF 1 "any_fp_register_operand" ""))]
2419   "TARGET_64BIT && reload_completed"
2420   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2421    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2422   "")
2423
2424 (define_split
2425   [(set (match_operand:DF 0 "push_operand" "")
2426         (match_operand:DF 1 "general_operand" ""))]
2427   "reload_completed"
2428   [(const_int 0)]
2429   "ix86_split_long_move (operands); DONE;")
2430
2431 ;; Moving is usually shorter when only FP registers are used. This separate
2432 ;; movdf pattern avoids the use of integer registers for FP operations
2433 ;; when optimizing for size.
2434
2435 (define_insn "*movdf_nointeger"
2436   [(set (match_operand:DF 0 "nonimmediate_operand"
2437                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2438         (match_operand:DF 1 "general_operand"
2439                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2440   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2441    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2442    && (reload_in_progress || reload_completed
2443        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2444        || GET_CODE (operands[1]) != CONST_DOUBLE
2445        || memory_operand (operands[0], DFmode))" 
2446 {
2447   switch (which_alternative)
2448     {
2449     case 0:
2450       return output_387_reg_move (insn, operands);
2451
2452     case 1:
2453       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2454         return "fstp%z0\t%y0";
2455       else
2456         return "fst%z0\t%y0";
2457
2458     case 2:
2459       return standard_80387_constant_opcode (operands[1]);
2460
2461     case 3:
2462     case 4:
2463       return "#";
2464     case 5:
2465       switch (get_attr_mode (insn))
2466         {
2467         case MODE_V4SF:
2468           return "xorps\t%0, %0";
2469         case MODE_V2DF:
2470           return "xorpd\t%0, %0";
2471         case MODE_TI:
2472           return "pxor\t%0, %0";
2473         default:
2474           gcc_unreachable ();
2475         }
2476     case 6:
2477     case 7:
2478     case 8:
2479       switch (get_attr_mode (insn))
2480         {
2481         case MODE_V4SF:
2482           return "movaps\t{%1, %0|%0, %1}";
2483         case MODE_V2DF:
2484           return "movapd\t{%1, %0|%0, %1}";
2485         case MODE_TI:
2486           return "movdqa\t{%1, %0|%0, %1}";
2487         case MODE_DI:
2488           return "movq\t{%1, %0|%0, %1}";
2489         case MODE_DF:
2490           return "movsd\t{%1, %0|%0, %1}";
2491         case MODE_V1DF:
2492           return "movlpd\t{%1, %0|%0, %1}";
2493         case MODE_V2SF:
2494           return "movlps\t{%1, %0|%0, %1}";
2495         default:
2496           gcc_unreachable ();
2497         }
2498
2499     default:
2500       gcc_unreachable ();
2501     }
2502 }
2503   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2504    (set (attr "mode")
2505         (cond [(eq_attr "alternative" "0,1,2")
2506                  (const_string "DF")
2507                (eq_attr "alternative" "3,4")
2508                  (const_string "SI")
2509
2510                /* For SSE1, we have many fewer alternatives.  */
2511                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2512                  (cond [(eq_attr "alternative" "5,6")
2513                           (const_string "V4SF")
2514                        ]
2515                    (const_string "V2SF"))
2516
2517                /* xorps is one byte shorter.  */
2518                (eq_attr "alternative" "5")
2519                  (cond [(ne (symbol_ref "optimize_size")
2520                             (const_int 0))
2521                           (const_string "V4SF")
2522                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2523                             (const_int 0))
2524                           (const_string "TI")
2525                        ]
2526                        (const_string "V2DF"))
2527
2528                /* For architectures resolving dependencies on
2529                   whole SSE registers use APD move to break dependency
2530                   chains, otherwise use short move to avoid extra work.
2531
2532                   movaps encodes one byte shorter.  */
2533                (eq_attr "alternative" "6")
2534                  (cond
2535                    [(ne (symbol_ref "optimize_size")
2536                         (const_int 0))
2537                       (const_string "V4SF")
2538                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2539                         (const_int 0))
2540                       (const_string "V2DF")
2541                    ]
2542                    (const_string "DF"))
2543                /* For architectures resolving dependencies on register
2544                   parts we may avoid extra work to zero out upper part
2545                   of register.  */
2546                (eq_attr "alternative" "7")
2547                  (if_then_else
2548                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2549                        (const_int 0))
2550                    (const_string "V1DF")
2551                    (const_string "DF"))
2552               ]
2553               (const_string "DF")))])
2554
2555 (define_insn "*movdf_integer"
2556   [(set (match_operand:DF 0 "nonimmediate_operand"
2557                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2558         (match_operand:DF 1 "general_operand"
2559                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2560   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2561    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2562    && (reload_in_progress || reload_completed
2563        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2564        || GET_CODE (operands[1]) != CONST_DOUBLE
2565        || memory_operand (operands[0], DFmode))" 
2566 {
2567   switch (which_alternative)
2568     {
2569     case 0:
2570       return output_387_reg_move (insn, operands);
2571
2572     case 1:
2573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2574         return "fstp%z0\t%y0";
2575       else
2576         return "fst%z0\t%y0";
2577
2578     case 2:
2579       return standard_80387_constant_opcode (operands[1]);
2580
2581     case 3:
2582     case 4:
2583       return "#";
2584
2585     case 5:
2586       switch (get_attr_mode (insn))
2587         {
2588         case MODE_V4SF:
2589           return "xorps\t%0, %0";
2590         case MODE_V2DF:
2591           return "xorpd\t%0, %0";
2592         case MODE_TI:
2593           return "pxor\t%0, %0";
2594         default:
2595           gcc_unreachable ();
2596         }
2597     case 6:
2598     case 7:
2599     case 8:
2600       switch (get_attr_mode (insn))
2601         {
2602         case MODE_V4SF:
2603           return "movaps\t{%1, %0|%0, %1}";
2604         case MODE_V2DF:
2605           return "movapd\t{%1, %0|%0, %1}";
2606         case MODE_TI:
2607           return "movdqa\t{%1, %0|%0, %1}";
2608         case MODE_DI:
2609           return "movq\t{%1, %0|%0, %1}";
2610         case MODE_DF:
2611           return "movsd\t{%1, %0|%0, %1}";
2612         case MODE_V1DF:
2613           return "movlpd\t{%1, %0|%0, %1}";
2614         case MODE_V2SF:
2615           return "movlps\t{%1, %0|%0, %1}";
2616         default:
2617           gcc_unreachable ();
2618         }
2619
2620     default:
2621       gcc_unreachable();
2622     }
2623 }
2624   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2625    (set (attr "mode")
2626         (cond [(eq_attr "alternative" "0,1,2")
2627                  (const_string "DF")
2628                (eq_attr "alternative" "3,4")
2629                  (const_string "SI")
2630
2631                /* For SSE1, we have many fewer alternatives.  */
2632                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2633                  (cond [(eq_attr "alternative" "5,6")
2634                           (const_string "V4SF")
2635                        ]
2636                    (const_string "V2SF"))
2637
2638                /* xorps is one byte shorter.  */
2639                (eq_attr "alternative" "5")
2640                  (cond [(ne (symbol_ref "optimize_size")
2641                             (const_int 0))
2642                           (const_string "V4SF")
2643                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2644                             (const_int 0))
2645                           (const_string "TI")
2646                        ]
2647                        (const_string "V2DF"))
2648
2649                /* For architectures resolving dependencies on
2650                   whole SSE registers use APD move to break dependency
2651                   chains, otherwise use short move to avoid extra work.
2652
2653                   movaps encodes one byte shorter.  */
2654                (eq_attr "alternative" "6")
2655                  (cond
2656                    [(ne (symbol_ref "optimize_size")
2657                         (const_int 0))
2658                       (const_string "V4SF")
2659                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2660                         (const_int 0))
2661                       (const_string "V2DF")
2662                    ]
2663                    (const_string "DF"))
2664                /* For architectures resolving dependencies on register
2665                   parts we may avoid extra work to zero out upper part
2666                   of register.  */
2667                (eq_attr "alternative" "7")
2668                  (if_then_else
2669                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2670                        (const_int 0))
2671                    (const_string "V1DF")
2672                    (const_string "DF"))
2673               ]
2674               (const_string "DF")))])
2675
2676 (define_split
2677   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2678         (match_operand:DF 1 "general_operand" ""))]
2679   "reload_completed
2680    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2681    && ! (ANY_FP_REG_P (operands[0]) || 
2682          (GET_CODE (operands[0]) == SUBREG
2683           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2684    && ! (ANY_FP_REG_P (operands[1]) || 
2685          (GET_CODE (operands[1]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2687   [(const_int 0)]
2688   "ix86_split_long_move (operands); DONE;")
2689
2690 (define_insn "*swapdf"
2691   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2692         (match_operand:DF 1 "fp_register_operand" "+f"))
2693    (set (match_dup 1)
2694         (match_dup 0))]
2695   "reload_completed || TARGET_80387"
2696 {
2697   if (STACK_TOP_P (operands[0]))
2698     return "fxch\t%1";
2699   else
2700     return "fxch\t%0";
2701 }
2702   [(set_attr "type" "fxch")
2703    (set_attr "mode" "DF")])
2704
2705 (define_expand "movxf"
2706   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2707         (match_operand:XF 1 "general_operand" ""))]
2708   ""
2709   "ix86_expand_move (XFmode, operands); DONE;")
2710
2711 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2712 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2713 ;; Pushing using integer instructions is longer except for constants
2714 ;; and direct memory references.
2715 ;; (assuming that any given constant is pushed only once, but this ought to be
2716 ;;  handled elsewhere).
2717
2718 (define_insn "*pushxf_nointeger"
2719   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2720         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2721   "optimize_size"
2722 {
2723   /* This insn should be already split before reg-stack.  */
2724   gcc_unreachable ();
2725 }
2726   [(set_attr "type" "multi")
2727    (set_attr "unit" "i387,*,*")
2728    (set_attr "mode" "XF,SI,SI")])
2729
2730 (define_insn "*pushxf_integer"
2731   [(set (match_operand:XF 0 "push_operand" "=<,<")
2732         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2733   "!optimize_size"
2734 {
2735   /* This insn should be already split before reg-stack.  */
2736   gcc_unreachable ();
2737 }
2738   [(set_attr "type" "multi")
2739    (set_attr "unit" "i387,*")
2740    (set_attr "mode" "XF,SI")])
2741
2742 (define_split
2743   [(set (match_operand 0 "push_operand" "")
2744         (match_operand 1 "general_operand" ""))]
2745   "reload_completed
2746    && (GET_MODE (operands[0]) == XFmode
2747        || GET_MODE (operands[0]) == DFmode)
2748    && !ANY_FP_REG_P (operands[1])"
2749   [(const_int 0)]
2750   "ix86_split_long_move (operands); DONE;")
2751
2752 (define_split
2753   [(set (match_operand:XF 0 "push_operand" "")
2754         (match_operand:XF 1 "any_fp_register_operand" ""))]
2755   "!TARGET_64BIT"
2756   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2757    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2758   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759
2760 (define_split
2761   [(set (match_operand:XF 0 "push_operand" "")
2762         (match_operand:XF 1 "any_fp_register_operand" ""))]
2763   "TARGET_64BIT"
2764   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2765    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2766   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2772   "optimize_size
2773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774    && (reload_in_progress || reload_completed
2775        || GET_CODE (operands[1]) != CONST_DOUBLE
2776        || memory_operand (operands[0], XFmode))" 
2777 {
2778   switch (which_alternative)
2779     {
2780     case 0:
2781       return output_387_reg_move (insn, operands);
2782
2783     case 1:
2784       /* There is no non-popping store to memory for XFmode.  So if
2785          we need one, follow the store with a load.  */
2786       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787         return "fstp%z0\t%y0\;fld%z0\t%y0";
2788       else
2789         return "fstp%z0\t%y0";
2790
2791     case 2:
2792       return standard_80387_constant_opcode (operands[1]);
2793
2794     case 3: case 4:
2795       return "#";
2796     default:
2797       gcc_unreachable ();
2798     }
2799 }
2800   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2801    (set_attr "mode" "XF,XF,XF,SI,SI")])
2802
2803 (define_insn "*movxf_integer"
2804   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2805         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2806   "!optimize_size
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (reload_in_progress || reload_completed
2809        || GET_CODE (operands[1]) != CONST_DOUBLE
2810        || memory_operand (operands[0], XFmode))" 
2811 {
2812   switch (which_alternative)
2813     {
2814     case 0:
2815       return output_387_reg_move (insn, operands);
2816
2817     case 1:
2818       /* There is no non-popping store to memory for XFmode.  So if
2819          we need one, follow the store with a load.  */
2820       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821         return "fstp%z0\t%y0\;fld%z0\t%y0";
2822       else
2823         return "fstp%z0\t%y0";
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3: case 4:
2829       return "#";
2830
2831     default:
2832       gcc_unreachable ();
2833     }
2834 }
2835   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2836    (set_attr "mode" "XF,XF,XF,SI,SI")])
2837
2838 (define_split
2839   [(set (match_operand 0 "nonimmediate_operand" "")
2840         (match_operand 1 "general_operand" ""))]
2841   "reload_completed
2842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2843    && GET_MODE (operands[0]) == XFmode
2844    && ! (ANY_FP_REG_P (operands[0]) || 
2845          (GET_CODE (operands[0]) == SUBREG
2846           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2847    && ! (ANY_FP_REG_P (operands[1]) || 
2848          (GET_CODE (operands[1]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2850   [(const_int 0)]
2851   "ix86_split_long_move (operands); DONE;")
2852
2853 (define_split
2854   [(set (match_operand 0 "register_operand" "")
2855         (match_operand 1 "memory_operand" ""))]
2856   "reload_completed
2857    && GET_CODE (operands[1]) == MEM
2858    && (GET_MODE (operands[0]) == XFmode
2859        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2860    && constant_pool_reference_p (operands[1])"
2861   [(set (match_dup 0) (match_dup 1))]
2862 {
2863   rtx c = avoid_constant_pool_reference (operands[1]);
2864   rtx r = operands[0];
2865
2866   if (GET_CODE (r) == SUBREG)
2867     r = SUBREG_REG (r);
2868
2869   if (SSE_REG_P (r))
2870     {
2871       if (!standard_sse_constant_p (c))
2872         FAIL;
2873     }
2874   else if (FP_REG_P (r))
2875     {
2876       if (!standard_80387_constant_p (c))
2877         FAIL;
2878     }
2879   else if (MMX_REG_P (r))
2880     FAIL;
2881
2882   operands[1] = c;
2883 })
2884
2885 (define_insn "swapxf"
2886   [(set (match_operand:XF 0 "register_operand" "+f")
2887         (match_operand:XF 1 "register_operand" "+f"))
2888    (set (match_dup 1)
2889         (match_dup 0))]
2890   "TARGET_80387"
2891 {
2892   if (STACK_TOP_P (operands[0]))
2893     return "fxch\t%1";
2894   else
2895     return "fxch\t%0";
2896 }
2897   [(set_attr "type" "fxch")
2898    (set_attr "mode" "XF")])
2899
2900 (define_expand "movtf"
2901   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2902         (match_operand:TF 1 "nonimmediate_operand" ""))]
2903   "TARGET_64BIT"
2904 {
2905   ix86_expand_move (TFmode, operands);
2906   DONE;
2907 })
2908
2909 (define_insn "*movtf_internal"
2910   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2911         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2912   "TARGET_64BIT
2913    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2914 {
2915   switch (which_alternative)
2916     {
2917     case 0:
2918     case 1:
2919       return "#";
2920     case 2:
2921       if (get_attr_mode (insn) == MODE_V4SF)
2922         return "xorps\t%0, %0";
2923       else
2924         return "pxor\t%0, %0";
2925     case 3:
2926     case 4:
2927       if (get_attr_mode (insn) == MODE_V4SF)
2928         return "movaps\t{%1, %0|%0, %1}";
2929       else
2930         return "movdqa\t{%1, %0|%0, %1}";
2931     default:
2932       gcc_unreachable ();
2933     }
2934 }
2935   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2936    (set (attr "mode")
2937         (cond [(eq_attr "alternative" "2,3")
2938                  (if_then_else
2939                    (ne (symbol_ref "optimize_size")
2940                        (const_int 0))
2941                    (const_string "V4SF")
2942                    (const_string "TI"))
2943                (eq_attr "alternative" "4")
2944                  (if_then_else
2945                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2946                             (const_int 0))
2947                         (ne (symbol_ref "optimize_size")
2948                             (const_int 0)))
2949                    (const_string "V4SF")
2950                    (const_string "TI"))]
2951                (const_string "DI")))])
2952
2953 (define_split
2954   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2955         (match_operand:TF 1 "general_operand" ""))]
2956   "reload_completed && !SSE_REG_P (operands[0])
2957    && !SSE_REG_P (operands[1])"
2958   [(const_int 0)]
2959   "ix86_split_long_move (operands); DONE;")
2960 \f
2961 ;; Zero extension instructions
2962
2963 (define_expand "zero_extendhisi2"
2964   [(set (match_operand:SI 0 "register_operand" "")
2965      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2966   ""
2967 {
2968   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2969     {
2970       operands[1] = force_reg (HImode, operands[1]);
2971       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2972       DONE;
2973     }
2974 })
2975
2976 (define_insn "zero_extendhisi2_and"
2977   [(set (match_operand:SI 0 "register_operand" "=r")
2978      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2979    (clobber (reg:CC FLAGS_REG))]
2980   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2981   "#"
2982   [(set_attr "type" "alu1")
2983    (set_attr "mode" "SI")])
2984
2985 (define_split
2986   [(set (match_operand:SI 0 "register_operand" "")
2987         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2988    (clobber (reg:CC FLAGS_REG))]
2989   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2991               (clobber (reg:CC FLAGS_REG))])]
2992   "")
2993
2994 (define_insn "*zero_extendhisi2_movzwl"
2995   [(set (match_operand:SI 0 "register_operand" "=r")
2996      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2997   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2998   "movz{wl|x}\t{%1, %0|%0, %1}"
2999   [(set_attr "type" "imovx")
3000    (set_attr "mode" "SI")])
3001
3002 (define_expand "zero_extendqihi2"
3003   [(parallel
3004     [(set (match_operand:HI 0 "register_operand" "")
3005        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3006      (clobber (reg:CC FLAGS_REG))])]
3007   ""
3008   "")
3009
3010 (define_insn "*zero_extendqihi2_and"
3011   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3012      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "HI")])
3018
3019 (define_insn "*zero_extendqihi2_movzbw_and"
3020   [(set (match_operand:HI 0 "register_operand" "=r,r")
3021      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3024   "#"
3025   [(set_attr "type" "imovx,alu1")
3026    (set_attr "mode" "HI")])
3027
3028 ; zero extend to SImode here to avoid partial register stalls
3029 (define_insn "*zero_extendqihi2_movzbl"
3030   [(set (match_operand:HI 0 "register_operand" "=r")
3031      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3032   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3033   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3034   [(set_attr "type" "imovx")
3035    (set_attr "mode" "SI")])
3036
3037 ;; For the movzbw case strip only the clobber
3038 (define_split
3039   [(set (match_operand:HI 0 "register_operand" "")
3040         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041    (clobber (reg:CC FLAGS_REG))]
3042   "reload_completed 
3043    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3044    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3047
3048 ;; When source and destination does not overlap, clear destination
3049 ;; first and then do the movb
3050 (define_split
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed
3055    && ANY_QI_REG_P (operands[0])
3056    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3057    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3058   [(set (match_dup 0) (const_int 0))
3059    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060   "operands[2] = gen_lowpart (QImode, operands[0]);")
3061
3062 ;; Rest is handled by single and.
3063 (define_split
3064   [(set (match_operand:HI 0 "register_operand" "")
3065         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "reload_completed
3068    && true_regnum (operands[0]) == true_regnum (operands[1])"
3069   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3070               (clobber (reg:CC FLAGS_REG))])]
3071   "")
3072
3073 (define_expand "zero_extendqisi2"
3074   [(parallel
3075     [(set (match_operand:SI 0 "register_operand" "")
3076        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3077      (clobber (reg:CC FLAGS_REG))])]
3078   ""
3079   "")
3080
3081 (define_insn "*zero_extendqisi2_and"
3082   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3083      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3084    (clobber (reg:CC FLAGS_REG))]
3085   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3086   "#"
3087   [(set_attr "type" "alu1")
3088    (set_attr "mode" "SI")])
3089
3090 (define_insn "*zero_extendqisi2_movzbw_and"
3091   [(set (match_operand:SI 0 "register_operand" "=r,r")
3092      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3093    (clobber (reg:CC FLAGS_REG))]
3094   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3095   "#"
3096   [(set_attr "type" "imovx,alu1")
3097    (set_attr "mode" "SI")])
3098
3099 (define_insn "*zero_extendqisi2_movzbw"
3100   [(set (match_operand:SI 0 "register_operand" "=r")
3101      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3102   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3103   "movz{bl|x}\t{%1, %0|%0, %1}"
3104   [(set_attr "type" "imovx")
3105    (set_attr "mode" "SI")])
3106
3107 ;; For the movzbl case strip only the clobber
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed 
3113    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3114    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3115   [(set (match_dup 0)
3116         (zero_extend:SI (match_dup 1)))])
3117
3118 ;; When source and destination does not overlap, clear destination
3119 ;; first and then do the movb
3120 (define_split
3121   [(set (match_operand:SI 0 "register_operand" "")
3122         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "reload_completed
3125    && ANY_QI_REG_P (operands[0])
3126    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3127    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3128    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3129   [(set (match_dup 0) (const_int 0))
3130    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3131   "operands[2] = gen_lowpart (QImode, operands[0]);")
3132
3133 ;; Rest is handled by single and.
3134 (define_split
3135   [(set (match_operand:SI 0 "register_operand" "")
3136         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3137    (clobber (reg:CC FLAGS_REG))]
3138   "reload_completed
3139    && true_regnum (operands[0]) == true_regnum (operands[1])"
3140   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3141               (clobber (reg:CC FLAGS_REG))])]
3142   "")
3143
3144 ;; %%% Kill me once multi-word ops are sane.
3145 (define_expand "zero_extendsidi2"
3146   [(set (match_operand:DI 0 "register_operand" "=r")
3147      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3148   ""
3149   "if (!TARGET_64BIT)
3150      {
3151        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3152        DONE;
3153      }
3154   ")
3155
3156 (define_insn "zero_extendsidi2_32"
3157   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3158         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3159    (clobber (reg:CC FLAGS_REG))]
3160   "!TARGET_64BIT"
3161   "@
3162    #
3163    #
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "mode" "SI,SI,SI,DI,TI")
3168    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3169
3170 (define_insn "zero_extendsidi2_rex64"
3171   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3172      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3173   "TARGET_64BIT"
3174   "@
3175    mov\t{%k1, %k0|%k0, %k1}
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3180    (set_attr "mode" "SI,DI,SI,SI")])
3181
3182 (define_split
3183   [(set (match_operand:DI 0 "memory_operand" "")
3184      (zero_extend:DI (match_dup 0)))]
3185   "TARGET_64BIT"
3186   [(set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_split 
3190   [(set (match_operand:DI 0 "register_operand" "")
3191         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192    (clobber (reg:CC FLAGS_REG))]
3193   "!TARGET_64BIT && reload_completed
3194    && true_regnum (operands[0]) == true_regnum (operands[1])"
3195   [(set (match_dup 4) (const_int 0))]
3196   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197
3198 (define_split 
3199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3200         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201    (clobber (reg:CC FLAGS_REG))]
3202   "!TARGET_64BIT && reload_completed
3203    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3204   [(set (match_dup 3) (match_dup 1))
3205    (set (match_dup 4) (const_int 0))]
3206   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3207
3208 (define_insn "zero_extendhidi2"
3209   [(set (match_operand:DI 0 "register_operand" "=r")
3210      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3211   "TARGET_64BIT"
3212   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3213   [(set_attr "type" "imovx")
3214    (set_attr "mode" "DI")])
3215
3216 (define_insn "zero_extendqidi2"
3217   [(set (match_operand:DI 0 "register_operand" "=r")
3218      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3219   "TARGET_64BIT"
3220   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3221   [(set_attr "type" "imovx")
3222    (set_attr "mode" "DI")])
3223 \f
3224 ;; Sign extension instructions
3225
3226 (define_expand "extendsidi2"
3227   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3228                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3229               (clobber (reg:CC FLAGS_REG))
3230               (clobber (match_scratch:SI 2 ""))])]
3231   ""
3232 {
3233   if (TARGET_64BIT)
3234     {
3235       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3236       DONE;
3237     }
3238 })
3239
3240 (define_insn "*extendsidi2_1"
3241   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3242         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3243    (clobber (reg:CC FLAGS_REG))
3244    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3245   "!TARGET_64BIT"
3246   "#")
3247
3248 (define_insn "extendsidi2_rex64"
3249   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3250         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3251   "TARGET_64BIT"
3252   "@
3253    {cltq|cdqe}
3254    movs{lq|x}\t{%1,%0|%0, %1}"
3255   [(set_attr "type" "imovx")
3256    (set_attr "mode" "DI")
3257    (set_attr "prefix_0f" "0")
3258    (set_attr "modrm" "0,1")])
3259
3260 (define_insn "extendhidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3263   "TARGET_64BIT"
3264   "movs{wq|x}\t{%1,%0|%0, %1}"
3265   [(set_attr "type" "imovx")
3266    (set_attr "mode" "DI")])
3267
3268 (define_insn "extendqidi2"
3269   [(set (match_operand:DI 0 "register_operand" "=r")
3270         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3271   "TARGET_64BIT"
3272   "movs{bq|x}\t{%1,%0|%0, %1}"
3273    [(set_attr "type" "imovx")
3274     (set_attr "mode" "DI")])
3275
3276 ;; Extend to memory case when source register does die.
3277 (define_split 
3278   [(set (match_operand:DI 0 "memory_operand" "")
3279         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3280    (clobber (reg:CC FLAGS_REG))
3281    (clobber (match_operand:SI 2 "register_operand" ""))]
3282   "(reload_completed
3283     && dead_or_set_p (insn, operands[1])
3284     && !reg_mentioned_p (operands[1], operands[0]))"
3285   [(set (match_dup 3) (match_dup 1))
3286    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3287               (clobber (reg:CC FLAGS_REG))])
3288    (set (match_dup 4) (match_dup 1))]
3289   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3290
3291 ;; Extend to memory case when source register does not die.
3292 (define_split 
3293   [(set (match_operand:DI 0 "memory_operand" "")
3294         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295    (clobber (reg:CC FLAGS_REG))
3296    (clobber (match_operand:SI 2 "register_operand" ""))]
3297   "reload_completed"
3298   [(const_int 0)]
3299 {
3300   split_di (&operands[0], 1, &operands[3], &operands[4]);
3301
3302   emit_move_insn (operands[3], operands[1]);
3303
3304   /* Generate a cltd if possible and doing so it profitable.  */
3305   if (true_regnum (operands[1]) == 0
3306       && true_regnum (operands[2]) == 1
3307       && (optimize_size || TARGET_USE_CLTD))
3308     {
3309       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3310     }
3311   else
3312     {
3313       emit_move_insn (operands[2], operands[1]);
3314       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3315     }
3316   emit_move_insn (operands[4], operands[2]);
3317   DONE;
3318 })
3319
3320 ;; Extend to register case.  Optimize case where source and destination
3321 ;; registers match and cases where we can use cltd.
3322 (define_split 
3323   [(set (match_operand:DI 0 "register_operand" "")
3324         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3325    (clobber (reg:CC FLAGS_REG))
3326    (clobber (match_scratch:SI 2 ""))]
3327   "reload_completed"
3328   [(const_int 0)]
3329 {
3330   split_di (&operands[0], 1, &operands[3], &operands[4]);
3331
3332   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3333     emit_move_insn (operands[3], operands[1]);
3334
3335   /* Generate a cltd if possible and doing so it profitable.  */
3336   if (true_regnum (operands[3]) == 0
3337       && (optimize_size || TARGET_USE_CLTD))
3338     {
3339       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3340       DONE;
3341     }
3342
3343   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3344     emit_move_insn (operands[4], operands[1]);
3345
3346   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3347   DONE;
3348 })
3349
3350 (define_insn "extendhisi2"
3351   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3352         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3353   ""
3354 {
3355   switch (get_attr_prefix_0f (insn))
3356     {
3357     case 0:
3358       return "{cwtl|cwde}";
3359     default:
3360       return "movs{wl|x}\t{%1,%0|%0, %1}";
3361     }
3362 }
3363   [(set_attr "type" "imovx")
3364    (set_attr "mode" "SI")
3365    (set (attr "prefix_0f")
3366      ;; movsx is short decodable while cwtl is vector decoded.
3367      (if_then_else (and (eq_attr "cpu" "!k6")
3368                         (eq_attr "alternative" "0"))
3369         (const_string "0")
3370         (const_string "1")))
3371    (set (attr "modrm")
3372      (if_then_else (eq_attr "prefix_0f" "0")
3373         (const_string "0")
3374         (const_string "1")))])
3375
3376 (define_insn "*extendhisi2_zext"
3377   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3378         (zero_extend:DI
3379           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3380   "TARGET_64BIT"
3381 {
3382   switch (get_attr_prefix_0f (insn))
3383     {
3384     case 0:
3385       return "{cwtl|cwde}";
3386     default:
3387       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3388     }
3389 }
3390   [(set_attr "type" "imovx")
3391    (set_attr "mode" "SI")
3392    (set (attr "prefix_0f")
3393      ;; movsx is short decodable while cwtl is vector decoded.
3394      (if_then_else (and (eq_attr "cpu" "!k6")
3395                         (eq_attr "alternative" "0"))
3396         (const_string "0")
3397         (const_string "1")))
3398    (set (attr "modrm")
3399      (if_then_else (eq_attr "prefix_0f" "0")
3400         (const_string "0")
3401         (const_string "1")))])
3402
3403 (define_insn "extendqihi2"
3404   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3405         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3406   ""
3407 {
3408   switch (get_attr_prefix_0f (insn))
3409     {
3410     case 0:
3411       return "{cbtw|cbw}";
3412     default:
3413       return "movs{bw|x}\t{%1,%0|%0, %1}";
3414     }
3415 }
3416   [(set_attr "type" "imovx")
3417    (set_attr "mode" "HI")
3418    (set (attr "prefix_0f")
3419      ;; movsx is short decodable while cwtl is vector decoded.
3420      (if_then_else (and (eq_attr "cpu" "!k6")
3421                         (eq_attr "alternative" "0"))
3422         (const_string "0")
3423         (const_string "1")))
3424    (set (attr "modrm")
3425      (if_then_else (eq_attr "prefix_0f" "0")
3426         (const_string "0")
3427         (const_string "1")))])
3428
3429 (define_insn "extendqisi2"
3430   [(set (match_operand:SI 0 "register_operand" "=r")
3431         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3432   ""
3433   "movs{bl|x}\t{%1,%0|%0, %1}"
3434    [(set_attr "type" "imovx")
3435     (set_attr "mode" "SI")])
3436
3437 (define_insn "*extendqisi2_zext"
3438   [(set (match_operand:DI 0 "register_operand" "=r")
3439         (zero_extend:DI
3440           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3441   "TARGET_64BIT"
3442   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3443    [(set_attr "type" "imovx")
3444     (set_attr "mode" "SI")])
3445 \f
3446 ;; Conversions between float and double.
3447
3448 ;; These are all no-ops in the model used for the 80387.  So just
3449 ;; emit moves.
3450
3451 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3452 (define_insn "*dummy_extendsfdf2"
3453   [(set (match_operand:DF 0 "push_operand" "=<")
3454         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3455   "0"
3456   "#")
3457
3458 (define_split
3459   [(set (match_operand:DF 0 "push_operand" "")
3460         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "!TARGET_64BIT"
3462   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3463    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3464
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "TARGET_64BIT"
3469   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472 (define_insn "*dummy_extendsfxf2"
3473   [(set (match_operand:XF 0 "push_operand" "=<")
3474         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3475   "0"
3476   "#")
3477
3478 (define_split
3479   [(set (match_operand:XF 0 "push_operand" "")
3480         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3481   ""
3482   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3483    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3484   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3485
3486 (define_split
3487   [(set (match_operand:XF 0 "push_operand" "")
3488         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489   "TARGET_64BIT"
3490   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3491    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3492   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493
3494 (define_split
3495   [(set (match_operand:XF 0 "push_operand" "")
3496         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3497   ""
3498   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3499    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3500   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501
3502 (define_split
3503   [(set (match_operand:XF 0 "push_operand" "")
3504         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505   "TARGET_64BIT"
3506   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3507    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3508   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509
3510 (define_expand "extendsfdf2"
3511   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3512         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3513   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3514 {
3515   /* ??? Needed for compress_float_constant since all fp constants
3516      are LEGITIMATE_CONSTANT_P.  */
3517   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3520     operands[1] = force_reg (SFmode, operands[1]);
3521 })
3522
3523 (define_insn "*extendsfdf2_mixed"
3524   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3525         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3526   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3527    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3528 {
3529   switch (which_alternative)
3530     {
3531     case 0:
3532       return output_387_reg_move (insn, operands);
3533
3534     case 1:
3535       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3536         return "fstp%z0\t%y0";
3537       else
3538         return "fst%z0\t%y0";
3539
3540     case 2:
3541       return "cvtss2sd\t{%1, %0|%0, %1}";
3542
3543     default:
3544       gcc_unreachable ();
3545     }
3546 }
3547   [(set_attr "type" "fmov,fmov,ssecvt")
3548    (set_attr "mode" "SF,XF,DF")])
3549
3550 (define_insn "*extendsfdf2_sse"
3551   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3552         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3553   "TARGET_SSE2 && TARGET_SSE_MATH
3554    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3555   "cvtss2sd\t{%1, %0|%0, %1}"
3556   [(set_attr "type" "ssecvt")
3557    (set_attr "mode" "DF")])
3558
3559 (define_insn "*extendsfdf2_i387"
3560   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3561         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3562   "TARGET_80387
3563    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3564 {
3565   switch (which_alternative)
3566     {
3567     case 0:
3568       return output_387_reg_move (insn, operands);
3569
3570     case 1:
3571       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3572         return "fstp%z0\t%y0";
3573       else
3574         return "fst%z0\t%y0";
3575
3576     default:
3577       gcc_unreachable ();
3578     }
3579 }
3580   [(set_attr "type" "fmov")
3581    (set_attr "mode" "SF,XF")])
3582
3583 (define_expand "extendsfxf2"
3584   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3585         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3586   "TARGET_80387"
3587 {
3588   /* ??? Needed for compress_float_constant since all fp constants
3589      are LEGITIMATE_CONSTANT_P.  */
3590   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3591     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3592   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3593     operands[1] = force_reg (SFmode, operands[1]);
3594 })
3595
3596 (define_insn "*extendsfxf2_i387"
3597   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3598         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3599   "TARGET_80387
3600    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3601 {
3602   switch (which_alternative)
3603     {
3604     case 0:
3605       return output_387_reg_move (insn, operands);
3606
3607     case 1:
3608       /* There is no non-popping store to memory for XFmode.  So if
3609          we need one, follow the store with a load.  */
3610       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3611         return "fstp%z0\t%y0";
3612       else
3613         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3614
3615     default:
3616       gcc_unreachable ();
3617     }
3618 }
3619   [(set_attr "type" "fmov")
3620    (set_attr "mode" "SF,XF")])
3621
3622 (define_expand "extenddfxf2"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3624         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3625   "TARGET_80387"
3626 {
3627   /* ??? Needed for compress_float_constant since all fp constants
3628      are LEGITIMATE_CONSTANT_P.  */
3629   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3630     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3631   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3632     operands[1] = force_reg (DFmode, operands[1]);
3633 })
3634
3635 (define_insn "*extenddfxf2_i387"
3636   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3637         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3638   "TARGET_80387
3639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3640 {
3641   switch (which_alternative)
3642     {
3643     case 0:
3644       return output_387_reg_move (insn, operands);
3645
3646     case 1:
3647       /* There is no non-popping store to memory for XFmode.  So if
3648          we need one, follow the store with a load.  */
3649       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3650         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3651       else
3652         return "fstp%z0\t%y0";
3653
3654     default:
3655       gcc_unreachable ();
3656     }
3657 }
3658   [(set_attr "type" "fmov")
3659    (set_attr "mode" "DF,XF")])
3660
3661 ;; %%% This seems bad bad news.
3662 ;; This cannot output into an f-reg because there is no way to be sure
3663 ;; of truncating in that case.  Otherwise this is just like a simple move
3664 ;; insn.  So we pretend we can output to a reg in order to get better
3665 ;; register preferencing, but we really use a stack slot.
3666
3667 ;; Conversion from DFmode to SFmode.
3668
3669 (define_expand "truncdfsf2"
3670   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3671         (float_truncate:SF
3672           (match_operand:DF 1 "nonimmediate_operand" "")))]
3673   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3674 {
3675   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3676     operands[1] = force_reg (DFmode, operands[1]);
3677
3678   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3679     ;
3680   else if (flag_unsafe_math_optimizations)
3681     ;
3682   else
3683     {
3684       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3685       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3686       DONE;
3687     }
3688 })
3689
3690 (define_expand "truncdfsf2_with_temp"
3691   [(parallel [(set (match_operand:SF 0 "" "")
3692                    (float_truncate:SF (match_operand:DF 1 "" "")))
3693               (clobber (match_operand:SF 2 "" ""))])]
3694   "")
3695
3696 (define_insn "*truncdfsf_fast_mixed"
3697   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3698         (float_truncate:SF
3699           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3700   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3701 {
3702   switch (which_alternative)
3703     {
3704     case 0:
3705       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3706         return "fstp%z0\t%y0";
3707       else
3708         return "fst%z0\t%y0";
3709     case 1:
3710       return output_387_reg_move (insn, operands);
3711     case 2:
3712       return "cvtsd2ss\t{%1, %0|%0, %1}";
3713     default:
3714       gcc_unreachable ();
3715     }
3716 }
3717   [(set_attr "type" "fmov,fmov,ssecvt")
3718    (set_attr "mode" "SF")])
3719
3720 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3721 ;; because nothing we do here is unsafe.
3722 (define_insn "*truncdfsf_fast_sse"
3723   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3724         (float_truncate:SF
3725           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3726   "TARGET_SSE2 && TARGET_SSE_MATH"
3727   "cvtsd2ss\t{%1, %0|%0, %1}"
3728   [(set_attr "type" "ssecvt")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf_fast_i387"
3732   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3735   "TARGET_80387 && flag_unsafe_math_optimizations"
3736   "* return output_387_reg_move (insn, operands);"
3737   [(set_attr "type" "fmov")
3738    (set_attr "mode" "SF")])
3739
3740 (define_insn "*truncdfsf_mixed"
3741   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3742         (float_truncate:SF
3743           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3744    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3745   "TARGET_MIX_SSE_I387"
3746 {
3747   switch (which_alternative)
3748     {
3749     case 0:
3750       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3751         return "fstp%z0\t%y0";
3752       else
3753         return "fst%z0\t%y0";
3754     case 1:
3755       return "#";
3756     case 2:
3757       return "cvtsd2ss\t{%1, %0|%0, %1}";
3758     default:
3759       gcc_unreachable ();
3760     }
3761 }
3762   [(set_attr "type" "fmov,multi,ssecvt")
3763    (set_attr "unit" "*,i387,*")
3764    (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3770    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3771   "TARGET_80387"
3772 {
3773   switch (which_alternative)
3774     {
3775     case 0:
3776       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777         return "fstp%z0\t%y0";
3778       else
3779         return "fst%z0\t%y0";
3780     case 1:
3781       return "#";
3782     default:
3783       gcc_unreachable ();
3784     }
3785 }
3786   [(set_attr "type" "fmov,multi")
3787    (set_attr "unit" "*,i387")
3788    (set_attr "mode" "SF")])
3789
3790 (define_insn "*truncdfsf2_i387_1"
3791   [(set (match_operand:SF 0 "memory_operand" "=m")
3792         (float_truncate:SF
3793           (match_operand:DF 1 "register_operand" "f")))]
3794   "TARGET_80387
3795    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3796    && !TARGET_MIX_SSE_I387"
3797 {
3798   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799     return "fstp%z0\t%y0";
3800   else
3801     return "fst%z0\t%y0";
3802 }
3803   [(set_attr "type" "fmov")
3804    (set_attr "mode" "SF")])
3805
3806 (define_split
3807   [(set (match_operand:SF 0 "register_operand" "")
3808         (float_truncate:SF
3809          (match_operand:DF 1 "fp_register_operand" "")))
3810    (clobber (match_operand 2 "" ""))]
3811   "reload_completed"
3812   [(set (match_dup 2) (match_dup 1))
3813    (set (match_dup 0) (match_dup 2))]
3814 {
3815   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3816 })
3817
3818 ;; Conversion from XFmode to SFmode.
3819
3820 (define_expand "truncxfsf2"
3821   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3822                    (float_truncate:SF
3823                     (match_operand:XF 1 "register_operand" "")))
3824               (clobber (match_dup 2))])]
3825   "TARGET_80387"
3826 {
3827   if (flag_unsafe_math_optimizations)
3828     {
3829       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3830       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3831       if (reg != operands[0])
3832         emit_move_insn (operands[0], reg);
3833       DONE;
3834     }
3835   else
3836     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3837 })
3838
3839 (define_insn "*truncxfsf2_mixed"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_MIX_SSE_I387"
3845 {
3846   gcc_assert (!which_alternative);
3847   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3848     return "fstp%z0\t%y0";
3849   else
3850     return "fst%z0\t%y0";
3851 }
3852   [(set_attr "type" "fmov,multi,multi,multi")
3853    (set_attr "unit" "*,i387,i387,i387")
3854    (set_attr "mode" "SF")])
3855
3856 (define_insn "truncxfsf2_i387_noop"
3857   [(set (match_operand:SF 0 "register_operand" "=f")
3858         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3859   "TARGET_80387 && flag_unsafe_math_optimizations"
3860 {
3861   return output_387_reg_move (insn, operands);
3862 }
3863   [(set_attr "type" "fmov")
3864    (set_attr "mode" "SF")])
3865
3866 (define_insn "*truncxfsf2_i387"
3867   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3868         (float_truncate:SF
3869          (match_operand:XF 1 "register_operand" "f,f,f")))
3870    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3871   "TARGET_80387"
3872 {
3873   gcc_assert (!which_alternative);
3874   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3875     return "fstp%z0\t%y0";
3876    else
3877      return "fst%z0\t%y0";
3878 }
3879   [(set_attr "type" "fmov,multi,multi")
3880    (set_attr "unit" "*,i387,i387")
3881    (set_attr "mode" "SF")])
3882
3883 (define_insn "*truncxfsf2_i387_1"
3884   [(set (match_operand:SF 0 "memory_operand" "=m")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "f")))]
3887   "TARGET_80387"
3888 {
3889   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3890     return "fstp%z0\t%y0";
3891   else
3892     return "fst%z0\t%y0";
3893 }
3894   [(set_attr "type" "fmov")
3895    (set_attr "mode" "SF")])
3896
3897 (define_split
3898   [(set (match_operand:SF 0 "register_operand" "")
3899         (float_truncate:SF
3900          (match_operand:XF 1 "register_operand" "")))
3901    (clobber (match_operand:SF 2 "memory_operand" ""))]
3902   "TARGET_80387 && reload_completed"
3903   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3904    (set (match_dup 0) (match_dup 2))]
3905   "")
3906
3907 (define_split
3908   [(set (match_operand:SF 0 "memory_operand" "")
3909         (float_truncate:SF
3910          (match_operand:XF 1 "register_operand" "")))
3911    (clobber (match_operand:SF 2 "memory_operand" ""))]
3912   "TARGET_80387"
3913   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3914   "")
3915
3916 ;; Conversion from XFmode to DFmode.
3917
3918 (define_expand "truncxfdf2"
3919   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3920                    (float_truncate:DF
3921                     (match_operand:XF 1 "register_operand" "")))
3922               (clobber (match_dup 2))])]
3923   "TARGET_80387"
3924 {
3925   if (flag_unsafe_math_optimizations)
3926     {
3927       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3928       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3929       if (reg != operands[0])
3930         emit_move_insn (operands[0], reg);
3931       DONE;
3932     }
3933   else
3934     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3935 })
3936
3937 (define_insn "*truncxfdf2_mixed"
3938   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3939         (float_truncate:DF
3940          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3941    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3942   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3943 {
3944   gcc_assert (!which_alternative);
3945   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946     return "fstp%z0\t%y0";
3947   else
3948     return "fst%z0\t%y0";
3949 }
3950   [(set_attr "type" "fmov,multi,multi,multi")
3951    (set_attr "unit" "*,i387,i387,i387")
3952    (set_attr "mode" "DF")])
3953
3954 (define_insn "truncxfdf2_i387_noop"
3955   [(set (match_operand:DF 0 "register_operand" "=f")
3956         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3957   "TARGET_80387 && flag_unsafe_math_optimizations"
3958 {
3959   return output_387_reg_move (insn, operands);
3960 }
3961   [(set_attr "type" "fmov")
3962    (set_attr "mode" "DF")])
3963
3964 (define_insn "*truncxfdf2_i387"
3965   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3966         (float_truncate:DF
3967          (match_operand:XF 1 "register_operand" "f,f,f")))
3968    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3969   "TARGET_80387"
3970 {
3971   gcc_assert (!which_alternative);
3972   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3973     return "fstp%z0\t%y0";
3974   else
3975     return "fst%z0\t%y0";
3976 }
3977   [(set_attr "type" "fmov,multi,multi")
3978    (set_attr "unit" "*,i387,i387")
3979    (set_attr "mode" "DF")])
3980
3981 (define_insn "*truncxfdf2_i387_1"
3982   [(set (match_operand:DF 0 "memory_operand" "=m")
3983         (float_truncate:DF
3984           (match_operand:XF 1 "register_operand" "f")))]
3985   "TARGET_80387"
3986 {
3987   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988     return "fstp%z0\t%y0";
3989   else
3990     return "fst%z0\t%y0";
3991 }
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "DF")])
3994
3995 (define_split
3996   [(set (match_operand:DF 0 "register_operand" "")
3997         (float_truncate:DF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:DF 2 "memory_operand" ""))]
4000   "TARGET_80387 && reload_completed"
4001   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4002    (set (match_dup 0) (match_dup 2))]
4003   "")
4004
4005 (define_split
4006   [(set (match_operand:DF 0 "memory_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387"
4011   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4012   "")
4013 \f
4014 ;; Signed conversion to DImode.
4015
4016 (define_expand "fix_truncxfdi2"
4017   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4019               (clobber (reg:CC FLAGS_REG))])]
4020   "TARGET_80387"
4021 {
4022   if (TARGET_FISTTP)
4023    {
4024      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4025      DONE;
4026    }
4027 })
4028
4029 (define_expand "fix_trunc<mode>di2"
4030   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4031                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4032               (clobber (reg:CC FLAGS_REG))])]
4033   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4034 {
4035   if (TARGET_FISTTP
4036       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4037    {
4038      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4039      DONE;
4040    }
4041   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4042    {
4043      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4044      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4045      if (out != operands[0])
4046         emit_move_insn (operands[0], out);
4047      DONE;
4048    }
4049 })
4050
4051 ;; Signed conversion to SImode.
4052
4053 (define_expand "fix_truncxfsi2"
4054   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "TARGET_80387"
4058 {
4059   if (TARGET_FISTTP)
4060    {
4061      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4062      DONE;
4063    }
4064 })
4065
4066 (define_expand "fix_trunc<mode>si2"
4067   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4068                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4069               (clobber (reg:CC FLAGS_REG))])]
4070   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4071 {
4072   if (TARGET_FISTTP
4073       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4074    {
4075      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4076      DONE;
4077    }
4078   if (SSE_FLOAT_MODE_P (<MODE>mode))
4079    {
4080      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4081      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4082      if (out != operands[0])
4083         emit_move_insn (operands[0], out);
4084      DONE;
4085    }
4086 })
4087
4088 ;; Signed conversion to HImode.
4089
4090 (define_expand "fix_trunc<mode>hi2"
4091   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4092                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4093               (clobber (reg:CC FLAGS_REG))])]
4094   "TARGET_80387
4095    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4096 {
4097   if (TARGET_FISTTP)
4098    {
4099      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4100      DONE;
4101    }
4102 })
4103
4104 ;; When SSE is available, it is always faster to use it!
4105 (define_insn "fix_truncsfdi_sse"
4106   [(set (match_operand:DI 0 "register_operand" "=r,r")
4107         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4108   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4109   "cvttss2si{q}\t{%1, %0|%0, %1}"
4110   [(set_attr "type" "sseicvt")
4111    (set_attr "mode" "SF")
4112    (set_attr "athlon_decode" "double,vector")])
4113
4114 (define_insn "fix_truncdfdi_sse"
4115   [(set (match_operand:DI 0 "register_operand" "=r,r")
4116         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4117   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4118   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4119   [(set_attr "type" "sseicvt")
4120    (set_attr "mode" "DF")
4121    (set_attr "athlon_decode" "double,vector")])
4122
4123 (define_insn "fix_truncsfsi_sse"
4124   [(set (match_operand:SI 0 "register_operand" "=r,r")
4125         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4126   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4127   "cvttss2si\t{%1, %0|%0, %1}"
4128   [(set_attr "type" "sseicvt")
4129    (set_attr "mode" "DF")
4130    (set_attr "athlon_decode" "double,vector")])
4131
4132 (define_insn "fix_truncdfsi_sse"
4133   [(set (match_operand:SI 0 "register_operand" "=r,r")
4134         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4135   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4136   "cvttsd2si\t{%1, %0|%0, %1}"
4137   [(set_attr "type" "sseicvt")
4138    (set_attr "mode" "DF")
4139    (set_attr "athlon_decode" "double,vector")])
4140
4141 ;; Avoid vector decoded forms of the instruction.
4142 (define_peephole2
4143   [(match_scratch:DF 2 "Y")
4144    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4145         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4146   "TARGET_K8 && !optimize_size"
4147   [(set (match_dup 2) (match_dup 1))
4148    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4149   "")
4150
4151 (define_peephole2
4152   [(match_scratch:SF 2 "x")
4153    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4154         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4155   "TARGET_K8 && !optimize_size"
4156   [(set (match_dup 2) (match_dup 1))
4157    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4158   "")
4159
4160 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4161   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4162         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4163   "TARGET_FISTTP
4164    && FLOAT_MODE_P (GET_MODE (operands[1]))
4165    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4166          && (TARGET_64BIT || <MODE>mode != DImode))
4167         && TARGET_SSE_MATH)
4168    && !(reload_completed || reload_in_progress)"
4169   "#"
4170   "&& 1"
4171   [(const_int 0)]
4172 {
4173   if (memory_operand (operands[0], VOIDmode))
4174     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4175   else
4176     {
4177       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4178       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4179                                                             operands[1],
4180                                                             operands[2]));
4181     }
4182   DONE;
4183 }
4184   [(set_attr "type" "fisttp")
4185    (set_attr "mode" "<MODE>")])
4186
4187 (define_insn "fix_trunc<mode>_i387_fisttp"
4188   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4189         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4190    (clobber (match_scratch:XF 2 "=&1f"))]
4191   "TARGET_FISTTP
4192    && FLOAT_MODE_P (GET_MODE (operands[1]))
4193    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4194          && (TARGET_64BIT || <MODE>mode != DImode))
4195         && TARGET_SSE_MATH)"
4196   "* return output_fix_trunc (insn, operands, 1);"
4197   [(set_attr "type" "fisttp")
4198    (set_attr "mode" "<MODE>")])
4199
4200 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4201   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4202         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4203    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4204    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4205   "TARGET_FISTTP
4206    && FLOAT_MODE_P (GET_MODE (operands[1]))
4207    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208         && (TARGET_64BIT || <MODE>mode != DImode))
4209         && TARGET_SSE_MATH)"
4210   "#"
4211   [(set_attr "type" "fisttp")
4212    (set_attr "mode" "<MODE>")])
4213
4214 (define_split
4215   [(set (match_operand:X87MODEI 0 "register_operand" "")
4216         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4217    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4218    (clobber (match_scratch 3 ""))]
4219   "reload_completed"
4220   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4221               (clobber (match_dup 3))])
4222    (set (match_dup 0) (match_dup 2))]
4223   "")
4224
4225 (define_split
4226   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4227         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4228    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4229    (clobber (match_scratch 3 ""))]
4230   "reload_completed"
4231   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4232               (clobber (match_dup 3))])]
4233   "")
4234
4235 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4236 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4237 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4238 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4239 ;; function in i386.c.
4240 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4241   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4242         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4243    (clobber (reg:CC FLAGS_REG))]
4244   "TARGET_80387 && !TARGET_FISTTP
4245    && FLOAT_MODE_P (GET_MODE (operands[1]))
4246    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4247          && (TARGET_64BIT || <MODE>mode != DImode))
4248    && !(reload_completed || reload_in_progress)"
4249   "#"
4250   "&& 1"
4251   [(const_int 0)]
4252 {
4253   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4254
4255   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4256   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4257   if (memory_operand (operands[0], VOIDmode))
4258     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4259                                          operands[2], operands[3]));
4260   else
4261     {
4262       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4263       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4264                                                      operands[2], operands[3],
4265                                                      operands[4]));
4266     }
4267   DONE;
4268 }
4269   [(set_attr "type" "fistp")
4270    (set_attr "i387_cw" "trunc")
4271    (set_attr "mode" "<MODE>")])
4272
4273 (define_insn "fix_truncdi_i387"
4274   [(set (match_operand:DI 0 "memory_operand" "=m")
4275         (fix:DI (match_operand 1 "register_operand" "f")))
4276    (use (match_operand:HI 2 "memory_operand" "m"))
4277    (use (match_operand:HI 3 "memory_operand" "m"))
4278    (clobber (match_scratch:XF 4 "=&1f"))]
4279   "TARGET_80387 && !TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4282   "* return output_fix_trunc (insn, operands, 0);"
4283   [(set_attr "type" "fistp")
4284    (set_attr "i387_cw" "trunc")
4285    (set_attr "mode" "DI")])
4286
4287 (define_insn "fix_truncdi_i387_with_temp"
4288   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4289         (fix:DI (match_operand 1 "register_operand" "f,f")))
4290    (use (match_operand:HI 2 "memory_operand" "m,m"))
4291    (use (match_operand:HI 3 "memory_operand" "m,m"))
4292    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4293    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4294   "TARGET_80387 && !TARGET_FISTTP
4295    && FLOAT_MODE_P (GET_MODE (operands[1]))
4296    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4297   "#"
4298   [(set_attr "type" "fistp")
4299    (set_attr "i387_cw" "trunc")
4300    (set_attr "mode" "DI")])
4301
4302 (define_split 
4303   [(set (match_operand:DI 0 "register_operand" "")
4304         (fix:DI (match_operand 1 "register_operand" "")))
4305    (use (match_operand:HI 2 "memory_operand" ""))
4306    (use (match_operand:HI 3 "memory_operand" ""))
4307    (clobber (match_operand:DI 4 "memory_operand" ""))
4308    (clobber (match_scratch 5 ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4311               (use (match_dup 2))
4312               (use (match_dup 3))
4313               (clobber (match_dup 5))])
4314    (set (match_dup 0) (match_dup 4))]
4315   "")
4316
4317 (define_split 
4318   [(set (match_operand:DI 0 "memory_operand" "")
4319         (fix:DI (match_operand 1 "register_operand" "")))
4320    (use (match_operand:HI 2 "memory_operand" ""))
4321    (use (match_operand:HI 3 "memory_operand" ""))
4322    (clobber (match_operand:DI 4 "memory_operand" ""))
4323    (clobber (match_scratch 5 ""))]
4324   "reload_completed"
4325   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4326               (use (match_dup 2))
4327               (use (match_dup 3))
4328               (clobber (match_dup 5))])]
4329   "")
4330
4331 (define_insn "fix_trunc<mode>_i387"
4332   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4333         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4334    (use (match_operand:HI 2 "memory_operand" "m"))
4335    (use (match_operand:HI 3 "memory_operand" "m"))]
4336   "TARGET_80387 && !TARGET_FISTTP
4337    && FLOAT_MODE_P (GET_MODE (operands[1]))
4338    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4339   "* return output_fix_trunc (insn, operands, 0);"
4340   [(set_attr "type" "fistp")
4341    (set_attr "i387_cw" "trunc")
4342    (set_attr "mode" "<MODE>")])
4343
4344 (define_insn "fix_trunc<mode>_i387_with_temp"
4345   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4346         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4347    (use (match_operand:HI 2 "memory_operand" "m,m"))
4348    (use (match_operand:HI 3 "memory_operand" "m,m"))
4349    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4350   "TARGET_80387 && !TARGET_FISTTP
4351    && FLOAT_MODE_P (GET_MODE (operands[1]))
4352    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4353   "#"
4354   [(set_attr "type" "fistp")
4355    (set_attr "i387_cw" "trunc")
4356    (set_attr "mode" "<MODE>")])
4357
4358 (define_split 
4359   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4360         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4361    (use (match_operand:HI 2 "memory_operand" ""))
4362    (use (match_operand:HI 3 "memory_operand" ""))
4363    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4364   "reload_completed"
4365   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4366               (use (match_dup 2))
4367               (use (match_dup 3))])
4368    (set (match_dup 0) (match_dup 4))]
4369   "")
4370
4371 (define_split 
4372   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4373         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4374    (use (match_operand:HI 2 "memory_operand" ""))
4375    (use (match_operand:HI 3 "memory_operand" ""))
4376    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4377   "reload_completed"
4378   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4379               (use (match_dup 2))
4380               (use (match_dup 3))])]
4381   "")
4382
4383 (define_insn "x86_fnstcw_1"
4384   [(set (match_operand:HI 0 "memory_operand" "=m")
4385         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4386   "TARGET_80387"
4387   "fnstcw\t%0"
4388   [(set_attr "length" "2")
4389    (set_attr "mode" "HI")
4390    (set_attr "unit" "i387")])
4391
4392 (define_insn "x86_fldcw_1"
4393   [(set (reg:HI FPSR_REG)
4394         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4395   "TARGET_80387"
4396   "fldcw\t%0"
4397   [(set_attr "length" "2")
4398    (set_attr "mode" "HI")
4399    (set_attr "unit" "i387")
4400    (set_attr "athlon_decode" "vector")])
4401 \f
4402 ;; Conversion between fixed point and floating point.
4403
4404 ;; Even though we only accept memory inputs, the backend _really_
4405 ;; wants to be able to do this between registers.
4406
4407 (define_expand "floathisf2"
4408   [(set (match_operand:SF 0 "register_operand" "")
4409         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4410   "TARGET_80387 || TARGET_SSE_MATH"
4411 {
4412   if (TARGET_SSE_MATH)
4413     {
4414       emit_insn (gen_floatsisf2 (operands[0],
4415                                  convert_to_mode (SImode, operands[1], 0)));
4416       DONE;
4417     }
4418 })
4419
4420 (define_insn "*floathisf2_i387"
4421   [(set (match_operand:SF 0 "register_operand" "=f,f")
4422         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4423   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4424   "@
4425    fild%z1\t%1
4426    #"
4427   [(set_attr "type" "fmov,multi")
4428    (set_attr "mode" "SF")
4429    (set_attr "unit" "*,i387")
4430    (set_attr "fp_int_src" "true")])
4431
4432 (define_expand "floatsisf2"
4433   [(set (match_operand:SF 0 "register_operand" "")
4434         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4435   "TARGET_80387 || TARGET_SSE_MATH"
4436   "")
4437
4438 (define_insn "*floatsisf2_mixed"
4439   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4440         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4441   "TARGET_MIX_SSE_I387"
4442   "@
4443    fild%z1\t%1
4444    #
4445    cvtsi2ss\t{%1, %0|%0, %1}
4446    cvtsi2ss\t{%1, %0|%0, %1}"
4447   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4448    (set_attr "mode" "SF")
4449    (set_attr "unit" "*,i387,*,*")
4450    (set_attr "athlon_decode" "*,*,vector,double")
4451    (set_attr "fp_int_src" "true")])
4452
4453 (define_insn "*floatsisf2_sse"
4454   [(set (match_operand:SF 0 "register_operand" "=x,x")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4456   "TARGET_SSE_MATH"
4457   "cvtsi2ss\t{%1, %0|%0, %1}"
4458   [(set_attr "type" "sseicvt")
4459    (set_attr "mode" "SF")
4460    (set_attr "athlon_decode" "vector,double")
4461    (set_attr "fp_int_src" "true")])
4462
4463 (define_insn "*floatsisf2_i387"
4464   [(set (match_operand:SF 0 "register_operand" "=f,f")
4465         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4466   "TARGET_80387"
4467   "@
4468    fild%z1\t%1
4469    #"
4470   [(set_attr "type" "fmov,multi")
4471    (set_attr "mode" "SF")
4472    (set_attr "unit" "*,i387")
4473    (set_attr "fp_int_src" "true")])
4474
4475 (define_expand "floatdisf2"
4476   [(set (match_operand:SF 0 "register_operand" "")
4477         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4478   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4479   "")
4480
4481 (define_insn "*floatdisf2_mixed"
4482   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4483         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4484   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4485   "@
4486    fild%z1\t%1
4487    #
4488    cvtsi2ss{q}\t{%1, %0|%0, %1}
4489    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4490   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4491    (set_attr "mode" "SF")
4492    (set_attr "unit" "*,i387,*,*")
4493    (set_attr "athlon_decode" "*,*,vector,double")
4494    (set_attr "fp_int_src" "true")])
4495
4496 (define_insn "*floatdisf2_sse"
4497   [(set (match_operand:SF 0 "register_operand" "=x,x")
4498         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4499   "TARGET_64BIT && TARGET_SSE_MATH"
4500   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4501   [(set_attr "type" "sseicvt")
4502    (set_attr "mode" "SF")
4503    (set_attr "athlon_decode" "vector,double")
4504    (set_attr "fp_int_src" "true")])
4505
4506 (define_insn "*floatdisf2_i387"
4507   [(set (match_operand:SF 0 "register_operand" "=f,f")
4508         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4509   "TARGET_80387"
4510   "@
4511    fild%z1\t%1
4512    #"
4513   [(set_attr "type" "fmov,multi")
4514    (set_attr "mode" "SF")
4515    (set_attr "unit" "*,i387")
4516    (set_attr "fp_int_src" "true")])
4517
4518 (define_expand "floathidf2"
4519   [(set (match_operand:DF 0 "register_operand" "")
4520         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4521   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4522 {
4523   if (TARGET_SSE2 && TARGET_SSE_MATH)
4524     {
4525       emit_insn (gen_floatsidf2 (operands[0],
4526                                  convert_to_mode (SImode, operands[1], 0)));
4527       DONE;
4528     }
4529 })
4530
4531 (define_insn "*floathidf2_i387"
4532   [(set (match_operand:DF 0 "register_operand" "=f,f")
4533         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4534   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4535   "@
4536    fild%z1\t%1
4537    #"
4538   [(set_attr "type" "fmov,multi")
4539    (set_attr "mode" "DF")
4540    (set_attr "unit" "*,i387")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_expand "floatsidf2"
4544   [(set (match_operand:DF 0 "register_operand" "")
4545         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4547   "")
4548
4549 (define_insn "*floatsidf2_mixed"
4550   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4553   "@
4554    fild%z1\t%1
4555    #
4556    cvtsi2sd\t{%1, %0|%0, %1}
4557    cvtsi2sd\t{%1, %0|%0, %1}"
4558   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559    (set_attr "mode" "DF")
4560    (set_attr "unit" "*,i387,*,*")
4561    (set_attr "athlon_decode" "*,*,double,direct")
4562    (set_attr "fp_int_src" "true")])
4563
4564 (define_insn "*floatsidf2_sse"
4565   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4566         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4567   "TARGET_SSE2 && TARGET_SSE_MATH"
4568   "cvtsi2sd\t{%1, %0|%0, %1}"
4569   [(set_attr "type" "sseicvt")
4570    (set_attr "mode" "DF")
4571    (set_attr "athlon_decode" "double,direct")
4572    (set_attr "fp_int_src" "true")])
4573
4574 (define_insn "*floatsidf2_i387"
4575   [(set (match_operand:DF 0 "register_operand" "=f,f")
4576         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4577   "TARGET_80387"
4578   "@
4579    fild%z1\t%1
4580    #"
4581   [(set_attr "type" "fmov,multi")
4582    (set_attr "mode" "DF")
4583    (set_attr "unit" "*,i387")
4584    (set_attr "fp_int_src" "true")])
4585
4586 (define_expand "floatdidf2"
4587   [(set (match_operand:DF 0 "register_operand" "")
4588         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4589   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4590   "")
4591
4592 (define_insn "*floatdidf2_mixed"
4593   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4594         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4595   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4596   "@
4597    fild%z1\t%1
4598    #
4599    cvtsi2sd{q}\t{%1, %0|%0, %1}
4600    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4601   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4602    (set_attr "mode" "DF")
4603    (set_attr "unit" "*,i387,*,*")
4604    (set_attr "athlon_decode" "*,*,double,direct")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_insn "*floatdidf2_sse"
4608   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4609         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4610   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4611   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4612   [(set_attr "type" "sseicvt")
4613    (set_attr "mode" "DF")
4614    (set_attr "athlon_decode" "double,direct")
4615    (set_attr "fp_int_src" "true")])
4616
4617 (define_insn "*floatdidf2_i387"
4618   [(set (match_operand:DF 0 "register_operand" "=f,f")
4619         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4620   "TARGET_80387"
4621   "@
4622    fild%z1\t%1
4623    #"
4624   [(set_attr "type" "fmov,multi")
4625    (set_attr "mode" "DF")
4626    (set_attr "unit" "*,i387")
4627    (set_attr "fp_int_src" "true")])
4628
4629 (define_insn "floathixf2"
4630   [(set (match_operand:XF 0 "register_operand" "=f,f")
4631         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4632   "TARGET_80387"
4633   "@
4634    fild%z1\t%1
4635    #"
4636   [(set_attr "type" "fmov,multi")
4637    (set_attr "mode" "XF")
4638    (set_attr "unit" "*,i387")
4639    (set_attr "fp_int_src" "true")])
4640
4641 (define_insn "floatsixf2"
4642   [(set (match_operand:XF 0 "register_operand" "=f,f")
4643         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4644   "TARGET_80387"
4645   "@
4646    fild%z1\t%1
4647    #"
4648   [(set_attr "type" "fmov,multi")
4649    (set_attr "mode" "XF")
4650    (set_attr "unit" "*,i387")
4651    (set_attr "fp_int_src" "true")])
4652
4653 (define_insn "floatdixf2"
4654   [(set (match_operand:XF 0 "register_operand" "=f,f")
4655         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4656   "TARGET_80387"
4657   "@
4658    fild%z1\t%1
4659    #"
4660   [(set_attr "type" "fmov,multi")
4661    (set_attr "mode" "XF")
4662    (set_attr "unit" "*,i387")
4663    (set_attr "fp_int_src" "true")])
4664
4665 ;; %%% Kill these when reload knows how to do it.
4666 (define_split
4667   [(set (match_operand 0 "fp_register_operand" "")
4668         (float (match_operand 1 "register_operand" "")))]
4669   "reload_completed
4670    && TARGET_80387
4671    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4672   [(const_int 0)]
4673 {
4674   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4675   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4676   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4677   ix86_free_from_memory (GET_MODE (operands[1]));
4678   DONE;
4679 })
4680
4681 (define_expand "floatunssisf2"
4682   [(use (match_operand:SF 0 "register_operand" ""))
4683    (use (match_operand:SI 1 "register_operand" ""))]
4684   "!TARGET_64BIT && TARGET_SSE_MATH"
4685   "x86_emit_floatuns (operands); DONE;")
4686
4687 (define_expand "floatunsdisf2"
4688   [(use (match_operand:SF 0 "register_operand" ""))
4689    (use (match_operand:DI 1 "register_operand" ""))]
4690   "TARGET_64BIT && TARGET_SSE_MATH"
4691   "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdidf2"
4694   [(use (match_operand:DF 0 "register_operand" ""))
4695    (use (match_operand:DI 1 "register_operand" ""))]
4696   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4697   "x86_emit_floatuns (operands); DONE;")
4698 \f
4699 ;; SSE extract/set expanders
4700
4701 \f
4702 ;; Add instructions
4703
4704 ;; %%% splits for addditi3
4705
4706 (define_expand "addti3"
4707   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4708         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4709                  (match_operand:TI 2 "x86_64_general_operand" "")))
4710    (clobber (reg:CC FLAGS_REG))]
4711   "TARGET_64BIT"
4712   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4713
4714 (define_insn "*addti3_1"
4715   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4716         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4717                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4718    (clobber (reg:CC FLAGS_REG))]
4719   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4720   "#")
4721
4722 (define_split
4723   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4724         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4725                  (match_operand:TI 2 "general_operand" "")))
4726    (clobber (reg:CC FLAGS_REG))]
4727   "TARGET_64BIT && reload_completed"
4728   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4729                                           UNSPEC_ADD_CARRY))
4730               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4731    (parallel [(set (match_dup 3)
4732                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4733                                      (match_dup 4))
4734                             (match_dup 5)))
4735               (clobber (reg:CC FLAGS_REG))])]
4736   "split_ti (operands+0, 1, operands+0, operands+3);
4737    split_ti (operands+1, 1, operands+1, operands+4);
4738    split_ti (operands+2, 1, operands+2, operands+5);")
4739
4740 ;; %%% splits for addsidi3
4741 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4742 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4743 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4744
4745 (define_expand "adddi3"
4746   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4748                  (match_operand:DI 2 "x86_64_general_operand" "")))
4749    (clobber (reg:CC FLAGS_REG))]
4750   ""
4751   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4752
4753 (define_insn "*adddi3_1"
4754   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4756                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4757    (clobber (reg:CC FLAGS_REG))]
4758   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4759   "#")
4760
4761 (define_split
4762   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4763         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4764                  (match_operand:DI 2 "general_operand" "")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "!TARGET_64BIT && reload_completed"
4767   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4768                                           UNSPEC_ADD_CARRY))
4769               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4770    (parallel [(set (match_dup 3)
4771                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4772                                      (match_dup 4))
4773                             (match_dup 5)))
4774               (clobber (reg:CC FLAGS_REG))])]
4775   "split_di (operands+0, 1, operands+0, operands+3);
4776    split_di (operands+1, 1, operands+1, operands+4);
4777    split_di (operands+2, 1, operands+2, operands+5);")
4778
4779 (define_insn "adddi3_carry_rex64"
4780   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4781           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4782                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4783                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4784    (clobber (reg:CC FLAGS_REG))]
4785   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4786   "adc{q}\t{%2, %0|%0, %2}"
4787   [(set_attr "type" "alu")
4788    (set_attr "pent_pair" "pu")
4789    (set_attr "mode" "DI")])
4790
4791 (define_insn "*adddi3_cc_rex64"
4792   [(set (reg:CC FLAGS_REG)
4793         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4794                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4795                    UNSPEC_ADD_CARRY))
4796    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4797         (plus:DI (match_dup 1) (match_dup 2)))]
4798   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4799   "add{q}\t{%2, %0|%0, %2}"
4800   [(set_attr "type" "alu")
4801    (set_attr "mode" "DI")])
4802
4803 (define_insn "addqi3_carry"
4804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4805           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4806                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4807                    (match_operand:QI 2 "general_operand" "qi,qm")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4810   "adc{b}\t{%2, %0|%0, %2}"
4811   [(set_attr "type" "alu")
4812    (set_attr "pent_pair" "pu")
4813    (set_attr "mode" "QI")])
4814
4815 (define_insn "addhi3_carry"
4816   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4817           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4818                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4819                    (match_operand:HI 2 "general_operand" "ri,rm")))
4820    (clobber (reg:CC FLAGS_REG))]
4821   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4822   "adc{w}\t{%2, %0|%0, %2}"
4823   [(set_attr "type" "alu")
4824    (set_attr "pent_pair" "pu")
4825    (set_attr "mode" "HI")])
4826
4827 (define_insn "addsi3_carry"
4828   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4829           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4830                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4831                    (match_operand:SI 2 "general_operand" "ri,rm")))
4832    (clobber (reg:CC FLAGS_REG))]
4833   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4834   "adc{l}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "pent_pair" "pu")
4837    (set_attr "mode" "SI")])
4838
4839 (define_insn "*addsi3_carry_zext"
4840   [(set (match_operand:DI 0 "register_operand" "=r")
4841           (zero_extend:DI 
4842             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4843                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4844                      (match_operand:SI 2 "general_operand" "rim"))))
4845    (clobber (reg:CC FLAGS_REG))]
4846   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4847   "adc{l}\t{%2, %k0|%k0, %2}"
4848   [(set_attr "type" "alu")
4849    (set_attr "pent_pair" "pu")
4850    (set_attr "mode" "SI")])
4851
4852 (define_insn "*addsi3_cc"
4853   [(set (reg:CC FLAGS_REG)
4854         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4855                     (match_operand:SI 2 "general_operand" "ri,rm")]
4856                    UNSPEC_ADD_CARRY))
4857    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4858         (plus:SI (match_dup 1) (match_dup 2)))]
4859   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4860   "add{l}\t{%2, %0|%0, %2}"
4861   [(set_attr "type" "alu")
4862    (set_attr "mode" "SI")])
4863
4864 (define_insn "addqi3_cc"
4865   [(set (reg:CC FLAGS_REG)
4866         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4867                     (match_operand:QI 2 "general_operand" "qi,qm")]
4868                    UNSPEC_ADD_CARRY))
4869    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4870         (plus:QI (match_dup 1) (match_dup 2)))]
4871   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4872   "add{b}\t{%2, %0|%0, %2}"
4873   [(set_attr "type" "alu")
4874    (set_attr "mode" "QI")])
4875
4876 (define_expand "addsi3"
4877   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4879                             (match_operand:SI 2 "general_operand" "")))
4880               (clobber (reg:CC FLAGS_REG))])]
4881   ""
4882   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4883
4884 (define_insn "*lea_1"
4885   [(set (match_operand:SI 0 "register_operand" "=r")
4886         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4887   "!TARGET_64BIT"
4888   "lea{l}\t{%a1, %0|%0, %a1}"
4889   [(set_attr "type" "lea")
4890    (set_attr "mode" "SI")])
4891
4892 (define_insn "*lea_1_rex64"
4893   [(set (match_operand:SI 0 "register_operand" "=r")
4894         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4895   "TARGET_64BIT"
4896   "lea{l}\t{%a1, %0|%0, %a1}"
4897   [(set_attr "type" "lea")
4898    (set_attr "mode" "SI")])
4899
4900 (define_insn "*lea_1_zext"
4901   [(set (match_operand:DI 0 "register_operand" "=r")
4902         (zero_extend:DI
4903          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4904   "TARGET_64BIT"
4905   "lea{l}\t{%a1, %k0|%k0, %a1}"
4906   [(set_attr "type" "lea")
4907    (set_attr "mode" "SI")])
4908
4909 (define_insn "*lea_2_rex64"
4910   [(set (match_operand:DI 0 "register_operand" "=r")
4911         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4912   "TARGET_64BIT"
4913   "lea{q}\t{%a1, %0|%0, %a1}"
4914   [(set_attr "type" "lea")
4915    (set_attr "mode" "DI")])
4916
4917 ;; The lea patterns for non-Pmodes needs to be matched by several
4918 ;; insns converted to real lea by splitters.
4919
4920 (define_insn_and_split "*lea_general_1"
4921   [(set (match_operand 0 "register_operand" "=r")
4922         (plus (plus (match_operand 1 "index_register_operand" "l")
4923                     (match_operand 2 "register_operand" "r"))
4924               (match_operand 3 "immediate_operand" "i")))]
4925   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4926     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4927    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4928    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4929    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4930    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4931        || GET_MODE (operands[3]) == VOIDmode)"
4932   "#"
4933   "&& reload_completed"
4934   [(const_int 0)]
4935 {
4936   rtx pat;
4937   operands[0] = gen_lowpart (SImode, operands[0]);
4938   operands[1] = gen_lowpart (Pmode, operands[1]);
4939   operands[2] = gen_lowpart (Pmode, operands[2]);
4940   operands[3] = gen_lowpart (Pmode, operands[3]);
4941   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4942                       operands[3]);
4943   if (Pmode != SImode)
4944     pat = gen_rtx_SUBREG (SImode, pat, 0);
4945   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4946   DONE;
4947 }
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "SI")])
4950
4951 (define_insn_and_split "*lea_general_1_zext"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (zero_extend:DI
4954           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4955                             (match_operand:SI 2 "register_operand" "r"))
4956                    (match_operand:SI 3 "immediate_operand" "i"))))]
4957   "TARGET_64BIT"
4958   "#"
4959   "&& reload_completed"
4960   [(set (match_dup 0)
4961         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4962                                                      (match_dup 2))
4963                                             (match_dup 3)) 0)))]
4964 {
4965   operands[1] = gen_lowpart (Pmode, operands[1]);
4966   operands[2] = gen_lowpart (Pmode, operands[2]);
4967   operands[3] = gen_lowpart (Pmode, operands[3]);
4968 }
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4971
4972 (define_insn_and_split "*lea_general_2"
4973   [(set (match_operand 0 "register_operand" "=r")
4974         (plus (mult (match_operand 1 "index_register_operand" "l")
4975                     (match_operand 2 "const248_operand" "i"))
4976               (match_operand 3 "nonmemory_operand" "ri")))]
4977   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4978     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4979    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4980    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4981    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4982        || GET_MODE (operands[3]) == VOIDmode)"
4983   "#"
4984   "&& reload_completed"
4985   [(const_int 0)]
4986 {
4987   rtx pat;
4988   operands[0] = gen_lowpart (SImode, operands[0]);
4989   operands[1] = gen_lowpart (Pmode, operands[1]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4992                       operands[3]);
4993   if (Pmode != SImode)
4994     pat = gen_rtx_SUBREG (SImode, pat, 0);
4995   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996   DONE;
4997 }
4998   [(set_attr "type" "lea")
4999    (set_attr "mode" "SI")])
5000
5001 (define_insn_and_split "*lea_general_2_zext"
5002   [(set (match_operand:DI 0 "register_operand" "=r")
5003         (zero_extend:DI
5004           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5005                             (match_operand:SI 2 "const248_operand" "n"))
5006                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5007   "TARGET_64BIT"
5008   "#"
5009   "&& reload_completed"
5010   [(set (match_dup 0)
5011         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5012                                                      (match_dup 2))
5013                                             (match_dup 3)) 0)))]
5014 {
5015   operands[1] = gen_lowpart (Pmode, operands[1]);
5016   operands[3] = gen_lowpart (Pmode, operands[3]);
5017 }
5018   [(set_attr "type" "lea")
5019    (set_attr "mode" "SI")])
5020
5021 (define_insn_and_split "*lea_general_3"
5022   [(set (match_operand 0 "register_operand" "=r")
5023         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5024                           (match_operand 2 "const248_operand" "i"))
5025                     (match_operand 3 "register_operand" "r"))
5026               (match_operand 4 "immediate_operand" "i")))]
5027   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5032   "#"
5033   "&& reload_completed"
5034   [(const_int 0)]
5035 {
5036   rtx pat;
5037   operands[0] = gen_lowpart (SImode, operands[0]);
5038   operands[1] = gen_lowpart (Pmode, operands[1]);
5039   operands[3] = gen_lowpart (Pmode, operands[3]);
5040   operands[4] = gen_lowpart (Pmode, operands[4]);
5041   pat = gen_rtx_PLUS (Pmode,
5042                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5043                                                          operands[2]),
5044                                     operands[3]),
5045                       operands[4]);
5046   if (Pmode != SImode)
5047     pat = gen_rtx_SUBREG (SImode, pat, 0);
5048   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5049   DONE;
5050 }
5051   [(set_attr "type" "lea")
5052    (set_attr "mode" "SI")])
5053
5054 (define_insn_and_split "*lea_general_3_zext"
5055   [(set (match_operand:DI 0 "register_operand" "=r")
5056         (zero_extend:DI
5057           (plus:SI (plus:SI (mult:SI
5058                               (match_operand:SI 1 "index_register_operand" "l")
5059                               (match_operand:SI 2 "const248_operand" "n"))
5060                             (match_operand:SI 3 "register_operand" "r"))
5061                    (match_operand:SI 4 "immediate_operand" "i"))))]
5062   "TARGET_64BIT"
5063   "#"
5064   "&& reload_completed"
5065   [(set (match_dup 0)
5066         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5067                                                               (match_dup 2))
5068                                                      (match_dup 3))
5069                                             (match_dup 4)) 0)))]
5070 {
5071   operands[1] = gen_lowpart (Pmode, operands[1]);
5072   operands[3] = gen_lowpart (Pmode, operands[3]);
5073   operands[4] = gen_lowpart (Pmode, operands[4]);
5074 }
5075   [(set_attr "type" "lea")
5076    (set_attr "mode" "SI")])
5077
5078 (define_insn "*adddi_1_rex64"
5079   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5080         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5081                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5082    (clobber (reg:CC FLAGS_REG))]
5083   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5084 {
5085   switch (get_attr_type (insn))
5086     {
5087     case TYPE_LEA:
5088       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5089       return "lea{q}\t{%a2, %0|%0, %a2}";
5090
5091     case TYPE_INCDEC:
5092       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5093       if (operands[2] == const1_rtx)
5094         return "inc{q}\t%0";
5095       else
5096         {
5097           gcc_assert (operands[2] == constm1_rtx);
5098           return "dec{q}\t%0";
5099         }
5100
5101     default:
5102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5103
5104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5106       if (GET_CODE (operands[2]) == CONST_INT
5107           /* Avoid overflows.  */
5108           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5109           && (INTVAL (operands[2]) == 128
5110               || (INTVAL (operands[2]) < 0
5111                   && INTVAL (operands[2]) != -128)))
5112         {
5113           operands[2] = GEN_INT (-INTVAL (operands[2]));
5114           return "sub{q}\t{%2, %0|%0, %2}";
5115         }
5116       return "add{q}\t{%2, %0|%0, %2}";
5117     }
5118 }
5119   [(set (attr "type")
5120      (cond [(eq_attr "alternative" "2")
5121               (const_string "lea")
5122             ; Current assemblers are broken and do not allow @GOTOFF in
5123             ; ought but a memory context.
5124             (match_operand:DI 2 "pic_symbolic_operand" "")
5125               (const_string "lea")
5126             (match_operand:DI 2 "incdec_operand" "")
5127               (const_string "incdec")
5128            ]
5129            (const_string "alu")))
5130    (set_attr "mode" "DI")])
5131
5132 ;; Convert lea to the lea pattern to avoid flags dependency.
5133 (define_split
5134   [(set (match_operand:DI 0 "register_operand" "")
5135         (plus:DI (match_operand:DI 1 "register_operand" "")
5136                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5137    (clobber (reg:CC FLAGS_REG))]
5138   "TARGET_64BIT && reload_completed
5139    && true_regnum (operands[0]) != true_regnum (operands[1])"
5140   [(set (match_dup 0)
5141         (plus:DI (match_dup 1)
5142                  (match_dup 2)))]
5143   "")
5144
5145 (define_insn "*adddi_2_rex64"
5146   [(set (reg FLAGS_REG)
5147         (compare
5148           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5149                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5150           (const_int 0)))                       
5151    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5152         (plus:DI (match_dup 1) (match_dup 2)))]
5153   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5154    && ix86_binary_operator_ok (PLUS, DImode, operands)
5155    /* Current assemblers are broken and do not allow @GOTOFF in
5156       ought but a memory context.  */
5157    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5158 {
5159   switch (get_attr_type (insn))
5160     {
5161     case TYPE_INCDEC:
5162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5163       if (operands[2] == const1_rtx)
5164         return "inc{q}\t%0";
5165       else
5166         {
5167           gcc_assert (operands[2] == constm1_rtx);
5168           return "dec{q}\t%0";
5169         }
5170
5171     default:
5172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173       /* ???? We ought to handle there the 32bit case too
5174          - do we need new constraint?  */
5175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5177       if (GET_CODE (operands[2]) == CONST_INT
5178           /* Avoid overflows.  */
5179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180           && (INTVAL (operands[2]) == 128
5181               || (INTVAL (operands[2]) < 0
5182                   && INTVAL (operands[2]) != -128)))
5183         {
5184           operands[2] = GEN_INT (-INTVAL (operands[2]));
5185           return "sub{q}\t{%2, %0|%0, %2}";
5186         }
5187       return "add{q}\t{%2, %0|%0, %2}";
5188     }
5189 }
5190   [(set (attr "type")
5191      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192         (const_string "incdec")
5193         (const_string "alu")))
5194    (set_attr "mode" "DI")])
5195
5196 (define_insn "*adddi_3_rex64"
5197   [(set (reg FLAGS_REG)
5198         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5199                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5200    (clobber (match_scratch:DI 0 "=r"))]
5201   "TARGET_64BIT
5202    && ix86_match_ccmode (insn, CCZmode)
5203    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5204    /* Current assemblers are broken and do not allow @GOTOFF in
5205       ought but a memory context.  */
5206    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5207 {
5208   switch (get_attr_type (insn))
5209     {
5210     case TYPE_INCDEC:
5211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5212       if (operands[2] == const1_rtx)
5213         return "inc{q}\t%0";
5214       else
5215         {
5216           gcc_assert (operands[2] == constm1_rtx);
5217           return "dec{q}\t%0";
5218         }
5219
5220     default:
5221       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222       /* ???? We ought to handle there the 32bit case too
5223          - do we need new constraint?  */
5224       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5225          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5226       if (GET_CODE (operands[2]) == CONST_INT
5227           /* Avoid overflows.  */
5228           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5229           && (INTVAL (operands[2]) == 128
5230               || (INTVAL (operands[2]) < 0
5231                   && INTVAL (operands[2]) != -128)))
5232         {
5233           operands[2] = GEN_INT (-INTVAL (operands[2]));
5234           return "sub{q}\t{%2, %0|%0, %2}";
5235         }
5236       return "add{q}\t{%2, %0|%0, %2}";
5237     }
5238 }
5239   [(set (attr "type")
5240      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241         (const_string "incdec")
5242         (const_string "alu")))
5243    (set_attr "mode" "DI")])
5244
5245 ; For comparisons against 1, -1 and 128, we may generate better code
5246 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5247 ; is matched then.  We can't accept general immediate, because for
5248 ; case of overflows,  the result is messed up.
5249 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5250 ; when negated.
5251 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5252 ; only for comparisons not depending on it.
5253 (define_insn "*adddi_4_rex64"
5254   [(set (reg FLAGS_REG)
5255         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5256                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5257    (clobber (match_scratch:DI 0 "=rm"))]
5258   "TARGET_64BIT
5259    &&  ix86_match_ccmode (insn, CCGCmode)"
5260 {
5261   switch (get_attr_type (insn))
5262     {
5263     case TYPE_INCDEC:
5264       if (operands[2] == constm1_rtx)
5265         return "inc{q}\t%0";
5266       else
5267         {
5268           gcc_assert (operands[2] == const1_rtx);
5269           return "dec{q}\t%0";
5270         }
5271
5272     default:
5273       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5274       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5276       if ((INTVAL (operands[2]) == -128
5277            || (INTVAL (operands[2]) > 0
5278                && INTVAL (operands[2]) != 128))
5279           /* Avoid overflows.  */
5280           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5281         return "sub{q}\t{%2, %0|%0, %2}";
5282       operands[2] = GEN_INT (-INTVAL (operands[2]));
5283       return "add{q}\t{%2, %0|%0, %2}";
5284     }
5285 }
5286   [(set (attr "type")
5287      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288         (const_string "incdec")
5289         (const_string "alu")))
5290    (set_attr "mode" "DI")])
5291
5292 (define_insn "*adddi_5_rex64"
5293   [(set (reg FLAGS_REG)
5294         (compare
5295           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5296                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5297           (const_int 0)))                       
5298    (clobber (match_scratch:DI 0 "=r"))]
5299   "TARGET_64BIT
5300    && ix86_match_ccmode (insn, CCGOCmode)
5301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5302    /* Current assemblers are broken and do not allow @GOTOFF in
5303       ought but a memory context.  */
5304    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5305 {
5306   switch (get_attr_type (insn))
5307     {
5308     case TYPE_INCDEC:
5309       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310       if (operands[2] == const1_rtx)
5311         return "inc{q}\t%0";
5312       else
5313         {
5314           gcc_assert (operands[2] == constm1_rtx);
5315           return "dec{q}\t%0";
5316         }
5317
5318     default:
5319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5321          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5322       if (GET_CODE (operands[2]) == CONST_INT
5323           /* Avoid overflows.  */
5324           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5325           && (INTVAL (operands[2]) == 128
5326               || (INTVAL (operands[2]) < 0
5327                   && INTVAL (operands[2]) != -128)))
5328         {
5329           operands[2] = GEN_INT (-INTVAL (operands[2]));
5330           return "sub{q}\t{%2, %0|%0, %2}";
5331         }
5332       return "add{q}\t{%2, %0|%0, %2}";
5333     }
5334 }
5335   [(set (attr "type")
5336      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5337         (const_string "incdec")
5338         (const_string "alu")))
5339    (set_attr "mode" "DI")])
5340
5341
5342 (define_insn "*addsi_1"
5343   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5344         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5345                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5346    (clobber (reg:CC FLAGS_REG))]
5347   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5348 {
5349   switch (get_attr_type (insn))
5350     {
5351     case TYPE_LEA:
5352       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5353       return "lea{l}\t{%a2, %0|%0, %a2}";
5354
5355     case TYPE_INCDEC:
5356       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357       if (operands[2] == const1_rtx)
5358         return "inc{l}\t%0";
5359       else
5360         {
5361           gcc_assert (operands[2] == constm1_rtx);
5362           return "dec{l}\t%0";
5363         }
5364
5365     default:
5366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367
5368       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5369          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5370       if (GET_CODE (operands[2]) == CONST_INT
5371           && (INTVAL (operands[2]) == 128
5372               || (INTVAL (operands[2]) < 0
5373                   && INTVAL (operands[2]) != -128)))
5374         {
5375           operands[2] = GEN_INT (-INTVAL (operands[2]));
5376           return "sub{l}\t{%2, %0|%0, %2}";
5377         }
5378       return "add{l}\t{%2, %0|%0, %2}";
5379     }
5380 }
5381   [(set (attr "type")
5382      (cond [(eq_attr "alternative" "2")
5383               (const_string "lea")
5384             ; Current assemblers are broken and do not allow @GOTOFF in
5385             ; ought but a memory context.
5386             (match_operand:SI 2 "pic_symbolic_operand" "")
5387               (const_string "lea")
5388             (match_operand:SI 2 "incdec_operand" "")
5389               (const_string "incdec")
5390            ]
5391            (const_string "alu")))
5392    (set_attr "mode" "SI")])
5393
5394 ;; Convert lea to the lea pattern to avoid flags dependency.
5395 (define_split
5396   [(set (match_operand 0 "register_operand" "")
5397         (plus (match_operand 1 "register_operand" "")
5398               (match_operand 2 "nonmemory_operand" "")))
5399    (clobber (reg:CC FLAGS_REG))]
5400   "reload_completed
5401    && true_regnum (operands[0]) != true_regnum (operands[1])"
5402   [(const_int 0)]
5403 {
5404   rtx pat;
5405   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5406      may confuse gen_lowpart.  */
5407   if (GET_MODE (operands[0]) != Pmode)
5408     {
5409       operands[1] = gen_lowpart (Pmode, operands[1]);
5410       operands[2] = gen_lowpart (Pmode, operands[2]);
5411     }
5412   operands[0] = gen_lowpart (SImode, operands[0]);
5413   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5414   if (Pmode != SImode)
5415     pat = gen_rtx_SUBREG (SImode, pat, 0);
5416   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5417   DONE;
5418 })
5419
5420 ;; It may seem that nonimmediate operand is proper one for operand 1.
5421 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5422 ;; we take care in ix86_binary_operator_ok to not allow two memory
5423 ;; operands so proper swapping will be done in reload.  This allow
5424 ;; patterns constructed from addsi_1 to match.
5425 (define_insn "addsi_1_zext"
5426   [(set (match_operand:DI 0 "register_operand" "=r,r")
5427         (zero_extend:DI
5428           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5429                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5430    (clobber (reg:CC FLAGS_REG))]
5431   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5432 {
5433   switch (get_attr_type (insn))
5434     {
5435     case TYPE_LEA:
5436       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5438
5439     case TYPE_INCDEC:
5440       if (operands[2] == const1_rtx)
5441         return "inc{l}\t%k0";
5442       else
5443         {
5444           gcc_assert (operands[2] == constm1_rtx);
5445           return "dec{l}\t%k0";
5446         }
5447
5448     default:
5449       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5450          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5451       if (GET_CODE (operands[2]) == CONST_INT
5452           && (INTVAL (operands[2]) == 128
5453               || (INTVAL (operands[2]) < 0
5454                   && INTVAL (operands[2]) != -128)))
5455         {
5456           operands[2] = GEN_INT (-INTVAL (operands[2]));
5457           return "sub{l}\t{%2, %k0|%k0, %2}";
5458         }
5459       return "add{l}\t{%2, %k0|%k0, %2}";
5460     }
5461 }
5462   [(set (attr "type")
5463      (cond [(eq_attr "alternative" "1")
5464               (const_string "lea")
5465             ; Current assemblers are broken and do not allow @GOTOFF in
5466             ; ought but a memory context.
5467             (match_operand:SI 2 "pic_symbolic_operand" "")
5468               (const_string "lea")
5469             (match_operand:SI 2 "incdec_operand" "")
5470               (const_string "incdec")
5471            ]
5472            (const_string "alu")))
5473    (set_attr "mode" "SI")])
5474
5475 ;; Convert lea to the lea pattern to avoid flags dependency.
5476 (define_split
5477   [(set (match_operand:DI 0 "register_operand" "")
5478         (zero_extend:DI
5479           (plus:SI (match_operand:SI 1 "register_operand" "")
5480                    (match_operand:SI 2 "nonmemory_operand" ""))))
5481    (clobber (reg:CC FLAGS_REG))]
5482   "TARGET_64BIT && reload_completed
5483    && true_regnum (operands[0]) != true_regnum (operands[1])"
5484   [(set (match_dup 0)
5485         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5486 {
5487   operands[1] = gen_lowpart (Pmode, operands[1]);
5488   operands[2] = gen_lowpart (Pmode, operands[2]);
5489 })
5490
5491 (define_insn "*addsi_2"
5492   [(set (reg FLAGS_REG)
5493         (compare
5494           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5495                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5496           (const_int 0)))                       
5497    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5498         (plus:SI (match_dup 1) (match_dup 2)))]
5499   "ix86_match_ccmode (insn, CCGOCmode)
5500    && ix86_binary_operator_ok (PLUS, SImode, operands)
5501    /* Current assemblers are broken and do not allow @GOTOFF in
5502       ought but a memory context.  */
5503    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5504 {
5505   switch (get_attr_type (insn))
5506     {
5507     case TYPE_INCDEC:
5508       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5509       if (operands[2] == const1_rtx)
5510         return "inc{l}\t%0";
5511       else
5512         {
5513           gcc_assert (operands[2] == constm1_rtx);
5514           return "dec{l}\t%0";
5515         }
5516
5517     default:
5518       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5520          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5521       if (GET_CODE (operands[2]) == CONST_INT
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{l}\t{%2, %0|%0, %2}";
5528         }
5529       return "add{l}\t{%2, %0|%0, %2}";
5530     }
5531 }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "SI")])
5537
5538 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5539 (define_insn "*addsi_2_zext"
5540   [(set (reg FLAGS_REG)
5541         (compare
5542           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5543                    (match_operand:SI 2 "general_operand" "rmni"))
5544           (const_int 0)))                       
5545    (set (match_operand:DI 0 "register_operand" "=r")
5546         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5547   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5548    && ix86_binary_operator_ok (PLUS, SImode, operands)
5549    /* Current assemblers are broken and do not allow @GOTOFF in
5550       ought but a memory context.  */
5551    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5552 {
5553   switch (get_attr_type (insn))
5554     {
5555     case TYPE_INCDEC:
5556       if (operands[2] == const1_rtx)
5557         return "inc{l}\t%k0";
5558       else
5559         {
5560           gcc_assert (operands[2] == constm1_rtx);
5561           return "dec{l}\t%k0";
5562         }
5563
5564     default:
5565       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5566          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5567       if (GET_CODE (operands[2]) == CONST_INT
5568           && (INTVAL (operands[2]) == 128
5569               || (INTVAL (operands[2]) < 0
5570                   && INTVAL (operands[2]) != -128)))
5571         {
5572           operands[2] = GEN_INT (-INTVAL (operands[2]));
5573           return "sub{l}\t{%2, %k0|%k0, %2}";
5574         }
5575       return "add{l}\t{%2, %k0|%k0, %2}";
5576     }
5577 }
5578   [(set (attr "type")
5579      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5580         (const_string "incdec")
5581         (const_string "alu")))
5582    (set_attr "mode" "SI")])
5583
5584 (define_insn "*addsi_3"
5585   [(set (reg FLAGS_REG)
5586         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5587                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5588    (clobber (match_scratch:SI 0 "=r"))]
5589   "ix86_match_ccmode (insn, CCZmode)
5590    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{l}\t%0";
5605         }
5606
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5611       if (GET_CODE (operands[2]) == CONST_INT
5612           && (INTVAL (operands[2]) == 128
5613               || (INTVAL (operands[2]) < 0
5614                   && INTVAL (operands[2]) != -128)))
5615         {
5616           operands[2] = GEN_INT (-INTVAL (operands[2]));
5617           return "sub{l}\t{%2, %0|%0, %2}";
5618         }
5619       return "add{l}\t{%2, %0|%0, %2}";
5620     }
5621 }
5622   [(set (attr "type")
5623      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624         (const_string "incdec")
5625         (const_string "alu")))
5626    (set_attr "mode" "SI")])
5627
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_3_zext"
5630   [(set (reg FLAGS_REG)
5631         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5632                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5633    (set (match_operand:DI 0 "register_operand" "=r")
5634         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5635   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5636    && ix86_binary_operator_ok (PLUS, SImode, operands)
5637    /* Current assemblers are broken and do not allow @GOTOFF in
5638       ought but a memory context.  */
5639    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5640 {
5641   switch (get_attr_type (insn))
5642     {
5643     case TYPE_INCDEC:
5644       if (operands[2] == const1_rtx)
5645         return "inc{l}\t%k0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{l}\t%k0";
5650         }
5651
5652     default:
5653       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5655       if (GET_CODE (operands[2]) == CONST_INT
5656           && (INTVAL (operands[2]) == 128
5657               || (INTVAL (operands[2]) < 0
5658                   && INTVAL (operands[2]) != -128)))
5659         {
5660           operands[2] = GEN_INT (-INTVAL (operands[2]));
5661           return "sub{l}\t{%2, %k0|%k0, %2}";
5662         }
5663       return "add{l}\t{%2, %k0|%k0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5668         (const_string "incdec")
5669         (const_string "alu")))
5670    (set_attr "mode" "SI")])
5671
5672 ; For comparisons against 1, -1 and 128, we may generate better code
5673 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5674 ; is matched then.  We can't accept general immediate, because for
5675 ; case of overflows,  the result is messed up.
5676 ; This pattern also don't hold of 0x80000000, since the value overflows
5677 ; when negated.
5678 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5679 ; only for comparisons not depending on it.
5680 (define_insn "*addsi_4"
5681   [(set (reg FLAGS_REG)
5682         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5683                  (match_operand:SI 2 "const_int_operand" "n")))
5684    (clobber (match_scratch:SI 0 "=rm"))]
5685   "ix86_match_ccmode (insn, CCGCmode)
5686    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5687 {
5688   switch (get_attr_type (insn))
5689     {
5690     case TYPE_INCDEC:
5691       if (operands[2] == constm1_rtx)
5692         return "inc{l}\t%0";
5693       else
5694         {
5695           gcc_assert (operands[2] == const1_rtx);
5696           return "dec{l}\t%0";
5697         }
5698
5699     default:
5700       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5703       if ((INTVAL (operands[2]) == -128
5704            || (INTVAL (operands[2]) > 0
5705                && INTVAL (operands[2]) != 128)))
5706         return "sub{l}\t{%2, %0|%0, %2}";
5707       operands[2] = GEN_INT (-INTVAL (operands[2]));
5708       return "add{l}\t{%2, %0|%0, %2}";
5709     }
5710 }
5711   [(set (attr "type")
5712      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713         (const_string "incdec")
5714         (const_string "alu")))
5715    (set_attr "mode" "SI")])
5716
5717 (define_insn "*addsi_5"
5718   [(set (reg FLAGS_REG)
5719         (compare
5720           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5721                    (match_operand:SI 2 "general_operand" "rmni"))
5722           (const_int 0)))                       
5723    (clobber (match_scratch:SI 0 "=r"))]
5724   "ix86_match_ccmode (insn, CCGOCmode)
5725    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5726    /* Current assemblers are broken and do not allow @GOTOFF in
5727       ought but a memory context.  */
5728    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5729 {
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_INCDEC:
5733       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%0";
5736       else
5737         {
5738           gcc_assert (operands[2] == constm1_rtx);
5739           return "dec{l}\t%0";
5740         }
5741
5742     default:
5743       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5746       if (GET_CODE (operands[2]) == CONST_INT
5747           && (INTVAL (operands[2]) == 128
5748               || (INTVAL (operands[2]) < 0
5749                   && INTVAL (operands[2]) != -128)))
5750         {
5751           operands[2] = GEN_INT (-INTVAL (operands[2]));
5752           return "sub{l}\t{%2, %0|%0, %2}";
5753         }
5754       return "add{l}\t{%2, %0|%0, %2}";
5755     }
5756 }
5757   [(set (attr "type")
5758      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5759         (const_string "incdec")
5760         (const_string "alu")))
5761    (set_attr "mode" "SI")])
5762
5763 (define_expand "addhi3"
5764   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5765                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5766                             (match_operand:HI 2 "general_operand" "")))
5767               (clobber (reg:CC FLAGS_REG))])]
5768   "TARGET_HIMODE_MATH"
5769   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5770
5771 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5772 ;; type optimizations enabled by define-splits.  This is not important
5773 ;; for PII, and in fact harmful because of partial register stalls.
5774
5775 (define_insn "*addhi_1_lea"
5776   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5777         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5778                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5779    (clobber (reg:CC FLAGS_REG))]
5780   "!TARGET_PARTIAL_REG_STALL
5781    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 {
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_LEA:
5786       return "#";
5787     case TYPE_INCDEC:
5788       if (operands[2] == const1_rtx)
5789         return "inc{w}\t%0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{w}\t%0";
5794         }
5795
5796     default:
5797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5799       if (GET_CODE (operands[2]) == CONST_INT
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{w}\t{%2, %0|%0, %2}";
5806         }
5807       return "add{w}\t{%2, %0|%0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (if_then_else (eq_attr "alternative" "2")
5812         (const_string "lea")
5813         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5814            (const_string "incdec")
5815            (const_string "alu"))))
5816    (set_attr "mode" "HI,HI,SI")])
5817
5818 (define_insn "*addhi_1"
5819   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5820         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5821                  (match_operand:HI 2 "general_operand" "ri,rm")))
5822    (clobber (reg:CC FLAGS_REG))]
5823   "TARGET_PARTIAL_REG_STALL
5824    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5825 {
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       if (operands[2] == const1_rtx)
5830         return "inc{w}\t%0";
5831       else
5832         {
5833           gcc_assert (operands[2] == constm1_rtx);
5834           return "dec{w}\t%0";
5835         }
5836
5837     default:
5838       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5840       if (GET_CODE (operands[2]) == CONST_INT
5841           && (INTVAL (operands[2]) == 128
5842               || (INTVAL (operands[2]) < 0
5843                   && INTVAL (operands[2]) != -128)))
5844         {
5845           operands[2] = GEN_INT (-INTVAL (operands[2]));
5846           return "sub{w}\t{%2, %0|%0, %2}";
5847         }
5848       return "add{w}\t{%2, %0|%0, %2}";
5849     }
5850 }
5851   [(set (attr "type")
5852      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5853         (const_string "incdec")
5854         (const_string "alu")))
5855    (set_attr "mode" "HI")])
5856
5857 (define_insn "*addhi_2"
5858   [(set (reg FLAGS_REG)
5859         (compare
5860           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5861                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5862           (const_int 0)))                       
5863    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5864         (plus:HI (match_dup 1) (match_dup 2)))]
5865   "ix86_match_ccmode (insn, CCGOCmode)
5866    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5867 {
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{w}\t%0";
5873       else
5874         {
5875           gcc_assert (operands[2] == constm1_rtx);
5876           return "dec{w}\t%0";
5877         }
5878
5879     default:
5880       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5882       if (GET_CODE (operands[2]) == CONST_INT
5883           && (INTVAL (operands[2]) == 128
5884               || (INTVAL (operands[2]) < 0
5885                   && INTVAL (operands[2]) != -128)))
5886         {
5887           operands[2] = GEN_INT (-INTVAL (operands[2]));
5888           return "sub{w}\t{%2, %0|%0, %2}";
5889         }
5890       return "add{w}\t{%2, %0|%0, %2}";
5891     }
5892 }
5893   [(set (attr "type")
5894      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5895         (const_string "incdec")
5896         (const_string "alu")))
5897    (set_attr "mode" "HI")])
5898
5899 (define_insn "*addhi_3"
5900   [(set (reg FLAGS_REG)
5901         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5902                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5903    (clobber (match_scratch:HI 0 "=r"))]
5904   "ix86_match_ccmode (insn, CCZmode)
5905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5906 {
5907   switch (get_attr_type (insn))
5908     {
5909     case TYPE_INCDEC:
5910       if (operands[2] == const1_rtx)
5911         return "inc{w}\t%0";
5912       else
5913         {
5914           gcc_assert (operands[2] == constm1_rtx);
5915           return "dec{w}\t%0";
5916         }
5917
5918     default:
5919       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5920          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5921       if (GET_CODE (operands[2]) == CONST_INT
5922           && (INTVAL (operands[2]) == 128
5923               || (INTVAL (operands[2]) < 0
5924                   && INTVAL (operands[2]) != -128)))
5925         {
5926           operands[2] = GEN_INT (-INTVAL (operands[2]));
5927           return "sub{w}\t{%2, %0|%0, %2}";
5928         }
5929       return "add{w}\t{%2, %0|%0, %2}";
5930     }
5931 }
5932   [(set (attr "type")
5933      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5934         (const_string "incdec")
5935         (const_string "alu")))
5936    (set_attr "mode" "HI")])
5937
5938 ; See comments above addsi_4 for details.
5939 (define_insn "*addhi_4"
5940   [(set (reg FLAGS_REG)
5941         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5942                  (match_operand:HI 2 "const_int_operand" "n")))
5943    (clobber (match_scratch:HI 0 "=rm"))]
5944   "ix86_match_ccmode (insn, CCGCmode)
5945    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5946 {
5947   switch (get_attr_type (insn))
5948     {
5949     case TYPE_INCDEC:
5950       if (operands[2] == constm1_rtx)
5951         return "inc{w}\t%0";
5952       else
5953         {
5954           gcc_assert (operands[2] == const1_rtx);
5955           return "dec{w}\t%0";
5956         }
5957
5958     default:
5959       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962       if ((INTVAL (operands[2]) == -128
5963            || (INTVAL (operands[2]) > 0
5964                && INTVAL (operands[2]) != 128)))
5965         return "sub{w}\t{%2, %0|%0, %2}";
5966       operands[2] = GEN_INT (-INTVAL (operands[2]));
5967       return "add{w}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972         (const_string "incdec")
5973         (const_string "alu")))
5974    (set_attr "mode" "SI")])
5975
5976
5977 (define_insn "*addhi_5"
5978   [(set (reg FLAGS_REG)
5979         (compare
5980           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5981                    (match_operand:HI 2 "general_operand" "rmni"))
5982           (const_int 0)))                       
5983    (clobber (match_scratch:HI 0 "=r"))]
5984   "ix86_match_ccmode (insn, CCGOCmode)
5985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5986 {
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_INCDEC:
5990       if (operands[2] == const1_rtx)
5991         return "inc{w}\t%0";
5992       else
5993         {
5994           gcc_assert (operands[2] == constm1_rtx);
5995           return "dec{w}\t%0";
5996         }
5997
5998     default:
5999       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6000          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6001       if (GET_CODE (operands[2]) == CONST_INT
6002           && (INTVAL (operands[2]) == 128
6003               || (INTVAL (operands[2]) < 0
6004                   && INTVAL (operands[2]) != -128)))
6005         {
6006           operands[2] = GEN_INT (-INTVAL (operands[2]));
6007           return "sub{w}\t{%2, %0|%0, %2}";
6008         }
6009       return "add{w}\t{%2, %0|%0, %2}";
6010     }
6011 }
6012   [(set (attr "type")
6013      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6014         (const_string "incdec")
6015         (const_string "alu")))
6016    (set_attr "mode" "HI")])
6017
6018 (define_expand "addqi3"
6019   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6020                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6021                             (match_operand:QI 2 "general_operand" "")))
6022               (clobber (reg:CC FLAGS_REG))])]
6023   "TARGET_QIMODE_MATH"
6024   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6025
6026 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6027 (define_insn "*addqi_1_lea"
6028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6029         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6030                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "!TARGET_PARTIAL_REG_STALL
6033    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6034 {
6035   int widen = (which_alternative == 2);
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_LEA:
6039       return "#";
6040     case TYPE_INCDEC:
6041       if (operands[2] == const1_rtx)
6042         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6043       else
6044         {
6045           gcc_assert (operands[2] == constm1_rtx);
6046           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6047         }
6048
6049     default:
6050       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052       if (GET_CODE (operands[2]) == CONST_INT
6053           && (INTVAL (operands[2]) == 128
6054               || (INTVAL (operands[2]) < 0
6055                   && INTVAL (operands[2]) != -128)))
6056         {
6057           operands[2] = GEN_INT (-INTVAL (operands[2]));
6058           if (widen)
6059             return "sub{l}\t{%2, %k0|%k0, %2}";
6060           else
6061             return "sub{b}\t{%2, %0|%0, %2}";
6062         }
6063       if (widen)
6064         return "add{l}\t{%k2, %k0|%k0, %k2}";
6065       else
6066         return "add{b}\t{%2, %0|%0, %2}";
6067     }
6068 }
6069   [(set (attr "type")
6070      (if_then_else (eq_attr "alternative" "3")
6071         (const_string "lea")
6072         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6073            (const_string "incdec")
6074            (const_string "alu"))))
6075    (set_attr "mode" "QI,QI,SI,SI")])
6076
6077 (define_insn "*addqi_1"
6078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6079         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6080                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "TARGET_PARTIAL_REG_STALL
6083    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084 {
6085   int widen = (which_alternative == 2);
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_INCDEC:
6089       if (operands[2] == const1_rtx)
6090         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6091       else
6092         {
6093           gcc_assert (operands[2] == constm1_rtx);
6094           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6095         }
6096
6097     default:
6098       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6099          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6100       if (GET_CODE (operands[2]) == CONST_INT
6101           && (INTVAL (operands[2]) == 128
6102               || (INTVAL (operands[2]) < 0
6103                   && INTVAL (operands[2]) != -128)))
6104         {
6105           operands[2] = GEN_INT (-INTVAL (operands[2]));
6106           if (widen)
6107             return "sub{l}\t{%2, %k0|%k0, %2}";
6108           else
6109             return "sub{b}\t{%2, %0|%0, %2}";
6110         }
6111       if (widen)
6112         return "add{l}\t{%k2, %k0|%k0, %k2}";
6113       else
6114         return "add{b}\t{%2, %0|%0, %2}";
6115     }
6116 }
6117   [(set (attr "type")
6118      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6119         (const_string "incdec")
6120         (const_string "alu")))
6121    (set_attr "mode" "QI,QI,SI")])
6122
6123 (define_insn "*addqi_1_slp"
6124   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6125         (plus:QI (match_dup 0)
6126                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[1] == const1_rtx)
6135         return "inc{b}\t%0";
6136       else
6137         {
6138           gcc_assert (operands[1] == constm1_rtx);
6139           return "dec{b}\t%0";
6140         }
6141
6142     default:
6143       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6144       if (GET_CODE (operands[1]) == CONST_INT
6145           && INTVAL (operands[1]) < 0)
6146         {
6147           operands[1] = GEN_INT (-INTVAL (operands[1]));
6148           return "sub{b}\t{%1, %0|%0, %1}";
6149         }
6150       return "add{b}\t{%1, %0|%0, %1}";
6151     }
6152 }
6153   [(set (attr "type")
6154      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6155         (const_string "incdec")
6156         (const_string "alu1")))
6157    (set (attr "memory")
6158      (if_then_else (match_operand 1 "memory_operand" "")
6159         (const_string "load")
6160         (const_string "none")))
6161    (set_attr "mode" "QI")])
6162
6163 (define_insn "*addqi_2"
6164   [(set (reg FLAGS_REG)
6165         (compare
6166           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6167                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6168           (const_int 0)))
6169    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6170         (plus:QI (match_dup 1) (match_dup 2)))]
6171   "ix86_match_ccmode (insn, CCGOCmode)
6172    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{b}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx
6182                       || (GET_CODE (operands[2]) == CONST_INT
6183                           && INTVAL (operands[2]) == 255));
6184           return "dec{b}\t%0";
6185         }
6186
6187     default:
6188       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && INTVAL (operands[2]) < 0)
6191         {
6192           operands[2] = GEN_INT (-INTVAL (operands[2]));
6193           return "sub{b}\t{%2, %0|%0, %2}";
6194         }
6195       return "add{b}\t{%2, %0|%0, %2}";
6196     }
6197 }
6198   [(set (attr "type")
6199      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6200         (const_string "incdec")
6201         (const_string "alu")))
6202    (set_attr "mode" "QI")])
6203
6204 (define_insn "*addqi_3"
6205   [(set (reg FLAGS_REG)
6206         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6207                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6208    (clobber (match_scratch:QI 0 "=q"))]
6209   "ix86_match_ccmode (insn, CCZmode)
6210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6211 {
6212   switch (get_attr_type (insn))
6213     {
6214     case TYPE_INCDEC:
6215       if (operands[2] == const1_rtx)
6216         return "inc{b}\t%0";
6217       else
6218         {
6219           gcc_assert (operands[2] == constm1_rtx
6220                       || (GET_CODE (operands[2]) == CONST_INT
6221                           && INTVAL (operands[2]) == 255));
6222           return "dec{b}\t%0";
6223         }
6224
6225     default:
6226       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6227       if (GET_CODE (operands[2]) == CONST_INT
6228           && INTVAL (operands[2]) < 0)
6229         {
6230           operands[2] = GEN_INT (-INTVAL (operands[2]));
6231           return "sub{b}\t{%2, %0|%0, %2}";
6232         }
6233       return "add{b}\t{%2, %0|%0, %2}";
6234     }
6235 }
6236   [(set (attr "type")
6237      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6238         (const_string "incdec")
6239         (const_string "alu")))
6240    (set_attr "mode" "QI")])
6241
6242 ; See comments above addsi_4 for details.
6243 (define_insn "*addqi_4"
6244   [(set (reg FLAGS_REG)
6245         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6246                  (match_operand:QI 2 "const_int_operand" "n")))
6247    (clobber (match_scratch:QI 0 "=qm"))]
6248   "ix86_match_ccmode (insn, CCGCmode)
6249    && (INTVAL (operands[2]) & 0xff) != 0x80"
6250 {
6251   switch (get_attr_type (insn))
6252     {
6253     case TYPE_INCDEC:
6254       if (operands[2] == constm1_rtx
6255           || (GET_CODE (operands[2]) == CONST_INT
6256               && INTVAL (operands[2]) == 255))
6257         return "inc{b}\t%0";
6258       else
6259         {
6260           gcc_assert (operands[2] == const1_rtx);
6261           return "dec{b}\t%0";
6262         }
6263
6264     default:
6265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266       if (INTVAL (operands[2]) < 0)
6267         {
6268           operands[2] = GEN_INT (-INTVAL (operands[2]));
6269           return "add{b}\t{%2, %0|%0, %2}";
6270         }
6271       return "sub{b}\t{%2, %0|%0, %2}";
6272     }
6273 }
6274   [(set (attr "type")
6275      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6276         (const_string "incdec")
6277         (const_string "alu")))
6278    (set_attr "mode" "QI")])
6279
6280
6281 (define_insn "*addqi_5"
6282   [(set (reg FLAGS_REG)
6283         (compare
6284           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6285                    (match_operand:QI 2 "general_operand" "qmni"))
6286           (const_int 0)))
6287    (clobber (match_scratch:QI 0 "=q"))]
6288   "ix86_match_ccmode (insn, CCGOCmode)
6289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6290 {
6291   switch (get_attr_type (insn))
6292     {
6293     case TYPE_INCDEC:
6294       if (operands[2] == const1_rtx)
6295         return "inc{b}\t%0";
6296       else
6297         {
6298           gcc_assert (operands[2] == constm1_rtx
6299                       || (GET_CODE (operands[2]) == CONST_INT
6300                           && INTVAL (operands[2]) == 255));
6301           return "dec{b}\t%0";
6302         }
6303
6304     default:
6305       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6306       if (GET_CODE (operands[2]) == CONST_INT
6307           && INTVAL (operands[2]) < 0)
6308         {
6309           operands[2] = GEN_INT (-INTVAL (operands[2]));
6310           return "sub{b}\t{%2, %0|%0, %2}";
6311         }
6312       return "add{b}\t{%2, %0|%0, %2}";
6313     }
6314 }
6315   [(set (attr "type")
6316      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6317         (const_string "incdec")
6318         (const_string "alu")))
6319    (set_attr "mode" "QI")])
6320
6321
6322 (define_insn "addqi_ext_1"
6323   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6324                          (const_int 8)
6325                          (const_int 8))
6326         (plus:SI
6327           (zero_extract:SI
6328             (match_operand 1 "ext_register_operand" "0")
6329             (const_int 8)
6330             (const_int 8))
6331           (match_operand:QI 2 "general_operand" "Qmn")))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "!TARGET_64BIT"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{b}\t%h0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx
6343                       || (GET_CODE (operands[2]) == CONST_INT
6344                           && INTVAL (operands[2]) == 255));
6345           return "dec{b}\t%h0";
6346         }
6347
6348     default:
6349       return "add{b}\t{%2, %h0|%h0, %2}";
6350     }
6351 }
6352   [(set (attr "type")
6353      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6354         (const_string "incdec")
6355         (const_string "alu")))
6356    (set_attr "mode" "QI")])
6357
6358 (define_insn "*addqi_ext_1_rex64"
6359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6360                          (const_int 8)
6361                          (const_int 8))
6362         (plus:SI
6363           (zero_extract:SI
6364             (match_operand 1 "ext_register_operand" "0")
6365             (const_int 8)
6366             (const_int 8))
6367           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6368    (clobber (reg:CC FLAGS_REG))]
6369   "TARGET_64BIT"
6370 {
6371   switch (get_attr_type (insn))
6372     {
6373     case TYPE_INCDEC:
6374       if (operands[2] == const1_rtx)
6375         return "inc{b}\t%h0";
6376       else
6377         {
6378           gcc_assert (operands[2] == constm1_rtx
6379                       || (GET_CODE (operands[2]) == CONST_INT
6380                           && INTVAL (operands[2]) == 255));
6381           return "dec{b}\t%h0";
6382         }
6383
6384     default:
6385       return "add{b}\t{%2, %h0|%h0, %2}";
6386     }
6387 }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu")))
6392    (set_attr "mode" "QI")])
6393
6394 (define_insn "*addqi_ext_2"
6395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6396                          (const_int 8)
6397                          (const_int 8))
6398         (plus:SI
6399           (zero_extract:SI
6400             (match_operand 1 "ext_register_operand" "%0")
6401             (const_int 8)
6402             (const_int 8))
6403           (zero_extract:SI
6404             (match_operand 2 "ext_register_operand" "Q")
6405             (const_int 8)
6406             (const_int 8))))
6407    (clobber (reg:CC FLAGS_REG))]
6408   ""
6409   "add{b}\t{%h2, %h0|%h0, %h2}"
6410   [(set_attr "type" "alu")
6411    (set_attr "mode" "QI")])
6412
6413 ;; The patterns that match these are at the end of this file.
6414
6415 (define_expand "addxf3"
6416   [(set (match_operand:XF 0 "register_operand" "")
6417         (plus:XF (match_operand:XF 1 "register_operand" "")
6418                  (match_operand:XF 2 "register_operand" "")))]
6419   "TARGET_80387"
6420   "")
6421
6422 (define_expand "adddf3"
6423   [(set (match_operand:DF 0 "register_operand" "")
6424         (plus:DF (match_operand:DF 1 "register_operand" "")
6425                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6426   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6427   "")
6428
6429 (define_expand "addsf3"
6430   [(set (match_operand:SF 0 "register_operand" "")
6431         (plus:SF (match_operand:SF 1 "register_operand" "")
6432                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6433   "TARGET_80387 || TARGET_SSE_MATH"
6434   "")
6435 \f
6436 ;; Subtract instructions
6437
6438 ;; %%% splits for subditi3
6439
6440 (define_expand "subti3"
6441   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6442                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6443                              (match_operand:TI 2 "x86_64_general_operand" "")))
6444               (clobber (reg:CC FLAGS_REG))])]
6445   "TARGET_64BIT"
6446   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6447
6448 (define_insn "*subti3_1"
6449   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6450         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6451                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6452    (clobber (reg:CC FLAGS_REG))]
6453   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6454   "#")
6455
6456 (define_split
6457   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6458         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6459                   (match_operand:TI 2 "general_operand" "")))
6460    (clobber (reg:CC FLAGS_REG))]
6461   "TARGET_64BIT && reload_completed"
6462   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6463               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6464    (parallel [(set (match_dup 3)
6465                    (minus:DI (match_dup 4)
6466                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6467                                       (match_dup 5))))
6468               (clobber (reg:CC FLAGS_REG))])]
6469   "split_ti (operands+0, 1, operands+0, operands+3);
6470    split_ti (operands+1, 1, operands+1, operands+4);
6471    split_ti (operands+2, 1, operands+2, operands+5);")
6472
6473 ;; %%% splits for subsidi3
6474
6475 (define_expand "subdi3"
6476   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6477                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6478                              (match_operand:DI 2 "x86_64_general_operand" "")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   ""
6481   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6482
6483 (define_insn "*subdi3_1"
6484   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6485         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6486                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6489   "#")
6490
6491 (define_split
6492   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6493         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6494                   (match_operand:DI 2 "general_operand" "")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "!TARGET_64BIT && reload_completed"
6497   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6499    (parallel [(set (match_dup 3)
6500                    (minus:SI (match_dup 4)
6501                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6502                                       (match_dup 5))))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   "split_di (operands+0, 1, operands+0, operands+3);
6505    split_di (operands+1, 1, operands+1, operands+4);
6506    split_di (operands+2, 1, operands+2, operands+5);")
6507
6508 (define_insn "subdi3_carry_rex64"
6509   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6510           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6511             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6512                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6513    (clobber (reg:CC FLAGS_REG))]
6514   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6515   "sbb{q}\t{%2, %0|%0, %2}"
6516   [(set_attr "type" "alu")
6517    (set_attr "pent_pair" "pu")
6518    (set_attr "mode" "DI")])
6519
6520 (define_insn "*subdi_1_rex64"
6521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6522         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6523                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6524    (clobber (reg:CC FLAGS_REG))]
6525   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6526   "sub{q}\t{%2, %0|%0, %2}"
6527   [(set_attr "type" "alu")
6528    (set_attr "mode" "DI")])
6529
6530 (define_insn "*subdi_2_rex64"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6534                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6535           (const_int 0)))
6536    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6537         (minus:DI (match_dup 1) (match_dup 2)))]
6538   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6539    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6540   "sub{q}\t{%2, %0|%0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "DI")])
6543
6544 (define_insn "*subdi_3_rex63"
6545   [(set (reg FLAGS_REG)
6546         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6547                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6548    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6549         (minus:DI (match_dup 1) (match_dup 2)))]
6550   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6551    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552   "sub{q}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "DI")])
6555
6556 (define_insn "subqi3_carry"
6557   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6558           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6559             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6560                (match_operand:QI 2 "general_operand" "qi,qm"))))
6561    (clobber (reg:CC FLAGS_REG))]
6562   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6563   "sbb{b}\t{%2, %0|%0, %2}"
6564   [(set_attr "type" "alu")
6565    (set_attr "pent_pair" "pu")
6566    (set_attr "mode" "QI")])
6567
6568 (define_insn "subhi3_carry"
6569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6570           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6571             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6572                (match_operand:HI 2 "general_operand" "ri,rm"))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6575   "sbb{w}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "pent_pair" "pu")
6578    (set_attr "mode" "HI")])
6579
6580 (define_insn "subsi3_carry"
6581   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6582           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6583             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6584                (match_operand:SI 2 "general_operand" "ri,rm"))))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sbb{l}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "pent_pair" "pu")
6590    (set_attr "mode" "SI")])
6591
6592 (define_insn "subsi3_carry_zext"
6593   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6594           (zero_extend:DI
6595             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6596               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6597                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6598    (clobber (reg:CC FLAGS_REG))]
6599   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6600   "sbb{l}\t{%2, %k0|%k0, %2}"
6601   [(set_attr "type" "alu")
6602    (set_attr "pent_pair" "pu")
6603    (set_attr "mode" "SI")])
6604
6605 (define_expand "subsi3"
6606   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6607                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6608                              (match_operand:SI 2 "general_operand" "")))
6609               (clobber (reg:CC FLAGS_REG))])]
6610   ""
6611   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6612
6613 (define_insn "*subsi_1"
6614   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6616                   (match_operand:SI 2 "general_operand" "ri,rm")))
6617    (clobber (reg:CC FLAGS_REG))]
6618   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6619   "sub{l}\t{%2, %0|%0, %2}"
6620   [(set_attr "type" "alu")
6621    (set_attr "mode" "SI")])
6622
6623 (define_insn "*subsi_1_zext"
6624   [(set (match_operand:DI 0 "register_operand" "=r")
6625         (zero_extend:DI
6626           (minus:SI (match_operand:SI 1 "register_operand" "0")
6627                     (match_operand:SI 2 "general_operand" "rim"))))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6630   "sub{l}\t{%2, %k0|%k0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "SI")])
6633
6634 (define_insn "*subsi_2"
6635   [(set (reg FLAGS_REG)
6636         (compare
6637           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6638                     (match_operand:SI 2 "general_operand" "ri,rm"))
6639           (const_int 0)))
6640    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6641         (minus:SI (match_dup 1) (match_dup 2)))]
6642   "ix86_match_ccmode (insn, CCGOCmode)
6643    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6644   "sub{l}\t{%2, %0|%0, %2}"
6645   [(set_attr "type" "alu")
6646    (set_attr "mode" "SI")])
6647
6648 (define_insn "*subsi_2_zext"
6649   [(set (reg FLAGS_REG)
6650         (compare
6651           (minus:SI (match_operand:SI 1 "register_operand" "0")
6652                     (match_operand:SI 2 "general_operand" "rim"))
6653           (const_int 0)))
6654    (set (match_operand:DI 0 "register_operand" "=r")
6655         (zero_extend:DI
6656           (minus:SI (match_dup 1)
6657                     (match_dup 2))))]
6658   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6659    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6660   "sub{l}\t{%2, %k0|%k0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "mode" "SI")])
6663
6664 (define_insn "*subsi_3"
6665   [(set (reg FLAGS_REG)
6666         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6667                  (match_operand:SI 2 "general_operand" "ri,rm")))
6668    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669         (minus:SI (match_dup 1) (match_dup 2)))]
6670   "ix86_match_ccmode (insn, CCmode)
6671    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672   "sub{l}\t{%2, %0|%0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "mode" "SI")])
6675
6676 (define_insn "*subsi_3_zext"
6677   [(set (reg FLAGS_REG)
6678         (compare (match_operand:SI 1 "register_operand" "0")
6679                  (match_operand:SI 2 "general_operand" "rim")))
6680    (set (match_operand:DI 0 "register_operand" "=r")
6681         (zero_extend:DI
6682           (minus:SI (match_dup 1)
6683                     (match_dup 2))))]
6684   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686   "sub{q}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "DI")])
6689
6690 (define_expand "subhi3"
6691   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6692                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6693                              (match_operand:HI 2 "general_operand" "")))
6694               (clobber (reg:CC FLAGS_REG))])]
6695   "TARGET_HIMODE_MATH"
6696   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6697
6698 (define_insn "*subhi_1"
6699   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701                   (match_operand:HI 2 "general_operand" "ri,rm")))
6702    (clobber (reg:CC FLAGS_REG))]
6703   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6704   "sub{w}\t{%2, %0|%0, %2}"
6705   [(set_attr "type" "alu")
6706    (set_attr "mode" "HI")])
6707
6708 (define_insn "*subhi_2"
6709   [(set (reg FLAGS_REG)
6710         (compare
6711           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6712                     (match_operand:HI 2 "general_operand" "ri,rm"))
6713           (const_int 0)))
6714    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6715         (minus:HI (match_dup 1) (match_dup 2)))]
6716   "ix86_match_ccmode (insn, CCGOCmode)
6717    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6718   "sub{w}\t{%2, %0|%0, %2}"
6719   [(set_attr "type" "alu")
6720    (set_attr "mode" "HI")])
6721
6722 (define_insn "*subhi_3"
6723   [(set (reg FLAGS_REG)
6724         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6725                  (match_operand:HI 2 "general_operand" "ri,rm")))
6726    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6727         (minus:HI (match_dup 1) (match_dup 2)))]
6728   "ix86_match_ccmode (insn, CCmode)
6729    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6730   "sub{w}\t{%2, %0|%0, %2}"
6731   [(set_attr "type" "alu")
6732    (set_attr "mode" "HI")])
6733
6734 (define_expand "subqi3"
6735   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6736                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6737                              (match_operand:QI 2 "general_operand" "")))
6738               (clobber (reg:CC FLAGS_REG))])]
6739   "TARGET_QIMODE_MATH"
6740   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6741
6742 (define_insn "*subqi_1"
6743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6746    (clobber (reg:CC FLAGS_REG))]
6747   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6748   "sub{b}\t{%2, %0|%0, %2}"
6749   [(set_attr "type" "alu")
6750    (set_attr "mode" "QI")])
6751
6752 (define_insn "*subqi_1_slp"
6753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6754         (minus:QI (match_dup 0)
6755                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6759   "sub{b}\t{%1, %0|%0, %1}"
6760   [(set_attr "type" "alu1")
6761    (set_attr "mode" "QI")])
6762
6763 (define_insn "*subqi_2"
6764   [(set (reg FLAGS_REG)
6765         (compare
6766           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6767                     (match_operand:QI 2 "general_operand" "qi,qm"))
6768           (const_int 0)))
6769    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6770         (minus:HI (match_dup 1) (match_dup 2)))]
6771   "ix86_match_ccmode (insn, CCGOCmode)
6772    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6773   "sub{b}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "mode" "QI")])
6776
6777 (define_insn "*subqi_3"
6778   [(set (reg FLAGS_REG)
6779         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780                  (match_operand:QI 2 "general_operand" "qi,qm")))
6781    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6782         (minus:HI (match_dup 1) (match_dup 2)))]
6783   "ix86_match_ccmode (insn, CCmode)
6784    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6785   "sub{b}\t{%2, %0|%0, %2}"
6786   [(set_attr "type" "alu")
6787    (set_attr "mode" "QI")])
6788
6789 ;; The patterns that match these are at the end of this file.
6790
6791 (define_expand "subxf3"
6792   [(set (match_operand:XF 0 "register_operand" "")
6793         (minus:XF (match_operand:XF 1 "register_operand" "")
6794                   (match_operand:XF 2 "register_operand" "")))]
6795   "TARGET_80387"
6796   "")
6797
6798 (define_expand "subdf3"
6799   [(set (match_operand:DF 0 "register_operand" "")
6800         (minus:DF (match_operand:DF 1 "register_operand" "")
6801                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6802   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6803   "")
6804
6805 (define_expand "subsf3"
6806   [(set (match_operand:SF 0 "register_operand" "")
6807         (minus:SF (match_operand:SF 1 "register_operand" "")
6808                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6809   "TARGET_80387 || TARGET_SSE_MATH"
6810   "")
6811 \f
6812 ;; Multiply instructions
6813
6814 (define_expand "muldi3"
6815   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6816                    (mult:DI (match_operand:DI 1 "register_operand" "")
6817                             (match_operand:DI 2 "x86_64_general_operand" "")))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   "TARGET_64BIT"
6820   "")
6821
6822 (define_insn "*muldi3_1_rex64"
6823   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6824         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6825                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "TARGET_64BIT
6828    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6829   "@
6830    imul{q}\t{%2, %1, %0|%0, %1, %2}
6831    imul{q}\t{%2, %1, %0|%0, %1, %2}
6832    imul{q}\t{%2, %0|%0, %2}"
6833   [(set_attr "type" "imul")
6834    (set_attr "prefix_0f" "0,0,1")
6835    (set (attr "athlon_decode")
6836         (cond [(eq_attr "cpu" "athlon")
6837                   (const_string "vector")
6838                (eq_attr "alternative" "1")
6839                   (const_string "vector")
6840                (and (eq_attr "alternative" "2")
6841                     (match_operand 1 "memory_operand" ""))
6842                   (const_string "vector")]
6843               (const_string "direct")))
6844    (set_attr "mode" "DI")])
6845
6846 (define_expand "mulsi3"
6847   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6848                    (mult:SI (match_operand:SI 1 "register_operand" "")
6849                             (match_operand:SI 2 "general_operand" "")))
6850               (clobber (reg:CC FLAGS_REG))])]
6851   ""
6852   "")
6853
6854 (define_insn "*mulsi3_1"
6855   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6856         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6857                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6860   "@
6861    imul{l}\t{%2, %1, %0|%0, %1, %2}
6862    imul{l}\t{%2, %1, %0|%0, %1, %2}
6863    imul{l}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "imul")
6865    (set_attr "prefix_0f" "0,0,1")
6866    (set (attr "athlon_decode")
6867         (cond [(eq_attr "cpu" "athlon")
6868                   (const_string "vector")
6869                (eq_attr "alternative" "1")
6870                   (const_string "vector")
6871                (and (eq_attr "alternative" "2")
6872                     (match_operand 1 "memory_operand" ""))
6873                   (const_string "vector")]
6874               (const_string "direct")))
6875    (set_attr "mode" "SI")])
6876
6877 (define_insn "*mulsi3_1_zext"
6878   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6879         (zero_extend:DI
6880           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6881                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6882    (clobber (reg:CC FLAGS_REG))]
6883   "TARGET_64BIT
6884    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6885   "@
6886    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6887    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888    imul{l}\t{%2, %k0|%k0, %2}"
6889   [(set_attr "type" "imul")
6890    (set_attr "prefix_0f" "0,0,1")
6891    (set (attr "athlon_decode")
6892         (cond [(eq_attr "cpu" "athlon")
6893                   (const_string "vector")
6894                (eq_attr "alternative" "1")
6895                   (const_string "vector")
6896                (and (eq_attr "alternative" "2")
6897                     (match_operand 1 "memory_operand" ""))
6898                   (const_string "vector")]
6899               (const_string "direct")))
6900    (set_attr "mode" "SI")])
6901
6902 (define_expand "mulhi3"
6903   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904                    (mult:HI (match_operand:HI 1 "register_operand" "")
6905                             (match_operand:HI 2 "general_operand" "")))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_HIMODE_MATH"
6908   "")
6909
6910 (define_insn "*mulhi3_1"
6911   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6912         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6913                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6916   "@
6917    imul{w}\t{%2, %1, %0|%0, %1, %2}
6918    imul{w}\t{%2, %1, %0|%0, %1, %2}
6919    imul{w}\t{%2, %0|%0, %2}"
6920   [(set_attr "type" "imul")
6921    (set_attr "prefix_0f" "0,0,1")
6922    (set (attr "athlon_decode")
6923         (cond [(eq_attr "cpu" "athlon")
6924                   (const_string "vector")
6925                (eq_attr "alternative" "1,2")
6926                   (const_string "vector")]
6927               (const_string "direct")))
6928    (set_attr "mode" "HI")])
6929
6930 (define_expand "mulqi3"
6931   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6932                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6933                             (match_operand:QI 2 "register_operand" "")))
6934               (clobber (reg:CC FLAGS_REG))])]
6935   "TARGET_QIMODE_MATH"
6936   "")
6937
6938 (define_insn "*mulqi3_1"
6939   [(set (match_operand:QI 0 "register_operand" "=a")
6940         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6941                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "TARGET_QIMODE_MATH
6944    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6945   "mul{b}\t%2"
6946   [(set_attr "type" "imul")
6947    (set_attr "length_immediate" "0")
6948    (set (attr "athlon_decode")
6949      (if_then_else (eq_attr "cpu" "athlon")
6950         (const_string "vector")
6951         (const_string "direct")))
6952    (set_attr "mode" "QI")])
6953
6954 (define_expand "umulqihi3"
6955   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6956                    (mult:HI (zero_extend:HI
6957                               (match_operand:QI 1 "nonimmediate_operand" ""))
6958                             (zero_extend:HI
6959                               (match_operand:QI 2 "register_operand" ""))))
6960               (clobber (reg:CC FLAGS_REG))])]
6961   "TARGET_QIMODE_MATH"
6962   "")
6963
6964 (define_insn "*umulqihi3_1"
6965   [(set (match_operand:HI 0 "register_operand" "=a")
6966         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "TARGET_QIMODE_MATH
6970    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6971   "mul{b}\t%2"
6972   [(set_attr "type" "imul")
6973    (set_attr "length_immediate" "0")
6974    (set (attr "athlon_decode")
6975      (if_then_else (eq_attr "cpu" "athlon")
6976         (const_string "vector")
6977         (const_string "direct")))
6978    (set_attr "mode" "QI")])
6979
6980 (define_expand "mulqihi3"
6981   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6982                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6983                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6984               (clobber (reg:CC FLAGS_REG))])]
6985   "TARGET_QIMODE_MATH"
6986   "")
6987
6988 (define_insn "*mulqihi3_insn"
6989   [(set (match_operand:HI 0 "register_operand" "=a")
6990         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6991                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6992    (clobber (reg:CC FLAGS_REG))]
6993   "TARGET_QIMODE_MATH
6994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995   "imul{b}\t%2"
6996   [(set_attr "type" "imul")
6997    (set_attr "length_immediate" "0")
6998    (set (attr "athlon_decode")
6999      (if_then_else (eq_attr "cpu" "athlon")
7000         (const_string "vector")
7001         (const_string "direct")))
7002    (set_attr "mode" "QI")])
7003
7004 (define_expand "umulditi3"
7005   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7006                    (mult:TI (zero_extend:TI
7007                               (match_operand:DI 1 "nonimmediate_operand" ""))
7008                             (zero_extend:TI
7009                               (match_operand:DI 2 "register_operand" ""))))
7010               (clobber (reg:CC FLAGS_REG))])]
7011   "TARGET_64BIT"
7012   "")
7013
7014 (define_insn "*umulditi3_insn"
7015   [(set (match_operand:TI 0 "register_operand" "=A")
7016         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7017                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7018    (clobber (reg:CC FLAGS_REG))]
7019   "TARGET_64BIT
7020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021   "mul{q}\t%2"
7022   [(set_attr "type" "imul")
7023    (set_attr "length_immediate" "0")
7024    (set (attr "athlon_decode")
7025      (if_then_else (eq_attr "cpu" "athlon")
7026         (const_string "vector")
7027         (const_string "double")))
7028    (set_attr "mode" "DI")])
7029
7030 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7031 (define_expand "umulsidi3"
7032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033                    (mult:DI (zero_extend:DI
7034                               (match_operand:SI 1 "nonimmediate_operand" ""))
7035                             (zero_extend:DI
7036                               (match_operand:SI 2 "register_operand" ""))))
7037               (clobber (reg:CC FLAGS_REG))])]
7038   "!TARGET_64BIT"
7039   "")
7040
7041 (define_insn "*umulsidi3_insn"
7042   [(set (match_operand:DI 0 "register_operand" "=A")
7043         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7044                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "!TARGET_64BIT
7047    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7048   "mul{l}\t%2"
7049   [(set_attr "type" "imul")
7050    (set_attr "length_immediate" "0")
7051    (set (attr "athlon_decode")
7052      (if_then_else (eq_attr "cpu" "athlon")
7053         (const_string "vector")
7054         (const_string "double")))
7055    (set_attr "mode" "SI")])
7056
7057 (define_expand "mulditi3"
7058   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7059                    (mult:TI (sign_extend:TI
7060                               (match_operand:DI 1 "nonimmediate_operand" ""))
7061                             (sign_extend:TI
7062                               (match_operand:DI 2 "register_operand" ""))))
7063               (clobber (reg:CC FLAGS_REG))])]
7064   "TARGET_64BIT"
7065   "")
7066
7067 (define_insn "*mulditi3_insn"
7068   [(set (match_operand:TI 0 "register_operand" "=A")
7069         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7070                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7071    (clobber (reg:CC FLAGS_REG))]
7072   "TARGET_64BIT
7073    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7074   "imul{q}\t%2"
7075   [(set_attr "type" "imul")
7076    (set_attr "length_immediate" "0")
7077    (set (attr "athlon_decode")
7078      (if_then_else (eq_attr "cpu" "athlon")
7079         (const_string "vector")
7080         (const_string "double")))
7081    (set_attr "mode" "DI")])
7082
7083 (define_expand "mulsidi3"
7084   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7085                    (mult:DI (sign_extend:DI
7086                               (match_operand:SI 1 "nonimmediate_operand" ""))
7087                             (sign_extend:DI
7088                               (match_operand:SI 2 "register_operand" ""))))
7089               (clobber (reg:CC FLAGS_REG))])]
7090   "!TARGET_64BIT"
7091   "")
7092
7093 (define_insn "*mulsidi3_insn"
7094   [(set (match_operand:DI 0 "register_operand" "=A")
7095         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7096                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "!TARGET_64BIT
7099    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7100   "imul{l}\t%2"
7101   [(set_attr "type" "imul")
7102    (set_attr "length_immediate" "0")
7103    (set (attr "athlon_decode")
7104      (if_then_else (eq_attr "cpu" "athlon")
7105         (const_string "vector")
7106         (const_string "double")))
7107    (set_attr "mode" "SI")])
7108
7109 (define_expand "umuldi3_highpart"
7110   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7111                    (truncate:DI
7112                      (lshiftrt:TI
7113                        (mult:TI (zero_extend:TI
7114                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7115                                 (zero_extend:TI
7116                                   (match_operand:DI 2 "register_operand" "")))
7117                        (const_int 64))))
7118               (clobber (match_scratch:DI 3 ""))
7119               (clobber (reg:CC FLAGS_REG))])]
7120   "TARGET_64BIT"
7121   "")
7122
7123 (define_insn "*umuldi3_highpart_rex64"
7124   [(set (match_operand:DI 0 "register_operand" "=d")
7125         (truncate:DI
7126           (lshiftrt:TI
7127             (mult:TI (zero_extend:TI
7128                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7129                      (zero_extend:TI
7130                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7131             (const_int 64))))
7132    (clobber (match_scratch:DI 3 "=1"))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "TARGET_64BIT
7135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136   "mul{q}\t%2"
7137   [(set_attr "type" "imul")
7138    (set_attr "length_immediate" "0")
7139    (set (attr "athlon_decode")
7140      (if_then_else (eq_attr "cpu" "athlon")
7141         (const_string "vector")
7142         (const_string "double")))
7143    (set_attr "mode" "DI")])
7144
7145 (define_expand "umulsi3_highpart"
7146   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7147                    (truncate:SI
7148                      (lshiftrt:DI
7149                        (mult:DI (zero_extend:DI
7150                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7151                                 (zero_extend:DI
7152                                   (match_operand:SI 2 "register_operand" "")))
7153                        (const_int 32))))
7154               (clobber (match_scratch:SI 3 ""))
7155               (clobber (reg:CC FLAGS_REG))])]
7156   ""
7157   "")
7158
7159 (define_insn "*umulsi3_highpart_insn"
7160   [(set (match_operand:SI 0 "register_operand" "=d")
7161         (truncate:SI
7162           (lshiftrt:DI
7163             (mult:DI (zero_extend:DI
7164                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7165                      (zero_extend:DI
7166                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7167             (const_int 32))))
7168    (clobber (match_scratch:SI 3 "=1"))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7171   "mul{l}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "SI")])
7179
7180 (define_insn "*umulsi3_highpart_zext"
7181   [(set (match_operand:DI 0 "register_operand" "=d")
7182         (zero_extend:DI (truncate:SI
7183           (lshiftrt:DI
7184             (mult:DI (zero_extend:DI
7185                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7186                      (zero_extend:DI
7187                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7188             (const_int 32)))))
7189    (clobber (match_scratch:SI 3 "=1"))
7190    (clobber (reg:CC FLAGS_REG))]
7191   "TARGET_64BIT
7192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7193   "mul{l}\t%2"
7194   [(set_attr "type" "imul")
7195    (set_attr "length_immediate" "0")
7196    (set (attr "athlon_decode")
7197      (if_then_else (eq_attr "cpu" "athlon")
7198         (const_string "vector")
7199         (const_string "double")))
7200    (set_attr "mode" "SI")])
7201
7202 (define_expand "smuldi3_highpart"
7203   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7204                    (truncate:DI
7205                      (lshiftrt:TI
7206                        (mult:TI (sign_extend:TI
7207                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7208                                 (sign_extend:TI
7209                                   (match_operand:DI 2 "register_operand" "")))
7210                        (const_int 64))))
7211               (clobber (match_scratch:DI 3 ""))
7212               (clobber (reg:CC FLAGS_REG))])]
7213   "TARGET_64BIT"
7214   "")
7215
7216 (define_insn "*smuldi3_highpart_rex64"
7217   [(set (match_operand:DI 0 "register_operand" "=d")
7218         (truncate:DI
7219           (lshiftrt:TI
7220             (mult:TI (sign_extend:TI
7221                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7222                      (sign_extend:TI
7223                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7224             (const_int 64))))
7225    (clobber (match_scratch:DI 3 "=1"))
7226    (clobber (reg:CC FLAGS_REG))]
7227   "TARGET_64BIT
7228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229   "imul{q}\t%2"
7230   [(set_attr "type" "imul")
7231    (set (attr "athlon_decode")
7232      (if_then_else (eq_attr "cpu" "athlon")
7233         (const_string "vector")
7234         (const_string "double")))
7235    (set_attr "mode" "DI")])
7236
7237 (define_expand "smulsi3_highpart"
7238   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7239                    (truncate:SI
7240                      (lshiftrt:DI
7241                        (mult:DI (sign_extend:DI
7242                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7243                                 (sign_extend:DI
7244                                   (match_operand:SI 2 "register_operand" "")))
7245                        (const_int 32))))
7246               (clobber (match_scratch:SI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   ""
7249   "")
7250
7251 (define_insn "*smulsi3_highpart_insn"
7252   [(set (match_operand:SI 0 "register_operand" "=d")
7253         (truncate:SI
7254           (lshiftrt:DI
7255             (mult:DI (sign_extend:DI
7256                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7257                      (sign_extend:DI
7258                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7259             (const_int 32))))
7260    (clobber (match_scratch:SI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7263   "imul{l}\t%2"
7264   [(set_attr "type" "imul")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "SI")])
7270
7271 (define_insn "*smulsi3_highpart_zext"
7272   [(set (match_operand:DI 0 "register_operand" "=d")
7273         (zero_extend:DI (truncate:SI
7274           (lshiftrt:DI
7275             (mult:DI (sign_extend:DI
7276                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277                      (sign_extend:DI
7278                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279             (const_int 32)))))
7280    (clobber (match_scratch:SI 3 "=1"))
7281    (clobber (reg:CC FLAGS_REG))]
7282   "TARGET_64BIT
7283    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284   "imul{l}\t%2"
7285   [(set_attr "type" "imul")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7291
7292 ;; The patterns that match these are at the end of this file.
7293
7294 (define_expand "mulxf3"
7295   [(set (match_operand:XF 0 "register_operand" "")
7296         (mult:XF (match_operand:XF 1 "register_operand" "")
7297                  (match_operand:XF 2 "register_operand" "")))]
7298   "TARGET_80387"
7299   "")
7300
7301 (define_expand "muldf3"
7302   [(set (match_operand:DF 0 "register_operand" "")
7303         (mult:DF (match_operand:DF 1 "register_operand" "")
7304                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7305   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7306   "")
7307
7308 (define_expand "mulsf3"
7309   [(set (match_operand:SF 0 "register_operand" "")
7310         (mult:SF (match_operand:SF 1 "register_operand" "")
7311                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7312   "TARGET_80387 || TARGET_SSE_MATH"
7313   "")
7314 \f
7315 ;; Divide instructions
7316
7317 (define_insn "divqi3"
7318   [(set (match_operand:QI 0 "register_operand" "=a")
7319         (div:QI (match_operand:HI 1 "register_operand" "0")
7320                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7321    (clobber (reg:CC FLAGS_REG))]
7322   "TARGET_QIMODE_MATH"
7323   "idiv{b}\t%2"
7324   [(set_attr "type" "idiv")
7325    (set_attr "mode" "QI")])
7326
7327 (define_insn "udivqi3"
7328   [(set (match_operand:QI 0 "register_operand" "=a")
7329         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7330                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_QIMODE_MATH"
7333   "div{b}\t%2"
7334   [(set_attr "type" "idiv")
7335    (set_attr "mode" "QI")])
7336
7337 ;; The patterns that match these are at the end of this file.
7338
7339 (define_expand "divxf3"
7340   [(set (match_operand:XF 0 "register_operand" "")
7341         (div:XF (match_operand:XF 1 "register_operand" "")
7342                 (match_operand:XF 2 "register_operand" "")))]
7343   "TARGET_80387"
7344   "")
7345
7346 (define_expand "divdf3"
7347   [(set (match_operand:DF 0 "register_operand" "")
7348         (div:DF (match_operand:DF 1 "register_operand" "")
7349                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7350    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7351    "")
7352  
7353 (define_expand "divsf3"
7354   [(set (match_operand:SF 0 "register_operand" "")
7355         (div:SF (match_operand:SF 1 "register_operand" "")
7356                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7357   "TARGET_80387 || TARGET_SSE_MATH"
7358   "")
7359 \f
7360 ;; Remainder instructions.
7361
7362 (define_expand "divmoddi4"
7363   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7364                    (div:DI (match_operand:DI 1 "register_operand" "")
7365                            (match_operand:DI 2 "nonimmediate_operand" "")))
7366               (set (match_operand:DI 3 "register_operand" "")
7367                    (mod:DI (match_dup 1) (match_dup 2)))
7368               (clobber (reg:CC FLAGS_REG))])]
7369   "TARGET_64BIT"
7370   "")
7371
7372 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7373 ;; Penalize eax case slightly because it results in worse scheduling
7374 ;; of code.
7375 (define_insn "*divmoddi4_nocltd_rex64"
7376   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7377         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7378                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7379    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7380         (mod:DI (match_dup 2) (match_dup 3)))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7383   "#"
7384   [(set_attr "type" "multi")])
7385
7386 (define_insn "*divmoddi4_cltd_rex64"
7387   [(set (match_operand:DI 0 "register_operand" "=a")
7388         (div:DI (match_operand:DI 2 "register_operand" "a")
7389                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7390    (set (match_operand:DI 1 "register_operand" "=&d")
7391         (mod:DI (match_dup 2) (match_dup 3)))
7392    (clobber (reg:CC FLAGS_REG))]
7393   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7394   "#"
7395   [(set_attr "type" "multi")])
7396
7397 (define_insn "*divmoddi_noext_rex64"
7398   [(set (match_operand:DI 0 "register_operand" "=a")
7399         (div:DI (match_operand:DI 1 "register_operand" "0")
7400                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7401    (set (match_operand:DI 3 "register_operand" "=d")
7402         (mod:DI (match_dup 1) (match_dup 2)))
7403    (use (match_operand:DI 4 "register_operand" "3"))
7404    (clobber (reg:CC FLAGS_REG))]
7405   "TARGET_64BIT"
7406   "idiv{q}\t%2"
7407   [(set_attr "type" "idiv")
7408    (set_attr "mode" "DI")])
7409
7410 (define_split
7411   [(set (match_operand:DI 0 "register_operand" "")
7412         (div:DI (match_operand:DI 1 "register_operand" "")
7413                 (match_operand:DI 2 "nonimmediate_operand" "")))
7414    (set (match_operand:DI 3 "register_operand" "")
7415         (mod:DI (match_dup 1) (match_dup 2)))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT && reload_completed"
7418   [(parallel [(set (match_dup 3)
7419                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7420               (clobber (reg:CC FLAGS_REG))])
7421    (parallel [(set (match_dup 0)
7422                    (div:DI (reg:DI 0) (match_dup 2)))
7423               (set (match_dup 3)
7424                    (mod:DI (reg:DI 0) (match_dup 2)))
7425               (use (match_dup 3))
7426               (clobber (reg:CC FLAGS_REG))])]
7427 {
7428   /* Avoid use of cltd in favor of a mov+shift.  */
7429   if (!TARGET_USE_CLTD && !optimize_size)
7430     {
7431       if (true_regnum (operands[1]))
7432         emit_move_insn (operands[0], operands[1]);
7433       else
7434         emit_move_insn (operands[3], operands[1]);
7435       operands[4] = operands[3];
7436     }
7437   else
7438     {
7439       gcc_assert (!true_regnum (operands[1]));
7440       operands[4] = operands[1];
7441     }
7442 })
7443
7444
7445 (define_expand "divmodsi4"
7446   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7447                    (div:SI (match_operand:SI 1 "register_operand" "")
7448                            (match_operand:SI 2 "nonimmediate_operand" "")))
7449               (set (match_operand:SI 3 "register_operand" "")
7450                    (mod:SI (match_dup 1) (match_dup 2)))
7451               (clobber (reg:CC FLAGS_REG))])]
7452   ""
7453   "")
7454
7455 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7456 ;; Penalize eax case slightly because it results in worse scheduling
7457 ;; of code.
7458 (define_insn "*divmodsi4_nocltd"
7459   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7460         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7461                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7462    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7463         (mod:SI (match_dup 2) (match_dup 3)))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "!optimize_size && !TARGET_USE_CLTD"
7466   "#"
7467   [(set_attr "type" "multi")])
7468
7469 (define_insn "*divmodsi4_cltd"
7470   [(set (match_operand:SI 0 "register_operand" "=a")
7471         (div:SI (match_operand:SI 2 "register_operand" "a")
7472                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7473    (set (match_operand:SI 1 "register_operand" "=&d")
7474         (mod:SI (match_dup 2) (match_dup 3)))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "optimize_size || TARGET_USE_CLTD"
7477   "#"
7478   [(set_attr "type" "multi")])
7479
7480 (define_insn "*divmodsi_noext"
7481   [(set (match_operand:SI 0 "register_operand" "=a")
7482         (div:SI (match_operand:SI 1 "register_operand" "0")
7483                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7484    (set (match_operand:SI 3 "register_operand" "=d")
7485         (mod:SI (match_dup 1) (match_dup 2)))
7486    (use (match_operand:SI 4 "register_operand" "3"))
7487    (clobber (reg:CC FLAGS_REG))]
7488   ""
7489   "idiv{l}\t%2"
7490   [(set_attr "type" "idiv")
7491    (set_attr "mode" "SI")])
7492
7493 (define_split
7494   [(set (match_operand:SI 0 "register_operand" "")
7495         (div:SI (match_operand:SI 1 "register_operand" "")
7496                 (match_operand:SI 2 "nonimmediate_operand" "")))
7497    (set (match_operand:SI 3 "register_operand" "")
7498         (mod:SI (match_dup 1) (match_dup 2)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "reload_completed"
7501   [(parallel [(set (match_dup 3)
7502                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7503               (clobber (reg:CC FLAGS_REG))])
7504    (parallel [(set (match_dup 0)
7505                    (div:SI (reg:SI 0) (match_dup 2)))
7506               (set (match_dup 3)
7507                    (mod:SI (reg:SI 0) (match_dup 2)))
7508               (use (match_dup 3))
7509               (clobber (reg:CC FLAGS_REG))])]
7510 {
7511   /* Avoid use of cltd in favor of a mov+shift.  */
7512   if (!TARGET_USE_CLTD && !optimize_size)
7513     {
7514       if (true_regnum (operands[1]))
7515         emit_move_insn (operands[0], operands[1]);
7516       else
7517         emit_move_insn (operands[3], operands[1]);
7518       operands[4] = operands[3];
7519     }
7520   else
7521     {
7522       gcc_assert (!true_regnum (operands[1]));
7523       operands[4] = operands[1];
7524     }
7525 })
7526 ;; %%% Split me.
7527 (define_insn "divmodhi4"
7528   [(set (match_operand:HI 0 "register_operand" "=a")
7529         (div:HI (match_operand:HI 1 "register_operand" "0")
7530                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7531    (set (match_operand:HI 3 "register_operand" "=&d")
7532         (mod:HI (match_dup 1) (match_dup 2)))
7533    (clobber (reg:CC FLAGS_REG))]
7534   "TARGET_HIMODE_MATH"
7535   "cwtd\;idiv{w}\t%2"
7536   [(set_attr "type" "multi")
7537    (set_attr "length_immediate" "0")
7538    (set_attr "mode" "SI")])
7539
7540 (define_insn "udivmoddi4"
7541   [(set (match_operand:DI 0 "register_operand" "=a")
7542         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7543                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544    (set (match_operand:DI 3 "register_operand" "=&d")
7545         (umod:DI (match_dup 1) (match_dup 2)))
7546    (clobber (reg:CC FLAGS_REG))]
7547   "TARGET_64BIT"
7548   "xor{q}\t%3, %3\;div{q}\t%2"
7549   [(set_attr "type" "multi")
7550    (set_attr "length_immediate" "0")
7551    (set_attr "mode" "DI")])
7552
7553 (define_insn "*udivmoddi4_noext"
7554   [(set (match_operand:DI 0 "register_operand" "=a")
7555         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7556                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7557    (set (match_operand:DI 3 "register_operand" "=d")
7558         (umod:DI (match_dup 1) (match_dup 2)))
7559    (use (match_dup 3))
7560    (clobber (reg:CC FLAGS_REG))]
7561   "TARGET_64BIT"
7562   "div{q}\t%2"
7563   [(set_attr "type" "idiv")
7564    (set_attr "mode" "DI")])
7565
7566 (define_split
7567   [(set (match_operand:DI 0 "register_operand" "")
7568         (udiv:DI (match_operand:DI 1 "register_operand" "")
7569                  (match_operand:DI 2 "nonimmediate_operand" "")))
7570    (set (match_operand:DI 3 "register_operand" "")
7571         (umod:DI (match_dup 1) (match_dup 2)))
7572    (clobber (reg:CC FLAGS_REG))]
7573   "TARGET_64BIT && reload_completed"
7574   [(set (match_dup 3) (const_int 0))
7575    (parallel [(set (match_dup 0)
7576                    (udiv:DI (match_dup 1) (match_dup 2)))
7577               (set (match_dup 3)
7578                    (umod:DI (match_dup 1) (match_dup 2)))
7579               (use (match_dup 3))
7580               (clobber (reg:CC FLAGS_REG))])]
7581   "")
7582
7583 (define_insn "udivmodsi4"
7584   [(set (match_operand:SI 0 "register_operand" "=a")
7585         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7586                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7587    (set (match_operand:SI 3 "register_operand" "=&d")
7588         (umod:SI (match_dup 1) (match_dup 2)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   ""
7591   "xor{l}\t%3, %3\;div{l}\t%2"
7592   [(set_attr "type" "multi")
7593    (set_attr "length_immediate" "0")
7594    (set_attr "mode" "SI")])
7595
7596 (define_insn "*udivmodsi4_noext"
7597   [(set (match_operand:SI 0 "register_operand" "=a")
7598         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7599                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7600    (set (match_operand:SI 3 "register_operand" "=d")
7601         (umod:SI (match_dup 1) (match_dup 2)))
7602    (use (match_dup 3))
7603    (clobber (reg:CC FLAGS_REG))]
7604   ""
7605   "div{l}\t%2"
7606   [(set_attr "type" "idiv")
7607    (set_attr "mode" "SI")])
7608
7609 (define_split
7610   [(set (match_operand:SI 0 "register_operand" "")
7611         (udiv:SI (match_operand:SI 1 "register_operand" "")
7612                  (match_operand:SI 2 "nonimmediate_operand" "")))
7613    (set (match_operand:SI 3 "register_operand" "")
7614         (umod:SI (match_dup 1) (match_dup 2)))
7615    (clobber (reg:CC FLAGS_REG))]
7616   "reload_completed"
7617   [(set (match_dup 3) (const_int 0))
7618    (parallel [(set (match_dup 0)
7619                    (udiv:SI (match_dup 1) (match_dup 2)))
7620               (set (match_dup 3)
7621                    (umod:SI (match_dup 1) (match_dup 2)))
7622               (use (match_dup 3))
7623               (clobber (reg:CC FLAGS_REG))])]
7624   "")
7625
7626 (define_expand "udivmodhi4"
7627   [(set (match_dup 4) (const_int 0))
7628    (parallel [(set (match_operand:HI 0 "register_operand" "")
7629                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7630                             (match_operand:HI 2 "nonimmediate_operand" "")))
7631               (set (match_operand:HI 3 "register_operand" "")
7632                    (umod:HI (match_dup 1) (match_dup 2)))
7633               (use (match_dup 4))
7634               (clobber (reg:CC FLAGS_REG))])]
7635   "TARGET_HIMODE_MATH"
7636   "operands[4] = gen_reg_rtx (HImode);")
7637
7638 (define_insn "*udivmodhi_noext"
7639   [(set (match_operand:HI 0 "register_operand" "=a")
7640         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7641                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7642    (set (match_operand:HI 3 "register_operand" "=d")
7643         (umod:HI (match_dup 1) (match_dup 2)))
7644    (use (match_operand:HI 4 "register_operand" "3"))
7645    (clobber (reg:CC FLAGS_REG))]
7646   ""
7647   "div{w}\t%2"
7648   [(set_attr "type" "idiv")
7649    (set_attr "mode" "HI")])
7650
7651 ;; We cannot use div/idiv for double division, because it causes
7652 ;; "division by zero" on the overflow and that's not what we expect
7653 ;; from truncate.  Because true (non truncating) double division is
7654 ;; never generated, we can't create this insn anyway.
7655 ;
7656 ;(define_insn ""
7657 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7658 ;       (truncate:SI
7659 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7660 ;                  (zero_extend:DI
7661 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7662 ;   (set (match_operand:SI 3 "register_operand" "=d")
7663 ;       (truncate:SI
7664 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7665 ;   (clobber (reg:CC FLAGS_REG))]
7666 ;  ""
7667 ;  "div{l}\t{%2, %0|%0, %2}"
7668 ;  [(set_attr "type" "idiv")])
7669 \f
7670 ;;- Logical AND instructions
7671
7672 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7673 ;; Note that this excludes ah.
7674
7675 (define_insn "*testdi_1_rex64"
7676   [(set (reg FLAGS_REG)
7677         (compare
7678           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7679                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7680           (const_int 0)))]
7681   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7682    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7683   "@
7684    test{l}\t{%k1, %k0|%k0, %k1}
7685    test{l}\t{%k1, %k0|%k0, %k1}
7686    test{q}\t{%1, %0|%0, %1}
7687    test{q}\t{%1, %0|%0, %1}
7688    test{q}\t{%1, %0|%0, %1}"
7689   [(set_attr "type" "test")
7690    (set_attr "modrm" "0,1,0,1,1")
7691    (set_attr "mode" "SI,SI,DI,DI,DI")
7692    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7693
7694 (define_insn "testsi_1"
7695   [(set (reg FLAGS_REG)
7696         (compare
7697           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7698                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7699           (const_int 0)))]
7700   "ix86_match_ccmode (insn, CCNOmode)
7701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7702   "test{l}\t{%1, %0|%0, %1}"
7703   [(set_attr "type" "test")
7704    (set_attr "modrm" "0,1,1")
7705    (set_attr "mode" "SI")
7706    (set_attr "pent_pair" "uv,np,uv")])
7707
7708 (define_expand "testsi_ccno_1"
7709   [(set (reg:CCNO FLAGS_REG)
7710         (compare:CCNO
7711           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7712                   (match_operand:SI 1 "nonmemory_operand" ""))
7713           (const_int 0)))]
7714   ""
7715   "")
7716
7717 (define_insn "*testhi_1"
7718   [(set (reg FLAGS_REG)
7719         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7720                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7721                  (const_int 0)))]
7722   "ix86_match_ccmode (insn, CCNOmode)
7723    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724   "test{w}\t{%1, %0|%0, %1}"
7725   [(set_attr "type" "test")
7726    (set_attr "modrm" "0,1,1")
7727    (set_attr "mode" "HI")
7728    (set_attr "pent_pair" "uv,np,uv")])
7729
7730 (define_expand "testqi_ccz_1"
7731   [(set (reg:CCZ FLAGS_REG)
7732         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7733                              (match_operand:QI 1 "nonmemory_operand" ""))
7734                  (const_int 0)))]
7735   ""
7736   "")
7737
7738 (define_insn "*testqi_1_maybe_si"
7739   [(set (reg FLAGS_REG)
7740         (compare
7741           (and:QI
7742             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7743             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7744           (const_int 0)))]
7745    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7746     && ix86_match_ccmode (insn,
7747                          GET_CODE (operands[1]) == CONST_INT
7748                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7749 {
7750   if (which_alternative == 3)
7751     {
7752       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7753         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7754       return "test{l}\t{%1, %k0|%k0, %1}";
7755     }
7756   return "test{b}\t{%1, %0|%0, %1}";
7757 }
7758   [(set_attr "type" "test")
7759    (set_attr "modrm" "0,1,1,1")
7760    (set_attr "mode" "QI,QI,QI,SI")
7761    (set_attr "pent_pair" "uv,np,uv,np")])
7762
7763 (define_insn "*testqi_1"
7764   [(set (reg FLAGS_REG)
7765         (compare
7766           (and:QI
7767             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7768             (match_operand:QI 1 "general_operand" "n,n,qn"))
7769           (const_int 0)))]
7770   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7771    && ix86_match_ccmode (insn, CCNOmode)"
7772   "test{b}\t{%1, %0|%0, %1}"
7773   [(set_attr "type" "test")
7774    (set_attr "modrm" "0,1,1")
7775    (set_attr "mode" "QI")
7776    (set_attr "pent_pair" "uv,np,uv")])
7777
7778 (define_expand "testqi_ext_ccno_0"
7779   [(set (reg:CCNO FLAGS_REG)
7780         (compare:CCNO
7781           (and:SI
7782             (zero_extract:SI
7783               (match_operand 0 "ext_register_operand" "")
7784               (const_int 8)
7785               (const_int 8))
7786             (match_operand 1 "const_int_operand" ""))
7787           (const_int 0)))]
7788   ""
7789   "")
7790
7791 (define_insn "*testqi_ext_0"
7792   [(set (reg FLAGS_REG)
7793         (compare
7794           (and:SI
7795             (zero_extract:SI
7796               (match_operand 0 "ext_register_operand" "Q")
7797               (const_int 8)
7798               (const_int 8))
7799             (match_operand 1 "const_int_operand" "n"))
7800           (const_int 0)))]
7801   "ix86_match_ccmode (insn, CCNOmode)"
7802   "test{b}\t{%1, %h0|%h0, %1}"
7803   [(set_attr "type" "test")
7804    (set_attr "mode" "QI")
7805    (set_attr "length_immediate" "1")
7806    (set_attr "pent_pair" "np")])
7807
7808 (define_insn "*testqi_ext_1"
7809   [(set (reg FLAGS_REG)
7810         (compare
7811           (and:SI
7812             (zero_extract:SI
7813               (match_operand 0 "ext_register_operand" "Q")
7814               (const_int 8)
7815               (const_int 8))
7816             (zero_extend:SI
7817               (match_operand:QI 1 "general_operand" "Qm")))
7818           (const_int 0)))]
7819   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7821   "test{b}\t{%1, %h0|%h0, %1}"
7822   [(set_attr "type" "test")
7823    (set_attr "mode" "QI")])
7824
7825 (define_insn "*testqi_ext_1_rex64"
7826   [(set (reg FLAGS_REG)
7827         (compare
7828           (and:SI
7829             (zero_extract:SI
7830               (match_operand 0 "ext_register_operand" "Q")
7831               (const_int 8)
7832               (const_int 8))
7833             (zero_extend:SI
7834               (match_operand:QI 1 "register_operand" "Q")))
7835           (const_int 0)))]
7836   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7837   "test{b}\t{%1, %h0|%h0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "mode" "QI")])
7840
7841 (define_insn "*testqi_ext_2"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (zero_extract:SI
7850               (match_operand 1 "ext_register_operand" "Q")
7851               (const_int 8)
7852               (const_int 8)))
7853           (const_int 0)))]
7854   "ix86_match_ccmode (insn, CCNOmode)"
7855   "test{b}\t{%h1, %h0|%h0, %h1}"
7856   [(set_attr "type" "test")
7857    (set_attr "mode" "QI")])
7858
7859 ;; Combine likes to form bit extractions for some tests.  Humor it.
7860 (define_insn "*testqi_ext_3"
7861   [(set (reg FLAGS_REG)
7862         (compare (zero_extract:SI
7863                    (match_operand 0 "nonimmediate_operand" "rm")
7864                    (match_operand:SI 1 "const_int_operand" "")
7865                    (match_operand:SI 2 "const_int_operand" ""))
7866                  (const_int 0)))]
7867   "ix86_match_ccmode (insn, CCNOmode)
7868    && (GET_MODE (operands[0]) == SImode
7869        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7870        || GET_MODE (operands[0]) == HImode
7871        || GET_MODE (operands[0]) == QImode)"
7872   "#")
7873
7874 (define_insn "*testqi_ext_3_rex64"
7875   [(set (reg FLAGS_REG)
7876         (compare (zero_extract:DI
7877                    (match_operand 0 "nonimmediate_operand" "rm")
7878                    (match_operand:DI 1 "const_int_operand" "")
7879                    (match_operand:DI 2 "const_int_operand" ""))
7880                  (const_int 0)))]
7881   "TARGET_64BIT
7882    && ix86_match_ccmode (insn, CCNOmode)
7883    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7884    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7885    /* Ensure that resulting mask is zero or sign extended operand.  */
7886    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7887        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7888            && INTVAL (operands[1]) > 32))
7889    && (GET_MODE (operands[0]) == SImode
7890        || GET_MODE (operands[0]) == DImode
7891        || GET_MODE (operands[0]) == HImode
7892        || GET_MODE (operands[0]) == QImode)"
7893   "#")
7894
7895 (define_split
7896   [(set (match_operand 0 "flags_reg_operand" "")
7897         (match_operator 1 "compare_operator"
7898           [(zero_extract
7899              (match_operand 2 "nonimmediate_operand" "")
7900              (match_operand 3 "const_int_operand" "")
7901              (match_operand 4 "const_int_operand" ""))
7902            (const_int 0)]))]
7903   "ix86_match_ccmode (insn, CCNOmode)"
7904   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7905 {
7906   rtx val = operands[2];
7907   HOST_WIDE_INT len = INTVAL (operands[3]);
7908   HOST_WIDE_INT pos = INTVAL (operands[4]);
7909   HOST_WIDE_INT mask;
7910   enum machine_mode mode, submode;
7911
7912   mode = GET_MODE (val);
7913   if (GET_CODE (val) == MEM)
7914     {
7915       /* ??? Combine likes to put non-volatile mem extractions in QImode
7916          no matter the size of the test.  So find a mode that works.  */
7917       if (! MEM_VOLATILE_P (val))
7918         {
7919           mode = smallest_mode_for_size (pos + len, MODE_INT);
7920           val = adjust_address (val, mode, 0);
7921         }
7922     }
7923   else if (GET_CODE (val) == SUBREG
7924            && (submode = GET_MODE (SUBREG_REG (val)),
7925                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7926            && pos + len <= GET_MODE_BITSIZE (submode))
7927     {
7928       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7929       mode = submode;
7930       val = SUBREG_REG (val);
7931     }
7932   else if (mode == HImode && pos + len <= 8)
7933     {
7934       /* Small HImode tests can be converted to QImode.  */
7935       mode = QImode;
7936       val = gen_lowpart (QImode, val);
7937     }
7938
7939   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7940   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7941
7942   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7943 })
7944
7945 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7946 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7947 ;; this is relatively important trick.
7948 ;; Do the conversion only post-reload to avoid limiting of the register class
7949 ;; to QI regs.
7950 (define_split
7951   [(set (match_operand 0 "flags_reg_operand" "")
7952         (match_operator 1 "compare_operator"
7953           [(and (match_operand 2 "register_operand" "")
7954                 (match_operand 3 "const_int_operand" ""))
7955            (const_int 0)]))]
7956    "reload_completed
7957     && QI_REG_P (operands[2])
7958     && GET_MODE (operands[2]) != QImode
7959     && ((ix86_match_ccmode (insn, CCZmode)
7960          && !(INTVAL (operands[3]) & ~(255 << 8)))
7961         || (ix86_match_ccmode (insn, CCNOmode)
7962             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7963   [(set (match_dup 0)
7964         (match_op_dup 1
7965           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7966                    (match_dup 3))
7967            (const_int 0)]))]
7968   "operands[2] = gen_lowpart (SImode, operands[2]);
7969    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7970
7971 (define_split
7972   [(set (match_operand 0 "flags_reg_operand" "")
7973         (match_operator 1 "compare_operator"
7974           [(and (match_operand 2 "nonimmediate_operand" "")
7975                 (match_operand 3 "const_int_operand" ""))
7976            (const_int 0)]))]
7977    "reload_completed
7978     && GET_MODE (operands[2]) != QImode
7979     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7980     && ((ix86_match_ccmode (insn, CCZmode)
7981          && !(INTVAL (operands[3]) & ~255))
7982         || (ix86_match_ccmode (insn, CCNOmode)
7983             && !(INTVAL (operands[3]) & ~127)))"
7984   [(set (match_dup 0)
7985         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7986                          (const_int 0)]))]
7987   "operands[2] = gen_lowpart (QImode, operands[2]);
7988    operands[3] = gen_lowpart (QImode, operands[3]);")
7989
7990
7991 ;; %%% This used to optimize known byte-wide and operations to memory,
7992 ;; and sometimes to QImode registers.  If this is considered useful,
7993 ;; it should be done with splitters.
7994
7995 (define_expand "anddi3"
7996   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7997         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7998                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7999    (clobber (reg:CC FLAGS_REG))]
8000   "TARGET_64BIT"
8001   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8002
8003 (define_insn "*anddi_1_rex64"
8004   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8005         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8006                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8007    (clobber (reg:CC FLAGS_REG))]
8008   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8009 {
8010   switch (get_attr_type (insn))
8011     {
8012     case TYPE_IMOVX:
8013       {
8014         enum machine_mode mode;
8015
8016         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8017         if (INTVAL (operands[2]) == 0xff)
8018           mode = QImode;
8019         else
8020           {
8021             gcc_assert (INTVAL (operands[2]) == 0xffff);
8022             mode = HImode;
8023           }
8024         
8025         operands[1] = gen_lowpart (mode, operands[1]);
8026         if (mode == QImode)
8027           return "movz{bq|x}\t{%1,%0|%0, %1}";
8028         else
8029           return "movz{wq|x}\t{%1,%0|%0, %1}";
8030       }
8031
8032     default:
8033       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8034       if (get_attr_mode (insn) == MODE_SI)
8035         return "and{l}\t{%k2, %k0|%k0, %k2}";
8036       else
8037         return "and{q}\t{%2, %0|%0, %2}";
8038     }
8039 }
8040   [(set_attr "type" "alu,alu,alu,imovx")
8041    (set_attr "length_immediate" "*,*,*,0")
8042    (set_attr "mode" "SI,DI,DI,DI")])
8043
8044 (define_insn "*anddi_2"
8045   [(set (reg FLAGS_REG)
8046         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8047                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8048                  (const_int 0)))
8049    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8050         (and:DI (match_dup 1) (match_dup 2)))]
8051   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8052    && ix86_binary_operator_ok (AND, DImode, operands)"
8053   "@
8054    and{l}\t{%k2, %k0|%k0, %k2}
8055    and{q}\t{%2, %0|%0, %2}
8056    and{q}\t{%2, %0|%0, %2}"
8057   [(set_attr "type" "alu")
8058    (set_attr "mode" "SI,DI,DI")])
8059
8060 (define_expand "andsi3"
8061   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8062         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8063                 (match_operand:SI 2 "general_operand" "")))
8064    (clobber (reg:CC FLAGS_REG))]
8065   ""
8066   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8067
8068 (define_insn "*andsi_1"
8069   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8070         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8071                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "ix86_binary_operator_ok (AND, SImode, operands)"
8074 {
8075   switch (get_attr_type (insn))
8076     {
8077     case TYPE_IMOVX:
8078       {
8079         enum machine_mode mode;
8080
8081         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8082         if (INTVAL (operands[2]) == 0xff)
8083           mode = QImode;
8084         else
8085           {
8086             gcc_assert (INTVAL (operands[2]) == 0xffff);
8087             mode = HImode;
8088           }
8089         
8090         operands[1] = gen_lowpart (mode, operands[1]);
8091         if (mode == QImode)
8092           return "movz{bl|x}\t{%1,%0|%0, %1}";
8093         else
8094           return "movz{wl|x}\t{%1,%0|%0, %1}";
8095       }
8096
8097     default:
8098       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8099       return "and{l}\t{%2, %0|%0, %2}";
8100     }
8101 }
8102   [(set_attr "type" "alu,alu,imovx")
8103    (set_attr "length_immediate" "*,*,0")
8104    (set_attr "mode" "SI")])
8105
8106 (define_split
8107   [(set (match_operand 0 "register_operand" "")
8108         (and (match_dup 0)
8109              (const_int -65536)))
8110    (clobber (reg:CC FLAGS_REG))]
8111   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8112   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8113   "operands[1] = gen_lowpart (HImode, operands[0]);")
8114
8115 (define_split
8116   [(set (match_operand 0 "ext_register_operand" "")
8117         (and (match_dup 0)
8118              (const_int -256)))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8121   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8122   "operands[1] = gen_lowpart (QImode, operands[0]);")
8123
8124 (define_split
8125   [(set (match_operand 0 "ext_register_operand" "")
8126         (and (match_dup 0)
8127              (const_int -65281)))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8130   [(parallel [(set (zero_extract:SI (match_dup 0)
8131                                     (const_int 8)
8132                                     (const_int 8))
8133                    (xor:SI 
8134                      (zero_extract:SI (match_dup 0)
8135                                       (const_int 8)
8136                                       (const_int 8))
8137                      (zero_extract:SI (match_dup 0)
8138                                       (const_int 8)
8139                                       (const_int 8))))
8140               (clobber (reg:CC FLAGS_REG))])]
8141   "operands[0] = gen_lowpart (SImode, operands[0]);")
8142
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*andsi_1_zext"
8145   [(set (match_operand:DI 0 "register_operand" "=r")
8146         (zero_extend:DI
8147           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8148                   (match_operand:SI 2 "general_operand" "rim"))))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8151   "and{l}\t{%2, %k0|%k0, %2}"
8152   [(set_attr "type" "alu")
8153    (set_attr "mode" "SI")])
8154
8155 (define_insn "*andsi_2"
8156   [(set (reg FLAGS_REG)
8157         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8158                          (match_operand:SI 2 "general_operand" "rim,ri"))
8159                  (const_int 0)))
8160    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8161         (and:SI (match_dup 1) (match_dup 2)))]
8162   "ix86_match_ccmode (insn, CCNOmode)
8163    && ix86_binary_operator_ok (AND, SImode, operands)"
8164   "and{l}\t{%2, %0|%0, %2}"
8165   [(set_attr "type" "alu")
8166    (set_attr "mode" "SI")])
8167
8168 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8169 (define_insn "*andsi_2_zext"
8170   [(set (reg FLAGS_REG)
8171         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8172                          (match_operand:SI 2 "general_operand" "rim"))
8173                  (const_int 0)))
8174    (set (match_operand:DI 0 "register_operand" "=r")
8175         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8176   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8177    && ix86_binary_operator_ok (AND, SImode, operands)"
8178   "and{l}\t{%2, %k0|%k0, %2}"
8179   [(set_attr "type" "alu")
8180    (set_attr "mode" "SI")])
8181
8182 (define_expand "andhi3"
8183   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8184         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8185                 (match_operand:HI 2 "general_operand" "")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "TARGET_HIMODE_MATH"
8188   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8189
8190 (define_insn "*andhi_1"
8191   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8192         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8193                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "ix86_binary_operator_ok (AND, HImode, operands)"
8196 {
8197   switch (get_attr_type (insn))
8198     {
8199     case TYPE_IMOVX:
8200       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8201       gcc_assert (INTVAL (operands[2]) == 0xff);
8202       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8203
8204     default:
8205       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8206
8207       return "and{w}\t{%2, %0|%0, %2}";
8208     }
8209 }
8210   [(set_attr "type" "alu,alu,imovx")
8211    (set_attr "length_immediate" "*,*,0")
8212    (set_attr "mode" "HI,HI,SI")])
8213
8214 (define_insn "*andhi_2"
8215   [(set (reg FLAGS_REG)
8216         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8217                          (match_operand:HI 2 "general_operand" "rim,ri"))
8218                  (const_int 0)))
8219    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8220         (and:HI (match_dup 1) (match_dup 2)))]
8221   "ix86_match_ccmode (insn, CCNOmode)
8222    && ix86_binary_operator_ok (AND, HImode, operands)"
8223   "and{w}\t{%2, %0|%0, %2}"
8224   [(set_attr "type" "alu")
8225    (set_attr "mode" "HI")])
8226
8227 (define_expand "andqi3"
8228   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8229         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8230                 (match_operand:QI 2 "general_operand" "")))
8231    (clobber (reg:CC FLAGS_REG))]
8232   "TARGET_QIMODE_MATH"
8233   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8234
8235 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8236 (define_insn "*andqi_1"
8237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8238         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8239                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "ix86_binary_operator_ok (AND, QImode, operands)"
8242   "@
8243    and{b}\t{%2, %0|%0, %2}
8244    and{b}\t{%2, %0|%0, %2}
8245    and{l}\t{%k2, %k0|%k0, %k2}"
8246   [(set_attr "type" "alu")
8247    (set_attr "mode" "QI,QI,SI")])
8248
8249 (define_insn "*andqi_1_slp"
8250   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8251         (and:QI (match_dup 0)
8252                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8253    (clobber (reg:CC FLAGS_REG))]
8254   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8255    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8256   "and{b}\t{%1, %0|%0, %1}"
8257   [(set_attr "type" "alu1")
8258    (set_attr "mode" "QI")])
8259
8260 (define_insn "*andqi_2_maybe_si"
8261   [(set (reg FLAGS_REG)
8262         (compare (and:QI
8263                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8264                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8265                  (const_int 0)))
8266    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8267         (and:QI (match_dup 1) (match_dup 2)))]
8268   "ix86_binary_operator_ok (AND, QImode, operands)
8269    && ix86_match_ccmode (insn,
8270                          GET_CODE (operands[2]) == CONST_INT
8271                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8272 {
8273   if (which_alternative == 2)
8274     {
8275       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8276         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8277       return "and{l}\t{%2, %k0|%k0, %2}";
8278     }
8279   return "and{b}\t{%2, %0|%0, %2}";
8280 }
8281   [(set_attr "type" "alu")
8282    (set_attr "mode" "QI,QI,SI")])
8283
8284 (define_insn "*andqi_2"
8285   [(set (reg FLAGS_REG)
8286         (compare (and:QI
8287                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8288                    (match_operand:QI 2 "general_operand" "qim,qi"))
8289                  (const_int 0)))
8290    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8291         (and:QI (match_dup 1) (match_dup 2)))]
8292   "ix86_match_ccmode (insn, CCNOmode)
8293    && ix86_binary_operator_ok (AND, QImode, operands)"
8294   "and{b}\t{%2, %0|%0, %2}"
8295   [(set_attr "type" "alu")
8296    (set_attr "mode" "QI")])
8297
8298 (define_insn "*andqi_2_slp"
8299   [(set (reg FLAGS_REG)
8300         (compare (and:QI
8301                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8302                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8303                  (const_int 0)))
8304    (set (strict_low_part (match_dup 0))
8305         (and:QI (match_dup 0) (match_dup 1)))]
8306   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8307    && ix86_match_ccmode (insn, CCNOmode)
8308    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8309   "and{b}\t{%1, %0|%0, %1}"
8310   [(set_attr "type" "alu1")
8311    (set_attr "mode" "QI")])
8312
8313 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8314 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8315 ;; for a QImode operand, which of course failed.
8316
8317 (define_insn "andqi_ext_0"
8318   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8319                          (const_int 8)
8320                          (const_int 8))
8321         (and:SI 
8322           (zero_extract:SI
8323             (match_operand 1 "ext_register_operand" "0")
8324             (const_int 8)
8325             (const_int 8))
8326           (match_operand 2 "const_int_operand" "n")))
8327    (clobber (reg:CC FLAGS_REG))]
8328   ""
8329   "and{b}\t{%2, %h0|%h0, %2}"
8330   [(set_attr "type" "alu")
8331    (set_attr "length_immediate" "1")
8332    (set_attr "mode" "QI")])
8333
8334 ;; Generated by peephole translating test to and.  This shows up
8335 ;; often in fp comparisons.
8336
8337 (define_insn "*andqi_ext_0_cc"
8338   [(set (reg FLAGS_REG)
8339         (compare
8340           (and:SI
8341             (zero_extract:SI
8342               (match_operand 1 "ext_register_operand" "0")
8343               (const_int 8)
8344               (const_int 8))
8345             (match_operand 2 "const_int_operand" "n"))
8346           (const_int 0)))
8347    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8348                          (const_int 8)
8349                          (const_int 8))
8350         (and:SI 
8351           (zero_extract:SI
8352             (match_dup 1)
8353             (const_int 8)
8354             (const_int 8))
8355           (match_dup 2)))]
8356   "ix86_match_ccmode (insn, CCNOmode)"
8357   "and{b}\t{%2, %h0|%h0, %2}"
8358   [(set_attr "type" "alu")
8359    (set_attr "length_immediate" "1")
8360    (set_attr "mode" "QI")])
8361
8362 (define_insn "*andqi_ext_1"
8363   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364                          (const_int 8)
8365                          (const_int 8))
8366         (and:SI 
8367           (zero_extract:SI
8368             (match_operand 1 "ext_register_operand" "0")
8369             (const_int 8)
8370             (const_int 8))
8371           (zero_extend:SI
8372             (match_operand:QI 2 "general_operand" "Qm"))))
8373    (clobber (reg:CC FLAGS_REG))]
8374   "!TARGET_64BIT"
8375   "and{b}\t{%2, %h0|%h0, %2}"
8376   [(set_attr "type" "alu")
8377    (set_attr "length_immediate" "0")
8378    (set_attr "mode" "QI")])
8379
8380 (define_insn "*andqi_ext_1_rex64"
8381   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8382                          (const_int 8)
8383                          (const_int 8))
8384         (and:SI 
8385           (zero_extract:SI
8386             (match_operand 1 "ext_register_operand" "0")
8387             (const_int 8)
8388             (const_int 8))
8389           (zero_extend:SI
8390             (match_operand 2 "ext_register_operand" "Q"))))
8391    (clobber (reg:CC FLAGS_REG))]
8392   "TARGET_64BIT"
8393   "and{b}\t{%2, %h0|%h0, %2}"
8394   [(set_attr "type" "alu")
8395    (set_attr "length_immediate" "0")
8396    (set_attr "mode" "QI")])
8397
8398 (define_insn "*andqi_ext_2"
8399   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8400                          (const_int 8)
8401                          (const_int 8))
8402         (and:SI
8403           (zero_extract:SI
8404             (match_operand 1 "ext_register_operand" "%0")
8405             (const_int 8)
8406             (const_int 8))
8407           (zero_extract:SI
8408             (match_operand 2 "ext_register_operand" "Q")
8409             (const_int 8)
8410             (const_int 8))))
8411    (clobber (reg:CC FLAGS_REG))]
8412   ""
8413   "and{b}\t{%h2, %h0|%h0, %h2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "length_immediate" "0")
8416    (set_attr "mode" "QI")])
8417
8418 ;; Convert wide AND instructions with immediate operand to shorter QImode
8419 ;; equivalents when possible.
8420 ;; Don't do the splitting with memory operands, since it introduces risk
8421 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8422 ;; for size, but that can (should?) be handled by generic code instead.
8423 (define_split
8424   [(set (match_operand 0 "register_operand" "")
8425         (and (match_operand 1 "register_operand" "")
8426              (match_operand 2 "const_int_operand" "")))
8427    (clobber (reg:CC FLAGS_REG))]
8428    "reload_completed
8429     && QI_REG_P (operands[0])
8430     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8431     && !(~INTVAL (operands[2]) & ~(255 << 8))
8432     && GET_MODE (operands[0]) != QImode"
8433   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8434                    (and:SI (zero_extract:SI (match_dup 1)
8435                                             (const_int 8) (const_int 8))
8436                            (match_dup 2)))
8437               (clobber (reg:CC FLAGS_REG))])]
8438   "operands[0] = gen_lowpart (SImode, operands[0]);
8439    operands[1] = gen_lowpart (SImode, operands[1]);
8440    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8441
8442 ;; Since AND can be encoded with sign extended immediate, this is only
8443 ;; profitable when 7th bit is not set.
8444 (define_split
8445   [(set (match_operand 0 "register_operand" "")
8446         (and (match_operand 1 "general_operand" "")
8447              (match_operand 2 "const_int_operand" "")))
8448    (clobber (reg:CC FLAGS_REG))]
8449    "reload_completed
8450     && ANY_QI_REG_P (operands[0])
8451     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8452     && !(~INTVAL (operands[2]) & ~255)
8453     && !(INTVAL (operands[2]) & 128)
8454     && GET_MODE (operands[0]) != QImode"
8455   [(parallel [(set (strict_low_part (match_dup 0))
8456                    (and:QI (match_dup 1)
8457                            (match_dup 2)))
8458               (clobber (reg:CC FLAGS_REG))])]
8459   "operands[0] = gen_lowpart (QImode, operands[0]);
8460    operands[1] = gen_lowpart (QImode, operands[1]);
8461    operands[2] = gen_lowpart (QImode, operands[2]);")
8462 \f
8463 ;; Logical inclusive OR instructions
8464
8465 ;; %%% This used to optimize known byte-wide and operations to memory.
8466 ;; If this is considered useful, it should be done with splitters.
8467
8468 (define_expand "iordi3"
8469   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8470         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8471                 (match_operand:DI 2 "x86_64_general_operand" "")))
8472    (clobber (reg:CC FLAGS_REG))]
8473   "TARGET_64BIT"
8474   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8475
8476 (define_insn "*iordi_1_rex64"
8477   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8478         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8479                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "TARGET_64BIT
8482    && ix86_binary_operator_ok (IOR, DImode, operands)"
8483   "or{q}\t{%2, %0|%0, %2}"
8484   [(set_attr "type" "alu")
8485    (set_attr "mode" "DI")])
8486
8487 (define_insn "*iordi_2_rex64"
8488   [(set (reg FLAGS_REG)
8489         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8490                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8491                  (const_int 0)))
8492    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8493         (ior:DI (match_dup 1) (match_dup 2)))]
8494   "TARGET_64BIT
8495    && ix86_match_ccmode (insn, CCNOmode)
8496    && ix86_binary_operator_ok (IOR, DImode, operands)"
8497   "or{q}\t{%2, %0|%0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "mode" "DI")])
8500
8501 (define_insn "*iordi_3_rex64"
8502   [(set (reg FLAGS_REG)
8503         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8504                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8505                  (const_int 0)))
8506    (clobber (match_scratch:DI 0 "=r"))]
8507   "TARGET_64BIT
8508    && ix86_match_ccmode (insn, CCNOmode)
8509    && ix86_binary_operator_ok (IOR, DImode, operands)"
8510   "or{q}\t{%2, %0|%0, %2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "mode" "DI")])
8513
8514
8515 (define_expand "iorsi3"
8516   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8517         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8518                 (match_operand:SI 2 "general_operand" "")))
8519    (clobber (reg:CC FLAGS_REG))]
8520   ""
8521   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8522
8523 (define_insn "*iorsi_1"
8524   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8525         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8526                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "ix86_binary_operator_ok (IOR, SImode, operands)"
8529   "or{l}\t{%2, %0|%0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "mode" "SI")])
8532
8533 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8534 (define_insn "*iorsi_1_zext"
8535   [(set (match_operand:DI 0 "register_operand" "=rm")
8536         (zero_extend:DI
8537           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8538                   (match_operand:SI 2 "general_operand" "rim"))))
8539    (clobber (reg:CC FLAGS_REG))]
8540   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8541   "or{l}\t{%2, %k0|%k0, %2}"
8542   [(set_attr "type" "alu")
8543    (set_attr "mode" "SI")])
8544
8545 (define_insn "*iorsi_1_zext_imm"
8546   [(set (match_operand:DI 0 "register_operand" "=rm")
8547         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8548                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8549    (clobber (reg:CC FLAGS_REG))]
8550   "TARGET_64BIT"
8551   "or{l}\t{%2, %k0|%k0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "SI")])
8554
8555 (define_insn "*iorsi_2"
8556   [(set (reg FLAGS_REG)
8557         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8558                          (match_operand:SI 2 "general_operand" "rim,ri"))
8559                  (const_int 0)))
8560    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8561         (ior:SI (match_dup 1) (match_dup 2)))]
8562   "ix86_match_ccmode (insn, CCNOmode)
8563    && ix86_binary_operator_ok (IOR, SImode, operands)"
8564   "or{l}\t{%2, %0|%0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8569 ;; ??? Special case for immediate operand is missing - it is tricky.
8570 (define_insn "*iorsi_2_zext"
8571   [(set (reg FLAGS_REG)
8572         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8573                          (match_operand:SI 2 "general_operand" "rim"))
8574                  (const_int 0)))
8575    (set (match_operand:DI 0 "register_operand" "=r")
8576         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8577   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8578    && ix86_binary_operator_ok (IOR, SImode, operands)"
8579   "or{l}\t{%2, %k0|%k0, %2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "SI")])
8582
8583 (define_insn "*iorsi_2_zext_imm"
8584   [(set (reg FLAGS_REG)
8585         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8586                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "register_operand" "=r")
8589         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8590   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8591    && ix86_binary_operator_ok (IOR, SImode, operands)"
8592   "or{l}\t{%2, %k0|%k0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "SI")])
8595
8596 (define_insn "*iorsi_3"
8597   [(set (reg FLAGS_REG)
8598         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8599                          (match_operand:SI 2 "general_operand" "rim"))
8600                  (const_int 0)))
8601    (clobber (match_scratch:SI 0 "=r"))]
8602   "ix86_match_ccmode (insn, CCNOmode)
8603    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8604   "or{l}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "SI")])
8607
8608 (define_expand "iorhi3"
8609   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8610         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8611                 (match_operand:HI 2 "general_operand" "")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "TARGET_HIMODE_MATH"
8614   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8615
8616 (define_insn "*iorhi_1"
8617   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8618         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8619                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "ix86_binary_operator_ok (IOR, HImode, operands)"
8622   "or{w}\t{%2, %0|%0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "HI")])
8625
8626 (define_insn "*iorhi_2"
8627   [(set (reg FLAGS_REG)
8628         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8629                          (match_operand:HI 2 "general_operand" "rim,ri"))
8630                  (const_int 0)))
8631    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8632         (ior:HI (match_dup 1) (match_dup 2)))]
8633   "ix86_match_ccmode (insn, CCNOmode)
8634    && ix86_binary_operator_ok (IOR, HImode, operands)"
8635   "or{w}\t{%2, %0|%0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "HI")])
8638
8639 (define_insn "*iorhi_3"
8640   [(set (reg FLAGS_REG)
8641         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8642                          (match_operand:HI 2 "general_operand" "rim"))
8643                  (const_int 0)))
8644    (clobber (match_scratch:HI 0 "=r"))]
8645   "ix86_match_ccmode (insn, CCNOmode)
8646    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8647   "or{w}\t{%2, %0|%0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "HI")])
8650
8651 (define_expand "iorqi3"
8652   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8653         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8654                 (match_operand:QI 2 "general_operand" "")))
8655    (clobber (reg:CC FLAGS_REG))]
8656   "TARGET_QIMODE_MATH"
8657   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8658
8659 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8660 (define_insn "*iorqi_1"
8661   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8662         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8663                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "ix86_binary_operator_ok (IOR, QImode, operands)"
8666   "@
8667    or{b}\t{%2, %0|%0, %2}
8668    or{b}\t{%2, %0|%0, %2}
8669    or{l}\t{%k2, %k0|%k0, %k2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "QI,QI,SI")])
8672
8673 (define_insn "*iorqi_1_slp"
8674   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8675         (ior:QI (match_dup 0)
8676                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8679    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8680   "or{b}\t{%1, %0|%0, %1}"
8681   [(set_attr "type" "alu1")
8682    (set_attr "mode" "QI")])
8683
8684 (define_insn "*iorqi_2"
8685   [(set (reg FLAGS_REG)
8686         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8687                          (match_operand:QI 2 "general_operand" "qim,qi"))
8688                  (const_int 0)))
8689    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8690         (ior:QI (match_dup 1) (match_dup 2)))]
8691   "ix86_match_ccmode (insn, CCNOmode)
8692    && ix86_binary_operator_ok (IOR, QImode, operands)"
8693   "or{b}\t{%2, %0|%0, %2}"
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "QI")])
8696
8697 (define_insn "*iorqi_2_slp"
8698   [(set (reg FLAGS_REG)
8699         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8700                          (match_operand:QI 1 "general_operand" "qim,qi"))
8701                  (const_int 0)))
8702    (set (strict_low_part (match_dup 0))
8703         (ior:QI (match_dup 0) (match_dup 1)))]
8704   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8705    && ix86_match_ccmode (insn, CCNOmode)
8706    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8707   "or{b}\t{%1, %0|%0, %1}"
8708   [(set_attr "type" "alu1")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*iorqi_3"
8712   [(set (reg FLAGS_REG)
8713         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8714                          (match_operand:QI 2 "general_operand" "qim"))
8715                  (const_int 0)))
8716    (clobber (match_scratch:QI 0 "=q"))]
8717   "ix86_match_ccmode (insn, CCNOmode)
8718    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8719   "or{b}\t{%2, %0|%0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "QI")])
8722
8723 (define_insn "iorqi_ext_0"
8724   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8725                          (const_int 8)
8726                          (const_int 8))
8727         (ior:SI 
8728           (zero_extract:SI
8729             (match_operand 1 "ext_register_operand" "0")
8730             (const_int 8)
8731             (const_int 8))
8732           (match_operand 2 "const_int_operand" "n")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8735   "or{b}\t{%2, %h0|%h0, %2}"
8736   [(set_attr "type" "alu")
8737    (set_attr "length_immediate" "1")
8738    (set_attr "mode" "QI")])
8739
8740 (define_insn "*iorqi_ext_1"
8741   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8742                          (const_int 8)
8743                          (const_int 8))
8744         (ior:SI 
8745           (zero_extract:SI
8746             (match_operand 1 "ext_register_operand" "0")
8747             (const_int 8)
8748             (const_int 8))
8749           (zero_extend:SI
8750             (match_operand:QI 2 "general_operand" "Qm"))))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "!TARGET_64BIT
8753    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8754   "or{b}\t{%2, %h0|%h0, %2}"
8755   [(set_attr "type" "alu")
8756    (set_attr "length_immediate" "0")
8757    (set_attr "mode" "QI")])
8758
8759 (define_insn "*iorqi_ext_1_rex64"
8760   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8761                          (const_int 8)
8762                          (const_int 8))
8763         (ior:SI 
8764           (zero_extract:SI
8765             (match_operand 1 "ext_register_operand" "0")
8766             (const_int 8)
8767             (const_int 8))
8768           (zero_extend:SI
8769             (match_operand 2 "ext_register_operand" "Q"))))
8770    (clobber (reg:CC FLAGS_REG))]
8771   "TARGET_64BIT
8772    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8773   "or{b}\t{%2, %h0|%h0, %2}"
8774   [(set_attr "type" "alu")
8775    (set_attr "length_immediate" "0")
8776    (set_attr "mode" "QI")])
8777
8778 (define_insn "*iorqi_ext_2"
8779   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8780                          (const_int 8)
8781                          (const_int 8))
8782         (ior:SI 
8783           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8784                            (const_int 8)
8785                            (const_int 8))
8786           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8787                            (const_int 8)
8788                            (const_int 8))))
8789    (clobber (reg:CC FLAGS_REG))]
8790   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791   "ior{b}\t{%h2, %h0|%h0, %h2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "length_immediate" "0")
8794    (set_attr "mode" "QI")])
8795
8796 (define_split
8797   [(set (match_operand 0 "register_operand" "")
8798         (ior (match_operand 1 "register_operand" "")
8799              (match_operand 2 "const_int_operand" "")))
8800    (clobber (reg:CC FLAGS_REG))]
8801    "reload_completed
8802     && QI_REG_P (operands[0])
8803     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8804     && !(INTVAL (operands[2]) & ~(255 << 8))
8805     && GET_MODE (operands[0]) != QImode"
8806   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8807                    (ior:SI (zero_extract:SI (match_dup 1)
8808                                             (const_int 8) (const_int 8))
8809                            (match_dup 2)))
8810               (clobber (reg:CC FLAGS_REG))])]
8811   "operands[0] = gen_lowpart (SImode, operands[0]);
8812    operands[1] = gen_lowpart (SImode, operands[1]);
8813    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8814
8815 ;; Since OR can be encoded with sign extended immediate, this is only
8816 ;; profitable when 7th bit is set.
8817 (define_split
8818   [(set (match_operand 0 "register_operand" "")
8819         (ior (match_operand 1 "general_operand" "")
8820              (match_operand 2 "const_int_operand" "")))
8821    (clobber (reg:CC FLAGS_REG))]
8822    "reload_completed
8823     && ANY_QI_REG_P (operands[0])
8824     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8825     && !(INTVAL (operands[2]) & ~255)
8826     && (INTVAL (operands[2]) & 128)
8827     && GET_MODE (operands[0]) != QImode"
8828   [(parallel [(set (strict_low_part (match_dup 0))
8829                    (ior:QI (match_dup 1)
8830                            (match_dup 2)))
8831               (clobber (reg:CC FLAGS_REG))])]
8832   "operands[0] = gen_lowpart (QImode, operands[0]);
8833    operands[1] = gen_lowpart (QImode, operands[1]);
8834    operands[2] = gen_lowpart (QImode, operands[2]);")
8835 \f
8836 ;; Logical XOR instructions
8837
8838 ;; %%% This used to optimize known byte-wide and operations to memory.
8839 ;; If this is considered useful, it should be done with splitters.
8840
8841 (define_expand "xordi3"
8842   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8843         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8844                 (match_operand:DI 2 "x86_64_general_operand" "")))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "TARGET_64BIT"
8847   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8848
8849 (define_insn "*xordi_1_rex64"
8850   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8851         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8852                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT
8855    && ix86_binary_operator_ok (XOR, DImode, operands)"
8856   "@
8857    xor{q}\t{%2, %0|%0, %2}
8858    xor{q}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "DI,DI")])
8861
8862 (define_insn "*xordi_2_rex64"
8863   [(set (reg FLAGS_REG)
8864         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8866                  (const_int 0)))
8867    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8868         (xor:DI (match_dup 1) (match_dup 2)))]
8869   "TARGET_64BIT
8870    && ix86_match_ccmode (insn, CCNOmode)
8871    && ix86_binary_operator_ok (XOR, DImode, operands)"
8872   "@
8873    xor{q}\t{%2, %0|%0, %2}
8874    xor{q}\t{%2, %0|%0, %2}"
8875   [(set_attr "type" "alu")
8876    (set_attr "mode" "DI,DI")])
8877
8878 (define_insn "*xordi_3_rex64"
8879   [(set (reg FLAGS_REG)
8880         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8881                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8882                  (const_int 0)))
8883    (clobber (match_scratch:DI 0 "=r"))]
8884   "TARGET_64BIT
8885    && ix86_match_ccmode (insn, CCNOmode)
8886    && ix86_binary_operator_ok (XOR, DImode, operands)"
8887   "xor{q}\t{%2, %0|%0, %2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "mode" "DI")])
8890
8891 (define_expand "xorsi3"
8892   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8893         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8894                 (match_operand:SI 2 "general_operand" "")))
8895    (clobber (reg:CC FLAGS_REG))]
8896   ""
8897   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8898
8899 (define_insn "*xorsi_1"
8900   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8901         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8902                 (match_operand:SI 2 "general_operand" "ri,rm")))
8903    (clobber (reg:CC FLAGS_REG))]
8904   "ix86_binary_operator_ok (XOR, SImode, operands)"
8905   "xor{l}\t{%2, %0|%0, %2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "mode" "SI")])
8908
8909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8910 ;; Add speccase for immediates
8911 (define_insn "*xorsi_1_zext"
8912   [(set (match_operand:DI 0 "register_operand" "=r")
8913         (zero_extend:DI
8914           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8915                   (match_operand:SI 2 "general_operand" "rim"))))
8916    (clobber (reg:CC FLAGS_REG))]
8917   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8918   "xor{l}\t{%2, %k0|%k0, %2}"
8919   [(set_attr "type" "alu")
8920    (set_attr "mode" "SI")])
8921
8922 (define_insn "*xorsi_1_zext_imm"
8923   [(set (match_operand:DI 0 "register_operand" "=r")
8924         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8925                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8928   "xor{l}\t{%2, %k0|%k0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "SI")])
8931
8932 (define_insn "*xorsi_2"
8933   [(set (reg FLAGS_REG)
8934         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8935                          (match_operand:SI 2 "general_operand" "rim,ri"))
8936                  (const_int 0)))
8937    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8938         (xor:SI (match_dup 1) (match_dup 2)))]
8939   "ix86_match_ccmode (insn, CCNOmode)
8940    && ix86_binary_operator_ok (XOR, SImode, operands)"
8941   "xor{l}\t{%2, %0|%0, %2}"
8942   [(set_attr "type" "alu")
8943    (set_attr "mode" "SI")])
8944
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 ;; ??? Special case for immediate operand is missing - it is tricky.
8947 (define_insn "*xorsi_2_zext"
8948   [(set (reg FLAGS_REG)
8949         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950                          (match_operand:SI 2 "general_operand" "rim"))
8951                  (const_int 0)))
8952    (set (match_operand:DI 0 "register_operand" "=r")
8953         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8954   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955    && ix86_binary_operator_ok (XOR, SImode, operands)"
8956   "xor{l}\t{%2, %k0|%k0, %2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "SI")])
8959
8960 (define_insn "*xorsi_2_zext_imm"
8961   [(set (reg FLAGS_REG)
8962         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8963                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8964                  (const_int 0)))
8965    (set (match_operand:DI 0 "register_operand" "=r")
8966         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8967   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8968    && ix86_binary_operator_ok (XOR, SImode, operands)"
8969   "xor{l}\t{%2, %k0|%k0, %2}"
8970   [(set_attr "type" "alu")
8971    (set_attr "mode" "SI")])
8972
8973 (define_insn "*xorsi_3"
8974   [(set (reg FLAGS_REG)
8975         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976                          (match_operand:SI 2 "general_operand" "rim"))
8977                  (const_int 0)))
8978    (clobber (match_scratch:SI 0 "=r"))]
8979   "ix86_match_ccmode (insn, CCNOmode)
8980    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8981   "xor{l}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "SI")])
8984
8985 (define_expand "xorhi3"
8986   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8987         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8988                 (match_operand:HI 2 "general_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "TARGET_HIMODE_MATH"
8991   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8992
8993 (define_insn "*xorhi_1"
8994   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8995         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8996                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "ix86_binary_operator_ok (XOR, HImode, operands)"
8999   "xor{w}\t{%2, %0|%0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "HI")])
9002
9003 (define_insn "*xorhi_2"
9004   [(set (reg FLAGS_REG)
9005         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9006                          (match_operand:HI 2 "general_operand" "rim,ri"))
9007                  (const_int 0)))
9008    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9009         (xor:HI (match_dup 1) (match_dup 2)))]
9010   "ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, HImode, operands)"
9012   "xor{w}\t{%2, %0|%0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "HI")])
9015
9016 (define_insn "*xorhi_3"
9017   [(set (reg FLAGS_REG)
9018         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9019                          (match_operand:HI 2 "general_operand" "rim"))
9020                  (const_int 0)))
9021    (clobber (match_scratch:HI 0 "=r"))]
9022   "ix86_match_ccmode (insn, CCNOmode)
9023    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9024   "xor{w}\t{%2, %0|%0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "HI")])
9027
9028 (define_expand "xorqi3"
9029   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9030         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9031                 (match_operand:QI 2 "general_operand" "")))
9032    (clobber (reg:CC FLAGS_REG))]
9033   "TARGET_QIMODE_MATH"
9034   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9035
9036 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9037 (define_insn "*xorqi_1"
9038   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9039         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9040                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "ix86_binary_operator_ok (XOR, QImode, operands)"
9043   "@
9044    xor{b}\t{%2, %0|%0, %2}
9045    xor{b}\t{%2, %0|%0, %2}
9046    xor{l}\t{%k2, %k0|%k0, %k2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "QI,QI,SI")])
9049
9050 (define_insn "*xorqi_1_slp"
9051   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9052         (xor:QI (match_dup 0)
9053                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9054    (clobber (reg:CC FLAGS_REG))]
9055   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9056    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9057   "xor{b}\t{%1, %0|%0, %1}"
9058   [(set_attr "type" "alu1")
9059    (set_attr "mode" "QI")])
9060
9061 (define_insn "xorqi_ext_0"
9062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063                          (const_int 8)
9064                          (const_int 8))
9065         (xor:SI 
9066           (zero_extract:SI
9067             (match_operand 1 "ext_register_operand" "0")
9068             (const_int 8)
9069             (const_int 8))
9070           (match_operand 2 "const_int_operand" "n")))
9071    (clobber (reg:CC FLAGS_REG))]
9072   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9073   "xor{b}\t{%2, %h0|%h0, %2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "length_immediate" "1")
9076    (set_attr "mode" "QI")])
9077
9078 (define_insn "*xorqi_ext_1"
9079   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9080                          (const_int 8)
9081                          (const_int 8))
9082         (xor:SI 
9083           (zero_extract:SI
9084             (match_operand 1 "ext_register_operand" "0")
9085             (const_int 8)
9086             (const_int 8))
9087           (zero_extend:SI
9088             (match_operand:QI 2 "general_operand" "Qm"))))
9089    (clobber (reg:CC FLAGS_REG))]
9090   "!TARGET_64BIT
9091    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9092   "xor{b}\t{%2, %h0|%h0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "length_immediate" "0")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*xorqi_ext_1_rex64"
9098   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9099                          (const_int 8)
9100                          (const_int 8))
9101         (xor:SI 
9102           (zero_extract:SI
9103             (match_operand 1 "ext_register_operand" "0")
9104             (const_int 8)
9105             (const_int 8))
9106           (zero_extend:SI
9107             (match_operand 2 "ext_register_operand" "Q"))))
9108    (clobber (reg:CC FLAGS_REG))]
9109   "TARGET_64BIT
9110    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9111   "xor{b}\t{%2, %h0|%h0, %2}"
9112   [(set_attr "type" "alu")
9113    (set_attr "length_immediate" "0")
9114    (set_attr "mode" "QI")])
9115
9116 (define_insn "*xorqi_ext_2"
9117   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9118                          (const_int 8)
9119                          (const_int 8))
9120         (xor:SI 
9121           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9122                            (const_int 8)
9123                            (const_int 8))
9124           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9125                            (const_int 8)
9126                            (const_int 8))))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129   "xor{b}\t{%h2, %h0|%h0, %h2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "length_immediate" "0")
9132    (set_attr "mode" "QI")])
9133
9134 (define_insn "*xorqi_cc_1"
9135   [(set (reg FLAGS_REG)
9136         (compare
9137           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9138                   (match_operand:QI 2 "general_operand" "qim,qi"))
9139           (const_int 0)))
9140    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9141         (xor:QI (match_dup 1) (match_dup 2)))]
9142   "ix86_match_ccmode (insn, CCNOmode)
9143    && ix86_binary_operator_ok (XOR, QImode, operands)"
9144   "xor{b}\t{%2, %0|%0, %2}"
9145   [(set_attr "type" "alu")
9146    (set_attr "mode" "QI")])
9147
9148 (define_insn "*xorqi_2_slp"
9149   [(set (reg FLAGS_REG)
9150         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9151                          (match_operand:QI 1 "general_operand" "qim,qi"))
9152                  (const_int 0)))
9153    (set (strict_low_part (match_dup 0))
9154         (xor:QI (match_dup 0) (match_dup 1)))]
9155   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9156    && ix86_match_ccmode (insn, CCNOmode)
9157    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9158   "xor{b}\t{%1, %0|%0, %1}"
9159   [(set_attr "type" "alu1")
9160    (set_attr "mode" "QI")])
9161
9162 (define_insn "*xorqi_cc_2"
9163   [(set (reg FLAGS_REG)
9164         (compare
9165           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9166                   (match_operand:QI 2 "general_operand" "qim"))
9167           (const_int 0)))
9168    (clobber (match_scratch:QI 0 "=q"))]
9169   "ix86_match_ccmode (insn, CCNOmode)
9170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9171   "xor{b}\t{%2, %0|%0, %2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_cc_ext_1"
9176   [(set (reg FLAGS_REG)
9177         (compare
9178           (xor:SI
9179             (zero_extract:SI
9180               (match_operand 1 "ext_register_operand" "0")
9181               (const_int 8)
9182               (const_int 8))
9183             (match_operand:QI 2 "general_operand" "qmn"))
9184           (const_int 0)))
9185    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9186                          (const_int 8)
9187                          (const_int 8))
9188         (xor:SI 
9189           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9190           (match_dup 2)))]
9191   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9192   "xor{b}\t{%2, %h0|%h0, %2}"
9193   [(set_attr "type" "alu")
9194    (set_attr "mode" "QI")])
9195
9196 (define_insn "*xorqi_cc_ext_1_rex64"
9197   [(set (reg FLAGS_REG)
9198         (compare
9199           (xor:SI
9200             (zero_extract:SI
9201               (match_operand 1 "ext_register_operand" "0")
9202               (const_int 8)
9203               (const_int 8))
9204             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9205           (const_int 0)))
9206    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207                          (const_int 8)
9208                          (const_int 8))
9209         (xor:SI 
9210           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9211           (match_dup 2)))]
9212   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9213   "xor{b}\t{%2, %h0|%h0, %2}"
9214   [(set_attr "type" "alu")
9215    (set_attr "mode" "QI")])
9216
9217 (define_expand "xorqi_cc_ext_1"
9218   [(parallel [
9219      (set (reg:CCNO FLAGS_REG)
9220           (compare:CCNO
9221             (xor:SI
9222               (zero_extract:SI
9223                 (match_operand 1 "ext_register_operand" "")
9224                 (const_int 8)
9225                 (const_int 8))
9226               (match_operand:QI 2 "general_operand" ""))
9227             (const_int 0)))
9228      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9229                            (const_int 8)
9230                            (const_int 8))
9231           (xor:SI 
9232             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9233             (match_dup 2)))])]
9234   ""
9235   "")
9236
9237 (define_split
9238   [(set (match_operand 0 "register_operand" "")
9239         (xor (match_operand 1 "register_operand" "")
9240              (match_operand 2 "const_int_operand" "")))
9241    (clobber (reg:CC FLAGS_REG))]
9242    "reload_completed
9243     && QI_REG_P (operands[0])
9244     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9245     && !(INTVAL (operands[2]) & ~(255 << 8))
9246     && GET_MODE (operands[0]) != QImode"
9247   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9248                    (xor:SI (zero_extract:SI (match_dup 1)
9249                                             (const_int 8) (const_int 8))
9250                            (match_dup 2)))
9251               (clobber (reg:CC FLAGS_REG))])]
9252   "operands[0] = gen_lowpart (SImode, operands[0]);
9253    operands[1] = gen_lowpart (SImode, operands[1]);
9254    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9255
9256 ;; Since XOR can be encoded with sign extended immediate, this is only
9257 ;; profitable when 7th bit is set.
9258 (define_split
9259   [(set (match_operand 0 "register_operand" "")
9260         (xor (match_operand 1 "general_operand" "")
9261              (match_operand 2 "const_int_operand" "")))
9262    (clobber (reg:CC FLAGS_REG))]
9263    "reload_completed
9264     && ANY_QI_REG_P (operands[0])
9265     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9266     && !(INTVAL (operands[2]) & ~255)
9267     && (INTVAL (operands[2]) & 128)
9268     && GET_MODE (operands[0]) != QImode"
9269   [(parallel [(set (strict_low_part (match_dup 0))
9270                    (xor:QI (match_dup 1)
9271                            (match_dup 2)))
9272               (clobber (reg:CC FLAGS_REG))])]
9273   "operands[0] = gen_lowpart (QImode, operands[0]);
9274    operands[1] = gen_lowpart (QImode, operands[1]);
9275    operands[2] = gen_lowpart (QImode, operands[2]);")
9276 \f
9277 ;; Negation instructions
9278
9279 (define_expand "negti2"
9280   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9281                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9282               (clobber (reg:CC FLAGS_REG))])]
9283   "TARGET_64BIT"
9284   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9285
9286 (define_insn "*negti2_1"
9287   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9288         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9289    (clobber (reg:CC FLAGS_REG))]
9290   "TARGET_64BIT
9291    && ix86_unary_operator_ok (NEG, TImode, operands)"
9292   "#")
9293
9294 (define_split
9295   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9296         (neg:TI (match_operand:TI 1 "general_operand" "")))
9297    (clobber (reg:CC FLAGS_REG))]
9298   "TARGET_64BIT && reload_completed"
9299   [(parallel
9300     [(set (reg:CCZ FLAGS_REG)
9301           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9302      (set (match_dup 0) (neg:DI (match_dup 2)))])
9303    (parallel
9304     [(set (match_dup 1)
9305           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9306                             (match_dup 3))
9307                    (const_int 0)))
9308      (clobber (reg:CC FLAGS_REG))])
9309    (parallel
9310     [(set (match_dup 1)
9311           (neg:DI (match_dup 1)))
9312      (clobber (reg:CC FLAGS_REG))])]
9313   "split_ti (operands+1, 1, operands+2, operands+3);
9314    split_ti (operands+0, 1, operands+0, operands+1);")
9315
9316 (define_expand "negdi2"
9317   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9318                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9319               (clobber (reg:CC FLAGS_REG))])]
9320   ""
9321   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9322
9323 (define_insn "*negdi2_1"
9324   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9325         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "!TARGET_64BIT
9328    && ix86_unary_operator_ok (NEG, DImode, operands)"
9329   "#")
9330
9331 (define_split
9332   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9333         (neg:DI (match_operand:DI 1 "general_operand" "")))
9334    (clobber (reg:CC FLAGS_REG))]
9335   "!TARGET_64BIT && reload_completed"
9336   [(parallel
9337     [(set (reg:CCZ FLAGS_REG)
9338           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9339      (set (match_dup 0) (neg:SI (match_dup 2)))])
9340    (parallel
9341     [(set (match_dup 1)
9342           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9343                             (match_dup 3))
9344                    (const_int 0)))
9345      (clobber (reg:CC FLAGS_REG))])
9346    (parallel
9347     [(set (match_dup 1)
9348           (neg:SI (match_dup 1)))
9349      (clobber (reg:CC FLAGS_REG))])]
9350   "split_di (operands+1, 1, operands+2, operands+3);
9351    split_di (operands+0, 1, operands+0, operands+1);")
9352
9353 (define_insn "*negdi2_1_rex64"
9354   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9355         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9356    (clobber (reg:CC FLAGS_REG))]
9357   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9358   "neg{q}\t%0"
9359   [(set_attr "type" "negnot")
9360    (set_attr "mode" "DI")])
9361
9362 ;; The problem with neg is that it does not perform (compare x 0),
9363 ;; it really performs (compare 0 x), which leaves us with the zero
9364 ;; flag being the only useful item.
9365
9366 (define_insn "*negdi2_cmpz_rex64"
9367   [(set (reg:CCZ FLAGS_REG)
9368         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9369                      (const_int 0)))
9370    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9371         (neg:DI (match_dup 1)))]
9372   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9373   "neg{q}\t%0"
9374   [(set_attr "type" "negnot")
9375    (set_attr "mode" "DI")])
9376
9377
9378 (define_expand "negsi2"
9379   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9380                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9381               (clobber (reg:CC FLAGS_REG))])]
9382   ""
9383   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9384
9385 (define_insn "*negsi2_1"
9386   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9387         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9388    (clobber (reg:CC FLAGS_REG))]
9389   "ix86_unary_operator_ok (NEG, SImode, operands)"
9390   "neg{l}\t%0"
9391   [(set_attr "type" "negnot")
9392    (set_attr "mode" "SI")])
9393
9394 ;; Combine is quite creative about this pattern.
9395 (define_insn "*negsi2_1_zext"
9396   [(set (match_operand:DI 0 "register_operand" "=r")
9397         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9398                                         (const_int 32)))
9399                      (const_int 32)))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9402   "neg{l}\t%k0"
9403   [(set_attr "type" "negnot")
9404    (set_attr "mode" "SI")])
9405
9406 ;; The problem with neg is that it does not perform (compare x 0),
9407 ;; it really performs (compare 0 x), which leaves us with the zero
9408 ;; flag being the only useful item.
9409
9410 (define_insn "*negsi2_cmpz"
9411   [(set (reg:CCZ FLAGS_REG)
9412         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9413                      (const_int 0)))
9414    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9415         (neg:SI (match_dup 1)))]
9416   "ix86_unary_operator_ok (NEG, SImode, operands)"
9417   "neg{l}\t%0"
9418   [(set_attr "type" "negnot")
9419    (set_attr "mode" "SI")])
9420
9421 (define_insn "*negsi2_cmpz_zext"
9422   [(set (reg:CCZ FLAGS_REG)
9423         (compare:CCZ (lshiftrt:DI
9424                        (neg:DI (ashift:DI
9425                                  (match_operand:DI 1 "register_operand" "0")
9426                                  (const_int 32)))
9427                        (const_int 32))
9428                      (const_int 0)))
9429    (set (match_operand:DI 0 "register_operand" "=r")
9430         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9431                                         (const_int 32)))
9432                      (const_int 32)))]
9433   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9434   "neg{l}\t%k0"
9435   [(set_attr "type" "negnot")
9436    (set_attr "mode" "SI")])
9437
9438 (define_expand "neghi2"
9439   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9440                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9441               (clobber (reg:CC FLAGS_REG))])]
9442   "TARGET_HIMODE_MATH"
9443   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9444
9445 (define_insn "*neghi2_1"
9446   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9447         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "ix86_unary_operator_ok (NEG, HImode, operands)"
9450   "neg{w}\t%0"
9451   [(set_attr "type" "negnot")
9452    (set_attr "mode" "HI")])
9453
9454 (define_insn "*neghi2_cmpz"
9455   [(set (reg:CCZ FLAGS_REG)
9456         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9457                      (const_int 0)))
9458    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9459         (neg:HI (match_dup 1)))]
9460   "ix86_unary_operator_ok (NEG, HImode, operands)"
9461   "neg{w}\t%0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "HI")])
9464
9465 (define_expand "negqi2"
9466   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9467                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9468               (clobber (reg:CC FLAGS_REG))])]
9469   "TARGET_QIMODE_MATH"
9470   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9471
9472 (define_insn "*negqi2_1"
9473   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9474         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "ix86_unary_operator_ok (NEG, QImode, operands)"
9477   "neg{b}\t%0"
9478   [(set_attr "type" "negnot")
9479    (set_attr "mode" "QI")])
9480
9481 (define_insn "*negqi2_cmpz"
9482   [(set (reg:CCZ FLAGS_REG)
9483         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9484                      (const_int 0)))
9485    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9486         (neg:QI (match_dup 1)))]
9487   "ix86_unary_operator_ok (NEG, QImode, operands)"
9488   "neg{b}\t%0"
9489   [(set_attr "type" "negnot")
9490    (set_attr "mode" "QI")])
9491
9492 ;; Changing of sign for FP values is doable using integer unit too.
9493
9494 (define_expand "negsf2"
9495   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9496         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9497   "TARGET_80387 || TARGET_SSE_MATH"
9498   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9499
9500 (define_expand "abssf2"
9501   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387 || TARGET_SSE_MATH"
9504   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9505
9506 (define_insn "*absnegsf2_mixed"
9507   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9508         (match_operator:SF 3 "absneg_operator"
9509           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9510    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9513    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9514   "#")
9515
9516 (define_insn "*absnegsf2_sse"
9517   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9518         (match_operator:SF 3 "absneg_operator"
9519           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9520    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9521    (clobber (reg:CC FLAGS_REG))]
9522   "TARGET_SSE_MATH
9523    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9524   "#")
9525
9526 (define_insn "*absnegsf2_i387"
9527   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9528         (match_operator:SF 3 "absneg_operator"
9529           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9530    (use (match_operand 2 "" ""))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "TARGET_80387 && !TARGET_SSE_MATH
9533    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9534   "#")
9535
9536 (define_expand "copysignsf3"
9537   [(match_operand:SF 0 "register_operand" "")
9538    (match_operand:SF 1 "nonmemory_operand" "")
9539    (match_operand:SF 2 "register_operand" "")]
9540   "TARGET_SSE_MATH"
9541 {
9542   ix86_expand_copysign (operands);
9543   DONE;
9544 })
9545
9546 (define_insn_and_split "copysignsf3_const"
9547   [(set (match_operand:SF 0 "register_operand"          "=x")
9548         (unspec:SF
9549           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9550            (match_operand:SF 2 "register_operand"       "0")
9551            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9552           UNSPEC_COPYSIGN))]
9553   "TARGET_SSE_MATH"
9554   "#"
9555   "&& reload_completed"
9556   [(const_int 0)]
9557 {
9558   ix86_split_copysign_const (operands);
9559   DONE;
9560 })
9561
9562 (define_insn "copysignsf3_var"
9563   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9564         (unspec:SF
9565           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9566            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9567            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9568            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9569           UNSPEC_COPYSIGN))
9570    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9571   "TARGET_SSE_MATH"
9572   "#")
9573
9574 (define_split
9575   [(set (match_operand:SF 0 "register_operand" "")
9576         (unspec:SF
9577           [(match_operand:SF 2 "register_operand" "")
9578            (match_operand:SF 3 "register_operand" "")
9579            (match_operand:V4SF 4 "" "")
9580            (match_operand:V4SF 5 "" "")]
9581           UNSPEC_COPYSIGN))
9582    (clobber (match_scratch:V4SF 1 ""))]
9583   "TARGET_SSE_MATH && reload_completed"
9584   [(const_int 0)]
9585 {
9586   ix86_split_copysign_var (operands);
9587   DONE;
9588 })
9589
9590 (define_expand "negdf2"
9591   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9592         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9593   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9594   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9595
9596 (define_expand "absdf2"
9597   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9601
9602 (define_insn "*absnegdf2_mixed"
9603   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9604         (match_operator:DF 3 "absneg_operator"
9605           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9606    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9610   "#")
9611
9612 (define_insn "*absnegdf2_sse"
9613   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9614         (match_operator:DF 3 "absneg_operator"
9615           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9616    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_SSE2 && TARGET_SSE_MATH
9619    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9620   "#")
9621
9622 (define_insn "*absnegdf2_i387"
9623   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9624         (match_operator:DF 3 "absneg_operator"
9625           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9626    (use (match_operand 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9629    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9630   "#")
9631
9632 (define_expand "copysigndf3"
9633   [(match_operand:DF 0 "register_operand" "")
9634    (match_operand:DF 1 "nonmemory_operand" "")
9635    (match_operand:DF 2 "register_operand" "")]
9636   "TARGET_SSE2 && TARGET_SSE_MATH"
9637 {
9638   ix86_expand_copysign (operands);
9639   DONE;
9640 })
9641
9642 (define_insn_and_split "copysigndf3_const"
9643   [(set (match_operand:DF 0 "register_operand"          "=x")
9644         (unspec:DF
9645           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9646            (match_operand:DF 2 "register_operand"       "0")
9647            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9648           UNSPEC_COPYSIGN))]
9649   "TARGET_SSE2 && TARGET_SSE_MATH"
9650   "#"
9651   "&& reload_completed"
9652   [(const_int 0)]
9653 {
9654   ix86_split_copysign_const (operands);
9655   DONE;
9656 })
9657
9658 (define_insn "copysigndf3_var"
9659   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9660         (unspec:DF
9661           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9662            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9663            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665           UNSPEC_COPYSIGN))
9666    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9667   "TARGET_SSE2 && TARGET_SSE_MATH"
9668   "#")
9669
9670 (define_split
9671   [(set (match_operand:DF 0 "register_operand" "")
9672         (unspec:DF
9673           [(match_operand:DF 2 "register_operand" "")
9674            (match_operand:DF 3 "register_operand" "")
9675            (match_operand:V2DF 4 "" "")
9676            (match_operand:V2DF 5 "" "")]
9677           UNSPEC_COPYSIGN))
9678    (clobber (match_scratch:V2DF 1 ""))]
9679   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9680   [(const_int 0)]
9681 {
9682   ix86_split_copysign_var (operands);
9683   DONE;
9684 })
9685
9686 (define_expand "negxf2"
9687   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9688         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9689   "TARGET_80387"
9690   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9691
9692 (define_expand "absxf2"
9693   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387"
9696   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9697
9698 (define_insn "*absnegxf2_i387"
9699   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9700         (match_operator:XF 3 "absneg_operator"
9701           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9702    (use (match_operand 2 "" ""))
9703    (clobber (reg:CC FLAGS_REG))]
9704   "TARGET_80387
9705    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9706   "#")
9707
9708 ;; Splitters for fp abs and neg.
9709
9710 (define_split
9711   [(set (match_operand 0 "fp_register_operand" "")
9712         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9713    (use (match_operand 2 "" ""))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "reload_completed"
9716   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9717
9718 (define_split
9719   [(set (match_operand 0 "register_operand" "")
9720         (match_operator 3 "absneg_operator"
9721           [(match_operand 1 "register_operand" "")]))
9722    (use (match_operand 2 "nonimmediate_operand" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed && SSE_REG_P (operands[0])"
9725   [(set (match_dup 0) (match_dup 3))]
9726 {
9727   enum machine_mode mode = GET_MODE (operands[0]);
9728   enum machine_mode vmode = GET_MODE (operands[2]);
9729   rtx tmp;
9730   
9731   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9732   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9733   if (operands_match_p (operands[0], operands[2]))
9734     {
9735       tmp = operands[1];
9736       operands[1] = operands[2];
9737       operands[2] = tmp;
9738     }
9739   if (GET_CODE (operands[3]) == ABS)
9740     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9741   else
9742     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9743   operands[3] = tmp;
9744 })
9745
9746 (define_split
9747   [(set (match_operand:SF 0 "register_operand" "")
9748         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9749    (use (match_operand:V4SF 2 "" ""))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "reload_completed"
9752   [(parallel [(set (match_dup 0) (match_dup 1))
9753               (clobber (reg:CC FLAGS_REG))])]
9754
9755   rtx tmp;
9756   operands[0] = gen_lowpart (SImode, operands[0]);
9757   if (GET_CODE (operands[1]) == ABS)
9758     {
9759       tmp = gen_int_mode (0x7fffffff, SImode);
9760       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9761     }
9762   else
9763     {
9764       tmp = gen_int_mode (0x80000000, SImode);
9765       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9766     }
9767   operands[1] = tmp;
9768 })
9769
9770 (define_split
9771   [(set (match_operand:DF 0 "register_operand" "")
9772         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9773    (use (match_operand 2 "" ""))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "reload_completed"
9776   [(parallel [(set (match_dup 0) (match_dup 1))
9777               (clobber (reg:CC FLAGS_REG))])]
9778 {
9779   rtx tmp;
9780   if (TARGET_64BIT)
9781     {
9782       tmp = gen_lowpart (DImode, operands[0]);
9783       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9784       operands[0] = tmp;
9785
9786       if (GET_CODE (operands[1]) == ABS)
9787         tmp = const0_rtx;
9788       else
9789         tmp = gen_rtx_NOT (DImode, tmp);
9790     }
9791   else
9792     {
9793       operands[0] = gen_highpart (SImode, operands[0]);
9794       if (GET_CODE (operands[1]) == ABS)
9795         {
9796           tmp = gen_int_mode (0x7fffffff, SImode);
9797           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9798         }
9799       else
9800         {
9801           tmp = gen_int_mode (0x80000000, SImode);
9802           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9803         }
9804     }
9805   operands[1] = tmp;
9806 })
9807
9808 (define_split
9809   [(set (match_operand:XF 0 "register_operand" "")
9810         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9811    (use (match_operand 2 "" ""))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "reload_completed"
9814   [(parallel [(set (match_dup 0) (match_dup 1))
9815               (clobber (reg:CC FLAGS_REG))])]
9816 {
9817   rtx tmp;
9818   operands[0] = gen_rtx_REG (SImode,
9819                              true_regnum (operands[0])
9820                              + (TARGET_64BIT ? 1 : 2));
9821   if (GET_CODE (operands[1]) == ABS)
9822     {
9823       tmp = GEN_INT (0x7fff);
9824       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9825     }
9826   else
9827     {
9828       tmp = GEN_INT (0x8000);
9829       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9830     }
9831   operands[1] = tmp;
9832 })
9833
9834 (define_split
9835   [(set (match_operand 0 "memory_operand" "")
9836         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9837    (use (match_operand 2 "" ""))
9838    (clobber (reg:CC FLAGS_REG))]
9839   "reload_completed"
9840   [(parallel [(set (match_dup 0) (match_dup 1))
9841               (clobber (reg:CC FLAGS_REG))])]
9842 {
9843   enum machine_mode mode = GET_MODE (operands[0]);
9844   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9845   rtx tmp;
9846
9847   operands[0] = adjust_address (operands[0], QImode, size - 1);
9848   if (GET_CODE (operands[1]) == ABS)
9849     {
9850       tmp = gen_int_mode (0x7f, QImode);
9851       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9852     }
9853   else
9854     {
9855       tmp = gen_int_mode (0x80, QImode);
9856       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9857     }
9858   operands[1] = tmp;
9859 })
9860
9861 ;; Conditionalize these after reload. If they match before reload, we 
9862 ;; lose the clobber and ability to use integer instructions.
9863
9864 (define_insn "*negsf2_1"
9865   [(set (match_operand:SF 0 "register_operand" "=f")
9866         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9867   "TARGET_80387 && reload_completed"
9868   "fchs"
9869   [(set_attr "type" "fsgn")
9870    (set_attr "mode" "SF")])
9871
9872 (define_insn "*negdf2_1"
9873   [(set (match_operand:DF 0 "register_operand" "=f")
9874         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9875   "TARGET_80387 && reload_completed"
9876   "fchs"
9877   [(set_attr "type" "fsgn")
9878    (set_attr "mode" "DF")])
9879
9880 (define_insn "*negxf2_1"
9881   [(set (match_operand:XF 0 "register_operand" "=f")
9882         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9883   "TARGET_80387 && reload_completed"
9884   "fchs"
9885   [(set_attr "type" "fsgn")
9886    (set_attr "mode" "XF")])
9887
9888 (define_insn "*abssf2_1"
9889   [(set (match_operand:SF 0 "register_operand" "=f")
9890         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9891   "TARGET_80387 && reload_completed"
9892   "fabs"
9893   [(set_attr "type" "fsgn")
9894    (set_attr "mode" "SF")])
9895
9896 (define_insn "*absdf2_1"
9897   [(set (match_operand:DF 0 "register_operand" "=f")
9898         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9899   "TARGET_80387 && reload_completed"
9900   "fabs"
9901   [(set_attr "type" "fsgn")
9902    (set_attr "mode" "DF")])
9903
9904 (define_insn "*absxf2_1"
9905   [(set (match_operand:XF 0 "register_operand" "=f")
9906         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9907   "TARGET_80387 && reload_completed"
9908   "fabs"
9909   [(set_attr "type" "fsgn")
9910    (set_attr "mode" "DF")])
9911
9912 (define_insn "*negextendsfdf2"
9913   [(set (match_operand:DF 0 "register_operand" "=f")
9914         (neg:DF (float_extend:DF
9915                   (match_operand:SF 1 "register_operand" "0"))))]
9916   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9917   "fchs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "DF")])
9920
9921 (define_insn "*negextenddfxf2"
9922   [(set (match_operand:XF 0 "register_operand" "=f")
9923         (neg:XF (float_extend:XF
9924                   (match_operand:DF 1 "register_operand" "0"))))]
9925   "TARGET_80387"
9926   "fchs"
9927   [(set_attr "type" "fsgn")
9928    (set_attr "mode" "XF")])
9929
9930 (define_insn "*negextendsfxf2"
9931   [(set (match_operand:XF 0 "register_operand" "=f")
9932         (neg:XF (float_extend:XF
9933                   (match_operand:SF 1 "register_operand" "0"))))]
9934   "TARGET_80387"
9935   "fchs"
9936   [(set_attr "type" "fsgn")
9937    (set_attr "mode" "XF")])
9938
9939 (define_insn "*absextendsfdf2"
9940   [(set (match_operand:DF 0 "register_operand" "=f")
9941         (abs:DF (float_extend:DF
9942                   (match_operand:SF 1 "register_operand" "0"))))]
9943   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9944   "fabs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "DF")])
9947
9948 (define_insn "*absextenddfxf2"
9949   [(set (match_operand:XF 0 "register_operand" "=f")
9950         (abs:XF (float_extend:XF
9951           (match_operand:DF 1 "register_operand" "0"))))]
9952   "TARGET_80387"
9953   "fabs"
9954   [(set_attr "type" "fsgn")
9955    (set_attr "mode" "XF")])
9956
9957 (define_insn "*absextendsfxf2"
9958   [(set (match_operand:XF 0 "register_operand" "=f")
9959         (abs:XF (float_extend:XF
9960           (match_operand:SF 1 "register_operand" "0"))))]
9961   "TARGET_80387"
9962   "fabs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")])
9965 \f
9966 ;; One complement instructions
9967
9968 (define_expand "one_cmpldi2"
9969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9970         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9971   "TARGET_64BIT"
9972   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9973
9974 (define_insn "*one_cmpldi2_1_rex64"
9975   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9976         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9977   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9978   "not{q}\t%0"
9979   [(set_attr "type" "negnot")
9980    (set_attr "mode" "DI")])
9981
9982 (define_insn "*one_cmpldi2_2_rex64"
9983   [(set (reg FLAGS_REG)
9984         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9985                  (const_int 0)))
9986    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9987         (not:DI (match_dup 1)))]
9988   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9989    && ix86_unary_operator_ok (NOT, DImode, operands)"
9990   "#"
9991   [(set_attr "type" "alu1")
9992    (set_attr "mode" "DI")])
9993
9994 (define_split
9995   [(set (match_operand 0 "flags_reg_operand" "")
9996         (match_operator 2 "compare_operator"
9997           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9998            (const_int 0)]))
9999    (set (match_operand:DI 1 "nonimmediate_operand" "")
10000         (not:DI (match_dup 3)))]
10001   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10002   [(parallel [(set (match_dup 0)
10003                    (match_op_dup 2
10004                      [(xor:DI (match_dup 3) (const_int -1))
10005                       (const_int 0)]))
10006               (set (match_dup 1)
10007                    (xor:DI (match_dup 3) (const_int -1)))])]
10008   "")
10009
10010 (define_expand "one_cmplsi2"
10011   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10012         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10013   ""
10014   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10015
10016 (define_insn "*one_cmplsi2_1"
10017   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10018         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10019   "ix86_unary_operator_ok (NOT, SImode, operands)"
10020   "not{l}\t%0"
10021   [(set_attr "type" "negnot")
10022    (set_attr "mode" "SI")])
10023
10024 ;; ??? Currently never generated - xor is used instead.
10025 (define_insn "*one_cmplsi2_1_zext"
10026   [(set (match_operand:DI 0 "register_operand" "=r")
10027         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10028   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10029   "not{l}\t%k0"
10030   [(set_attr "type" "negnot")
10031    (set_attr "mode" "SI")])
10032
10033 (define_insn "*one_cmplsi2_2"
10034   [(set (reg FLAGS_REG)
10035         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10036                  (const_int 0)))
10037    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10038         (not:SI (match_dup 1)))]
10039   "ix86_match_ccmode (insn, CCNOmode)
10040    && ix86_unary_operator_ok (NOT, SImode, operands)"
10041   "#"
10042   [(set_attr "type" "alu1")
10043    (set_attr "mode" "SI")])
10044
10045 (define_split
10046   [(set (match_operand 0 "flags_reg_operand" "")
10047         (match_operator 2 "compare_operator"
10048           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10049            (const_int 0)]))
10050    (set (match_operand:SI 1 "nonimmediate_operand" "")
10051         (not:SI (match_dup 3)))]
10052   "ix86_match_ccmode (insn, CCNOmode)"
10053   [(parallel [(set (match_dup 0)
10054                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10055                                     (const_int 0)]))
10056               (set (match_dup 1)
10057                    (xor:SI (match_dup 3) (const_int -1)))])]
10058   "")
10059
10060 ;; ??? Currently never generated - xor is used instead.
10061 (define_insn "*one_cmplsi2_2_zext"
10062   [(set (reg FLAGS_REG)
10063         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10064                  (const_int 0)))
10065    (set (match_operand:DI 0 "register_operand" "=r")
10066         (zero_extend:DI (not:SI (match_dup 1))))]
10067   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10068    && ix86_unary_operator_ok (NOT, SImode, operands)"
10069   "#"
10070   [(set_attr "type" "alu1")
10071    (set_attr "mode" "SI")])
10072
10073 (define_split
10074   [(set (match_operand 0 "flags_reg_operand" "")
10075         (match_operator 2 "compare_operator"
10076           [(not:SI (match_operand:SI 3 "register_operand" ""))
10077            (const_int 0)]))
10078    (set (match_operand:DI 1 "register_operand" "")
10079         (zero_extend:DI (not:SI (match_dup 3))))]
10080   "ix86_match_ccmode (insn, CCNOmode)"
10081   [(parallel [(set (match_dup 0)
10082                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10083                                     (const_int 0)]))
10084               (set (match_dup 1)
10085                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10086   "")
10087
10088 (define_expand "one_cmplhi2"
10089   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10090         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10091   "TARGET_HIMODE_MATH"
10092   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10093
10094 (define_insn "*one_cmplhi2_1"
10095   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10096         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10097   "ix86_unary_operator_ok (NOT, HImode, operands)"
10098   "not{w}\t%0"
10099   [(set_attr "type" "negnot")
10100    (set_attr "mode" "HI")])
10101
10102 (define_insn "*one_cmplhi2_2"
10103   [(set (reg FLAGS_REG)
10104         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10105                  (const_int 0)))
10106    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10107         (not:HI (match_dup 1)))]
10108   "ix86_match_ccmode (insn, CCNOmode)
10109    && ix86_unary_operator_ok (NEG, HImode, operands)"
10110   "#"
10111   [(set_attr "type" "alu1")
10112    (set_attr "mode" "HI")])
10113
10114 (define_split
10115   [(set (match_operand 0 "flags_reg_operand" "")
10116         (match_operator 2 "compare_operator"
10117           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10118            (const_int 0)]))
10119    (set (match_operand:HI 1 "nonimmediate_operand" "")
10120         (not:HI (match_dup 3)))]
10121   "ix86_match_ccmode (insn, CCNOmode)"
10122   [(parallel [(set (match_dup 0)
10123                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10124                                     (const_int 0)]))
10125               (set (match_dup 1)
10126                    (xor:HI (match_dup 3) (const_int -1)))])]
10127   "")
10128
10129 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10130 (define_expand "one_cmplqi2"
10131   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10132         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10133   "TARGET_QIMODE_MATH"
10134   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10135
10136 (define_insn "*one_cmplqi2_1"
10137   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10138         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10139   "ix86_unary_operator_ok (NOT, QImode, operands)"
10140   "@
10141    not{b}\t%0
10142    not{l}\t%k0"
10143   [(set_attr "type" "negnot")
10144    (set_attr "mode" "QI,SI")])
10145
10146 (define_insn "*one_cmplqi2_2"
10147   [(set (reg FLAGS_REG)
10148         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10149                  (const_int 0)))
10150    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10151         (not:QI (match_dup 1)))]
10152   "ix86_match_ccmode (insn, CCNOmode)
10153    && ix86_unary_operator_ok (NOT, QImode, operands)"
10154   "#"
10155   [(set_attr "type" "alu1")
10156    (set_attr "mode" "QI")])
10157
10158 (define_split
10159   [(set (match_operand 0 "flags_reg_operand" "")
10160         (match_operator 2 "compare_operator"
10161           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10162            (const_int 0)]))
10163    (set (match_operand:QI 1 "nonimmediate_operand" "")
10164         (not:QI (match_dup 3)))]
10165   "ix86_match_ccmode (insn, CCNOmode)"
10166   [(parallel [(set (match_dup 0)
10167                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10168                                     (const_int 0)]))
10169               (set (match_dup 1)
10170                    (xor:QI (match_dup 3) (const_int -1)))])]
10171   "")
10172 \f
10173 ;; Arithmetic shift instructions
10174
10175 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10176 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10177 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10178 ;; from the assembler input.
10179 ;;
10180 ;; This instruction shifts the target reg/mem as usual, but instead of
10181 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10182 ;; is a left shift double, bits are taken from the high order bits of
10183 ;; reg, else if the insn is a shift right double, bits are taken from the
10184 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10185 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10186 ;;
10187 ;; Since sh[lr]d does not change the `reg' operand, that is done
10188 ;; separately, making all shifts emit pairs of shift double and normal
10189 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10190 ;; support a 63 bit shift, each shift where the count is in a reg expands
10191 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10192 ;;
10193 ;; If the shift count is a constant, we need never emit more than one
10194 ;; shift pair, instead using moves and sign extension for counts greater
10195 ;; than 31.
10196
10197 (define_expand "ashlti3"
10198   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10199                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10200                               (match_operand:QI 2 "nonmemory_operand" "")))
10201               (clobber (reg:CC FLAGS_REG))])]
10202   "TARGET_64BIT"
10203 {
10204   if (! immediate_operand (operands[2], QImode))
10205     {
10206       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10207       DONE;
10208     }
10209   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10210   DONE;
10211 })
10212
10213 (define_insn "ashlti3_1"
10214   [(set (match_operand:TI 0 "register_operand" "=r")
10215         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10216                    (match_operand:QI 2 "register_operand" "c")))
10217    (clobber (match_scratch:DI 3 "=&r"))
10218    (clobber (reg:CC FLAGS_REG))]
10219   "TARGET_64BIT"
10220   "#"
10221   [(set_attr "type" "multi")])
10222
10223 (define_insn "*ashlti3_2"
10224   [(set (match_operand:TI 0 "register_operand" "=r")
10225         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10226                    (match_operand:QI 2 "immediate_operand" "O")))
10227    (clobber (reg:CC FLAGS_REG))]
10228   "TARGET_64BIT"
10229   "#"
10230   [(set_attr "type" "multi")])
10231
10232 (define_split
10233   [(set (match_operand:TI 0 "register_operand" "")
10234         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10235                    (match_operand:QI 2 "register_operand" "")))
10236    (clobber (match_scratch:DI 3 ""))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "TARGET_64BIT && reload_completed"
10239   [(const_int 0)]
10240   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10241
10242 (define_split
10243   [(set (match_operand:TI 0 "register_operand" "")
10244         (ashift:TI (match_operand:TI 1 "register_operand" "")
10245                    (match_operand:QI 2 "immediate_operand" "")))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "TARGET_64BIT && reload_completed"
10248   [(const_int 0)]
10249   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10250
10251 (define_insn "x86_64_shld"
10252   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10253         (ior:DI (ashift:DI (match_dup 0)
10254                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10255                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10256                   (minus:QI (const_int 64) (match_dup 2)))))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "TARGET_64BIT"
10259   "@
10260    shld{q}\t{%2, %1, %0|%0, %1, %2}
10261    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10262   [(set_attr "type" "ishift")
10263    (set_attr "prefix_0f" "1")
10264    (set_attr "mode" "DI")
10265    (set_attr "athlon_decode" "vector")])
10266
10267 (define_expand "x86_64_shift_adj"
10268   [(set (reg:CCZ FLAGS_REG)
10269         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10270                              (const_int 64))
10271                      (const_int 0)))
10272    (set (match_operand:DI 0 "register_operand" "")
10273         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10274                          (match_operand:DI 1 "register_operand" "")
10275                          (match_dup 0)))
10276    (set (match_dup 1)
10277         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10278                          (match_operand:DI 3 "register_operand" "r")
10279                          (match_dup 1)))]
10280   "TARGET_64BIT"
10281   "")
10282
10283 (define_expand "ashldi3"
10284   [(set (match_operand:DI 0 "shiftdi_operand" "")
10285         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10286                    (match_operand:QI 2 "nonmemory_operand" "")))]
10287   ""
10288   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10289
10290 (define_insn "*ashldi3_1_rex64"
10291   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10292         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10293                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10294    (clobber (reg:CC FLAGS_REG))]
10295   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10296 {
10297   switch (get_attr_type (insn))
10298     {
10299     case TYPE_ALU:
10300       gcc_assert (operands[2] == const1_rtx);
10301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10302       return "add{q}\t{%0, %0|%0, %0}";
10303
10304     case TYPE_LEA:
10305       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10306       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10307       operands[1] = gen_rtx_MULT (DImode, operands[1],
10308                                   GEN_INT (1 << INTVAL (operands[2])));
10309       return "lea{q}\t{%a1, %0|%0, %a1}";
10310
10311     default:
10312       if (REG_P (operands[2]))
10313         return "sal{q}\t{%b2, %0|%0, %b2}";
10314       else if (operands[2] == const1_rtx
10315                && (TARGET_SHIFT1 || optimize_size))
10316         return "sal{q}\t%0";
10317       else
10318         return "sal{q}\t{%2, %0|%0, %2}";
10319     }
10320 }
10321   [(set (attr "type")
10322      (cond [(eq_attr "alternative" "1")
10323               (const_string "lea")
10324             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10325                           (const_int 0))
10326                       (match_operand 0 "register_operand" ""))
10327                  (match_operand 2 "const1_operand" ""))
10328               (const_string "alu")
10329            ]
10330            (const_string "ishift")))
10331    (set_attr "mode" "DI")])
10332
10333 ;; Convert lea to the lea pattern to avoid flags dependency.
10334 (define_split
10335   [(set (match_operand:DI 0 "register_operand" "")
10336         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10337                    (match_operand:QI 2 "immediate_operand" "")))
10338    (clobber (reg:CC FLAGS_REG))]
10339   "TARGET_64BIT && reload_completed
10340    && true_regnum (operands[0]) != true_regnum (operands[1])"
10341   [(set (match_dup 0)
10342         (mult:DI (match_dup 1)
10343                  (match_dup 2)))]
10344   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10345
10346 ;; This pattern can't accept a variable shift count, since shifts by
10347 ;; zero don't affect the flags.  We assume that shifts by constant
10348 ;; zero are optimized away.
10349 (define_insn "*ashldi3_cmp_rex64"
10350   [(set (reg FLAGS_REG)
10351         (compare
10352           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10353                      (match_operand:QI 2 "immediate_operand" "e"))
10354           (const_int 0)))
10355    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10356         (ashift:DI (match_dup 1) (match_dup 2)))]
10357   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10358    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10359 {
10360   switch (get_attr_type (insn))
10361     {
10362     case TYPE_ALU:
10363       gcc_assert (operands[2] == const1_rtx);
10364       return "add{q}\t{%0, %0|%0, %0}";
10365
10366     default:
10367       if (REG_P (operands[2]))
10368         return "sal{q}\t{%b2, %0|%0, %b2}";
10369       else if (operands[2] == const1_rtx
10370                && (TARGET_SHIFT1 || optimize_size))
10371         return "sal{q}\t%0";
10372       else
10373         return "sal{q}\t{%2, %0|%0, %2}";
10374     }
10375 }
10376   [(set (attr "type")
10377      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10378                           (const_int 0))
10379                       (match_operand 0 "register_operand" ""))
10380                  (match_operand 2 "const1_operand" ""))
10381               (const_string "alu")
10382            ]
10383            (const_string "ishift")))
10384    (set_attr "mode" "DI")])
10385
10386 (define_insn "*ashldi3_1"
10387   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10388         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10389                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "!TARGET_64BIT"
10392   "#"
10393   [(set_attr "type" "multi")])
10394
10395 ;; By default we don't ask for a scratch register, because when DImode
10396 ;; values are manipulated, registers are already at a premium.  But if
10397 ;; we have one handy, we won't turn it away.
10398 (define_peephole2
10399   [(match_scratch:SI 3 "r")
10400    (parallel [(set (match_operand:DI 0 "register_operand" "")
10401                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10402                               (match_operand:QI 2 "nonmemory_operand" "")))
10403               (clobber (reg:CC FLAGS_REG))])
10404    (match_dup 3)]
10405   "!TARGET_64BIT && TARGET_CMOVE"
10406   [(const_int 0)]
10407   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10408
10409 (define_split
10410   [(set (match_operand:DI 0 "register_operand" "")
10411         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10412                    (match_operand:QI 2 "nonmemory_operand" "")))
10413    (clobber (reg:CC FLAGS_REG))]
10414   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10415                      ? flow2_completed : reload_completed)"
10416   [(const_int 0)]
10417   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10418
10419 (define_insn "x86_shld_1"
10420   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10421         (ior:SI (ashift:SI (match_dup 0)
10422                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10423                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10424                   (minus:QI (const_int 32) (match_dup 2)))))
10425    (clobber (reg:CC FLAGS_REG))]
10426   ""
10427   "@
10428    shld{l}\t{%2, %1, %0|%0, %1, %2}
10429    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10430   [(set_attr "type" "ishift")
10431    (set_attr "prefix_0f" "1")
10432    (set_attr "mode" "SI")
10433    (set_attr "pent_pair" "np")
10434    (set_attr "athlon_decode" "vector")])
10435
10436 (define_expand "x86_shift_adj_1"
10437   [(set (reg:CCZ FLAGS_REG)
10438         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10439                              (const_int 32))
10440                      (const_int 0)))
10441    (set (match_operand:SI 0 "register_operand" "")
10442         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10443                          (match_operand:SI 1 "register_operand" "")
10444                          (match_dup 0)))
10445    (set (match_dup 1)
10446         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10447                          (match_operand:SI 3 "register_operand" "r")
10448                          (match_dup 1)))]
10449   "TARGET_CMOVE"
10450   "")
10451
10452 (define_expand "x86_shift_adj_2"
10453   [(use (match_operand:SI 0 "register_operand" ""))
10454    (use (match_operand:SI 1 "register_operand" ""))
10455    (use (match_operand:QI 2 "register_operand" ""))]
10456   ""
10457 {
10458   rtx label = gen_label_rtx ();
10459   rtx tmp;
10460
10461   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10462
10463   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10464   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10465   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10466                               gen_rtx_LABEL_REF (VOIDmode, label),
10467                               pc_rtx);
10468   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10469   JUMP_LABEL (tmp) = label;
10470
10471   emit_move_insn (operands[0], operands[1]);
10472   ix86_expand_clear (operands[1]);
10473
10474   emit_label (label);
10475   LABEL_NUSES (label) = 1;
10476
10477   DONE;
10478 })
10479
10480 (define_expand "ashlsi3"
10481   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10482         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10483                    (match_operand:QI 2 "nonmemory_operand" "")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   ""
10486   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10487
10488 (define_insn "*ashlsi3_1"
10489   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10490         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10491                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10492    (clobber (reg:CC FLAGS_REG))]
10493   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10494 {
10495   switch (get_attr_type (insn))
10496     {
10497     case TYPE_ALU:
10498       gcc_assert (operands[2] == const1_rtx);
10499       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10500       return "add{l}\t{%0, %0|%0, %0}";
10501
10502     case TYPE_LEA:
10503       return "#";
10504
10505     default:
10506       if (REG_P (operands[2]))
10507         return "sal{l}\t{%b2, %0|%0, %b2}";
10508       else if (operands[2] == const1_rtx
10509                && (TARGET_SHIFT1 || optimize_size))
10510         return "sal{l}\t%0";
10511       else
10512         return "sal{l}\t{%2, %0|%0, %2}";
10513     }
10514 }
10515   [(set (attr "type")
10516      (cond [(eq_attr "alternative" "1")
10517               (const_string "lea")
10518             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10519                           (const_int 0))
10520                       (match_operand 0 "register_operand" ""))
10521                  (match_operand 2 "const1_operand" ""))
10522               (const_string "alu")
10523            ]
10524            (const_string "ishift")))
10525    (set_attr "mode" "SI")])
10526
10527 ;; Convert lea to the lea pattern to avoid flags dependency.
10528 (define_split
10529   [(set (match_operand 0 "register_operand" "")
10530         (ashift (match_operand 1 "index_register_operand" "")
10531                 (match_operand:QI 2 "const_int_operand" "")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "reload_completed
10534    && true_regnum (operands[0]) != true_regnum (operands[1])
10535    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10536   [(const_int 0)]
10537 {
10538   rtx pat;
10539   enum machine_mode mode = GET_MODE (operands[0]);
10540
10541   if (GET_MODE_SIZE (mode) < 4)
10542     operands[0] = gen_lowpart (SImode, operands[0]);
10543   if (mode != Pmode)
10544     operands[1] = gen_lowpart (Pmode, operands[1]);
10545   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10546
10547   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10548   if (Pmode != SImode)
10549     pat = gen_rtx_SUBREG (SImode, pat, 0);
10550   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10551   DONE;
10552 })
10553
10554 ;; Rare case of shifting RSP is handled by generating move and shift
10555 (define_split
10556   [(set (match_operand 0 "register_operand" "")
10557         (ashift (match_operand 1 "register_operand" "")
10558                 (match_operand:QI 2 "const_int_operand" "")))
10559    (clobber (reg:CC FLAGS_REG))]
10560   "reload_completed
10561    && true_regnum (operands[0]) != true_regnum (operands[1])"
10562   [(const_int 0)]
10563 {
10564   rtx pat, clob;
10565   emit_move_insn (operands[1], operands[0]);
10566   pat = gen_rtx_SET (VOIDmode, operands[0],
10567                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10568                                      operands[0], operands[2]));
10569   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10570   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10571   DONE;
10572 })
10573
10574 (define_insn "*ashlsi3_1_zext"
10575   [(set (match_operand:DI 0 "register_operand" "=r,r")
10576         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10577                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10578    (clobber (reg:CC FLAGS_REG))]
10579   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10580 {
10581   switch (get_attr_type (insn))
10582     {
10583     case TYPE_ALU:
10584       gcc_assert (operands[2] == const1_rtx);
10585       return "add{l}\t{%k0, %k0|%k0, %k0}";
10586
10587     case TYPE_LEA:
10588       return "#";
10589
10590     default:
10591       if (REG_P (operands[2]))
10592         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10593       else if (operands[2] == const1_rtx
10594                && (TARGET_SHIFT1 || optimize_size))
10595         return "sal{l}\t%k0";
10596       else
10597         return "sal{l}\t{%2, %k0|%k0, %2}";
10598     }
10599 }
10600   [(set (attr "type")
10601      (cond [(eq_attr "alternative" "1")
10602               (const_string "lea")
10603             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604                      (const_int 0))
10605                  (match_operand 2 "const1_operand" ""))
10606               (const_string "alu")
10607            ]
10608            (const_string "ishift")))
10609    (set_attr "mode" "SI")])
10610
10611 ;; Convert lea to the lea pattern to avoid flags dependency.
10612 (define_split
10613   [(set (match_operand:DI 0 "register_operand" "")
10614         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10615                                 (match_operand:QI 2 "const_int_operand" ""))))
10616    (clobber (reg:CC FLAGS_REG))]
10617   "TARGET_64BIT && reload_completed
10618    && true_regnum (operands[0]) != true_regnum (operands[1])"
10619   [(set (match_dup 0) (zero_extend:DI
10620                         (subreg:SI (mult:SI (match_dup 1)
10621                                             (match_dup 2)) 0)))]
10622 {
10623   operands[1] = gen_lowpart (Pmode, operands[1]);
10624   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10625 })
10626
10627 ;; This pattern can't accept a variable shift count, since shifts by
10628 ;; zero don't affect the flags.  We assume that shifts by constant
10629 ;; zero are optimized away.
10630 (define_insn "*ashlsi3_cmp"
10631   [(set (reg FLAGS_REG)
10632         (compare
10633           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10634                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10635           (const_int 0)))
10636    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10637         (ashift:SI (match_dup 1) (match_dup 2)))]
10638   "ix86_match_ccmode (insn, CCGOCmode)
10639    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10640 {
10641   switch (get_attr_type (insn))
10642     {
10643     case TYPE_ALU:
10644       gcc_assert (operands[2] == const1_rtx);
10645       return "add{l}\t{%0, %0|%0, %0}";
10646
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{l}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{l}\t%0";
10653       else
10654         return "sal{l}\t{%2, %0|%0, %2}";
10655     }
10656 }
10657   [(set (attr "type")
10658      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659                           (const_int 0))
10660                       (match_operand 0 "register_operand" ""))
10661                  (match_operand 2 "const1_operand" ""))
10662               (const_string "alu")
10663            ]
10664            (const_string "ishift")))
10665    (set_attr "mode" "SI")])
10666
10667 (define_insn "*ashlsi3_cmp_zext"
10668   [(set (reg FLAGS_REG)
10669         (compare
10670           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10671                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10672           (const_int 0)))
10673    (set (match_operand:DI 0 "register_operand" "=r")
10674         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10675   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10676    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10677 {
10678   switch (get_attr_type (insn))
10679     {
10680     case TYPE_ALU:
10681       gcc_assert (operands[2] == const1_rtx);
10682       return "add{l}\t{%k0, %k0|%k0, %k0}";
10683
10684     default:
10685       if (REG_P (operands[2]))
10686         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10687       else if (operands[2] == const1_rtx
10688                && (TARGET_SHIFT1 || optimize_size))
10689         return "sal{l}\t%k0";
10690       else
10691         return "sal{l}\t{%2, %k0|%k0, %2}";
10692     }
10693 }
10694   [(set (attr "type")
10695      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10696                      (const_int 0))
10697                  (match_operand 2 "const1_operand" ""))
10698               (const_string "alu")
10699            ]
10700            (const_string "ishift")))
10701    (set_attr "mode" "SI")])
10702
10703 (define_expand "ashlhi3"
10704   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10705         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10706                    (match_operand:QI 2 "nonmemory_operand" "")))
10707    (clobber (reg:CC FLAGS_REG))]
10708   "TARGET_HIMODE_MATH"
10709   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10710
10711 (define_insn "*ashlhi3_1_lea"
10712   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10713         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10714                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10715    (clobber (reg:CC FLAGS_REG))]
10716   "!TARGET_PARTIAL_REG_STALL
10717    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10718 {
10719   switch (get_attr_type (insn))
10720     {
10721     case TYPE_LEA:
10722       return "#";
10723     case TYPE_ALU:
10724       gcc_assert (operands[2] == const1_rtx);
10725       return "add{w}\t{%0, %0|%0, %0}";
10726
10727     default:
10728       if (REG_P (operands[2]))
10729         return "sal{w}\t{%b2, %0|%0, %b2}";
10730       else if (operands[2] == const1_rtx
10731                && (TARGET_SHIFT1 || optimize_size))
10732         return "sal{w}\t%0";
10733       else
10734         return "sal{w}\t{%2, %0|%0, %2}";
10735     }
10736 }
10737   [(set (attr "type")
10738      (cond [(eq_attr "alternative" "1")
10739               (const_string "lea")
10740             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10741                           (const_int 0))
10742                       (match_operand 0 "register_operand" ""))
10743                  (match_operand 2 "const1_operand" ""))
10744               (const_string "alu")
10745            ]
10746            (const_string "ishift")))
10747    (set_attr "mode" "HI,SI")])
10748
10749 (define_insn "*ashlhi3_1"
10750   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10751         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10752                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10753    (clobber (reg:CC FLAGS_REG))]
10754   "TARGET_PARTIAL_REG_STALL
10755    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10756 {
10757   switch (get_attr_type (insn))
10758     {
10759     case TYPE_ALU:
10760       gcc_assert (operands[2] == const1_rtx);
10761       return "add{w}\t{%0, %0|%0, %0}";
10762
10763     default:
10764       if (REG_P (operands[2]))
10765         return "sal{w}\t{%b2, %0|%0, %b2}";
10766       else if (operands[2] == const1_rtx
10767                && (TARGET_SHIFT1 || optimize_size))
10768         return "sal{w}\t%0";
10769       else
10770         return "sal{w}\t{%2, %0|%0, %2}";
10771     }
10772 }
10773   [(set (attr "type")
10774      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10775                           (const_int 0))
10776                       (match_operand 0 "register_operand" ""))
10777                  (match_operand 2 "const1_operand" ""))
10778               (const_string "alu")
10779            ]
10780            (const_string "ishift")))
10781    (set_attr "mode" "HI")])
10782
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags.  We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashlhi3_cmp"
10787   [(set (reg FLAGS_REG)
10788         (compare
10789           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10790                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10791           (const_int 0)))
10792    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10793         (ashift:HI (match_dup 1) (match_dup 2)))]
10794   "ix86_match_ccmode (insn, CCGOCmode)
10795    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10796 {
10797   switch (get_attr_type (insn))
10798     {
10799     case TYPE_ALU:
10800       gcc_assert (operands[2] == const1_rtx);
10801       return "add{w}\t{%0, %0|%0, %0}";
10802
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{w}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_size))
10808         return "sal{w}\t%0";
10809       else
10810         return "sal{w}\t{%2, %0|%0, %2}";
10811     }
10812 }
10813   [(set (attr "type")
10814      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10815                           (const_int 0))
10816                       (match_operand 0 "register_operand" ""))
10817                  (match_operand 2 "const1_operand" ""))
10818               (const_string "alu")
10819            ]
10820            (const_string "ishift")))
10821    (set_attr "mode" "HI")])
10822
10823 (define_expand "ashlqi3"
10824   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10825         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10826                    (match_operand:QI 2 "nonmemory_operand" "")))
10827    (clobber (reg:CC FLAGS_REG))]
10828   "TARGET_QIMODE_MATH"
10829   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10830
10831 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10832
10833 (define_insn "*ashlqi3_1_lea"
10834   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10835         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10836                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10837    (clobber (reg:CC FLAGS_REG))]
10838   "!TARGET_PARTIAL_REG_STALL
10839    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10840 {
10841   switch (get_attr_type (insn))
10842     {
10843     case TYPE_LEA:
10844       return "#";
10845     case TYPE_ALU:
10846       gcc_assert (operands[2] == const1_rtx);
10847       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10848         return "add{l}\t{%k0, %k0|%k0, %k0}";
10849       else
10850         return "add{b}\t{%0, %0|%0, %0}";
10851
10852     default:
10853       if (REG_P (operands[2]))
10854         {
10855           if (get_attr_mode (insn) == MODE_SI)
10856             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10857           else
10858             return "sal{b}\t{%b2, %0|%0, %b2}";
10859         }
10860       else if (operands[2] == const1_rtx
10861                && (TARGET_SHIFT1 || optimize_size))
10862         {
10863           if (get_attr_mode (insn) == MODE_SI)
10864             return "sal{l}\t%0";
10865           else
10866             return "sal{b}\t%0";
10867         }
10868       else
10869         {
10870           if (get_attr_mode (insn) == MODE_SI)
10871             return "sal{l}\t{%2, %k0|%k0, %2}";
10872           else
10873             return "sal{b}\t{%2, %0|%0, %2}";
10874         }
10875     }
10876 }
10877   [(set (attr "type")
10878      (cond [(eq_attr "alternative" "2")
10879               (const_string "lea")
10880             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10881                           (const_int 0))
10882                       (match_operand 0 "register_operand" ""))
10883                  (match_operand 2 "const1_operand" ""))
10884               (const_string "alu")
10885            ]
10886            (const_string "ishift")))
10887    (set_attr "mode" "QI,SI,SI")])
10888
10889 (define_insn "*ashlqi3_1"
10890   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10891         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10892                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10893    (clobber (reg:CC FLAGS_REG))]
10894   "TARGET_PARTIAL_REG_STALL
10895    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10896 {
10897   switch (get_attr_type (insn))
10898     {
10899     case TYPE_ALU:
10900       gcc_assert (operands[2] == const1_rtx);
10901       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10902         return "add{l}\t{%k0, %k0|%k0, %k0}";
10903       else
10904         return "add{b}\t{%0, %0|%0, %0}";
10905
10906     default:
10907       if (REG_P (operands[2]))
10908         {
10909           if (get_attr_mode (insn) == MODE_SI)
10910             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10911           else
10912             return "sal{b}\t{%b2, %0|%0, %b2}";
10913         }
10914       else if (operands[2] == const1_rtx
10915                && (TARGET_SHIFT1 || optimize_size))
10916         {
10917           if (get_attr_mode (insn) == MODE_SI)
10918             return "sal{l}\t%0";
10919           else
10920             return "sal{b}\t%0";
10921         }
10922       else
10923         {
10924           if (get_attr_mode (insn) == MODE_SI)
10925             return "sal{l}\t{%2, %k0|%k0, %2}";
10926           else
10927             return "sal{b}\t{%2, %0|%0, %2}";
10928         }
10929     }
10930 }
10931   [(set (attr "type")
10932      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10933                           (const_int 0))
10934                       (match_operand 0 "register_operand" ""))
10935                  (match_operand 2 "const1_operand" ""))
10936               (const_string "alu")
10937            ]
10938            (const_string "ishift")))
10939    (set_attr "mode" "QI,SI")])
10940
10941 ;; This pattern can't accept a variable shift count, since shifts by
10942 ;; zero don't affect the flags.  We assume that shifts by constant
10943 ;; zero are optimized away.
10944 (define_insn "*ashlqi3_cmp"
10945   [(set (reg FLAGS_REG)
10946         (compare
10947           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10948                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10949           (const_int 0)))
10950    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10951         (ashift:QI (match_dup 1) (match_dup 2)))]
10952   "ix86_match_ccmode (insn, CCGOCmode)
10953    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10954 {
10955   switch (get_attr_type (insn))
10956     {
10957     case TYPE_ALU:
10958       gcc_assert (operands[2] == const1_rtx);
10959       return "add{b}\t{%0, %0|%0, %0}";
10960
10961     default:
10962       if (REG_P (operands[2]))
10963         return "sal{b}\t{%b2, %0|%0, %b2}";
10964       else if (operands[2] == const1_rtx
10965                && (TARGET_SHIFT1 || optimize_size))
10966         return "sal{b}\t%0";
10967       else
10968         return "sal{b}\t{%2, %0|%0, %2}";
10969     }
10970 }
10971   [(set (attr "type")
10972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973                           (const_int 0))
10974                       (match_operand 0 "register_operand" ""))
10975                  (match_operand 2 "const1_operand" ""))
10976               (const_string "alu")
10977            ]
10978            (const_string "ishift")))
10979    (set_attr "mode" "QI")])
10980
10981 ;; See comment above `ashldi3' about how this works.
10982
10983 (define_expand "ashrti3"
10984   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10985                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10986                                 (match_operand:QI 2 "nonmemory_operand" "")))
10987               (clobber (reg:CC FLAGS_REG))])]
10988   "TARGET_64BIT"
10989 {
10990   if (! immediate_operand (operands[2], QImode))
10991     {
10992       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10993       DONE;
10994     }
10995   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
10996   DONE;
10997 })
10998
10999 (define_insn "ashrti3_1"
11000   [(set (match_operand:TI 0 "register_operand" "=r")
11001         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11002                      (match_operand:QI 2 "register_operand" "c")))
11003    (clobber (match_scratch:DI 3 "=&r"))
11004    (clobber (reg:CC FLAGS_REG))]
11005   "TARGET_64BIT"
11006   "#"
11007   [(set_attr "type" "multi")])
11008
11009 (define_insn "*ashrti3_2"
11010   [(set (match_operand:TI 0 "register_operand" "=r")
11011         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11012                      (match_operand:QI 2 "immediate_operand" "O")))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "TARGET_64BIT"
11015   "#"
11016   [(set_attr "type" "multi")])
11017
11018 (define_split
11019   [(set (match_operand:TI 0 "register_operand" "")
11020         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11021                      (match_operand:QI 2 "register_operand" "")))
11022    (clobber (match_scratch:DI 3 ""))
11023    (clobber (reg:CC FLAGS_REG))]
11024   "TARGET_64BIT && reload_completed"
11025   [(const_int 0)]
11026   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11027
11028 (define_split
11029   [(set (match_operand:TI 0 "register_operand" "")
11030         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11031                      (match_operand:QI 2 "immediate_operand" "")))
11032    (clobber (reg:CC FLAGS_REG))]
11033   "TARGET_64BIT && reload_completed"
11034   [(const_int 0)]
11035   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11036
11037 (define_insn "x86_64_shrd"
11038   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11039         (ior:DI (ashiftrt:DI (match_dup 0)
11040                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11041                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11042                   (minus:QI (const_int 64) (match_dup 2)))))
11043    (clobber (reg:CC FLAGS_REG))]
11044   "TARGET_64BIT"
11045   "@
11046    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11047    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11048   [(set_attr "type" "ishift")
11049    (set_attr "prefix_0f" "1")
11050    (set_attr "mode" "DI")
11051    (set_attr "athlon_decode" "vector")])
11052
11053 (define_expand "ashrdi3"
11054   [(set (match_operand:DI 0 "shiftdi_operand" "")
11055         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11056                      (match_operand:QI 2 "nonmemory_operand" "")))]
11057   ""
11058   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11059
11060 (define_insn "*ashrdi3_63_rex64"
11061   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11062         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11063                      (match_operand:DI 2 "const_int_operand" "i,i")))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "TARGET_64BIT && INTVAL (operands[2]) == 63
11066    && (TARGET_USE_CLTD || optimize_size)
11067    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11068   "@
11069    {cqto|cqo}
11070    sar{q}\t{%2, %0|%0, %2}"
11071   [(set_attr "type" "imovx,ishift")
11072    (set_attr "prefix_0f" "0,*")
11073    (set_attr "length_immediate" "0,*")
11074    (set_attr "modrm" "0,1")
11075    (set_attr "mode" "DI")])
11076
11077 (define_insn "*ashrdi3_1_one_bit_rex64"
11078   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11079         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11080                      (match_operand:QI 2 "const1_operand" "")))
11081    (clobber (reg:CC FLAGS_REG))]
11082   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11083    && (TARGET_SHIFT1 || optimize_size)"
11084   "sar{q}\t%0"
11085   [(set_attr "type" "ishift")
11086    (set (attr "length") 
11087      (if_then_else (match_operand:DI 0 "register_operand" "") 
11088         (const_string "2")
11089         (const_string "*")))])
11090
11091 (define_insn "*ashrdi3_1_rex64"
11092   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11093         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11094                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11095    (clobber (reg:CC FLAGS_REG))]
11096   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11097   "@
11098    sar{q}\t{%2, %0|%0, %2}
11099    sar{q}\t{%b2, %0|%0, %b2}"
11100   [(set_attr "type" "ishift")
11101    (set_attr "mode" "DI")])
11102
11103 ;; This pattern can't accept a variable shift count, since shifts by
11104 ;; zero don't affect the flags.  We assume that shifts by constant
11105 ;; zero are optimized away.
11106 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11107   [(set (reg FLAGS_REG)
11108         (compare
11109           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11110                        (match_operand:QI 2 "const1_operand" ""))
11111           (const_int 0)))
11112    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11113         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11114   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11115    && (TARGET_SHIFT1 || optimize_size)
11116    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11117   "sar{q}\t%0"
11118   [(set_attr "type" "ishift")
11119    (set (attr "length") 
11120      (if_then_else (match_operand:DI 0 "register_operand" "") 
11121         (const_string "2")
11122         (const_string "*")))])
11123
11124 ;; This pattern can't accept a variable shift count, since shifts by
11125 ;; zero don't affect the flags.  We assume that shifts by constant
11126 ;; zero are optimized away.
11127 (define_insn "*ashrdi3_cmp_rex64"
11128   [(set (reg FLAGS_REG)
11129         (compare
11130           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11131                        (match_operand:QI 2 "const_int_operand" "n"))
11132           (const_int 0)))
11133    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11134         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11135   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11136    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11137   "sar{q}\t{%2, %0|%0, %2}"
11138   [(set_attr "type" "ishift")
11139    (set_attr "mode" "DI")])
11140
11141 (define_insn "*ashrdi3_1"
11142   [(set (match_operand:DI 0 "register_operand" "=r")
11143         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11144                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11145    (clobber (reg:CC FLAGS_REG))]
11146   "!TARGET_64BIT"
11147   "#"
11148   [(set_attr "type" "multi")])
11149
11150 ;; By default we don't ask for a scratch register, because when DImode
11151 ;; values are manipulated, registers are already at a premium.  But if
11152 ;; we have one handy, we won't turn it away.
11153 (define_peephole2
11154   [(match_scratch:SI 3 "r")
11155    (parallel [(set (match_operand:DI 0 "register_operand" "")
11156                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11157                                 (match_operand:QI 2 "nonmemory_operand" "")))
11158               (clobber (reg:CC FLAGS_REG))])
11159    (match_dup 3)]
11160   "!TARGET_64BIT && TARGET_CMOVE"
11161   [(const_int 0)]
11162   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11163
11164 (define_split
11165   [(set (match_operand:DI 0 "register_operand" "")
11166         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11167                      (match_operand:QI 2 "nonmemory_operand" "")))
11168    (clobber (reg:CC FLAGS_REG))]
11169   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11170                      ? flow2_completed : reload_completed)"
11171   [(const_int 0)]
11172   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11173
11174 (define_insn "x86_shrd_1"
11175   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176         (ior:SI (ashiftrt:SI (match_dup 0)
11177                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11179                   (minus:QI (const_int 32) (match_dup 2)))))
11180    (clobber (reg:CC FLAGS_REG))]
11181   ""
11182   "@
11183    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11184    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "pent_pair" "np")
11188    (set_attr "mode" "SI")])
11189
11190 (define_expand "x86_shift_adj_3"
11191   [(use (match_operand:SI 0 "register_operand" ""))
11192    (use (match_operand:SI 1 "register_operand" ""))
11193    (use (match_operand:QI 2 "register_operand" ""))]
11194   ""
11195 {
11196   rtx label = gen_label_rtx ();
11197   rtx tmp;
11198
11199   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11200
11201   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11202   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11203   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11204                               gen_rtx_LABEL_REF (VOIDmode, label),
11205                               pc_rtx);
11206   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11207   JUMP_LABEL (tmp) = label;
11208
11209   emit_move_insn (operands[0], operands[1]);
11210   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11211
11212   emit_label (label);
11213   LABEL_NUSES (label) = 1;
11214
11215   DONE;
11216 })
11217
11218 (define_insn "ashrsi3_31"
11219   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11220         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11221                      (match_operand:SI 2 "const_int_operand" "i,i")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11224    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11225   "@
11226    {cltd|cdq}
11227    sar{l}\t{%2, %0|%0, %2}"
11228   [(set_attr "type" "imovx,ishift")
11229    (set_attr "prefix_0f" "0,*")
11230    (set_attr "length_immediate" "0,*")
11231    (set_attr "modrm" "0,1")
11232    (set_attr "mode" "SI")])
11233
11234 (define_insn "*ashrsi3_31_zext"
11235   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11236         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11237                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11240    && INTVAL (operands[2]) == 31
11241    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11242   "@
11243    {cltd|cdq}
11244    sar{l}\t{%2, %k0|%k0, %2}"
11245   [(set_attr "type" "imovx,ishift")
11246    (set_attr "prefix_0f" "0,*")
11247    (set_attr "length_immediate" "0,*")
11248    (set_attr "modrm" "0,1")
11249    (set_attr "mode" "SI")])
11250
11251 (define_expand "ashrsi3"
11252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11253         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11254                      (match_operand:QI 2 "nonmemory_operand" "")))
11255    (clobber (reg:CC FLAGS_REG))]
11256   ""
11257   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11258
11259 (define_insn "*ashrsi3_1_one_bit"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11262                      (match_operand:QI 2 "const1_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11265    && (TARGET_SHIFT1 || optimize_size)"
11266   "sar{l}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand:SI 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11272
11273 (define_insn "*ashrsi3_1_one_bit_zext"
11274   [(set (match_operand:DI 0 "register_operand" "=r")
11275         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11276                                      (match_operand:QI 2 "const1_operand" ""))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11279    && (TARGET_SHIFT1 || optimize_size)"
11280   "sar{l}\t%k0"
11281   [(set_attr "type" "ishift")
11282    (set_attr "length" "2")])
11283
11284 (define_insn "*ashrsi3_1"
11285   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11286         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11290   "@
11291    sar{l}\t{%2, %0|%0, %2}
11292    sar{l}\t{%b2, %0|%0, %b2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "mode" "SI")])
11295
11296 (define_insn "*ashrsi3_1_zext"
11297   [(set (match_operand:DI 0 "register_operand" "=r,r")
11298         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11299                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302   "@
11303    sar{l}\t{%2, %k0|%k0, %2}
11304    sar{l}\t{%b2, %k0|%k0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "SI")])
11307
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags.  We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*ashrsi3_one_bit_cmp"
11312   [(set (reg FLAGS_REG)
11313         (compare
11314           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11315                        (match_operand:QI 2 "const1_operand" ""))
11316           (const_int 0)))
11317    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11318         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11319   "ix86_match_ccmode (insn, CCGOCmode)
11320    && (TARGET_SHIFT1 || optimize_size)
11321    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11322   "sar{l}\t%0"
11323   [(set_attr "type" "ishift")
11324    (set (attr "length") 
11325      (if_then_else (match_operand:SI 0 "register_operand" "") 
11326         (const_string "2")
11327         (const_string "*")))])
11328
11329 (define_insn "*ashrsi3_one_bit_cmp_zext"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" ""))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "register_operand" "=r")
11336         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11340   "sar{l}\t%k0"
11341   [(set_attr "type" "ishift")
11342    (set_attr "length" "2")])
11343
11344 ;; This pattern can't accept a variable shift count, since shifts by
11345 ;; zero don't affect the flags.  We assume that shifts by constant
11346 ;; zero are optimized away.
11347 (define_insn "*ashrsi3_cmp"
11348   [(set (reg FLAGS_REG)
11349         (compare
11350           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11351                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11352           (const_int 0)))
11353    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11354         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11355   "ix86_match_ccmode (insn, CCGOCmode)
11356    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357   "sar{l}\t{%2, %0|%0, %2}"
11358   [(set_attr "type" "ishift")
11359    (set_attr "mode" "SI")])
11360
11361 (define_insn "*ashrsi3_cmp_zext"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11365                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11366           (const_int 0)))
11367    (set (match_operand:DI 0 "register_operand" "=r")
11368         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11369   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11370    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371   "sar{l}\t{%2, %k0|%k0, %2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "SI")])
11374
11375 (define_expand "ashrhi3"
11376   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11377         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_HIMODE_MATH"
11381   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11382
11383 (define_insn "*ashrhi3_1_one_bit"
11384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "sar{w}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11396
11397 (define_insn "*ashrhi3_1"
11398   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11399         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11400                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11403   "@
11404    sar{w}\t{%2, %0|%0, %2}
11405    sar{w}\t{%b2, %0|%0, %b2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "HI")])
11408
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags.  We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrhi3_one_bit_cmp"
11413   [(set (reg FLAGS_REG)
11414         (compare
11415           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11416                        (match_operand:QI 2 "const1_operand" ""))
11417           (const_int 0)))
11418    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11419         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11420   "ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11423   "sar{w}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set (attr "length") 
11426      (if_then_else (match_operand 0 "register_operand" "") 
11427         (const_string "2")
11428         (const_string "*")))])
11429
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags.  We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrhi3_cmp"
11434   [(set (reg FLAGS_REG)
11435         (compare
11436           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11437                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11438           (const_int 0)))
11439    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11440         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11441   "ix86_match_ccmode (insn, CCGOCmode)
11442    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "sar{w}\t{%2, %0|%0, %2}"
11444   [(set_attr "type" "ishift")
11445    (set_attr "mode" "HI")])
11446
11447 (define_expand "ashrqi3"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11449         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11450                      (match_operand:QI 2 "nonmemory_operand" "")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_QIMODE_MATH"
11453   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11454
11455 (define_insn "*ashrqi3_1_one_bit"
11456   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11457         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11458                      (match_operand:QI 2 "const1_operand" "")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11461    && (TARGET_SHIFT1 || optimize_size)"
11462   "sar{b}\t%0"
11463   [(set_attr "type" "ishift")
11464    (set (attr "length") 
11465      (if_then_else (match_operand 0 "register_operand" "") 
11466         (const_string "2")
11467         (const_string "*")))])
11468
11469 (define_insn "*ashrqi3_1_one_bit_slp"
11470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11471         (ashiftrt:QI (match_dup 0)
11472                      (match_operand:QI 1 "const1_operand" "")))
11473    (clobber (reg:CC FLAGS_REG))]
11474   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11475    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11476    && (TARGET_SHIFT1 || optimize_size)"
11477   "sar{b}\t%0"
11478   [(set_attr "type" "ishift1")
11479    (set (attr "length") 
11480      (if_then_else (match_operand 0 "register_operand" "") 
11481         (const_string "2")
11482         (const_string "*")))])
11483
11484 (define_insn "*ashrqi3_1"
11485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11486         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11487                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11490   "@
11491    sar{b}\t{%2, %0|%0, %2}
11492    sar{b}\t{%b2, %0|%0, %b2}"
11493   [(set_attr "type" "ishift")
11494    (set_attr "mode" "QI")])
11495
11496 (define_insn "*ashrqi3_1_slp"
11497   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11498         (ashiftrt:QI (match_dup 0)
11499                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11502    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11503   "@
11504    sar{b}\t{%1, %0|%0, %1}
11505    sar{b}\t{%b1, %0|%0, %b1}"
11506   [(set_attr "type" "ishift1")
11507    (set_attr "mode" "QI")])
11508
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags.  We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*ashrqi3_one_bit_cmp"
11513   [(set (reg FLAGS_REG)
11514         (compare
11515           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11516                        (match_operand:QI 2 "const1_operand" "I"))
11517           (const_int 0)))
11518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11519         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11520   "ix86_match_ccmode (insn, CCGOCmode)
11521    && (TARGET_SHIFT1 || optimize_size)
11522    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11523   "sar{b}\t%0"
11524   [(set_attr "type" "ishift")
11525    (set (attr "length") 
11526      (if_then_else (match_operand 0 "register_operand" "") 
11527         (const_string "2")
11528         (const_string "*")))])
11529
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags.  We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*ashrqi3_cmp"
11534   [(set (reg FLAGS_REG)
11535         (compare
11536           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11537                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11538           (const_int 0)))
11539    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11540         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11541   "ix86_match_ccmode (insn, CCGOCmode)
11542    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11543   "sar{b}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "ishift")
11545    (set_attr "mode" "QI")])
11546 \f
11547 ;; Logical shift instructions
11548
11549 ;; See comment above `ashldi3' about how this works.
11550
11551 (define_expand "lshrti3"
11552   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11553                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11554                                 (match_operand:QI 2 "nonmemory_operand" "")))
11555               (clobber (reg:CC FLAGS_REG))])]
11556   "TARGET_64BIT"
11557 {
11558   if (! immediate_operand (operands[2], QImode))
11559     {
11560       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11561       DONE;
11562     }
11563   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11564   DONE;
11565 })
11566
11567 (define_insn "lshrti3_1"
11568   [(set (match_operand:TI 0 "register_operand" "=r")
11569         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11570                      (match_operand:QI 2 "register_operand" "c")))
11571    (clobber (match_scratch:DI 3 "=&r"))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "TARGET_64BIT"
11574   "#"
11575   [(set_attr "type" "multi")])
11576
11577 (define_insn "*lshrti3_2"
11578   [(set (match_operand:TI 0 "register_operand" "=r")
11579         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580                      (match_operand:QI 2 "immediate_operand" "O")))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_split 
11587   [(set (match_operand:TI 0 "register_operand" "")
11588         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11589                      (match_operand:QI 2 "register_operand" "")))
11590    (clobber (match_scratch:DI 3 ""))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && reload_completed"
11593   [(const_int 0)]
11594   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11595
11596 (define_split 
11597   [(set (match_operand:TI 0 "register_operand" "")
11598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599                      (match_operand:QI 2 "immediate_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11604
11605 (define_expand "lshrdi3"
11606   [(set (match_operand:DI 0 "shiftdi_operand" "")
11607         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11608                      (match_operand:QI 2 "nonmemory_operand" "")))]
11609   ""
11610   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11611
11612 (define_insn "*lshrdi3_1_one_bit_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11614         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11615                      (match_operand:QI 2 "const1_operand" "")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11618    && (TARGET_SHIFT1 || optimize_size)"
11619   "shr{q}\t%0"
11620   [(set_attr "type" "ishift")
11621    (set (attr "length") 
11622      (if_then_else (match_operand:DI 0 "register_operand" "") 
11623         (const_string "2")
11624         (const_string "*")))])
11625
11626 (define_insn "*lshrdi3_1_rex64"
11627   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11628         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632   "@
11633    shr{q}\t{%2, %0|%0, %2}
11634    shr{q}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "DI")])
11637
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags.  We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11648         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11652   "shr{q}\t%0"
11653   [(set_attr "type" "ishift")
11654    (set (attr "length") 
11655      (if_then_else (match_operand:DI 0 "register_operand" "") 
11656         (const_string "2")
11657         (const_string "*")))])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*lshrdi3_cmp_rex64"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_operand" "e"))
11667           (const_int 0)))
11668    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "shr{q}\t{%2, %0|%0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "DI")])
11675
11676 (define_insn "*lshrdi3_1"
11677   [(set (match_operand:DI 0 "register_operand" "=r")
11678         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11679                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "!TARGET_64BIT"
11682   "#"
11683   [(set_attr "type" "multi")])
11684
11685 ;; By default we don't ask for a scratch register, because when DImode
11686 ;; values are manipulated, registers are already at a premium.  But if
11687 ;; we have one handy, we won't turn it away.
11688 (define_peephole2
11689   [(match_scratch:SI 3 "r")
11690    (parallel [(set (match_operand:DI 0 "register_operand" "")
11691                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11692                                 (match_operand:QI 2 "nonmemory_operand" "")))
11693               (clobber (reg:CC FLAGS_REG))])
11694    (match_dup 3)]
11695   "!TARGET_64BIT && TARGET_CMOVE"
11696   [(const_int 0)]
11697   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11698
11699 (define_split 
11700   [(set (match_operand:DI 0 "register_operand" "")
11701         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702                      (match_operand:QI 2 "nonmemory_operand" "")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11705                      ? flow2_completed : reload_completed)"
11706   [(const_int 0)]
11707   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11708
11709 (define_expand "lshrsi3"
11710   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11711         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11712                      (match_operand:QI 2 "nonmemory_operand" "")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   ""
11715   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11716
11717 (define_insn "*lshrsi3_1_one_bit"
11718   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11719         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11720                      (match_operand:QI 2 "const1_operand" "")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11723    && (TARGET_SHIFT1 || optimize_size)"
11724   "shr{l}\t%0"
11725   [(set_attr "type" "ishift")
11726    (set (attr "length") 
11727      (if_then_else (match_operand:SI 0 "register_operand" "") 
11728         (const_string "2")
11729         (const_string "*")))])
11730
11731 (define_insn "*lshrsi3_1_one_bit_zext"
11732   [(set (match_operand:DI 0 "register_operand" "=r")
11733         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11734                      (match_operand:QI 2 "const1_operand" "")))
11735    (clobber (reg:CC FLAGS_REG))]
11736   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11737    && (TARGET_SHIFT1 || optimize_size)"
11738   "shr{l}\t%k0"
11739   [(set_attr "type" "ishift")
11740    (set_attr "length" "2")])
11741
11742 (define_insn "*lshrsi3_1"
11743   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11744         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11745                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11746    (clobber (reg:CC FLAGS_REG))]
11747   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11748   "@
11749    shr{l}\t{%2, %0|%0, %2}
11750    shr{l}\t{%b2, %0|%0, %b2}"
11751   [(set_attr "type" "ishift")
11752    (set_attr "mode" "SI")])
11753
11754 (define_insn "*lshrsi3_1_zext"
11755   [(set (match_operand:DI 0 "register_operand" "=r,r")
11756         (zero_extend:DI
11757           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11758                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11759    (clobber (reg:CC FLAGS_REG))]
11760   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11761   "@
11762    shr{l}\t{%2, %k0|%k0, %2}
11763    shr{l}\t{%b2, %k0|%k0, %b2}"
11764   [(set_attr "type" "ishift")
11765    (set_attr "mode" "SI")])
11766
11767 ;; This pattern can't accept a variable shift count, since shifts by
11768 ;; zero don't affect the flags.  We assume that shifts by constant
11769 ;; zero are optimized away.
11770 (define_insn "*lshrsi3_one_bit_cmp"
11771   [(set (reg FLAGS_REG)
11772         (compare
11773           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11774                        (match_operand:QI 2 "const1_operand" ""))
11775           (const_int 0)))
11776    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11777         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11778   "ix86_match_ccmode (insn, CCGOCmode)
11779    && (TARGET_SHIFT1 || optimize_size)
11780    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11781   "shr{l}\t%0"
11782   [(set_attr "type" "ishift")
11783    (set (attr "length") 
11784      (if_then_else (match_operand:SI 0 "register_operand" "") 
11785         (const_string "2")
11786         (const_string "*")))])
11787
11788 (define_insn "*lshrsi3_cmp_one_bit_zext"
11789   [(set (reg FLAGS_REG)
11790         (compare
11791           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11792                        (match_operand:QI 2 "const1_operand" ""))
11793           (const_int 0)))
11794    (set (match_operand:DI 0 "register_operand" "=r")
11795         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11796   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11797    && (TARGET_SHIFT1 || optimize_size)
11798    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11799   "shr{l}\t%k0"
11800   [(set_attr "type" "ishift")
11801    (set_attr "length" "2")])
11802
11803 ;; This pattern can't accept a variable shift count, since shifts by
11804 ;; zero don't affect the flags.  We assume that shifts by constant
11805 ;; zero are optimized away.
11806 (define_insn "*lshrsi3_cmp"
11807   [(set (reg FLAGS_REG)
11808         (compare
11809           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11810                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11811           (const_int 0)))
11812    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11814   "ix86_match_ccmode (insn, CCGOCmode)
11815    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11816   "shr{l}\t{%2, %0|%0, %2}"
11817   [(set_attr "type" "ishift")
11818    (set_attr "mode" "SI")])
11819
11820 (define_insn "*lshrsi3_cmp_zext"
11821   [(set (reg FLAGS_REG)
11822         (compare
11823           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11824                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11825           (const_int 0)))
11826    (set (match_operand:DI 0 "register_operand" "=r")
11827         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11828   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11829    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11830   "shr{l}\t{%2, %k0|%k0, %2}"
11831   [(set_attr "type" "ishift")
11832    (set_attr "mode" "SI")])
11833
11834 (define_expand "lshrhi3"
11835   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11836         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11837                      (match_operand:QI 2 "nonmemory_operand" "")))
11838    (clobber (reg:CC FLAGS_REG))]
11839   "TARGET_HIMODE_MATH"
11840   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11841
11842 (define_insn "*lshrhi3_1_one_bit"
11843   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11844         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11845                      (match_operand:QI 2 "const1_operand" "")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11848    && (TARGET_SHIFT1 || optimize_size)"
11849   "shr{w}\t%0"
11850   [(set_attr "type" "ishift")
11851    (set (attr "length") 
11852      (if_then_else (match_operand 0 "register_operand" "") 
11853         (const_string "2")
11854         (const_string "*")))])
11855
11856 (define_insn "*lshrhi3_1"
11857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11858         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11859                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11862   "@
11863    shr{w}\t{%2, %0|%0, %2}
11864    shr{w}\t{%b2, %0|%0, %b2}"
11865   [(set_attr "type" "ishift")
11866    (set_attr "mode" "HI")])
11867
11868 ;; This pattern can't accept a variable shift count, since shifts by
11869 ;; zero don't affect the flags.  We assume that shifts by constant
11870 ;; zero are optimized away.
11871 (define_insn "*lshrhi3_one_bit_cmp"
11872   [(set (reg FLAGS_REG)
11873         (compare
11874           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11875                        (match_operand:QI 2 "const1_operand" ""))
11876           (const_int 0)))
11877    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11878         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11879   "ix86_match_ccmode (insn, CCGOCmode)
11880    && (TARGET_SHIFT1 || optimize_size)
11881    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11882   "shr{w}\t%0"
11883   [(set_attr "type" "ishift")
11884    (set (attr "length") 
11885      (if_then_else (match_operand:SI 0 "register_operand" "") 
11886         (const_string "2")
11887         (const_string "*")))])
11888
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags.  We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*lshrhi3_cmp"
11893   [(set (reg FLAGS_REG)
11894         (compare
11895           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11896                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11897           (const_int 0)))
11898    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11899         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11900   "ix86_match_ccmode (insn, CCGOCmode)
11901    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11902   "shr{w}\t{%2, %0|%0, %2}"
11903   [(set_attr "type" "ishift")
11904    (set_attr "mode" "HI")])
11905
11906 (define_expand "lshrqi3"
11907   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11908         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11909                      (match_operand:QI 2 "nonmemory_operand" "")))
11910    (clobber (reg:CC FLAGS_REG))]
11911   "TARGET_QIMODE_MATH"
11912   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11913
11914 (define_insn "*lshrqi3_1_one_bit"
11915   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11917                      (match_operand:QI 2 "const1_operand" "")))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11920    && (TARGET_SHIFT1 || optimize_size)"
11921   "shr{b}\t%0"
11922   [(set_attr "type" "ishift")
11923    (set (attr "length") 
11924      (if_then_else (match_operand 0 "register_operand" "") 
11925         (const_string "2")
11926         (const_string "*")))])
11927
11928 (define_insn "*lshrqi3_1_one_bit_slp"
11929   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11930         (lshiftrt:QI (match_dup 0)
11931                      (match_operand:QI 1 "const1_operand" "")))
11932    (clobber (reg:CC FLAGS_REG))]
11933   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11934    && (TARGET_SHIFT1 || optimize_size)"
11935   "shr{b}\t%0"
11936   [(set_attr "type" "ishift1")
11937    (set (attr "length") 
11938      (if_then_else (match_operand 0 "register_operand" "") 
11939         (const_string "2")
11940         (const_string "*")))])
11941
11942 (define_insn "*lshrqi3_1"
11943   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11944         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11945                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11948   "@
11949    shr{b}\t{%2, %0|%0, %2}
11950    shr{b}\t{%b2, %0|%0, %b2}"
11951   [(set_attr "type" "ishift")
11952    (set_attr "mode" "QI")])
11953
11954 (define_insn "*lshrqi3_1_slp"
11955   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11956         (lshiftrt:QI (match_dup 0)
11957                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11960    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11961   "@
11962    shr{b}\t{%1, %0|%0, %1}
11963    shr{b}\t{%b1, %0|%0, %b1}"
11964   [(set_attr "type" "ishift1")
11965    (set_attr "mode" "QI")])
11966
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags.  We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*lshrqi2_one_bit_cmp"
11971   [(set (reg FLAGS_REG)
11972         (compare
11973           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const1_operand" ""))
11975           (const_int 0)))
11976    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11977         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11978   "ix86_match_ccmode (insn, CCGOCmode)
11979    && (TARGET_SHIFT1 || optimize_size)
11980    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11981   "shr{b}\t%0"
11982   [(set_attr "type" "ishift")
11983    (set (attr "length") 
11984      (if_then_else (match_operand:SI 0 "register_operand" "") 
11985         (const_string "2")
11986         (const_string "*")))])
11987
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags.  We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*lshrqi2_cmp"
11992   [(set (reg FLAGS_REG)
11993         (compare
11994           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11996           (const_int 0)))
11997    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11999   "ix86_match_ccmode (insn, CCGOCmode)
12000    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12001   "shr{b}\t{%2, %0|%0, %2}"
12002   [(set_attr "type" "ishift")
12003    (set_attr "mode" "QI")])
12004 \f
12005 ;; Rotate instructions
12006
12007 (define_expand "rotldi3"
12008   [(set (match_operand:DI 0 "shiftdi_operand" "")
12009         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12010                    (match_operand:QI 2 "nonmemory_operand" "")))
12011    (clobber (reg:CC FLAGS_REG))]
12012  ""
12013 {
12014   if (TARGET_64BIT)
12015     {
12016       ix86_expand_binary_operator (ROTATE, DImode, operands);
12017       DONE;
12018     }
12019   if (!const_1_to_31_operand (operands[2], VOIDmode))
12020     FAIL;
12021   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12022   DONE;
12023 })
12024
12025 ;; Implement rotation using two double-precision shift instructions
12026 ;; and a scratch register.   
12027 (define_insn_and_split "ix86_rotldi3"
12028  [(set (match_operand:DI 0 "register_operand" "=r")
12029        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12030                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12031   (clobber (reg:CC FLAGS_REG))
12032   (clobber (match_scratch:SI 3 "=&r"))]
12033  "!TARGET_64BIT"
12034  "" 
12035  "&& reload_completed"
12036  [(set (match_dup 3) (match_dup 4))
12037   (parallel
12038    [(set (match_dup 4)
12039          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12040                  (lshiftrt:SI (match_dup 5)
12041                               (minus:QI (const_int 32) (match_dup 2)))))
12042     (clobber (reg:CC FLAGS_REG))])
12043   (parallel
12044    [(set (match_dup 5)
12045          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12046                  (lshiftrt:SI (match_dup 3)
12047                               (minus:QI (const_int 32) (match_dup 2)))))
12048     (clobber (reg:CC FLAGS_REG))])]
12049  "split_di (operands, 1, operands + 4, operands + 5);")
12050  
12051 (define_insn "*rotlsi3_1_one_bit_rex64"
12052   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12053         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12054                    (match_operand:QI 2 "const1_operand" "")))
12055    (clobber (reg:CC FLAGS_REG))]
12056   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12057    && (TARGET_SHIFT1 || optimize_size)"
12058   "rol{q}\t%0"
12059   [(set_attr "type" "rotate")
12060    (set (attr "length") 
12061      (if_then_else (match_operand:DI 0 "register_operand" "") 
12062         (const_string "2")
12063         (const_string "*")))])
12064
12065 (define_insn "*rotldi3_1_rex64"
12066   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12067         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12068                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12069    (clobber (reg:CC FLAGS_REG))]
12070   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12071   "@
12072    rol{q}\t{%2, %0|%0, %2}
12073    rol{q}\t{%b2, %0|%0, %b2}"
12074   [(set_attr "type" "rotate")
12075    (set_attr "mode" "DI")])
12076
12077 (define_expand "rotlsi3"
12078   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12079         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12080                    (match_operand:QI 2 "nonmemory_operand" "")))
12081    (clobber (reg:CC FLAGS_REG))]
12082   ""
12083   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12084
12085 (define_insn "*rotlsi3_1_one_bit"
12086   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12087         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12088                    (match_operand:QI 2 "const1_operand" "")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12091    && (TARGET_SHIFT1 || optimize_size)"
12092   "rol{l}\t%0"
12093   [(set_attr "type" "rotate")
12094    (set (attr "length") 
12095      (if_then_else (match_operand:SI 0 "register_operand" "") 
12096         (const_string "2")
12097         (const_string "*")))])
12098
12099 (define_insn "*rotlsi3_1_one_bit_zext"
12100   [(set (match_operand:DI 0 "register_operand" "=r")
12101         (zero_extend:DI
12102           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12103                      (match_operand:QI 2 "const1_operand" ""))))
12104    (clobber (reg:CC FLAGS_REG))]
12105   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12106    && (TARGET_SHIFT1 || optimize_size)"
12107   "rol{l}\t%k0"
12108   [(set_attr "type" "rotate")
12109    (set_attr "length" "2")])
12110
12111 (define_insn "*rotlsi3_1"
12112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12113         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12114                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12117   "@
12118    rol{l}\t{%2, %0|%0, %2}
12119    rol{l}\t{%b2, %0|%0, %b2}"
12120   [(set_attr "type" "rotate")
12121    (set_attr "mode" "SI")])
12122
12123 (define_insn "*rotlsi3_1_zext"
12124   [(set (match_operand:DI 0 "register_operand" "=r,r")
12125         (zero_extend:DI
12126           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12127                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12130   "@
12131    rol{l}\t{%2, %k0|%k0, %2}
12132    rol{l}\t{%b2, %k0|%k0, %b2}"
12133   [(set_attr "type" "rotate")
12134    (set_attr "mode" "SI")])
12135
12136 (define_expand "rotlhi3"
12137   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12138         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12139                    (match_operand:QI 2 "nonmemory_operand" "")))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_HIMODE_MATH"
12142   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12143
12144 (define_insn "*rotlhi3_1_one_bit"
12145   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12146         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12147                    (match_operand:QI 2 "const1_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12150    && (TARGET_SHIFT1 || optimize_size)"
12151   "rol{w}\t%0"
12152   [(set_attr "type" "rotate")
12153    (set (attr "length") 
12154      (if_then_else (match_operand 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12157
12158 (define_insn "*rotlhi3_1"
12159   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12160         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12161                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12164   "@
12165    rol{w}\t{%2, %0|%0, %2}
12166    rol{w}\t{%b2, %0|%0, %b2}"
12167   [(set_attr "type" "rotate")
12168    (set_attr "mode" "HI")])
12169
12170 (define_expand "rotlqi3"
12171   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12172         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12173                    (match_operand:QI 2 "nonmemory_operand" "")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "TARGET_QIMODE_MATH"
12176   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12177
12178 (define_insn "*rotlqi3_1_one_bit_slp"
12179   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12180         (rotate:QI (match_dup 0)
12181                    (match_operand:QI 1 "const1_operand" "")))
12182    (clobber (reg:CC FLAGS_REG))]
12183   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12184    && (TARGET_SHIFT1 || optimize_size)"
12185   "rol{b}\t%0"
12186   [(set_attr "type" "rotate1")
12187    (set (attr "length") 
12188      (if_then_else (match_operand 0 "register_operand" "") 
12189         (const_string "2")
12190         (const_string "*")))])
12191
12192 (define_insn "*rotlqi3_1_one_bit"
12193   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12194         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12195                    (match_operand:QI 2 "const1_operand" "")))
12196    (clobber (reg:CC FLAGS_REG))]
12197   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12198    && (TARGET_SHIFT1 || optimize_size)"
12199   "rol{b}\t%0"
12200   [(set_attr "type" "rotate")
12201    (set (attr "length") 
12202      (if_then_else (match_operand 0 "register_operand" "") 
12203         (const_string "2")
12204         (const_string "*")))])
12205
12206 (define_insn "*rotlqi3_1_slp"
12207   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12208         (rotate:QI (match_dup 0)
12209                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12210    (clobber (reg:CC FLAGS_REG))]
12211   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12212    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12213   "@
12214    rol{b}\t{%1, %0|%0, %1}
12215    rol{b}\t{%b1, %0|%0, %b1}"
12216   [(set_attr "type" "rotate1")
12217    (set_attr "mode" "QI")])
12218
12219 (define_insn "*rotlqi3_1"
12220   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12221         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12222                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12223    (clobber (reg:CC FLAGS_REG))]
12224   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12225   "@
12226    rol{b}\t{%2, %0|%0, %2}
12227    rol{b}\t{%b2, %0|%0, %b2}"
12228   [(set_attr "type" "rotate")
12229    (set_attr "mode" "QI")])
12230
12231 (define_expand "rotrdi3"
12232   [(set (match_operand:DI 0 "shiftdi_operand" "")
12233         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12234                    (match_operand:QI 2 "nonmemory_operand" "")))
12235    (clobber (reg:CC FLAGS_REG))]
12236  ""
12237 {
12238   if (TARGET_64BIT)
12239     {
12240       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12241       DONE;
12242     }
12243   if (!const_1_to_31_operand (operands[2], VOIDmode))
12244     FAIL;
12245   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12246   DONE;
12247 })
12248   
12249 ;; Implement rotation using two double-precision shift instructions
12250 ;; and a scratch register.   
12251 (define_insn_and_split "ix86_rotrdi3"
12252  [(set (match_operand:DI 0 "register_operand" "=r")
12253        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12254                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12255   (clobber (reg:CC FLAGS_REG))
12256   (clobber (match_scratch:SI 3 "=&r"))]
12257  "!TARGET_64BIT"
12258  ""
12259  "&& reload_completed"
12260  [(set (match_dup 3) (match_dup 4))
12261   (parallel
12262    [(set (match_dup 4)
12263          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12264                  (ashift:SI (match_dup 5)
12265                             (minus:QI (const_int 32) (match_dup 2)))))
12266     (clobber (reg:CC FLAGS_REG))])
12267   (parallel
12268    [(set (match_dup 5)
12269          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12270                  (ashift:SI (match_dup 3)
12271                             (minus:QI (const_int 32) (match_dup 2)))))
12272     (clobber (reg:CC FLAGS_REG))])]
12273  "split_di (operands, 1, operands + 4, operands + 5);")
12274
12275 (define_insn "*rotrdi3_1_one_bit_rex64"
12276   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12277         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12278                      (match_operand:QI 2 "const1_operand" "")))
12279    (clobber (reg:CC FLAGS_REG))]
12280   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12281    && (TARGET_SHIFT1 || optimize_size)"
12282   "ror{q}\t%0"
12283   [(set_attr "type" "rotate")
12284    (set (attr "length") 
12285      (if_then_else (match_operand:DI 0 "register_operand" "") 
12286         (const_string "2")
12287         (const_string "*")))])
12288
12289 (define_insn "*rotrdi3_1_rex64"
12290   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12291         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12292                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12293    (clobber (reg:CC FLAGS_REG))]
12294   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12295   "@
12296    ror{q}\t{%2, %0|%0, %2}
12297    ror{q}\t{%b2, %0|%0, %b2}"
12298   [(set_attr "type" "rotate")
12299    (set_attr "mode" "DI")])
12300
12301 (define_expand "rotrsi3"
12302   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12303         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12304                      (match_operand:QI 2 "nonmemory_operand" "")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   ""
12307   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12308
12309 (define_insn "*rotrsi3_1_one_bit"
12310   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12311         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12312                      (match_operand:QI 2 "const1_operand" "")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12315    && (TARGET_SHIFT1 || optimize_size)"
12316   "ror{l}\t%0"
12317   [(set_attr "type" "rotate")
12318    (set (attr "length") 
12319      (if_then_else (match_operand:SI 0 "register_operand" "") 
12320         (const_string "2")
12321         (const_string "*")))])
12322
12323 (define_insn "*rotrsi3_1_one_bit_zext"
12324   [(set (match_operand:DI 0 "register_operand" "=r")
12325         (zero_extend:DI
12326           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12327                        (match_operand:QI 2 "const1_operand" ""))))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12330    && (TARGET_SHIFT1 || optimize_size)"
12331   "ror{l}\t%k0"
12332   [(set_attr "type" "rotate")
12333    (set (attr "length") 
12334      (if_then_else (match_operand:SI 0 "register_operand" "") 
12335         (const_string "2")
12336         (const_string "*")))])
12337
12338 (define_insn "*rotrsi3_1"
12339   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12340         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12341                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12342    (clobber (reg:CC FLAGS_REG))]
12343   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12344   "@
12345    ror{l}\t{%2, %0|%0, %2}
12346    ror{l}\t{%b2, %0|%0, %b2}"
12347   [(set_attr "type" "rotate")
12348    (set_attr "mode" "SI")])
12349
12350 (define_insn "*rotrsi3_1_zext"
12351   [(set (match_operand:DI 0 "register_operand" "=r,r")
12352         (zero_extend:DI
12353           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12354                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12355    (clobber (reg:CC FLAGS_REG))]
12356   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12357   "@
12358    ror{l}\t{%2, %k0|%k0, %2}
12359    ror{l}\t{%b2, %k0|%k0, %b2}"
12360   [(set_attr "type" "rotate")
12361    (set_attr "mode" "SI")])
12362
12363 (define_expand "rotrhi3"
12364   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12365         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12366                      (match_operand:QI 2 "nonmemory_operand" "")))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "TARGET_HIMODE_MATH"
12369   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12370
12371 (define_insn "*rotrhi3_one_bit"
12372   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12373         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12374                      (match_operand:QI 2 "const1_operand" "")))
12375    (clobber (reg:CC FLAGS_REG))]
12376   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12377    && (TARGET_SHIFT1 || optimize_size)"
12378   "ror{w}\t%0"
12379   [(set_attr "type" "rotate")
12380    (set (attr "length") 
12381      (if_then_else (match_operand 0 "register_operand" "") 
12382         (const_string "2")
12383         (const_string "*")))])
12384
12385 (define_insn "*rotrhi3"
12386   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12387         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12388                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12389    (clobber (reg:CC FLAGS_REG))]
12390   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12391   "@
12392    ror{w}\t{%2, %0|%0, %2}
12393    ror{w}\t{%b2, %0|%0, %b2}"
12394   [(set_attr "type" "rotate")
12395    (set_attr "mode" "HI")])
12396
12397 (define_expand "rotrqi3"
12398   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12399         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12400                      (match_operand:QI 2 "nonmemory_operand" "")))
12401    (clobber (reg:CC FLAGS_REG))]
12402   "TARGET_QIMODE_MATH"
12403   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12404
12405 (define_insn "*rotrqi3_1_one_bit"
12406   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12407         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12408                      (match_operand:QI 2 "const1_operand" "")))
12409    (clobber (reg:CC FLAGS_REG))]
12410   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12411    && (TARGET_SHIFT1 || optimize_size)"
12412   "ror{b}\t%0"
12413   [(set_attr "type" "rotate")
12414    (set (attr "length") 
12415      (if_then_else (match_operand 0 "register_operand" "") 
12416         (const_string "2")
12417         (const_string "*")))])
12418
12419 (define_insn "*rotrqi3_1_one_bit_slp"
12420   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12421         (rotatert:QI (match_dup 0)
12422                      (match_operand:QI 1 "const1_operand" "")))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12425    && (TARGET_SHIFT1 || optimize_size)"
12426   "ror{b}\t%0"
12427   [(set_attr "type" "rotate1")
12428    (set (attr "length") 
12429      (if_then_else (match_operand 0 "register_operand" "") 
12430         (const_string "2")
12431         (const_string "*")))])
12432
12433 (define_insn "*rotrqi3_1"
12434   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12435         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12436                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12439   "@
12440    ror{b}\t{%2, %0|%0, %2}
12441    ror{b}\t{%b2, %0|%0, %b2}"
12442   [(set_attr "type" "rotate")
12443    (set_attr "mode" "QI")])
12444
12445 (define_insn "*rotrqi3_1_slp"
12446   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12447         (rotatert:QI (match_dup 0)
12448                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12451    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12452   "@
12453    ror{b}\t{%1, %0|%0, %1}
12454    ror{b}\t{%b1, %0|%0, %b1}"
12455   [(set_attr "type" "rotate1")
12456    (set_attr "mode" "QI")])
12457 \f
12458 ;; Bit set / bit test instructions
12459
12460 (define_expand "extv"
12461   [(set (match_operand:SI 0 "register_operand" "")
12462         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12463                          (match_operand:SI 2 "immediate_operand" "")
12464                          (match_operand:SI 3 "immediate_operand" "")))]
12465   ""
12466 {
12467   /* Handle extractions from %ah et al.  */
12468   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12469     FAIL;
12470
12471   /* From mips.md: extract_bit_field doesn't verify that our source
12472      matches the predicate, so check it again here.  */
12473   if (! ext_register_operand (operands[1], VOIDmode))
12474     FAIL;
12475 })
12476
12477 (define_expand "extzv"
12478   [(set (match_operand:SI 0 "register_operand" "")
12479         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12480                          (match_operand:SI 2 "immediate_operand" "")
12481                          (match_operand:SI 3 "immediate_operand" "")))]
12482   ""
12483 {
12484   /* Handle extractions from %ah et al.  */
12485   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12486     FAIL;
12487
12488   /* From mips.md: extract_bit_field doesn't verify that our source
12489      matches the predicate, so check it again here.  */
12490   if (! ext_register_operand (operands[1], VOIDmode))
12491     FAIL;
12492 })
12493
12494 (define_expand "insv"
12495   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12496                       (match_operand 1 "immediate_operand" "")
12497                       (match_operand 2 "immediate_operand" ""))
12498         (match_operand 3 "register_operand" ""))]
12499   ""
12500 {
12501   /* Handle extractions from %ah et al.  */
12502   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12503     FAIL;
12504
12505   /* From mips.md: insert_bit_field doesn't verify that our source
12506      matches the predicate, so check it again here.  */
12507   if (! ext_register_operand (operands[0], VOIDmode))
12508     FAIL;
12509
12510   if (TARGET_64BIT)
12511     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12512   else
12513     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12514
12515   DONE;
12516 })
12517
12518 ;; %%% bts, btr, btc, bt.
12519 ;; In general these instructions are *slow* when applied to memory,
12520 ;; since they enforce atomic operation.  When applied to registers,
12521 ;; it depends on the cpu implementation.  They're never faster than
12522 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12523 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12524 ;; within the instruction itself, so operating on bits in the high
12525 ;; 32-bits of a register becomes easier.
12526 ;;
12527 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12528 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12529 ;; negdf respectively, so they can never be disabled entirely.
12530
12531 (define_insn "*btsq"
12532   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12533                          (const_int 1)
12534                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12535         (const_int 1))
12536    (clobber (reg:CC FLAGS_REG))]
12537   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12538   "bts{q} %1,%0"
12539   [(set_attr "type" "alu1")])
12540
12541 (define_insn "*btrq"
12542   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12543                          (const_int 1)
12544                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12545         (const_int 0))
12546    (clobber (reg:CC FLAGS_REG))]
12547   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12548   "btr{q} %1,%0"
12549   [(set_attr "type" "alu1")])
12550
12551 (define_insn "*btcq"
12552   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12553                          (const_int 1)
12554                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12555         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12556    (clobber (reg:CC FLAGS_REG))]
12557   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12558   "btc{q} %1,%0"
12559   [(set_attr "type" "alu1")])
12560
12561 ;; Allow Nocona to avoid these instructions if a register is available.
12562
12563 (define_peephole2
12564   [(match_scratch:DI 2 "r")
12565    (parallel [(set (zero_extract:DI
12566                      (match_operand:DI 0 "register_operand" "")
12567                      (const_int 1)
12568                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12569                    (const_int 1))
12570               (clobber (reg:CC FLAGS_REG))])]
12571   "TARGET_64BIT && !TARGET_USE_BT"
12572   [(const_int 0)]
12573 {
12574   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12575   rtx op1;
12576
12577   if (HOST_BITS_PER_WIDE_INT >= 64)
12578     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12579   else if (i < HOST_BITS_PER_WIDE_INT)
12580     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12581   else
12582     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12583
12584   op1 = immed_double_const (lo, hi, DImode);
12585   if (i >= 31)
12586     {
12587       emit_move_insn (operands[2], op1);
12588       op1 = operands[2];
12589     }
12590
12591   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12592   DONE;
12593 })
12594
12595 (define_peephole2
12596   [(match_scratch:DI 2 "r")
12597    (parallel [(set (zero_extract:DI
12598                      (match_operand:DI 0 "register_operand" "")
12599                      (const_int 1)
12600                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12601                    (const_int 0))
12602               (clobber (reg:CC FLAGS_REG))])]
12603   "TARGET_64BIT && !TARGET_USE_BT"
12604   [(const_int 0)]
12605 {
12606   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12607   rtx op1;
12608
12609   if (HOST_BITS_PER_WIDE_INT >= 64)
12610     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12611   else if (i < HOST_BITS_PER_WIDE_INT)
12612     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12613   else
12614     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12615
12616   op1 = immed_double_const (~lo, ~hi, DImode);
12617   if (i >= 32)
12618     {
12619       emit_move_insn (operands[2], op1);
12620       op1 = operands[2];
12621     }
12622
12623   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12624   DONE;
12625 })
12626
12627 (define_peephole2
12628   [(match_scratch:DI 2 "r")
12629    (parallel [(set (zero_extract:DI
12630                      (match_operand:DI 0 "register_operand" "")
12631                      (const_int 1)
12632                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12633               (not:DI (zero_extract:DI
12634                         (match_dup 0) (const_int 1) (match_dup 1))))
12635               (clobber (reg:CC FLAGS_REG))])]
12636   "TARGET_64BIT && !TARGET_USE_BT"
12637   [(const_int 0)]
12638 {
12639   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12640   rtx op1;
12641
12642   if (HOST_BITS_PER_WIDE_INT >= 64)
12643     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12644   else if (i < HOST_BITS_PER_WIDE_INT)
12645     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12646   else
12647     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12648
12649   op1 = immed_double_const (lo, hi, DImode);
12650   if (i >= 31)
12651     {
12652       emit_move_insn (operands[2], op1);
12653       op1 = operands[2];
12654     }
12655
12656   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12657   DONE;
12658 })
12659 \f
12660 ;; Store-flag instructions.
12661
12662 ;; For all sCOND expanders, also expand the compare or test insn that
12663 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12664
12665 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12666 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12667 ;; way, which can later delete the movzx if only QImode is needed.
12668
12669 (define_expand "seq"
12670   [(set (match_operand:QI 0 "register_operand" "")
12671         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12672   ""
12673   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12674
12675 (define_expand "sne"
12676   [(set (match_operand:QI 0 "register_operand" "")
12677         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12678   ""
12679   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "sgt"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sgtu"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "slt"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sltu"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sge"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sgeu"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sle"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   ""
12721   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sleu"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   ""
12727   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sunordered"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   "TARGET_80387 || TARGET_SSE"
12733   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sordered"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   "TARGET_80387"
12739   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "suneq"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387 || TARGET_SSE"
12745   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "sunge"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387 || TARGET_SSE"
12751   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "sungt"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sunle"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sunlt"
12766   [(set (match_operand:QI 0 "register_operand" "")
12767         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768   "TARGET_80387 || TARGET_SSE"
12769   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sltgt"
12772   [(set (match_operand:QI 0 "register_operand" "")
12773         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774   "TARGET_80387 || TARGET_SSE"
12775   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12776
12777 (define_insn "*setcc_1"
12778   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779         (match_operator:QI 1 "ix86_comparison_operator"
12780           [(reg FLAGS_REG) (const_int 0)]))]
12781   ""
12782   "set%C1\t%0"
12783   [(set_attr "type" "setcc")
12784    (set_attr "mode" "QI")])
12785
12786 (define_insn "*setcc_2"
12787   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12788         (match_operator:QI 1 "ix86_comparison_operator"
12789           [(reg FLAGS_REG) (const_int 0)]))]
12790   ""
12791   "set%C1\t%0"
12792   [(set_attr "type" "setcc")
12793    (set_attr "mode" "QI")])
12794
12795 ;; In general it is not safe to assume too much about CCmode registers,
12796 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12797 ;; conditions this is safe on x86, so help combine not create
12798 ;;
12799 ;;      seta    %al
12800 ;;      testb   %al, %al
12801 ;;      sete    %al
12802
12803 (define_split 
12804   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12805         (ne:QI (match_operator 1 "ix86_comparison_operator"
12806                  [(reg FLAGS_REG) (const_int 0)])
12807             (const_int 0)))]
12808   ""
12809   [(set (match_dup 0) (match_dup 1))]
12810 {
12811   PUT_MODE (operands[1], QImode);
12812 })
12813
12814 (define_split 
12815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12816         (ne:QI (match_operator 1 "ix86_comparison_operator"
12817                  [(reg FLAGS_REG) (const_int 0)])
12818             (const_int 0)))]
12819   ""
12820   [(set (match_dup 0) (match_dup 1))]
12821 {
12822   PUT_MODE (operands[1], QImode);
12823 })
12824
12825 (define_split 
12826   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12827         (eq:QI (match_operator 1 "ix86_comparison_operator"
12828                  [(reg FLAGS_REG) (const_int 0)])
12829             (const_int 0)))]
12830   ""
12831   [(set (match_dup 0) (match_dup 1))]
12832 {
12833   rtx new_op1 = copy_rtx (operands[1]);
12834   operands[1] = new_op1;
12835   PUT_MODE (new_op1, QImode);
12836   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12837                                              GET_MODE (XEXP (new_op1, 0))));
12838
12839   /* Make sure that (a) the CCmode we have for the flags is strong
12840      enough for the reversed compare or (b) we have a valid FP compare.  */
12841   if (! ix86_comparison_operator (new_op1, VOIDmode))
12842     FAIL;
12843 })
12844
12845 (define_split 
12846   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12847         (eq:QI (match_operator 1 "ix86_comparison_operator"
12848                  [(reg FLAGS_REG) (const_int 0)])
12849             (const_int 0)))]
12850   ""
12851   [(set (match_dup 0) (match_dup 1))]
12852 {
12853   rtx new_op1 = copy_rtx (operands[1]);
12854   operands[1] = new_op1;
12855   PUT_MODE (new_op1, QImode);
12856   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12857                                              GET_MODE (XEXP (new_op1, 0))));
12858
12859   /* Make sure that (a) the CCmode we have for the flags is strong
12860      enough for the reversed compare or (b) we have a valid FP compare.  */
12861   if (! ix86_comparison_operator (new_op1, VOIDmode))
12862     FAIL;
12863 })
12864
12865 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12866 ;; subsequent logical operations are used to imitate conditional moves.
12867 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12868 ;; it directly.
12869
12870 (define_insn "*sse_setccsf"
12871   [(set (match_operand:SF 0 "register_operand" "=x")
12872         (match_operator:SF 1 "sse_comparison_operator"
12873           [(match_operand:SF 2 "register_operand" "0")
12874            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12875   "TARGET_SSE"
12876   "cmp%D1ss\t{%3, %0|%0, %3}"
12877   [(set_attr "type" "ssecmp")
12878    (set_attr "mode" "SF")])
12879
12880 (define_insn "*sse_setccdf"
12881   [(set (match_operand:DF 0 "register_operand" "=Y")
12882         (match_operator:DF 1 "sse_comparison_operator"
12883           [(match_operand:DF 2 "register_operand" "0")
12884            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12885   "TARGET_SSE2"
12886   "cmp%D1sd\t{%3, %0|%0, %3}"
12887   [(set_attr "type" "ssecmp")
12888    (set_attr "mode" "DF")])
12889 \f
12890 ;; Basic conditional jump instructions.
12891 ;; We ignore the overflow flag for signed branch instructions.
12892
12893 ;; For all bCOND expanders, also expand the compare or test insn that
12894 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12895
12896 (define_expand "beq"
12897   [(set (pc)
12898         (if_then_else (match_dup 1)
12899                       (label_ref (match_operand 0 "" ""))
12900                       (pc)))]
12901   ""
12902   "ix86_expand_branch (EQ, operands[0]); DONE;")
12903
12904 (define_expand "bne"
12905   [(set (pc)
12906         (if_then_else (match_dup 1)
12907                       (label_ref (match_operand 0 "" ""))
12908                       (pc)))]
12909   ""
12910   "ix86_expand_branch (NE, operands[0]); DONE;")
12911
12912 (define_expand "bgt"
12913   [(set (pc)
12914         (if_then_else (match_dup 1)
12915                       (label_ref (match_operand 0 "" ""))
12916                       (pc)))]
12917   ""
12918   "ix86_expand_branch (GT, operands[0]); DONE;")
12919
12920 (define_expand "bgtu"
12921   [(set (pc)
12922         (if_then_else (match_dup 1)
12923                       (label_ref (match_operand 0 "" ""))
12924                       (pc)))]
12925   ""
12926   "ix86_expand_branch (GTU, operands[0]); DONE;")
12927
12928 (define_expand "blt"
12929   [(set (pc)
12930         (if_then_else (match_dup 1)
12931                       (label_ref (match_operand 0 "" ""))
12932                       (pc)))]
12933   ""
12934   "ix86_expand_branch (LT, operands[0]); DONE;")
12935
12936 (define_expand "bltu"
12937   [(set (pc)
12938         (if_then_else (match_dup 1)
12939                       (label_ref (match_operand 0 "" ""))
12940                       (pc)))]
12941   ""
12942   "ix86_expand_branch (LTU, operands[0]); DONE;")
12943
12944 (define_expand "bge"
12945   [(set (pc)
12946         (if_then_else (match_dup 1)
12947                       (label_ref (match_operand 0 "" ""))
12948                       (pc)))]
12949   ""
12950   "ix86_expand_branch (GE, operands[0]); DONE;")
12951
12952 (define_expand "bgeu"
12953   [(set (pc)
12954         (if_then_else (match_dup 1)
12955                       (label_ref (match_operand 0 "" ""))
12956                       (pc)))]
12957   ""
12958   "ix86_expand_branch (GEU, operands[0]); DONE;")
12959
12960 (define_expand "ble"
12961   [(set (pc)
12962         (if_then_else (match_dup 1)
12963                       (label_ref (match_operand 0 "" ""))
12964                       (pc)))]
12965   ""
12966   "ix86_expand_branch (LE, operands[0]); DONE;")
12967
12968 (define_expand "bleu"
12969   [(set (pc)
12970         (if_then_else (match_dup 1)
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "ix86_expand_branch (LEU, operands[0]); DONE;")
12975
12976 (define_expand "bunordered"
12977   [(set (pc)
12978         (if_then_else (match_dup 1)
12979                       (label_ref (match_operand 0 "" ""))
12980                       (pc)))]
12981   "TARGET_80387 || TARGET_SSE_MATH"
12982   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12983
12984 (define_expand "bordered"
12985   [(set (pc)
12986         (if_then_else (match_dup 1)
12987                       (label_ref (match_operand 0 "" ""))
12988                       (pc)))]
12989   "TARGET_80387 || TARGET_SSE_MATH"
12990   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12991
12992 (define_expand "buneq"
12993   [(set (pc)
12994         (if_then_else (match_dup 1)
12995                       (label_ref (match_operand 0 "" ""))
12996                       (pc)))]
12997   "TARGET_80387 || TARGET_SSE_MATH"
12998   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12999
13000 (define_expand "bunge"
13001   [(set (pc)
13002         (if_then_else (match_dup 1)
13003                       (label_ref (match_operand 0 "" ""))
13004                       (pc)))]
13005   "TARGET_80387 || TARGET_SSE_MATH"
13006   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13007
13008 (define_expand "bungt"
13009   [(set (pc)
13010         (if_then_else (match_dup 1)
13011                       (label_ref (match_operand 0 "" ""))
13012                       (pc)))]
13013   "TARGET_80387 || TARGET_SSE_MATH"
13014   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13015
13016 (define_expand "bunle"
13017   [(set (pc)
13018         (if_then_else (match_dup 1)
13019                       (label_ref (match_operand 0 "" ""))
13020                       (pc)))]
13021   "TARGET_80387 || TARGET_SSE_MATH"
13022   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13023
13024 (define_expand "bunlt"
13025   [(set (pc)
13026         (if_then_else (match_dup 1)
13027                       (label_ref (match_operand 0 "" ""))
13028                       (pc)))]
13029   "TARGET_80387 || TARGET_SSE_MATH"
13030   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13031
13032 (define_expand "bltgt"
13033   [(set (pc)
13034         (if_then_else (match_dup 1)
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   "TARGET_80387 || TARGET_SSE_MATH"
13038   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13039
13040 (define_insn "*jcc_1"
13041   [(set (pc)
13042         (if_then_else (match_operator 1 "ix86_comparison_operator"
13043                                       [(reg FLAGS_REG) (const_int 0)])
13044                       (label_ref (match_operand 0 "" ""))
13045                       (pc)))]
13046   ""
13047   "%+j%C1\t%l0"
13048   [(set_attr "type" "ibr")
13049    (set_attr "modrm" "0")
13050    (set (attr "length")
13051            (if_then_else (and (ge (minus (match_dup 0) (pc))
13052                                   (const_int -126))
13053                               (lt (minus (match_dup 0) (pc))
13054                                   (const_int 128)))
13055              (const_int 2)
13056              (const_int 6)))])
13057
13058 (define_insn "*jcc_2"
13059   [(set (pc)
13060         (if_then_else (match_operator 1 "ix86_comparison_operator"
13061                                       [(reg FLAGS_REG) (const_int 0)])
13062                       (pc)
13063                       (label_ref (match_operand 0 "" ""))))]
13064   ""
13065   "%+j%c1\t%l0"
13066   [(set_attr "type" "ibr")
13067    (set_attr "modrm" "0")
13068    (set (attr "length")
13069            (if_then_else (and (ge (minus (match_dup 0) (pc))
13070                                   (const_int -126))
13071                               (lt (minus (match_dup 0) (pc))
13072                                   (const_int 128)))
13073              (const_int 2)
13074              (const_int 6)))])
13075
13076 ;; In general it is not safe to assume too much about CCmode registers,
13077 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13078 ;; conditions this is safe on x86, so help combine not create
13079 ;;
13080 ;;      seta    %al
13081 ;;      testb   %al, %al
13082 ;;      je      Lfoo
13083
13084 (define_split 
13085   [(set (pc)
13086         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13087                                       [(reg FLAGS_REG) (const_int 0)])
13088                           (const_int 0))
13089                       (label_ref (match_operand 1 "" ""))
13090                       (pc)))]
13091   ""
13092   [(set (pc)
13093         (if_then_else (match_dup 0)
13094                       (label_ref (match_dup 1))
13095                       (pc)))]
13096 {
13097   PUT_MODE (operands[0], VOIDmode);
13098 })
13099   
13100 (define_split 
13101   [(set (pc)
13102         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13103                                       [(reg FLAGS_REG) (const_int 0)])
13104                           (const_int 0))
13105                       (label_ref (match_operand 1 "" ""))
13106                       (pc)))]
13107   ""
13108   [(set (pc)
13109         (if_then_else (match_dup 0)
13110                       (label_ref (match_dup 1))
13111                       (pc)))]
13112 {
13113   rtx new_op0 = copy_rtx (operands[0]);
13114   operands[0] = new_op0;
13115   PUT_MODE (new_op0, VOIDmode);
13116   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13117                                              GET_MODE (XEXP (new_op0, 0))));
13118
13119   /* Make sure that (a) the CCmode we have for the flags is strong
13120      enough for the reversed compare or (b) we have a valid FP compare.  */
13121   if (! ix86_comparison_operator (new_op0, VOIDmode))
13122     FAIL;
13123 })
13124
13125 ;; Define combination compare-and-branch fp compare instructions to use
13126 ;; during early optimization.  Splitting the operation apart early makes
13127 ;; for bad code when we want to reverse the operation.
13128
13129 (define_insn "*fp_jcc_1_mixed"
13130   [(set (pc)
13131         (if_then_else (match_operator 0 "comparison_operator"
13132                         [(match_operand 1 "register_operand" "f#x,x#f")
13133                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13134           (label_ref (match_operand 3 "" ""))
13135           (pc)))
13136    (clobber (reg:CCFP FPSR_REG))
13137    (clobber (reg:CCFP FLAGS_REG))]
13138   "TARGET_MIX_SSE_I387
13139    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13140    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13141    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13142   "#")
13143
13144 (define_insn "*fp_jcc_1_sse"
13145   [(set (pc)
13146         (if_then_else (match_operator 0 "comparison_operator"
13147                         [(match_operand 1 "register_operand" "x")
13148                          (match_operand 2 "nonimmediate_operand" "xm")])
13149           (label_ref (match_operand 3 "" ""))
13150           (pc)))
13151    (clobber (reg:CCFP FPSR_REG))
13152    (clobber (reg:CCFP FLAGS_REG))]
13153   "TARGET_SSE_MATH
13154    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13155    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13156    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13157   "#")
13158
13159 (define_insn "*fp_jcc_1_387"
13160   [(set (pc)
13161         (if_then_else (match_operator 0 "comparison_operator"
13162                         [(match_operand 1 "register_operand" "f")
13163                          (match_operand 2 "register_operand" "f")])
13164           (label_ref (match_operand 3 "" ""))
13165           (pc)))
13166    (clobber (reg:CCFP FPSR_REG))
13167    (clobber (reg:CCFP FLAGS_REG))]
13168   "TARGET_CMOVE && TARGET_80387
13169    && FLOAT_MODE_P (GET_MODE (operands[1]))
13170    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13171    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13172   "#")
13173
13174 (define_insn "*fp_jcc_2_mixed"
13175   [(set (pc)
13176         (if_then_else (match_operator 0 "comparison_operator"
13177                         [(match_operand 1 "register_operand" "f#x,x#f")
13178                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13179           (pc)
13180           (label_ref (match_operand 3 "" ""))))
13181    (clobber (reg:CCFP FPSR_REG))
13182    (clobber (reg:CCFP FLAGS_REG))]
13183   "TARGET_MIX_SSE_I387
13184    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13185    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13186    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13187   "#")
13188
13189 (define_insn "*fp_jcc_2_sse"
13190   [(set (pc)
13191         (if_then_else (match_operator 0 "comparison_operator"
13192                         [(match_operand 1 "register_operand" "x")
13193                          (match_operand 2 "nonimmediate_operand" "xm")])
13194           (pc)
13195           (label_ref (match_operand 3 "" ""))))
13196    (clobber (reg:CCFP FPSR_REG))
13197    (clobber (reg:CCFP FLAGS_REG))]
13198   "TARGET_SSE_MATH
13199    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13200    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13202   "#")
13203
13204 (define_insn "*fp_jcc_2_387"
13205   [(set (pc)
13206         (if_then_else (match_operator 0 "comparison_operator"
13207                         [(match_operand 1 "register_operand" "f")
13208                          (match_operand 2 "register_operand" "f")])
13209           (pc)
13210           (label_ref (match_operand 3 "" ""))))
13211    (clobber (reg:CCFP FPSR_REG))
13212    (clobber (reg:CCFP FLAGS_REG))]
13213   "TARGET_CMOVE && TARGET_80387
13214    && FLOAT_MODE_P (GET_MODE (operands[1]))
13215    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13217   "#")
13218
13219 (define_insn "*fp_jcc_3_387"
13220   [(set (pc)
13221         (if_then_else (match_operator 0 "comparison_operator"
13222                         [(match_operand 1 "register_operand" "f")
13223                          (match_operand 2 "nonimmediate_operand" "fm")])
13224           (label_ref (match_operand 3 "" ""))
13225           (pc)))
13226    (clobber (reg:CCFP FPSR_REG))
13227    (clobber (reg:CCFP FLAGS_REG))
13228    (clobber (match_scratch:HI 4 "=a"))]
13229   "TARGET_80387
13230    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13231    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13232    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13233    && SELECT_CC_MODE (GET_CODE (operands[0]),
13234                       operands[1], operands[2]) == CCFPmode
13235    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13236   "#")
13237
13238 (define_insn "*fp_jcc_4_387"
13239   [(set (pc)
13240         (if_then_else (match_operator 0 "comparison_operator"
13241                         [(match_operand 1 "register_operand" "f")
13242                          (match_operand 2 "nonimmediate_operand" "fm")])
13243           (pc)
13244           (label_ref (match_operand 3 "" ""))))
13245    (clobber (reg:CCFP FPSR_REG))
13246    (clobber (reg:CCFP FLAGS_REG))
13247    (clobber (match_scratch:HI 4 "=a"))]
13248   "TARGET_80387
13249    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13250    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13251    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13252    && SELECT_CC_MODE (GET_CODE (operands[0]),
13253                       operands[1], operands[2]) == CCFPmode
13254    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13255   "#")
13256
13257 (define_insn "*fp_jcc_5_387"
13258   [(set (pc)
13259         (if_then_else (match_operator 0 "comparison_operator"
13260                         [(match_operand 1 "register_operand" "f")
13261                          (match_operand 2 "register_operand" "f")])
13262           (label_ref (match_operand 3 "" ""))
13263           (pc)))
13264    (clobber (reg:CCFP FPSR_REG))
13265    (clobber (reg:CCFP FLAGS_REG))
13266    (clobber (match_scratch:HI 4 "=a"))]
13267   "TARGET_80387
13268    && FLOAT_MODE_P (GET_MODE (operands[1]))
13269    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13270    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13271   "#")
13272
13273 (define_insn "*fp_jcc_6_387"
13274   [(set (pc)
13275         (if_then_else (match_operator 0 "comparison_operator"
13276                         [(match_operand 1 "register_operand" "f")
13277                          (match_operand 2 "register_operand" "f")])
13278           (pc)
13279           (label_ref (match_operand 3 "" ""))))
13280    (clobber (reg:CCFP FPSR_REG))
13281    (clobber (reg:CCFP FLAGS_REG))
13282    (clobber (match_scratch:HI 4 "=a"))]
13283   "TARGET_80387
13284    && FLOAT_MODE_P (GET_MODE (operands[1]))
13285    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13286    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13287   "#")
13288
13289 (define_insn "*fp_jcc_7_387"
13290   [(set (pc)
13291         (if_then_else (match_operator 0 "comparison_operator"
13292                         [(match_operand 1 "register_operand" "f")
13293                          (match_operand 2 "const0_operand" "X")])
13294           (label_ref (match_operand 3 "" ""))
13295           (pc)))
13296    (clobber (reg:CCFP FPSR_REG))
13297    (clobber (reg:CCFP FLAGS_REG))
13298    (clobber (match_scratch:HI 4 "=a"))]
13299   "TARGET_80387
13300    && FLOAT_MODE_P (GET_MODE (operands[1]))
13301    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13302    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13303    && SELECT_CC_MODE (GET_CODE (operands[0]),
13304                       operands[1], operands[2]) == CCFPmode
13305    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13306   "#")
13307
13308 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13309 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13310 ;; with a precedence over other operators and is always put in the first
13311 ;; place. Swap condition and operands to match ficom instruction.
13312
13313 (define_insn "*fp_jcc_8<mode>_387"
13314   [(set (pc)
13315         (if_then_else (match_operator 0 "comparison_operator"
13316                         [(match_operator 1 "float_operator"
13317                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13318                            (match_operand 3 "register_operand" "f,f")])
13319           (label_ref (match_operand 4 "" ""))
13320           (pc)))
13321    (clobber (reg:CCFP FPSR_REG))
13322    (clobber (reg:CCFP FLAGS_REG))
13323    (clobber (match_scratch:HI 5 "=a,a"))]
13324   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13325    && FLOAT_MODE_P (GET_MODE (operands[3]))
13326    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13327    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13328    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13329    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13330   "#")
13331
13332 (define_split
13333   [(set (pc)
13334         (if_then_else (match_operator 0 "comparison_operator"
13335                         [(match_operand 1 "register_operand" "")
13336                          (match_operand 2 "nonimmediate_operand" "")])
13337           (match_operand 3 "" "")
13338           (match_operand 4 "" "")))
13339    (clobber (reg:CCFP FPSR_REG))
13340    (clobber (reg:CCFP FLAGS_REG))]
13341   "reload_completed"
13342   [(const_int 0)]
13343 {
13344   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13345                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13346   DONE;
13347 })
13348
13349 (define_split
13350   [(set (pc)
13351         (if_then_else (match_operator 0 "comparison_operator"
13352                         [(match_operand 1 "register_operand" "")
13353                          (match_operand 2 "general_operand" "")])
13354           (match_operand 3 "" "")
13355           (match_operand 4 "" "")))
13356    (clobber (reg:CCFP FPSR_REG))
13357    (clobber (reg:CCFP FLAGS_REG))
13358    (clobber (match_scratch:HI 5 "=a"))]
13359   "reload_completed"
13360   [(const_int 0)]
13361 {
13362   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13363                         operands[3], operands[4], operands[5], NULL_RTX);
13364   DONE;
13365 })
13366
13367 (define_split
13368   [(set (pc)
13369         (if_then_else (match_operator 0 "comparison_operator"
13370                         [(match_operator 1 "float_operator"
13371                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13372                            (match_operand 3 "register_operand" "")])
13373           (match_operand 4 "" "")
13374           (match_operand 5 "" "")))
13375    (clobber (reg:CCFP FPSR_REG))
13376    (clobber (reg:CCFP FLAGS_REG))
13377    (clobber (match_scratch:HI 6 "=a"))]
13378   "reload_completed"
13379   [(const_int 0)]
13380 {
13381   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13382   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13383                         operands[3], operands[7],
13384                         operands[4], operands[5], operands[6], NULL_RTX);
13385   DONE;
13386 })
13387
13388 ;; %%% Kill this when reload knows how to do it.
13389 (define_split
13390   [(set (pc)
13391         (if_then_else (match_operator 0 "comparison_operator"
13392                         [(match_operator 1 "float_operator"
13393                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13394                            (match_operand 3 "register_operand" "")])
13395           (match_operand 4 "" "")
13396           (match_operand 5 "" "")))
13397    (clobber (reg:CCFP FPSR_REG))
13398    (clobber (reg:CCFP FLAGS_REG))
13399    (clobber (match_scratch:HI 6 "=a"))]
13400   "reload_completed"
13401   [(const_int 0)]
13402 {
13403   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13404   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13405   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13406                         operands[3], operands[7],
13407                         operands[4], operands[5], operands[6], operands[2]);
13408   DONE;
13409 })
13410 \f
13411 ;; Unconditional and other jump instructions
13412
13413 (define_insn "jump"
13414   [(set (pc)
13415         (label_ref (match_operand 0 "" "")))]
13416   ""
13417   "jmp\t%l0"
13418   [(set_attr "type" "ibr")
13419    (set (attr "length")
13420            (if_then_else (and (ge (minus (match_dup 0) (pc))
13421                                   (const_int -126))
13422                               (lt (minus (match_dup 0) (pc))
13423                                   (const_int 128)))
13424              (const_int 2)
13425              (const_int 5)))
13426    (set_attr "modrm" "0")])
13427
13428 (define_expand "indirect_jump"
13429   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13430   ""
13431   "")
13432
13433 (define_insn "*indirect_jump"
13434   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13435   "!TARGET_64BIT"
13436   "jmp\t%A0"
13437   [(set_attr "type" "ibr")
13438    (set_attr "length_immediate" "0")])
13439
13440 (define_insn "*indirect_jump_rtx64"
13441   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13442   "TARGET_64BIT"
13443   "jmp\t%A0"
13444   [(set_attr "type" "ibr")
13445    (set_attr "length_immediate" "0")])
13446
13447 (define_expand "tablejump"
13448   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13449               (use (label_ref (match_operand 1 "" "")))])]
13450   ""
13451 {
13452   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13453      relative.  Convert the relative address to an absolute address.  */
13454   if (flag_pic)
13455     {
13456       rtx op0, op1;
13457       enum rtx_code code;
13458
13459       if (TARGET_64BIT)
13460         {
13461           code = PLUS;
13462           op0 = operands[0];
13463           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13464         }
13465       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13466         {
13467           code = PLUS;
13468           op0 = operands[0];
13469           op1 = pic_offset_table_rtx;
13470         }
13471       else
13472         {
13473           code = MINUS;
13474           op0 = pic_offset_table_rtx;
13475           op1 = operands[0];
13476         }
13477
13478       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13479                                          OPTAB_DIRECT);
13480     }
13481 })
13482
13483 (define_insn "*tablejump_1"
13484   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13485    (use (label_ref (match_operand 1 "" "")))]
13486   "!TARGET_64BIT"
13487   "jmp\t%A0"
13488   [(set_attr "type" "ibr")
13489    (set_attr "length_immediate" "0")])
13490
13491 (define_insn "*tablejump_1_rtx64"
13492   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13493    (use (label_ref (match_operand 1 "" "")))]
13494   "TARGET_64BIT"
13495   "jmp\t%A0"
13496   [(set_attr "type" "ibr")
13497    (set_attr "length_immediate" "0")])
13498 \f
13499 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13500
13501 (define_peephole2
13502   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13503    (set (match_operand:QI 1 "register_operand" "")
13504         (match_operator:QI 2 "ix86_comparison_operator"
13505           [(reg FLAGS_REG) (const_int 0)]))
13506    (set (match_operand 3 "q_regs_operand" "")
13507         (zero_extend (match_dup 1)))]
13508   "(peep2_reg_dead_p (3, operands[1])
13509     || operands_match_p (operands[1], operands[3]))
13510    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13511   [(set (match_dup 4) (match_dup 0))
13512    (set (strict_low_part (match_dup 5))
13513         (match_dup 2))]
13514 {
13515   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13516   operands[5] = gen_lowpart (QImode, operands[3]);
13517   ix86_expand_clear (operands[3]);
13518 })
13519
13520 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13521
13522 (define_peephole2
13523   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13524    (set (match_operand:QI 1 "register_operand" "")
13525         (match_operator:QI 2 "ix86_comparison_operator"
13526           [(reg FLAGS_REG) (const_int 0)]))
13527    (parallel [(set (match_operand 3 "q_regs_operand" "")
13528                    (zero_extend (match_dup 1)))
13529               (clobber (reg:CC FLAGS_REG))])]
13530   "(peep2_reg_dead_p (3, operands[1])
13531     || operands_match_p (operands[1], operands[3]))
13532    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13533   [(set (match_dup 4) (match_dup 0))
13534    (set (strict_low_part (match_dup 5))
13535         (match_dup 2))]
13536 {
13537   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13538   operands[5] = gen_lowpart (QImode, operands[3]);
13539   ix86_expand_clear (operands[3]);
13540 })
13541 \f
13542 ;; Call instructions.
13543
13544 ;; The predicates normally associated with named expanders are not properly
13545 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13546 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13547
13548 ;; Call subroutine returning no value.
13549
13550 (define_expand "call_pop"
13551   [(parallel [(call (match_operand:QI 0 "" "")
13552                     (match_operand:SI 1 "" ""))
13553               (set (reg:SI SP_REG)
13554                    (plus:SI (reg:SI SP_REG)
13555                             (match_operand:SI 3 "" "")))])]
13556   "!TARGET_64BIT"
13557 {
13558   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13559   DONE;
13560 })
13561
13562 (define_insn "*call_pop_0"
13563   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13564          (match_operand:SI 1 "" ""))
13565    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13566                             (match_operand:SI 2 "immediate_operand" "")))]
13567   "!TARGET_64BIT"
13568 {
13569   if (SIBLING_CALL_P (insn))
13570     return "jmp\t%P0";
13571   else
13572     return "call\t%P0";
13573 }
13574   [(set_attr "type" "call")])
13575   
13576 (define_insn "*call_pop_1"
13577   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13578          (match_operand:SI 1 "" ""))
13579    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13580                             (match_operand:SI 2 "immediate_operand" "i")))]
13581   "!TARGET_64BIT"
13582 {
13583   if (constant_call_address_operand (operands[0], Pmode))
13584     {
13585       if (SIBLING_CALL_P (insn))
13586         return "jmp\t%P0";
13587       else
13588         return "call\t%P0";
13589     }
13590   if (SIBLING_CALL_P (insn))
13591     return "jmp\t%A0";
13592   else
13593     return "call\t%A0";
13594 }
13595   [(set_attr "type" "call")])
13596
13597 (define_expand "call"
13598   [(call (match_operand:QI 0 "" "")
13599          (match_operand 1 "" ""))
13600    (use (match_operand 2 "" ""))]
13601   ""
13602 {
13603   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13604   DONE;
13605 })
13606
13607 (define_expand "sibcall"
13608   [(call (match_operand:QI 0 "" "")
13609          (match_operand 1 "" ""))
13610    (use (match_operand 2 "" ""))]
13611   ""
13612 {
13613   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13614   DONE;
13615 })
13616
13617 (define_insn "*call_0"
13618   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13619          (match_operand 1 "" ""))]
13620   ""
13621 {
13622   if (SIBLING_CALL_P (insn))
13623     return "jmp\t%P0";
13624   else
13625     return "call\t%P0";
13626 }
13627   [(set_attr "type" "call")])
13628
13629 (define_insn "*call_1"
13630   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13631          (match_operand 1 "" ""))]
13632   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13633 {
13634   if (constant_call_address_operand (operands[0], Pmode))
13635     return "call\t%P0";
13636   return "call\t%A0";
13637 }
13638   [(set_attr "type" "call")])
13639
13640 (define_insn "*sibcall_1"
13641   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13642          (match_operand 1 "" ""))]
13643   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13644 {
13645   if (constant_call_address_operand (operands[0], Pmode))
13646     return "jmp\t%P0";
13647   return "jmp\t%A0";
13648 }
13649   [(set_attr "type" "call")])
13650
13651 (define_insn "*call_1_rex64"
13652   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13653          (match_operand 1 "" ""))]
13654   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13655 {
13656   if (constant_call_address_operand (operands[0], Pmode))
13657     return "call\t%P0";
13658   return "call\t%A0";
13659 }
13660   [(set_attr "type" "call")])
13661
13662 (define_insn "*sibcall_1_rex64"
13663   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13664          (match_operand 1 "" ""))]
13665   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13666   "jmp\t%P0"
13667   [(set_attr "type" "call")])
13668
13669 (define_insn "*sibcall_1_rex64_v"
13670   [(call (mem:QI (reg:DI 40))
13671          (match_operand 0 "" ""))]
13672   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13673   "jmp\t*%%r11"
13674   [(set_attr "type" "call")])
13675
13676
13677 ;; Call subroutine, returning value in operand 0
13678
13679 (define_expand "call_value_pop"
13680   [(parallel [(set (match_operand 0 "" "")
13681                    (call (match_operand:QI 1 "" "")
13682                          (match_operand:SI 2 "" "")))
13683               (set (reg:SI SP_REG)
13684                    (plus:SI (reg:SI SP_REG)
13685                             (match_operand:SI 4 "" "")))])]
13686   "!TARGET_64BIT"
13687 {
13688   ix86_expand_call (operands[0], operands[1], operands[2],
13689                     operands[3], operands[4], 0);
13690   DONE;
13691 })
13692
13693 (define_expand "call_value"
13694   [(set (match_operand 0 "" "")
13695         (call (match_operand:QI 1 "" "")
13696               (match_operand:SI 2 "" "")))
13697    (use (match_operand:SI 3 "" ""))]
13698   ;; Operand 2 not used on the i386.
13699   ""
13700 {
13701   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13702   DONE;
13703 })
13704
13705 (define_expand "sibcall_value"
13706   [(set (match_operand 0 "" "")
13707         (call (match_operand:QI 1 "" "")
13708               (match_operand:SI 2 "" "")))
13709    (use (match_operand:SI 3 "" ""))]
13710   ;; Operand 2 not used on the i386.
13711   ""
13712 {
13713   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13714   DONE;
13715 })
13716
13717 ;; Call subroutine returning any type.
13718
13719 (define_expand "untyped_call"
13720   [(parallel [(call (match_operand 0 "" "")
13721                     (const_int 0))
13722               (match_operand 1 "" "")
13723               (match_operand 2 "" "")])]
13724   ""
13725 {
13726   int i;
13727
13728   /* In order to give reg-stack an easier job in validating two
13729      coprocessor registers as containing a possible return value,
13730      simply pretend the untyped call returns a complex long double
13731      value.  */
13732
13733   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13734                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13735                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13736                     NULL, 0);
13737
13738   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13739     {
13740       rtx set = XVECEXP (operands[2], 0, i);
13741       emit_move_insn (SET_DEST (set), SET_SRC (set));
13742     }
13743
13744   /* The optimizer does not know that the call sets the function value
13745      registers we stored in the result block.  We avoid problems by
13746      claiming that all hard registers are used and clobbered at this
13747      point.  */
13748   emit_insn (gen_blockage (const0_rtx));
13749
13750   DONE;
13751 })
13752 \f
13753 ;; Prologue and epilogue instructions
13754
13755 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13756 ;; all of memory.  This blocks insns from being moved across this point.
13757
13758 (define_insn "blockage"
13759   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13760   ""
13761   ""
13762   [(set_attr "length" "0")])
13763
13764 ;; Insn emitted into the body of a function to return from a function.
13765 ;; This is only done if the function's epilogue is known to be simple.
13766 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13767
13768 (define_expand "return"
13769   [(return)]
13770   "ix86_can_use_return_insn_p ()"
13771 {
13772   if (current_function_pops_args)
13773     {
13774       rtx popc = GEN_INT (current_function_pops_args);
13775       emit_jump_insn (gen_return_pop_internal (popc));
13776       DONE;
13777     }
13778 })
13779
13780 (define_insn "return_internal"
13781   [(return)]
13782   "reload_completed"
13783   "ret"
13784   [(set_attr "length" "1")
13785    (set_attr "length_immediate" "0")
13786    (set_attr "modrm" "0")])
13787
13788 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13789 ;; instruction Athlon and K8 have.
13790
13791 (define_insn "return_internal_long"
13792   [(return)
13793    (unspec [(const_int 0)] UNSPEC_REP)]
13794   "reload_completed"
13795   "rep {;} ret"
13796   [(set_attr "length" "1")
13797    (set_attr "length_immediate" "0")
13798    (set_attr "prefix_rep" "1")
13799    (set_attr "modrm" "0")])
13800
13801 (define_insn "return_pop_internal"
13802   [(return)
13803    (use (match_operand:SI 0 "const_int_operand" ""))]
13804   "reload_completed"
13805   "ret\t%0"
13806   [(set_attr "length" "3")
13807    (set_attr "length_immediate" "2")
13808    (set_attr "modrm" "0")])
13809
13810 (define_insn "return_indirect_internal"
13811   [(return)
13812    (use (match_operand:SI 0 "register_operand" "r"))]
13813   "reload_completed"
13814   "jmp\t%A0"
13815   [(set_attr "type" "ibr")
13816    (set_attr "length_immediate" "0")])
13817
13818 (define_insn "nop"
13819   [(const_int 0)]
13820   ""
13821   "nop"
13822   [(set_attr "length" "1")
13823    (set_attr "length_immediate" "0")
13824    (set_attr "modrm" "0")])
13825
13826 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13827 ;; branch prediction penalty for the third jump in a 16-byte
13828 ;; block on K8.
13829
13830 (define_insn "align"
13831   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13832   ""
13833 {
13834 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13835   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13836 #else
13837   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13838      The align insn is used to avoid 3 jump instructions in the row to improve
13839      branch prediction and the benefits hardly outweight the cost of extra 8
13840      nops on the average inserted by full alignment pseudo operation.  */
13841 #endif
13842   return "";
13843 }
13844   [(set_attr "length" "16")])
13845
13846 (define_expand "prologue"
13847   [(const_int 1)]
13848   ""
13849   "ix86_expand_prologue (); DONE;")
13850
13851 (define_insn "set_got"
13852   [(set (match_operand:SI 0 "register_operand" "=r")
13853         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13854    (clobber (reg:CC FLAGS_REG))]
13855   "!TARGET_64BIT"
13856   { return output_set_got (operands[0]); }
13857   [(set_attr "type" "multi")
13858    (set_attr "length" "12")])
13859
13860 (define_insn "set_got_rex64"
13861   [(set (match_operand:DI 0 "register_operand" "=r")
13862         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13863   "TARGET_64BIT"
13864   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13865   [(set_attr "type" "lea")
13866    (set_attr "length" "6")])
13867
13868 (define_expand "epilogue"
13869   [(const_int 1)]
13870   ""
13871   "ix86_expand_epilogue (1); DONE;")
13872
13873 (define_expand "sibcall_epilogue"
13874   [(const_int 1)]
13875   ""
13876   "ix86_expand_epilogue (0); DONE;")
13877
13878 (define_expand "eh_return"
13879   [(use (match_operand 0 "register_operand" ""))]
13880   ""
13881 {
13882   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13883
13884   /* Tricky bit: we write the address of the handler to which we will
13885      be returning into someone else's stack frame, one word below the
13886      stack address we wish to restore.  */
13887   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13888   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13889   tmp = gen_rtx_MEM (Pmode, tmp);
13890   emit_move_insn (tmp, ra);
13891
13892   if (Pmode == SImode)
13893     emit_jump_insn (gen_eh_return_si (sa));
13894   else
13895     emit_jump_insn (gen_eh_return_di (sa));
13896   emit_barrier ();
13897   DONE;
13898 })
13899
13900 (define_insn_and_split "eh_return_si"
13901   [(set (pc) 
13902         (unspec [(match_operand:SI 0 "register_operand" "c")]
13903                  UNSPEC_EH_RETURN))]
13904   "!TARGET_64BIT"
13905   "#"
13906   "reload_completed"
13907   [(const_int 1)]
13908   "ix86_expand_epilogue (2); DONE;")
13909
13910 (define_insn_and_split "eh_return_di"
13911   [(set (pc) 
13912         (unspec [(match_operand:DI 0 "register_operand" "c")]
13913                  UNSPEC_EH_RETURN))]
13914   "TARGET_64BIT"
13915   "#"
13916   "reload_completed"
13917   [(const_int 1)]
13918   "ix86_expand_epilogue (2); DONE;")
13919
13920 (define_insn "leave"
13921   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13922    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13923    (clobber (mem:BLK (scratch)))]
13924   "!TARGET_64BIT"
13925   "leave"
13926   [(set_attr "type" "leave")])
13927
13928 (define_insn "leave_rex64"
13929   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13930    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13931    (clobber (mem:BLK (scratch)))]
13932   "TARGET_64BIT"
13933   "leave"
13934   [(set_attr "type" "leave")])
13935 \f
13936 (define_expand "ffssi2"
13937   [(parallel
13938      [(set (match_operand:SI 0 "register_operand" "") 
13939            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13940       (clobber (match_scratch:SI 2 ""))
13941       (clobber (reg:CC FLAGS_REG))])]
13942   ""
13943   "")
13944
13945 (define_insn_and_split "*ffs_cmove"
13946   [(set (match_operand:SI 0 "register_operand" "=r") 
13947         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13948    (clobber (match_scratch:SI 2 "=&r"))
13949    (clobber (reg:CC FLAGS_REG))]
13950   "TARGET_CMOVE"
13951   "#"
13952   "&& reload_completed"
13953   [(set (match_dup 2) (const_int -1))
13954    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13955               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13956    (set (match_dup 0) (if_then_else:SI
13957                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13958                         (match_dup 2)
13959                         (match_dup 0)))
13960    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13961               (clobber (reg:CC FLAGS_REG))])]
13962   "")
13963
13964 (define_insn_and_split "*ffs_no_cmove"
13965   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13966         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13967    (clobber (match_scratch:SI 2 "=&q"))
13968    (clobber (reg:CC FLAGS_REG))]
13969   ""
13970   "#"
13971   "reload_completed"
13972   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13973               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13974    (set (strict_low_part (match_dup 3))
13975         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13976    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13977               (clobber (reg:CC FLAGS_REG))])
13978    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13979               (clobber (reg:CC FLAGS_REG))])
13980    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13981               (clobber (reg:CC FLAGS_REG))])]
13982 {
13983   operands[3] = gen_lowpart (QImode, operands[2]);
13984   ix86_expand_clear (operands[2]);
13985 })
13986
13987 (define_insn "*ffssi_1"
13988   [(set (reg:CCZ FLAGS_REG)
13989         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13990                      (const_int 0)))
13991    (set (match_operand:SI 0 "register_operand" "=r")
13992         (ctz:SI (match_dup 1)))]
13993   ""
13994   "bsf{l}\t{%1, %0|%0, %1}"
13995   [(set_attr "prefix_0f" "1")])
13996
13997 (define_expand "ffsdi2"
13998   [(parallel
13999      [(set (match_operand:DI 0 "register_operand" "") 
14000            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14001       (clobber (match_scratch:DI 2 ""))
14002       (clobber (reg:CC FLAGS_REG))])]
14003   "TARGET_64BIT && TARGET_CMOVE"
14004   "")
14005
14006 (define_insn_and_split "*ffs_rex64"
14007   [(set (match_operand:DI 0 "register_operand" "=r") 
14008         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14009    (clobber (match_scratch:DI 2 "=&r"))
14010    (clobber (reg:CC FLAGS_REG))]
14011   "TARGET_64BIT && TARGET_CMOVE"
14012   "#"
14013   "&& reload_completed"
14014   [(set (match_dup 2) (const_int -1))
14015    (parallel [(set (reg:CCZ FLAGS_REG)
14016                    (compare:CCZ (match_dup 1) (const_int 0)))
14017               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14018    (set (match_dup 0) (if_then_else:DI
14019                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14020                         (match_dup 2)
14021                         (match_dup 0)))
14022    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14023               (clobber (reg:CC FLAGS_REG))])]
14024   "")
14025
14026 (define_insn "*ffsdi_1"
14027   [(set (reg:CCZ FLAGS_REG)
14028         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14029                      (const_int 0)))
14030    (set (match_operand:DI 0 "register_operand" "=r")
14031         (ctz:DI (match_dup 1)))]
14032   "TARGET_64BIT"
14033   "bsf{q}\t{%1, %0|%0, %1}"
14034   [(set_attr "prefix_0f" "1")])
14035
14036 (define_insn "ctzsi2"
14037   [(set (match_operand:SI 0 "register_operand" "=r")
14038         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14039    (clobber (reg:CC FLAGS_REG))]
14040   ""
14041   "bsf{l}\t{%1, %0|%0, %1}"
14042   [(set_attr "prefix_0f" "1")])
14043
14044 (define_insn "ctzdi2"
14045   [(set (match_operand:DI 0 "register_operand" "=r")
14046         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14047    (clobber (reg:CC FLAGS_REG))]
14048   "TARGET_64BIT"
14049   "bsf{q}\t{%1, %0|%0, %1}"
14050   [(set_attr "prefix_0f" "1")])
14051
14052 (define_expand "clzsi2"
14053   [(parallel
14054      [(set (match_operand:SI 0 "register_operand" "")
14055            (minus:SI (const_int 31)
14056                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14057       (clobber (reg:CC FLAGS_REG))])
14058    (parallel
14059      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14060       (clobber (reg:CC FLAGS_REG))])]
14061   ""
14062   "")
14063
14064 (define_insn "*bsr"
14065   [(set (match_operand:SI 0 "register_operand" "=r")
14066         (minus:SI (const_int 31)
14067                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14068    (clobber (reg:CC FLAGS_REG))]
14069   ""
14070   "bsr{l}\t{%1, %0|%0, %1}"
14071   [(set_attr "prefix_0f" "1")])
14072
14073 (define_expand "clzdi2"
14074   [(parallel
14075      [(set (match_operand:DI 0 "register_operand" "")
14076            (minus:DI (const_int 63)
14077                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14078       (clobber (reg:CC FLAGS_REG))])
14079    (parallel
14080      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14081       (clobber (reg:CC FLAGS_REG))])]
14082   "TARGET_64BIT"
14083   "")
14084
14085 (define_insn "*bsr_rex64"
14086   [(set (match_operand:DI 0 "register_operand" "=r")
14087         (minus:DI (const_int 63)
14088                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14089    (clobber (reg:CC FLAGS_REG))]
14090   "TARGET_64BIT"
14091   "bsr{q}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14093 \f
14094 ;; Thread-local storage patterns for ELF.
14095 ;;
14096 ;; Note that these code sequences must appear exactly as shown
14097 ;; in order to allow linker relaxation.
14098
14099 (define_insn "*tls_global_dynamic_32_gnu"
14100   [(set (match_operand:SI 0 "register_operand" "=a")
14101         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14102                     (match_operand:SI 2 "tls_symbolic_operand" "")
14103                     (match_operand:SI 3 "call_insn_operand" "")]
14104                     UNSPEC_TLS_GD))
14105    (clobber (match_scratch:SI 4 "=d"))
14106    (clobber (match_scratch:SI 5 "=c"))
14107    (clobber (reg:CC FLAGS_REG))]
14108   "!TARGET_64BIT && TARGET_GNU_TLS"
14109   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14110   [(set_attr "type" "multi")
14111    (set_attr "length" "12")])
14112
14113 (define_insn "*tls_global_dynamic_32_sun"
14114   [(set (match_operand:SI 0 "register_operand" "=a")
14115         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14116                     (match_operand:SI 2 "tls_symbolic_operand" "")
14117                     (match_operand:SI 3 "call_insn_operand" "")]
14118                     UNSPEC_TLS_GD))
14119    (clobber (match_scratch:SI 4 "=d"))
14120    (clobber (match_scratch:SI 5 "=c"))
14121    (clobber (reg:CC FLAGS_REG))]
14122   "!TARGET_64BIT && TARGET_SUN_TLS"
14123   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14124         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14125   [(set_attr "type" "multi")
14126    (set_attr "length" "14")])
14127
14128 (define_expand "tls_global_dynamic_32"
14129   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14130                    (unspec:SI
14131                     [(match_dup 2)
14132                      (match_operand:SI 1 "tls_symbolic_operand" "")
14133                      (match_dup 3)]
14134                     UNSPEC_TLS_GD))
14135               (clobber (match_scratch:SI 4 ""))
14136               (clobber (match_scratch:SI 5 ""))
14137               (clobber (reg:CC FLAGS_REG))])]
14138   ""
14139 {
14140   if (flag_pic)
14141     operands[2] = pic_offset_table_rtx;
14142   else
14143     {
14144       operands[2] = gen_reg_rtx (Pmode);
14145       emit_insn (gen_set_got (operands[2]));
14146     }
14147   operands[3] = ix86_tls_get_addr ();
14148 })
14149
14150 (define_insn "*tls_global_dynamic_64"
14151   [(set (match_operand:DI 0 "register_operand" "=a")
14152         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14153                  (match_operand:DI 3 "" "")))
14154    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14155               UNSPEC_TLS_GD)]
14156   "TARGET_64BIT"
14157   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14158   [(set_attr "type" "multi")
14159    (set_attr "length" "16")])
14160
14161 (define_expand "tls_global_dynamic_64"
14162   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14163                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14164               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14165                          UNSPEC_TLS_GD)])]
14166   ""
14167 {
14168   operands[2] = ix86_tls_get_addr ();
14169 })
14170
14171 (define_insn "*tls_local_dynamic_base_32_gnu"
14172   [(set (match_operand:SI 0 "register_operand" "=a")
14173         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14174                     (match_operand:SI 2 "call_insn_operand" "")]
14175                    UNSPEC_TLS_LD_BASE))
14176    (clobber (match_scratch:SI 3 "=d"))
14177    (clobber (match_scratch:SI 4 "=c"))
14178    (clobber (reg:CC FLAGS_REG))]
14179   "!TARGET_64BIT && TARGET_GNU_TLS"
14180   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14181   [(set_attr "type" "multi")
14182    (set_attr "length" "11")])
14183
14184 (define_insn "*tls_local_dynamic_base_32_sun"
14185   [(set (match_operand:SI 0 "register_operand" "=a")
14186         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14187                     (match_operand:SI 2 "call_insn_operand" "")]
14188                    UNSPEC_TLS_LD_BASE))
14189    (clobber (match_scratch:SI 3 "=d"))
14190    (clobber (match_scratch:SI 4 "=c"))
14191    (clobber (reg:CC FLAGS_REG))]
14192   "!TARGET_64BIT && TARGET_SUN_TLS"
14193   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14194         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14195   [(set_attr "type" "multi")
14196    (set_attr "length" "13")])
14197
14198 (define_expand "tls_local_dynamic_base_32"
14199   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14200                    (unspec:SI [(match_dup 1) (match_dup 2)]
14201                               UNSPEC_TLS_LD_BASE))
14202               (clobber (match_scratch:SI 3 ""))
14203               (clobber (match_scratch:SI 4 ""))
14204               (clobber (reg:CC FLAGS_REG))])]
14205   ""
14206 {
14207   if (flag_pic)
14208     operands[1] = pic_offset_table_rtx;
14209   else
14210     {
14211       operands[1] = gen_reg_rtx (Pmode);
14212       emit_insn (gen_set_got (operands[1]));
14213     }
14214   operands[2] = ix86_tls_get_addr ();
14215 })
14216
14217 (define_insn "*tls_local_dynamic_base_64"
14218   [(set (match_operand:DI 0 "register_operand" "=a")
14219         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14220                  (match_operand:DI 2 "" "")))
14221    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14222   "TARGET_64BIT"
14223   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14224   [(set_attr "type" "multi")
14225    (set_attr "length" "12")])
14226
14227 (define_expand "tls_local_dynamic_base_64"
14228   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14229                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14230               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14231   ""
14232 {
14233   operands[1] = ix86_tls_get_addr ();
14234 })
14235
14236 ;; Local dynamic of a single variable is a lose.  Show combine how
14237 ;; to convert that back to global dynamic.
14238
14239 (define_insn_and_split "*tls_local_dynamic_32_once"
14240   [(set (match_operand:SI 0 "register_operand" "=a")
14241         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14242                              (match_operand:SI 2 "call_insn_operand" "")]
14243                             UNSPEC_TLS_LD_BASE)
14244                  (const:SI (unspec:SI
14245                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14246                             UNSPEC_DTPOFF))))
14247    (clobber (match_scratch:SI 4 "=d"))
14248    (clobber (match_scratch:SI 5 "=c"))
14249    (clobber (reg:CC FLAGS_REG))]
14250   ""
14251   "#"
14252   ""
14253   [(parallel [(set (match_dup 0)
14254                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14255                               UNSPEC_TLS_GD))
14256               (clobber (match_dup 4))
14257               (clobber (match_dup 5))
14258               (clobber (reg:CC FLAGS_REG))])]
14259   "")
14260
14261 ;; Load and add the thread base pointer from %gs:0.
14262
14263 (define_insn "*load_tp_si"
14264   [(set (match_operand:SI 0 "register_operand" "=r")
14265         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14266   "!TARGET_64BIT"
14267   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14268   [(set_attr "type" "imov")
14269    (set_attr "modrm" "0")
14270    (set_attr "length" "7")
14271    (set_attr "memory" "load")
14272    (set_attr "imm_disp" "false")])
14273
14274 (define_insn "*add_tp_si"
14275   [(set (match_operand:SI 0 "register_operand" "=r")
14276         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14277                  (match_operand:SI 1 "register_operand" "0")))
14278    (clobber (reg:CC FLAGS_REG))]
14279   "!TARGET_64BIT"
14280   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14281   [(set_attr "type" "alu")
14282    (set_attr "modrm" "0")
14283    (set_attr "length" "7")
14284    (set_attr "memory" "load")
14285    (set_attr "imm_disp" "false")])
14286
14287 (define_insn "*load_tp_di"
14288   [(set (match_operand:DI 0 "register_operand" "=r")
14289         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14290   "TARGET_64BIT"
14291   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14292   [(set_attr "type" "imov")
14293    (set_attr "modrm" "0")
14294    (set_attr "length" "7")
14295    (set_attr "memory" "load")
14296    (set_attr "imm_disp" "false")])
14297
14298 (define_insn "*add_tp_di"
14299   [(set (match_operand:DI 0 "register_operand" "=r")
14300         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14301                  (match_operand:DI 1 "register_operand" "0")))
14302    (clobber (reg:CC FLAGS_REG))]
14303   "TARGET_64BIT"
14304   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14305   [(set_attr "type" "alu")
14306    (set_attr "modrm" "0")
14307    (set_attr "length" "7")
14308    (set_attr "memory" "load")
14309    (set_attr "imm_disp" "false")])
14310 \f
14311 ;; These patterns match the binary 387 instructions for addM3, subM3,
14312 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14313 ;; SFmode.  The first is the normal insn, the second the same insn but
14314 ;; with one operand a conversion, and the third the same insn but with
14315 ;; the other operand a conversion.  The conversion may be SFmode or
14316 ;; SImode if the target mode DFmode, but only SImode if the target mode
14317 ;; is SFmode.
14318
14319 ;; Gcc is slightly more smart about handling normal two address instructions
14320 ;; so use special patterns for add and mull.
14321
14322 (define_insn "*fop_sf_comm_mixed"
14323   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14324         (match_operator:SF 3 "binary_fp_operator"
14325                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14326                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14327   "TARGET_MIX_SSE_I387
14328    && COMMUTATIVE_ARITH_P (operands[3])
14329    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14330   "* return output_387_binary_op (insn, operands);"
14331   [(set (attr "type") 
14332         (if_then_else (eq_attr "alternative" "1")
14333            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14334               (const_string "ssemul")
14335               (const_string "sseadd"))
14336            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14337               (const_string "fmul")
14338               (const_string "fop"))))
14339    (set_attr "mode" "SF")])
14340
14341 (define_insn "*fop_sf_comm_sse"
14342   [(set (match_operand:SF 0 "register_operand" "=x")
14343         (match_operator:SF 3 "binary_fp_operator"
14344                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14345                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14346   "TARGET_SSE_MATH
14347    && COMMUTATIVE_ARITH_P (operands[3])
14348    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14349   "* return output_387_binary_op (insn, operands);"
14350   [(set (attr "type") 
14351         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14352            (const_string "ssemul")
14353            (const_string "sseadd")))
14354    (set_attr "mode" "SF")])
14355
14356 (define_insn "*fop_sf_comm_i387"
14357   [(set (match_operand:SF 0 "register_operand" "=f")
14358         (match_operator:SF 3 "binary_fp_operator"
14359                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14360                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14361   "TARGET_80387
14362    && COMMUTATIVE_ARITH_P (operands[3])
14363    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14364   "* return output_387_binary_op (insn, operands);"
14365   [(set (attr "type") 
14366         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14367            (const_string "fmul")
14368            (const_string "fop")))
14369    (set_attr "mode" "SF")])
14370
14371 (define_insn "*fop_sf_1_mixed"
14372   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14373         (match_operator:SF 3 "binary_fp_operator"
14374                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14375                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14376   "TARGET_MIX_SSE_I387
14377    && !COMMUTATIVE_ARITH_P (operands[3])
14378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14379   "* return output_387_binary_op (insn, operands);"
14380   [(set (attr "type") 
14381         (cond [(and (eq_attr "alternative" "2")
14382                     (match_operand:SF 3 "mult_operator" ""))
14383                  (const_string "ssemul")
14384                (and (eq_attr "alternative" "2")
14385                     (match_operand:SF 3 "div_operator" ""))
14386                  (const_string "ssediv")
14387                (eq_attr "alternative" "2")
14388                  (const_string "sseadd")
14389                (match_operand:SF 3 "mult_operator" "") 
14390                  (const_string "fmul")
14391                (match_operand:SF 3 "div_operator" "") 
14392                  (const_string "fdiv")
14393               ]
14394               (const_string "fop")))
14395    (set_attr "mode" "SF")])
14396
14397 (define_insn "*fop_sf_1_sse"
14398   [(set (match_operand:SF 0 "register_operand" "=x")
14399         (match_operator:SF 3 "binary_fp_operator"
14400                         [(match_operand:SF 1 "register_operand" "0")
14401                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14402   "TARGET_SSE_MATH
14403    && !COMMUTATIVE_ARITH_P (operands[3])"
14404   "* return output_387_binary_op (insn, operands);"
14405   [(set (attr "type") 
14406         (cond [(match_operand:SF 3 "mult_operator" "")
14407                  (const_string "ssemul")
14408                (match_operand:SF 3 "div_operator" "")
14409                  (const_string "ssediv")
14410               ]
14411               (const_string "sseadd")))
14412    (set_attr "mode" "SF")])
14413
14414 ;; This pattern is not fully shadowed by the pattern above.
14415 (define_insn "*fop_sf_1_i387"
14416   [(set (match_operand:SF 0 "register_operand" "=f,f")
14417         (match_operator:SF 3 "binary_fp_operator"
14418                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14419                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14420   "TARGET_80387 && !TARGET_SSE_MATH
14421    && !COMMUTATIVE_ARITH_P (operands[3])
14422    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14423   "* return output_387_binary_op (insn, operands);"
14424   [(set (attr "type") 
14425         (cond [(match_operand:SF 3 "mult_operator" "") 
14426                  (const_string "fmul")
14427                (match_operand:SF 3 "div_operator" "") 
14428                  (const_string "fdiv")
14429               ]
14430               (const_string "fop")))
14431    (set_attr "mode" "SF")])
14432
14433 ;; ??? Add SSE splitters for these!
14434 (define_insn "*fop_sf_2<mode>_i387"
14435   [(set (match_operand:SF 0 "register_operand" "=f,f")
14436         (match_operator:SF 3 "binary_fp_operator"
14437           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14438            (match_operand:SF 2 "register_operand" "0,0")]))]
14439   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14440   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14441   [(set (attr "type") 
14442         (cond [(match_operand:SF 3 "mult_operator" "") 
14443                  (const_string "fmul")
14444                (match_operand:SF 3 "div_operator" "") 
14445                  (const_string "fdiv")
14446               ]
14447               (const_string "fop")))
14448    (set_attr "fp_int_src" "true")
14449    (set_attr "mode" "<MODE>")])
14450
14451 (define_insn "*fop_sf_3<mode>_i387"
14452   [(set (match_operand:SF 0 "register_operand" "=f,f")
14453         (match_operator:SF 3 "binary_fp_operator"
14454           [(match_operand:SF 1 "register_operand" "0,0")
14455            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14456   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14457   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14458   [(set (attr "type") 
14459         (cond [(match_operand:SF 3 "mult_operator" "") 
14460                  (const_string "fmul")
14461                (match_operand:SF 3 "div_operator" "") 
14462                  (const_string "fdiv")
14463               ]
14464               (const_string "fop")))
14465    (set_attr "fp_int_src" "true")
14466    (set_attr "mode" "<MODE>")])
14467
14468 (define_insn "*fop_df_comm_mixed"
14469   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14470         (match_operator:DF 3 "binary_fp_operator"
14471                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14472                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14473   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14474    && COMMUTATIVE_ARITH_P (operands[3])
14475    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14476   "* return output_387_binary_op (insn, operands);"
14477   [(set (attr "type") 
14478         (if_then_else (eq_attr "alternative" "1")
14479            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14480               (const_string "ssemul")
14481               (const_string "sseadd"))
14482            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14483               (const_string "fmul")
14484               (const_string "fop"))))
14485    (set_attr "mode" "DF")])
14486
14487 (define_insn "*fop_df_comm_sse"
14488   [(set (match_operand:DF 0 "register_operand" "=Y")
14489         (match_operator:DF 3 "binary_fp_operator"
14490                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14491                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14492   "TARGET_SSE2 && TARGET_SSE_MATH
14493    && COMMUTATIVE_ARITH_P (operands[3])
14494    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14495   "* return output_387_binary_op (insn, operands);"
14496   [(set (attr "type") 
14497         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14498            (const_string "ssemul")
14499            (const_string "sseadd")))
14500    (set_attr "mode" "DF")])
14501
14502 (define_insn "*fop_df_comm_i387"
14503   [(set (match_operand:DF 0 "register_operand" "=f")
14504         (match_operator:DF 3 "binary_fp_operator"
14505                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14506                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14507   "TARGET_80387
14508    && COMMUTATIVE_ARITH_P (operands[3])
14509    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14510   "* return output_387_binary_op (insn, operands);"
14511   [(set (attr "type") 
14512         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14513            (const_string "fmul")
14514            (const_string "fop")))
14515    (set_attr "mode" "DF")])
14516
14517 (define_insn "*fop_df_1_mixed"
14518   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14519         (match_operator:DF 3 "binary_fp_operator"
14520                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14521                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14522   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14523    && !COMMUTATIVE_ARITH_P (operands[3])
14524    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14525   "* return output_387_binary_op (insn, operands);"
14526   [(set (attr "type") 
14527         (cond [(and (eq_attr "alternative" "2")
14528                     (match_operand:SF 3 "mult_operator" ""))
14529                  (const_string "ssemul")
14530                (and (eq_attr "alternative" "2")
14531                     (match_operand:SF 3 "div_operator" ""))
14532                  (const_string "ssediv")
14533                (eq_attr "alternative" "2")
14534                  (const_string "sseadd")
14535                (match_operand:DF 3 "mult_operator" "") 
14536                  (const_string "fmul")
14537                (match_operand:DF 3 "div_operator" "") 
14538                  (const_string "fdiv")
14539               ]
14540               (const_string "fop")))
14541    (set_attr "mode" "DF")])
14542
14543 (define_insn "*fop_df_1_sse"
14544   [(set (match_operand:DF 0 "register_operand" "=Y")
14545         (match_operator:DF 3 "binary_fp_operator"
14546                         [(match_operand:DF 1 "register_operand" "0")
14547                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14548   "TARGET_SSE2 && TARGET_SSE_MATH
14549    && !COMMUTATIVE_ARITH_P (operands[3])"
14550   "* return output_387_binary_op (insn, operands);"
14551   [(set_attr "mode" "DF")
14552    (set (attr "type") 
14553         (cond [(match_operand:SF 3 "mult_operator" "")
14554                  (const_string "ssemul")
14555                (match_operand:SF 3 "div_operator" "")
14556                  (const_string "ssediv")
14557               ]
14558               (const_string "sseadd")))])
14559
14560 ;; This pattern is not fully shadowed by the pattern above.
14561 (define_insn "*fop_df_1_i387"
14562   [(set (match_operand:DF 0 "register_operand" "=f,f")
14563         (match_operator:DF 3 "binary_fp_operator"
14564                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14565                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14566   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14567    && !COMMUTATIVE_ARITH_P (operands[3])
14568    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14569   "* return output_387_binary_op (insn, operands);"
14570   [(set (attr "type") 
14571         (cond [(match_operand:DF 3 "mult_operator" "") 
14572                  (const_string "fmul")
14573                (match_operand:DF 3 "div_operator" "")
14574                  (const_string "fdiv")
14575               ]
14576               (const_string "fop")))
14577    (set_attr "mode" "DF")])
14578
14579 ;; ??? Add SSE splitters for these!
14580 (define_insn "*fop_df_2<mode>_i387"
14581   [(set (match_operand:DF 0 "register_operand" "=f,f")
14582         (match_operator:DF 3 "binary_fp_operator"
14583            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14584             (match_operand:DF 2 "register_operand" "0,0")]))]
14585   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14586    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14587   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14588   [(set (attr "type") 
14589         (cond [(match_operand:DF 3 "mult_operator" "") 
14590                  (const_string "fmul")
14591                (match_operand:DF 3 "div_operator" "") 
14592                  (const_string "fdiv")
14593               ]
14594               (const_string "fop")))
14595    (set_attr "fp_int_src" "true")
14596    (set_attr "mode" "<MODE>")])
14597
14598 (define_insn "*fop_df_3<mode>_i387"
14599   [(set (match_operand:DF 0 "register_operand" "=f,f")
14600         (match_operator:DF 3 "binary_fp_operator"
14601            [(match_operand:DF 1 "register_operand" "0,0")
14602             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14603   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14604    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14605   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14606   [(set (attr "type") 
14607         (cond [(match_operand:DF 3 "mult_operator" "") 
14608                  (const_string "fmul")
14609                (match_operand:DF 3 "div_operator" "") 
14610                  (const_string "fdiv")
14611               ]
14612               (const_string "fop")))
14613    (set_attr "fp_int_src" "true")
14614    (set_attr "mode" "<MODE>")])
14615
14616 (define_insn "*fop_df_4_i387"
14617   [(set (match_operand:DF 0 "register_operand" "=f,f")
14618         (match_operator:DF 3 "binary_fp_operator"
14619            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14620             (match_operand:DF 2 "register_operand" "0,f")]))]
14621   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14622    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14623   "* return output_387_binary_op (insn, operands);"
14624   [(set (attr "type") 
14625         (cond [(match_operand:DF 3 "mult_operator" "") 
14626                  (const_string "fmul")
14627                (match_operand:DF 3 "div_operator" "") 
14628                  (const_string "fdiv")
14629               ]
14630               (const_string "fop")))
14631    (set_attr "mode" "SF")])
14632
14633 (define_insn "*fop_df_5_i387"
14634   [(set (match_operand:DF 0 "register_operand" "=f,f")
14635         (match_operator:DF 3 "binary_fp_operator"
14636           [(match_operand:DF 1 "register_operand" "0,f")
14637            (float_extend:DF
14638             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14639   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14640   "* return output_387_binary_op (insn, operands);"
14641   [(set (attr "type") 
14642         (cond [(match_operand:DF 3 "mult_operator" "") 
14643                  (const_string "fmul")
14644                (match_operand:DF 3 "div_operator" "") 
14645                  (const_string "fdiv")
14646               ]
14647               (const_string "fop")))
14648    (set_attr "mode" "SF")])
14649
14650 (define_insn "*fop_df_6_i387"
14651   [(set (match_operand:DF 0 "register_operand" "=f,f")
14652         (match_operator:DF 3 "binary_fp_operator"
14653           [(float_extend:DF
14654             (match_operand:SF 1 "register_operand" "0,f"))
14655            (float_extend:DF
14656             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14657   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14658   "* return output_387_binary_op (insn, operands);"
14659   [(set (attr "type") 
14660         (cond [(match_operand:DF 3 "mult_operator" "") 
14661                  (const_string "fmul")
14662                (match_operand:DF 3 "div_operator" "") 
14663                  (const_string "fdiv")
14664               ]
14665               (const_string "fop")))
14666    (set_attr "mode" "SF")])
14667
14668 (define_insn "*fop_xf_comm_i387"
14669   [(set (match_operand:XF 0 "register_operand" "=f")
14670         (match_operator:XF 3 "binary_fp_operator"
14671                         [(match_operand:XF 1 "register_operand" "%0")
14672                          (match_operand:XF 2 "register_operand" "f")]))]
14673   "TARGET_80387
14674    && COMMUTATIVE_ARITH_P (operands[3])"
14675   "* return output_387_binary_op (insn, operands);"
14676   [(set (attr "type") 
14677         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14678            (const_string "fmul")
14679            (const_string "fop")))
14680    (set_attr "mode" "XF")])
14681
14682 (define_insn "*fop_xf_1_i387"
14683   [(set (match_operand:XF 0 "register_operand" "=f,f")
14684         (match_operator:XF 3 "binary_fp_operator"
14685                         [(match_operand:XF 1 "register_operand" "0,f")
14686                          (match_operand:XF 2 "register_operand" "f,0")]))]
14687   "TARGET_80387
14688    && !COMMUTATIVE_ARITH_P (operands[3])"
14689   "* return output_387_binary_op (insn, operands);"
14690   [(set (attr "type") 
14691         (cond [(match_operand:XF 3 "mult_operator" "") 
14692                  (const_string "fmul")
14693                (match_operand:XF 3 "div_operator" "") 
14694                  (const_string "fdiv")
14695               ]
14696               (const_string "fop")))
14697    (set_attr "mode" "XF")])
14698
14699 (define_insn "*fop_xf_2<mode>_i387"
14700   [(set (match_operand:XF 0 "register_operand" "=f,f")
14701         (match_operator:XF 3 "binary_fp_operator"
14702            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14703             (match_operand:XF 2 "register_operand" "0,0")]))]
14704   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14705   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "fp_int_src" "true")
14714    (set_attr "mode" "<MODE>")])
14715
14716 (define_insn "*fop_xf_3<mode>_i387"
14717   [(set (match_operand:XF 0 "register_operand" "=f,f")
14718         (match_operator:XF 3 "binary_fp_operator"
14719           [(match_operand:XF 1 "register_operand" "0,0")
14720            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14721   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14722   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14723   [(set (attr "type") 
14724         (cond [(match_operand:XF 3 "mult_operator" "") 
14725                  (const_string "fmul")
14726                (match_operand:XF 3 "div_operator" "") 
14727                  (const_string "fdiv")
14728               ]
14729               (const_string "fop")))
14730    (set_attr "fp_int_src" "true")
14731    (set_attr "mode" "<MODE>")])
14732
14733 (define_insn "*fop_xf_4_i387"
14734   [(set (match_operand:XF 0 "register_operand" "=f,f")
14735         (match_operator:XF 3 "binary_fp_operator"
14736            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14737             (match_operand:XF 2 "register_operand" "0,f")]))]
14738   "TARGET_80387"
14739   "* return output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(match_operand:XF 3 "mult_operator" "") 
14742                  (const_string "fmul")
14743                (match_operand:XF 3 "div_operator" "") 
14744                  (const_string "fdiv")
14745               ]
14746               (const_string "fop")))
14747    (set_attr "mode" "SF")])
14748
14749 (define_insn "*fop_xf_5_i387"
14750   [(set (match_operand:XF 0 "register_operand" "=f,f")
14751         (match_operator:XF 3 "binary_fp_operator"
14752           [(match_operand:XF 1 "register_operand" "0,f")
14753            (float_extend:XF
14754             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14755   "TARGET_80387"
14756   "* return output_387_binary_op (insn, operands);"
14757   [(set (attr "type") 
14758         (cond [(match_operand:XF 3 "mult_operator" "") 
14759                  (const_string "fmul")
14760                (match_operand:XF 3 "div_operator" "") 
14761                  (const_string "fdiv")
14762               ]
14763               (const_string "fop")))
14764    (set_attr "mode" "SF")])
14765
14766 (define_insn "*fop_xf_6_i387"
14767   [(set (match_operand:XF 0 "register_operand" "=f,f")
14768         (match_operator:XF 3 "binary_fp_operator"
14769           [(float_extend:XF
14770             (match_operand 1 "register_operand" "0,f"))
14771            (float_extend:XF
14772             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14773   "TARGET_80387"
14774   "* return output_387_binary_op (insn, operands);"
14775   [(set (attr "type") 
14776         (cond [(match_operand:XF 3 "mult_operator" "") 
14777                  (const_string "fmul")
14778                (match_operand:XF 3 "div_operator" "") 
14779                  (const_string "fdiv")
14780               ]
14781               (const_string "fop")))
14782    (set_attr "mode" "SF")])
14783
14784 (define_split
14785   [(set (match_operand 0 "register_operand" "")
14786         (match_operator 3 "binary_fp_operator"
14787            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14788             (match_operand 2 "register_operand" "")]))]
14789   "TARGET_80387 && reload_completed
14790    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14791   [(const_int 0)]
14792
14793   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14794   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14795   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14796                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14797                                           GET_MODE (operands[3]),
14798                                           operands[4],
14799                                           operands[2])));
14800   ix86_free_from_memory (GET_MODE (operands[1]));
14801   DONE;
14802 })
14803
14804 (define_split
14805   [(set (match_operand 0 "register_operand" "")
14806         (match_operator 3 "binary_fp_operator"
14807            [(match_operand 1 "register_operand" "")
14808             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14809   "TARGET_80387 && reload_completed
14810    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14811   [(const_int 0)]
14812 {
14813   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14814   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14815   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14816                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14817                                           GET_MODE (operands[3]),
14818                                           operands[1],
14819                                           operands[4])));
14820   ix86_free_from_memory (GET_MODE (operands[2]));
14821   DONE;
14822 })
14823 \f
14824 ;; FPU special functions.
14825
14826 (define_expand "sqrtsf2"
14827   [(set (match_operand:SF 0 "register_operand" "")
14828         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14829   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14830 {
14831   if (!TARGET_SSE_MATH)
14832     operands[1] = force_reg (SFmode, operands[1]);
14833 })
14834
14835 (define_insn "*sqrtsf2_mixed"
14836   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14837         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14838   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14839   "@
14840    fsqrt
14841    sqrtss\t{%1, %0|%0, %1}"
14842   [(set_attr "type" "fpspc,sse")
14843    (set_attr "mode" "SF,SF")
14844    (set_attr "athlon_decode" "direct,*")])
14845
14846 (define_insn "*sqrtsf2_sse"
14847   [(set (match_operand:SF 0 "register_operand" "=x")
14848         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14849   "TARGET_SSE_MATH"
14850   "sqrtss\t{%1, %0|%0, %1}"
14851   [(set_attr "type" "sse")
14852    (set_attr "mode" "SF")
14853    (set_attr "athlon_decode" "*")])
14854
14855 (define_insn "*sqrtsf2_i387"
14856   [(set (match_operand:SF 0 "register_operand" "=f")
14857         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14858   "TARGET_USE_FANCY_MATH_387"
14859   "fsqrt"
14860   [(set_attr "type" "fpspc")
14861    (set_attr "mode" "SF")
14862    (set_attr "athlon_decode" "direct")])
14863
14864 (define_expand "sqrtdf2"
14865   [(set (match_operand:DF 0 "register_operand" "")
14866         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14867   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14868 {
14869   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14870     operands[1] = force_reg (DFmode, operands[1]);
14871 })
14872
14873 (define_insn "*sqrtdf2_mixed"
14874   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14875         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14876   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14877   "@
14878    fsqrt
14879    sqrtsd\t{%1, %0|%0, %1}"
14880   [(set_attr "type" "fpspc,sse")
14881    (set_attr "mode" "DF,DF")
14882    (set_attr "athlon_decode" "direct,*")])
14883
14884 (define_insn "*sqrtdf2_sse"
14885   [(set (match_operand:DF 0 "register_operand" "=Y")
14886         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14887   "TARGET_SSE2 && TARGET_SSE_MATH"
14888   "sqrtsd\t{%1, %0|%0, %1}"
14889   [(set_attr "type" "sse")
14890    (set_attr "mode" "DF")
14891    (set_attr "athlon_decode" "*")])
14892
14893 (define_insn "*sqrtdf2_i387"
14894   [(set (match_operand:DF 0 "register_operand" "=f")
14895         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14896   "TARGET_USE_FANCY_MATH_387"
14897   "fsqrt"
14898   [(set_attr "type" "fpspc")
14899    (set_attr "mode" "DF")
14900    (set_attr "athlon_decode" "direct")])
14901
14902 (define_insn "*sqrtextendsfdf2_i387"
14903   [(set (match_operand:DF 0 "register_operand" "=f")
14904         (sqrt:DF (float_extend:DF
14905                   (match_operand:SF 1 "register_operand" "0"))))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14908   "fsqrt"
14909   [(set_attr "type" "fpspc")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "direct")])
14912
14913 (define_insn "sqrtxf2"
14914   [(set (match_operand:XF 0 "register_operand" "=f")
14915         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14916   "TARGET_USE_FANCY_MATH_387 
14917    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "XF")
14921    (set_attr "athlon_decode" "direct")])
14922
14923 (define_insn "*sqrtextendsfxf2_i387"
14924   [(set (match_operand:XF 0 "register_operand" "=f")
14925         (sqrt:XF (float_extend:XF
14926                   (match_operand:SF 1 "register_operand" "0"))))]
14927   "TARGET_USE_FANCY_MATH_387"
14928   "fsqrt"
14929   [(set_attr "type" "fpspc")
14930    (set_attr "mode" "XF")
14931    (set_attr "athlon_decode" "direct")])
14932
14933 (define_insn "*sqrtextenddfxf2_i387"
14934   [(set (match_operand:XF 0 "register_operand" "=f")
14935         (sqrt:XF (float_extend:XF
14936                   (match_operand:DF 1 "register_operand" "0"))))]
14937   "TARGET_USE_FANCY_MATH_387"
14938   "fsqrt"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "XF")
14941    (set_attr "athlon_decode" "direct")])
14942
14943 (define_insn "fpremxf4"
14944   [(set (match_operand:XF 0 "register_operand" "=f")
14945         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14946                     (match_operand:XF 3 "register_operand" "1")]
14947                    UNSPEC_FPREM_F))
14948    (set (match_operand:XF 1 "register_operand" "=u")
14949         (unspec:XF [(match_dup 2) (match_dup 3)]
14950                    UNSPEC_FPREM_U))
14951    (set (reg:CCFP FPSR_REG)
14952         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14953   "TARGET_USE_FANCY_MATH_387
14954    && flag_unsafe_math_optimizations"
14955   "fprem"
14956   [(set_attr "type" "fpspc")
14957    (set_attr "mode" "XF")])
14958
14959 (define_expand "fmodsf3"
14960   [(use (match_operand:SF 0 "register_operand" ""))
14961    (use (match_operand:SF 1 "register_operand" ""))
14962    (use (match_operand:SF 2 "register_operand" ""))]
14963   "TARGET_USE_FANCY_MATH_387
14964    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14965    && flag_unsafe_math_optimizations"
14966 {
14967   rtx label = gen_label_rtx ();
14968
14969   rtx op1 = gen_reg_rtx (XFmode);
14970   rtx op2 = gen_reg_rtx (XFmode);
14971
14972   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14973   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14974
14975   emit_label (label);
14976
14977   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14978   ix86_emit_fp_unordered_jump (label);
14979
14980   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14981   DONE;
14982 })
14983
14984 (define_expand "fmoddf3"
14985   [(use (match_operand:DF 0 "register_operand" ""))
14986    (use (match_operand:DF 1 "register_operand" ""))
14987    (use (match_operand:DF 2 "register_operand" ""))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14990    && flag_unsafe_math_optimizations"
14991 {
14992   rtx label = gen_label_rtx ();
14993
14994   rtx op1 = gen_reg_rtx (XFmode);
14995   rtx op2 = gen_reg_rtx (XFmode);
14996
14997   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14998   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14999
15000   emit_label (label);
15001
15002   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15003   ix86_emit_fp_unordered_jump (label);
15004
15005   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15006   DONE;
15007 })
15008
15009 (define_expand "fmodxf3"
15010   [(use (match_operand:XF 0 "register_operand" ""))
15011    (use (match_operand:XF 1 "register_operand" ""))
15012    (use (match_operand:XF 2 "register_operand" ""))]
15013   "TARGET_USE_FANCY_MATH_387
15014    && flag_unsafe_math_optimizations"
15015 {
15016   rtx label = gen_label_rtx ();
15017
15018   emit_label (label);
15019
15020   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15021                            operands[1], operands[2]));
15022   ix86_emit_fp_unordered_jump (label);
15023
15024   emit_move_insn (operands[0], operands[1]);
15025   DONE;
15026 })
15027
15028 (define_insn "fprem1xf4"
15029   [(set (match_operand:XF 0 "register_operand" "=f")
15030         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15031                     (match_operand:XF 3 "register_operand" "1")]
15032                    UNSPEC_FPREM1_F))
15033    (set (match_operand:XF 1 "register_operand" "=u")
15034         (unspec:XF [(match_dup 2) (match_dup 3)]
15035                    UNSPEC_FPREM1_U))
15036    (set (reg:CCFP FPSR_REG)
15037         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15038   "TARGET_USE_FANCY_MATH_387
15039    && flag_unsafe_math_optimizations"
15040   "fprem1"
15041   [(set_attr "type" "fpspc")
15042    (set_attr "mode" "XF")])
15043
15044 (define_expand "dremsf3"
15045   [(use (match_operand:SF 0 "register_operand" ""))
15046    (use (match_operand:SF 1 "register_operand" ""))
15047    (use (match_operand:SF 2 "register_operand" ""))]
15048   "TARGET_USE_FANCY_MATH_387
15049    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15050    && flag_unsafe_math_optimizations"
15051 {
15052   rtx label = gen_label_rtx ();
15053
15054   rtx op1 = gen_reg_rtx (XFmode);
15055   rtx op2 = gen_reg_rtx (XFmode);
15056
15057   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15058   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15059
15060   emit_label (label);
15061
15062   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15063   ix86_emit_fp_unordered_jump (label);
15064
15065   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15066   DONE;
15067 })
15068
15069 (define_expand "dremdf3"
15070   [(use (match_operand:DF 0 "register_operand" ""))
15071    (use (match_operand:DF 1 "register_operand" ""))
15072    (use (match_operand:DF 2 "register_operand" ""))]
15073   "TARGET_USE_FANCY_MATH_387
15074    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15075    && flag_unsafe_math_optimizations"
15076 {
15077   rtx label = gen_label_rtx ();
15078
15079   rtx op1 = gen_reg_rtx (XFmode);
15080   rtx op2 = gen_reg_rtx (XFmode);
15081
15082   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15083   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15084
15085   emit_label (label);
15086
15087   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15088   ix86_emit_fp_unordered_jump (label);
15089
15090   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15091   DONE;
15092 })
15093
15094 (define_expand "dremxf3"
15095   [(use (match_operand:XF 0 "register_operand" ""))
15096    (use (match_operand:XF 1 "register_operand" ""))
15097    (use (match_operand:XF 2 "register_operand" ""))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && flag_unsafe_math_optimizations"
15100 {
15101   rtx label = gen_label_rtx ();
15102
15103   emit_label (label);
15104
15105   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15106                             operands[1], operands[2]));
15107   ix86_emit_fp_unordered_jump (label);
15108
15109   emit_move_insn (operands[0], operands[1]);
15110   DONE;
15111 })
15112
15113 (define_insn "*sindf2"
15114   [(set (match_operand:DF 0 "register_operand" "=f")
15115         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15118    && flag_unsafe_math_optimizations"
15119   "fsin"
15120   [(set_attr "type" "fpspc")
15121    (set_attr "mode" "DF")])
15122
15123 (define_insn "*sinsf2"
15124   [(set (match_operand:SF 0 "register_operand" "=f")
15125         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15128    && flag_unsafe_math_optimizations"
15129   "fsin"
15130   [(set_attr "type" "fpspc")
15131    (set_attr "mode" "SF")])
15132
15133 (define_insn "*sinextendsfdf2"
15134   [(set (match_operand:DF 0 "register_operand" "=f")
15135         (unspec:DF [(float_extend:DF
15136                      (match_operand:SF 1 "register_operand" "0"))]
15137                    UNSPEC_SIN))]
15138   "TARGET_USE_FANCY_MATH_387
15139    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15140    && flag_unsafe_math_optimizations"
15141   "fsin"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "DF")])
15144
15145 (define_insn "*sinxf2"
15146   [(set (match_operand:XF 0 "register_operand" "=f")
15147         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && flag_unsafe_math_optimizations"
15150   "fsin"
15151   [(set_attr "type" "fpspc")
15152    (set_attr "mode" "XF")])
15153
15154 (define_insn "*cosdf2"
15155   [(set (match_operand:DF 0 "register_operand" "=f")
15156         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15157   "TARGET_USE_FANCY_MATH_387
15158    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15159    && flag_unsafe_math_optimizations"
15160   "fcos"
15161   [(set_attr "type" "fpspc")
15162    (set_attr "mode" "DF")])
15163
15164 (define_insn "*cossf2"
15165   [(set (match_operand:SF 0 "register_operand" "=f")
15166         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15167   "TARGET_USE_FANCY_MATH_387
15168    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15169    && flag_unsafe_math_optimizations"
15170   "fcos"
15171   [(set_attr "type" "fpspc")
15172    (set_attr "mode" "SF")])
15173
15174 (define_insn "*cosextendsfdf2"
15175   [(set (match_operand:DF 0 "register_operand" "=f")
15176         (unspec:DF [(float_extend:DF
15177                      (match_operand:SF 1 "register_operand" "0"))]
15178                    UNSPEC_COS))]
15179   "TARGET_USE_FANCY_MATH_387
15180    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "DF")])
15185
15186 (define_insn "*cosxf2"
15187   [(set (match_operand:XF 0 "register_operand" "=f")
15188         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15189   "TARGET_USE_FANCY_MATH_387
15190    && flag_unsafe_math_optimizations"
15191   "fcos"
15192   [(set_attr "type" "fpspc")
15193    (set_attr "mode" "XF")])
15194
15195 ;; With sincos pattern defined, sin and cos builtin function will be
15196 ;; expanded to sincos pattern with one of its outputs left unused. 
15197 ;; Cse pass  will detected, if two sincos patterns can be combined,
15198 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15199 ;; depending on the unused output.
15200
15201 (define_insn "sincosdf3"
15202   [(set (match_operand:DF 0 "register_operand" "=f")
15203         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15204                    UNSPEC_SINCOS_COS))
15205    (set (match_operand:DF 1 "register_operand" "=u")
15206         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15209    && flag_unsafe_math_optimizations"
15210   "fsincos"
15211   [(set_attr "type" "fpspc")
15212    (set_attr "mode" "DF")])
15213
15214 (define_split
15215   [(set (match_operand:DF 0 "register_operand" "")
15216         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15217                    UNSPEC_SINCOS_COS))
15218    (set (match_operand:DF 1 "register_operand" "")
15219         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15220   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15221    && !reload_completed && !reload_in_progress"
15222   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15223   "")
15224
15225 (define_split
15226   [(set (match_operand:DF 0 "register_operand" "")
15227         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15228                    UNSPEC_SINCOS_COS))
15229    (set (match_operand:DF 1 "register_operand" "")
15230         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15231   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15232    && !reload_completed && !reload_in_progress"
15233   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15234   "")
15235
15236 (define_insn "sincossf3"
15237   [(set (match_operand:SF 0 "register_operand" "=f")
15238         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15239                    UNSPEC_SINCOS_COS))
15240    (set (match_operand:SF 1 "register_operand" "=u")
15241         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242   "TARGET_USE_FANCY_MATH_387
15243    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15244    && flag_unsafe_math_optimizations"
15245   "fsincos"
15246   [(set_attr "type" "fpspc")
15247    (set_attr "mode" "SF")])
15248
15249 (define_split
15250   [(set (match_operand:SF 0 "register_operand" "")
15251         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15252                    UNSPEC_SINCOS_COS))
15253    (set (match_operand:SF 1 "register_operand" "")
15254         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15255   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15256    && !reload_completed && !reload_in_progress"
15257   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15258   "")
15259
15260 (define_split
15261   [(set (match_operand:SF 0 "register_operand" "")
15262         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15263                    UNSPEC_SINCOS_COS))
15264    (set (match_operand:SF 1 "register_operand" "")
15265         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15266   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15267    && !reload_completed && !reload_in_progress"
15268   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15269   "")
15270
15271 (define_insn "*sincosextendsfdf3"
15272   [(set (match_operand:DF 0 "register_operand" "=f")
15273         (unspec:DF [(float_extend:DF
15274                      (match_operand:SF 2 "register_operand" "0"))]
15275                    UNSPEC_SINCOS_COS))
15276    (set (match_operand:DF 1 "register_operand" "=u")
15277         (unspec:DF [(float_extend:DF
15278                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15279   "TARGET_USE_FANCY_MATH_387
15280    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15281    && flag_unsafe_math_optimizations"
15282   "fsincos"
15283   [(set_attr "type" "fpspc")
15284    (set_attr "mode" "DF")])
15285
15286 (define_split
15287   [(set (match_operand:DF 0 "register_operand" "")
15288         (unspec:DF [(float_extend:DF
15289                      (match_operand:SF 2 "register_operand" ""))]
15290                    UNSPEC_SINCOS_COS))
15291    (set (match_operand:DF 1 "register_operand" "")
15292         (unspec:DF [(float_extend:DF
15293                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15294   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15295    && !reload_completed && !reload_in_progress"
15296   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15297                                    (match_dup 2))] UNSPEC_SIN))]
15298   "")
15299
15300 (define_split
15301   [(set (match_operand:DF 0 "register_operand" "")
15302         (unspec:DF [(float_extend:DF
15303                      (match_operand:SF 2 "register_operand" ""))]
15304                    UNSPEC_SINCOS_COS))
15305    (set (match_operand:DF 1 "register_operand" "")
15306         (unspec:DF [(float_extend:DF
15307                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15308   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15309    && !reload_completed && !reload_in_progress"
15310   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15311                                    (match_dup 2))] UNSPEC_COS))]
15312   "")
15313
15314 (define_insn "sincosxf3"
15315   [(set (match_operand:XF 0 "register_operand" "=f")
15316         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15317                    UNSPEC_SINCOS_COS))
15318    (set (match_operand:XF 1 "register_operand" "=u")
15319         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15320   "TARGET_USE_FANCY_MATH_387
15321    && flag_unsafe_math_optimizations"
15322   "fsincos"
15323   [(set_attr "type" "fpspc")
15324    (set_attr "mode" "XF")])
15325
15326 (define_split
15327   [(set (match_operand:XF 0 "register_operand" "")
15328         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15329                    UNSPEC_SINCOS_COS))
15330    (set (match_operand:XF 1 "register_operand" "")
15331         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15332   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15333    && !reload_completed && !reload_in_progress"
15334   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15335   "")
15336
15337 (define_split
15338   [(set (match_operand:XF 0 "register_operand" "")
15339         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15340                    UNSPEC_SINCOS_COS))
15341    (set (match_operand:XF 1 "register_operand" "")
15342         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15343   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15344    && !reload_completed && !reload_in_progress"
15345   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15346   "")
15347
15348 (define_insn "*tandf3_1"
15349   [(set (match_operand:DF 0 "register_operand" "=f")
15350         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15351                    UNSPEC_TAN_ONE))
15352    (set (match_operand:DF 1 "register_operand" "=u")
15353         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15354   "TARGET_USE_FANCY_MATH_387
15355    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15356    && flag_unsafe_math_optimizations"
15357   "fptan"
15358   [(set_attr "type" "fpspc")
15359    (set_attr "mode" "DF")])
15360
15361 ;; optimize sequence: fptan
15362 ;;                    fstp    %st(0)
15363 ;;                    fld1
15364 ;; into fptan insn.
15365
15366 (define_peephole2
15367   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15368                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15369                              UNSPEC_TAN_ONE))
15370              (set (match_operand:DF 1 "register_operand" "")
15371                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15372    (set (match_dup 0)
15373         (match_operand:DF 3 "immediate_operand" ""))]
15374   "standard_80387_constant_p (operands[3]) == 2"
15375   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15376              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15377   "")
15378
15379 (define_expand "tandf2"
15380   [(parallel [(set (match_dup 2)
15381                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15382                               UNSPEC_TAN_ONE))
15383               (set (match_operand:DF 0 "register_operand" "")
15384                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15385   "TARGET_USE_FANCY_MATH_387
15386    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15387    && flag_unsafe_math_optimizations"
15388 {
15389   operands[2] = gen_reg_rtx (DFmode);
15390 })
15391
15392 (define_insn "*tansf3_1"
15393   [(set (match_operand:SF 0 "register_operand" "=f")
15394         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15395                    UNSPEC_TAN_ONE))
15396    (set (match_operand:SF 1 "register_operand" "=u")
15397         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15398   "TARGET_USE_FANCY_MATH_387
15399    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15400    && flag_unsafe_math_optimizations"
15401   "fptan"
15402   [(set_attr "type" "fpspc")
15403    (set_attr "mode" "SF")])
15404
15405 ;; optimize sequence: fptan
15406 ;;                    fstp    %st(0)
15407 ;;                    fld1
15408 ;; into fptan insn.
15409
15410 (define_peephole2
15411   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15412                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15413                              UNSPEC_TAN_ONE))
15414              (set (match_operand:SF 1 "register_operand" "")
15415                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15416    (set (match_dup 0)
15417         (match_operand:SF 3 "immediate_operand" ""))]
15418   "standard_80387_constant_p (operands[3]) == 2"
15419   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15420              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15421   "")
15422
15423 (define_expand "tansf2"
15424   [(parallel [(set (match_dup 2)
15425                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15426                               UNSPEC_TAN_ONE))
15427               (set (match_operand:SF 0 "register_operand" "")
15428                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15429   "TARGET_USE_FANCY_MATH_387
15430    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15431    && flag_unsafe_math_optimizations"
15432 {
15433   operands[2] = gen_reg_rtx (SFmode);
15434 })
15435
15436 (define_insn "*tanxf3_1"
15437   [(set (match_operand:XF 0 "register_operand" "=f")
15438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15439                    UNSPEC_TAN_ONE))
15440    (set (match_operand:XF 1 "register_operand" "=u")
15441         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations"
15444   "fptan"
15445   [(set_attr "type" "fpspc")
15446    (set_attr "mode" "XF")])
15447
15448 ;; optimize sequence: fptan
15449 ;;                    fstp    %st(0)
15450 ;;                    fld1
15451 ;; into fptan insn.
15452
15453 (define_peephole2
15454   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15455                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15456                              UNSPEC_TAN_ONE))
15457              (set (match_operand:XF 1 "register_operand" "")
15458                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15459    (set (match_dup 0)
15460         (match_operand:XF 3 "immediate_operand" ""))]
15461   "standard_80387_constant_p (operands[3]) == 2"
15462   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15463              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15464   "")
15465
15466 (define_expand "tanxf2"
15467   [(parallel [(set (match_dup 2)
15468                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15469                               UNSPEC_TAN_ONE))
15470               (set (match_operand:XF 0 "register_operand" "")
15471                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15472   "TARGET_USE_FANCY_MATH_387
15473    && flag_unsafe_math_optimizations"
15474 {
15475   operands[2] = gen_reg_rtx (XFmode);
15476 })
15477
15478 (define_insn "atan2df3_1"
15479   [(set (match_operand:DF 0 "register_operand" "=f")
15480         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15481                     (match_operand:DF 1 "register_operand" "u")]
15482                    UNSPEC_FPATAN))
15483    (clobber (match_scratch:DF 3 "=1"))]
15484   "TARGET_USE_FANCY_MATH_387
15485    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15486    && flag_unsafe_math_optimizations"
15487   "fpatan"
15488   [(set_attr "type" "fpspc")
15489    (set_attr "mode" "DF")])
15490
15491 (define_expand "atan2df3"
15492   [(use (match_operand:DF 0 "register_operand" ""))
15493    (use (match_operand:DF 2 "register_operand" ""))
15494    (use (match_operand:DF 1 "register_operand" ""))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15497    && flag_unsafe_math_optimizations"
15498 {
15499   rtx copy = gen_reg_rtx (DFmode);
15500   emit_move_insn (copy, operands[1]);
15501   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15502   DONE;
15503 })
15504
15505 (define_expand "atandf2"
15506   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15507                    (unspec:DF [(match_dup 2)
15508                                (match_operand:DF 1 "register_operand" "")]
15509                     UNSPEC_FPATAN))
15510               (clobber (match_scratch:DF 3 ""))])]
15511   "TARGET_USE_FANCY_MATH_387
15512    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15513    && flag_unsafe_math_optimizations"
15514 {
15515   operands[2] = gen_reg_rtx (DFmode);
15516   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15517 })
15518
15519 (define_insn "atan2sf3_1"
15520   [(set (match_operand:SF 0 "register_operand" "=f")
15521         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15522                     (match_operand:SF 1 "register_operand" "u")]
15523                    UNSPEC_FPATAN))
15524    (clobber (match_scratch:SF 3 "=1"))]
15525   "TARGET_USE_FANCY_MATH_387
15526    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15527    && flag_unsafe_math_optimizations"
15528   "fpatan"
15529   [(set_attr "type" "fpspc")
15530    (set_attr "mode" "SF")])
15531
15532 (define_expand "atan2sf3"
15533   [(use (match_operand:SF 0 "register_operand" ""))
15534    (use (match_operand:SF 2 "register_operand" ""))
15535    (use (match_operand:SF 1 "register_operand" ""))]
15536   "TARGET_USE_FANCY_MATH_387
15537    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15538    && flag_unsafe_math_optimizations"
15539 {
15540   rtx copy = gen_reg_rtx (SFmode);
15541   emit_move_insn (copy, operands[1]);
15542   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15543   DONE;
15544 })
15545
15546 (define_expand "atansf2"
15547   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15548                    (unspec:SF [(match_dup 2)
15549                                (match_operand:SF 1 "register_operand" "")]
15550                     UNSPEC_FPATAN))
15551               (clobber (match_scratch:SF 3 ""))])]
15552   "TARGET_USE_FANCY_MATH_387
15553    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15554    && flag_unsafe_math_optimizations"
15555 {
15556   operands[2] = gen_reg_rtx (SFmode);
15557   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15558 })
15559
15560 (define_insn "atan2xf3_1"
15561   [(set (match_operand:XF 0 "register_operand" "=f")
15562         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15563                     (match_operand:XF 1 "register_operand" "u")]
15564                    UNSPEC_FPATAN))
15565    (clobber (match_scratch:XF 3 "=1"))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && flag_unsafe_math_optimizations"
15568   "fpatan"
15569   [(set_attr "type" "fpspc")
15570    (set_attr "mode" "XF")])
15571
15572 (define_expand "atan2xf3"
15573   [(use (match_operand:XF 0 "register_operand" ""))
15574    (use (match_operand:XF 2 "register_operand" ""))
15575    (use (match_operand:XF 1 "register_operand" ""))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && flag_unsafe_math_optimizations"
15578 {
15579   rtx copy = gen_reg_rtx (XFmode);
15580   emit_move_insn (copy, operands[1]);
15581   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15582   DONE;
15583 })
15584
15585 (define_expand "atanxf2"
15586   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15587                    (unspec:XF [(match_dup 2)
15588                                (match_operand:XF 1 "register_operand" "")]
15589                     UNSPEC_FPATAN))
15590               (clobber (match_scratch:XF 3 ""))])]
15591   "TARGET_USE_FANCY_MATH_387
15592    && flag_unsafe_math_optimizations"
15593 {
15594   operands[2] = gen_reg_rtx (XFmode);
15595   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15596 })
15597
15598 (define_expand "asindf2"
15599   [(set (match_dup 2)
15600         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15601    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15602    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15603    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15604    (parallel [(set (match_dup 7)
15605                    (unspec:XF [(match_dup 6) (match_dup 2)]
15606                               UNSPEC_FPATAN))
15607               (clobber (match_scratch:XF 8 ""))])
15608    (set (match_operand:DF 0 "register_operand" "")
15609         (float_truncate:DF (match_dup 7)))]
15610   "TARGET_USE_FANCY_MATH_387
15611    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15612    && flag_unsafe_math_optimizations"
15613 {
15614   int i;
15615
15616   for (i=2; i<8; i++)
15617     operands[i] = gen_reg_rtx (XFmode);
15618
15619   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15620 })
15621
15622 (define_expand "asinsf2"
15623   [(set (match_dup 2)
15624         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15625    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15626    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15627    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15628    (parallel [(set (match_dup 7)
15629                    (unspec:XF [(match_dup 6) (match_dup 2)]
15630                               UNSPEC_FPATAN))
15631               (clobber (match_scratch:XF 8 ""))])
15632    (set (match_operand:SF 0 "register_operand" "")
15633         (float_truncate:SF (match_dup 7)))]
15634   "TARGET_USE_FANCY_MATH_387
15635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15636    && flag_unsafe_math_optimizations"
15637 {
15638   int i;
15639
15640   for (i=2; i<8; i++)
15641     operands[i] = gen_reg_rtx (XFmode);
15642
15643   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15644 })
15645
15646 (define_expand "asinxf2"
15647   [(set (match_dup 2)
15648         (mult:XF (match_operand:XF 1 "register_operand" "")
15649                  (match_dup 1)))
15650    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15651    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15652    (parallel [(set (match_operand:XF 0 "register_operand" "")
15653                    (unspec:XF [(match_dup 5) (match_dup 1)]
15654                               UNSPEC_FPATAN))
15655               (clobber (match_scratch:XF 6 ""))])]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_unsafe_math_optimizations"
15658 {
15659   int i;
15660
15661   for (i=2; i<6; i++)
15662     operands[i] = gen_reg_rtx (XFmode);
15663
15664   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15665 })
15666
15667 (define_expand "acosdf2"
15668   [(set (match_dup 2)
15669         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15670    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15671    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15672    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15673    (parallel [(set (match_dup 7)
15674                    (unspec:XF [(match_dup 2) (match_dup 6)]
15675                               UNSPEC_FPATAN))
15676               (clobber (match_scratch:XF 8 ""))])
15677    (set (match_operand:DF 0 "register_operand" "")
15678         (float_truncate:DF (match_dup 7)))]
15679   "TARGET_USE_FANCY_MATH_387
15680    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15681    && flag_unsafe_math_optimizations"
15682 {
15683   int i;
15684
15685   for (i=2; i<8; i++)
15686     operands[i] = gen_reg_rtx (XFmode);
15687
15688   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15689 })
15690
15691 (define_expand "acossf2"
15692   [(set (match_dup 2)
15693         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15694    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15695    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15696    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15697    (parallel [(set (match_dup 7)
15698                    (unspec:XF [(match_dup 2) (match_dup 6)]
15699                               UNSPEC_FPATAN))
15700               (clobber (match_scratch:XF 8 ""))])
15701    (set (match_operand:SF 0 "register_operand" "")
15702         (float_truncate:SF (match_dup 7)))]
15703   "TARGET_USE_FANCY_MATH_387
15704    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15705    && flag_unsafe_math_optimizations"
15706 {
15707   int i;
15708
15709   for (i=2; i<8; i++)
15710     operands[i] = gen_reg_rtx (XFmode);
15711
15712   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15713 })
15714
15715 (define_expand "acosxf2"
15716   [(set (match_dup 2)
15717         (mult:XF (match_operand:XF 1 "register_operand" "")
15718                  (match_dup 1)))
15719    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15720    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15721    (parallel [(set (match_operand:XF 0 "register_operand" "")
15722                    (unspec:XF [(match_dup 1) (match_dup 5)]
15723                               UNSPEC_FPATAN))
15724               (clobber (match_scratch:XF 6 ""))])]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727 {
15728   int i;
15729
15730   for (i=2; i<6; i++)
15731     operands[i] = gen_reg_rtx (XFmode);
15732
15733   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15734 })
15735
15736 (define_insn "fyl2x_xf3"
15737   [(set (match_operand:XF 0 "register_operand" "=f")
15738         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15739                     (match_operand:XF 1 "register_operand" "u")]
15740                    UNSPEC_FYL2X))
15741    (clobber (match_scratch:XF 3 "=1"))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && flag_unsafe_math_optimizations"
15744   "fyl2x"
15745   [(set_attr "type" "fpspc")
15746    (set_attr "mode" "XF")])
15747
15748 (define_expand "logsf2"
15749   [(set (match_dup 2)
15750         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15751    (parallel [(set (match_dup 4)
15752                    (unspec:XF [(match_dup 2)
15753                                (match_dup 3)] UNSPEC_FYL2X))
15754               (clobber (match_scratch:XF 5 ""))])
15755    (set (match_operand:SF 0 "register_operand" "")
15756         (float_truncate:SF (match_dup 4)))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15759    && flag_unsafe_math_optimizations"
15760 {
15761   rtx temp;
15762
15763   operands[2] = gen_reg_rtx (XFmode);
15764   operands[3] = gen_reg_rtx (XFmode);
15765   operands[4] = gen_reg_rtx (XFmode);
15766
15767   temp = standard_80387_constant_rtx (4); /* fldln2 */
15768   emit_move_insn (operands[3], temp);
15769 })
15770
15771 (define_expand "logdf2"
15772   [(set (match_dup 2)
15773         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15774    (parallel [(set (match_dup 4)
15775                    (unspec:XF [(match_dup 2)
15776                                (match_dup 3)] UNSPEC_FYL2X))
15777               (clobber (match_scratch:XF 5 ""))])
15778    (set (match_operand:DF 0 "register_operand" "")
15779         (float_truncate:DF (match_dup 4)))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15782    && flag_unsafe_math_optimizations"
15783 {
15784   rtx temp;
15785
15786   operands[2] = gen_reg_rtx (XFmode);
15787   operands[3] = gen_reg_rtx (XFmode);
15788   operands[4] = gen_reg_rtx (XFmode);
15789
15790   temp = standard_80387_constant_rtx (4); /* fldln2 */
15791   emit_move_insn (operands[3], temp);
15792 })
15793
15794 (define_expand "logxf2"
15795   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15796                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15797                                (match_dup 2)] UNSPEC_FYL2X))
15798               (clobber (match_scratch:XF 3 ""))])]
15799   "TARGET_USE_FANCY_MATH_387
15800    && flag_unsafe_math_optimizations"
15801 {
15802   rtx temp;
15803
15804   operands[2] = gen_reg_rtx (XFmode);
15805   temp = standard_80387_constant_rtx (4); /* fldln2 */
15806   emit_move_insn (operands[2], temp);
15807 })
15808
15809 (define_expand "log10sf2"
15810   [(set (match_dup 2)
15811         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15812    (parallel [(set (match_dup 4)
15813                    (unspec:XF [(match_dup 2)
15814                                (match_dup 3)] UNSPEC_FYL2X))
15815               (clobber (match_scratch:XF 5 ""))])
15816    (set (match_operand:SF 0 "register_operand" "")
15817         (float_truncate:SF (match_dup 4)))]
15818   "TARGET_USE_FANCY_MATH_387
15819    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15820    && flag_unsafe_math_optimizations"
15821 {
15822   rtx temp;
15823
15824   operands[2] = gen_reg_rtx (XFmode);
15825   operands[3] = gen_reg_rtx (XFmode);
15826   operands[4] = gen_reg_rtx (XFmode);
15827
15828   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15829   emit_move_insn (operands[3], temp);
15830 })
15831
15832 (define_expand "log10df2"
15833   [(set (match_dup 2)
15834         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15835    (parallel [(set (match_dup 4)
15836                    (unspec:XF [(match_dup 2)
15837                                (match_dup 3)] UNSPEC_FYL2X))
15838               (clobber (match_scratch:XF 5 ""))])
15839    (set (match_operand:DF 0 "register_operand" "")
15840         (float_truncate:DF (match_dup 4)))]
15841   "TARGET_USE_FANCY_MATH_387
15842    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15843    && flag_unsafe_math_optimizations"
15844 {
15845   rtx temp;
15846
15847   operands[2] = gen_reg_rtx (XFmode);
15848   operands[3] = gen_reg_rtx (XFmode);
15849   operands[4] = gen_reg_rtx (XFmode);
15850
15851   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15852   emit_move_insn (operands[3], temp);
15853 })
15854
15855 (define_expand "log10xf2"
15856   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15857                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15858                                (match_dup 2)] UNSPEC_FYL2X))
15859               (clobber (match_scratch:XF 3 ""))])]
15860   "TARGET_USE_FANCY_MATH_387
15861    && flag_unsafe_math_optimizations"
15862 {
15863   rtx temp;
15864
15865   operands[2] = gen_reg_rtx (XFmode);
15866   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15867   emit_move_insn (operands[2], temp);
15868 })
15869
15870 (define_expand "log2sf2"
15871   [(set (match_dup 2)
15872         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15873    (parallel [(set (match_dup 4)
15874                    (unspec:XF [(match_dup 2)
15875                                (match_dup 3)] UNSPEC_FYL2X))
15876               (clobber (match_scratch:XF 5 ""))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 4)))]
15879   "TARGET_USE_FANCY_MATH_387
15880    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15881    && flag_unsafe_math_optimizations"
15882 {
15883   operands[2] = gen_reg_rtx (XFmode);
15884   operands[3] = gen_reg_rtx (XFmode);
15885   operands[4] = gen_reg_rtx (XFmode);
15886
15887   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15888 })
15889
15890 (define_expand "log2df2"
15891   [(set (match_dup 2)
15892         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15893    (parallel [(set (match_dup 4)
15894                    (unspec:XF [(match_dup 2)
15895                                (match_dup 3)] UNSPEC_FYL2X))
15896               (clobber (match_scratch:XF 5 ""))])
15897    (set (match_operand:DF 0 "register_operand" "")
15898         (float_truncate:DF (match_dup 4)))]
15899   "TARGET_USE_FANCY_MATH_387
15900    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15901    && flag_unsafe_math_optimizations"
15902 {
15903   operands[2] = gen_reg_rtx (XFmode);
15904   operands[3] = gen_reg_rtx (XFmode);
15905   operands[4] = gen_reg_rtx (XFmode);
15906
15907   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15908 })
15909
15910 (define_expand "log2xf2"
15911   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15912                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15913                                (match_dup 2)] UNSPEC_FYL2X))
15914               (clobber (match_scratch:XF 3 ""))])]
15915   "TARGET_USE_FANCY_MATH_387
15916    && flag_unsafe_math_optimizations"
15917 {
15918   operands[2] = gen_reg_rtx (XFmode);
15919   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15920 })
15921
15922 (define_insn "fyl2xp1_xf3"
15923   [(set (match_operand:XF 0 "register_operand" "=f")
15924         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925                     (match_operand:XF 1 "register_operand" "u")]
15926                    UNSPEC_FYL2XP1))
15927    (clobber (match_scratch:XF 3 "=1"))]
15928   "TARGET_USE_FANCY_MATH_387
15929    && flag_unsafe_math_optimizations"
15930   "fyl2xp1"
15931   [(set_attr "type" "fpspc")
15932    (set_attr "mode" "XF")])
15933
15934 (define_expand "log1psf2"
15935   [(use (match_operand:SF 0 "register_operand" ""))
15936    (use (match_operand:SF 1 "register_operand" ""))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15939    && flag_unsafe_math_optimizations"
15940 {
15941   rtx op0 = gen_reg_rtx (XFmode);
15942   rtx op1 = gen_reg_rtx (XFmode);
15943
15944   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15945   ix86_emit_i387_log1p (op0, op1);
15946   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15947   DONE;
15948 })
15949
15950 (define_expand "log1pdf2"
15951   [(use (match_operand:DF 0 "register_operand" ""))
15952    (use (match_operand:DF 1 "register_operand" ""))]
15953   "TARGET_USE_FANCY_MATH_387
15954    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15955    && flag_unsafe_math_optimizations"
15956 {
15957   rtx op0 = gen_reg_rtx (XFmode);
15958   rtx op1 = gen_reg_rtx (XFmode);
15959
15960   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15961   ix86_emit_i387_log1p (op0, op1);
15962   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15963   DONE;
15964 })
15965
15966 (define_expand "log1pxf2"
15967   [(use (match_operand:XF 0 "register_operand" ""))
15968    (use (match_operand:XF 1 "register_operand" ""))]
15969   "TARGET_USE_FANCY_MATH_387
15970    && flag_unsafe_math_optimizations"
15971 {
15972   ix86_emit_i387_log1p (operands[0], operands[1]);
15973   DONE;
15974 })
15975
15976 (define_insn "*fxtractxf3"
15977   [(set (match_operand:XF 0 "register_operand" "=f")
15978         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15979                    UNSPEC_XTRACT_FRACT))
15980    (set (match_operand:XF 1 "register_operand" "=u")
15981         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15982   "TARGET_USE_FANCY_MATH_387
15983    && flag_unsafe_math_optimizations"
15984   "fxtract"
15985   [(set_attr "type" "fpspc")
15986    (set_attr "mode" "XF")])
15987
15988 (define_expand "logbsf2"
15989   [(set (match_dup 2)
15990         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15991    (parallel [(set (match_dup 3)
15992                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15993               (set (match_dup 4)
15994                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15995    (set (match_operand:SF 0 "register_operand" "")
15996         (float_truncate:SF (match_dup 4)))]
15997   "TARGET_USE_FANCY_MATH_387
15998    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15999    && flag_unsafe_math_optimizations"
16000 {
16001   operands[2] = gen_reg_rtx (XFmode);
16002   operands[3] = gen_reg_rtx (XFmode);
16003   operands[4] = gen_reg_rtx (XFmode);
16004 })
16005
16006 (define_expand "logbdf2"
16007   [(set (match_dup 2)
16008         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16009    (parallel [(set (match_dup 3)
16010                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16011               (set (match_dup 4)
16012                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16013    (set (match_operand:DF 0 "register_operand" "")
16014         (float_truncate:DF (match_dup 4)))]
16015   "TARGET_USE_FANCY_MATH_387
16016    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16017    && flag_unsafe_math_optimizations"
16018 {
16019   operands[2] = gen_reg_rtx (XFmode);
16020   operands[3] = gen_reg_rtx (XFmode);
16021   operands[4] = gen_reg_rtx (XFmode);
16022 })
16023
16024 (define_expand "logbxf2"
16025   [(parallel [(set (match_dup 2)
16026                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16027                               UNSPEC_XTRACT_FRACT))
16028               (set (match_operand:XF 0 "register_operand" "")
16029                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16030   "TARGET_USE_FANCY_MATH_387
16031    && flag_unsafe_math_optimizations"
16032 {
16033   operands[2] = gen_reg_rtx (XFmode);
16034 })
16035
16036 (define_expand "ilogbsi2"
16037   [(parallel [(set (match_dup 2)
16038                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16039                               UNSPEC_XTRACT_FRACT))
16040               (set (match_operand:XF 3 "register_operand" "")
16041                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16042    (parallel [(set (match_operand:SI 0 "register_operand" "")
16043                    (fix:SI (match_dup 3)))
16044               (clobber (reg:CC FLAGS_REG))])]
16045   "TARGET_USE_FANCY_MATH_387
16046    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16047    && flag_unsafe_math_optimizations"
16048 {
16049   operands[2] = gen_reg_rtx (XFmode);
16050   operands[3] = gen_reg_rtx (XFmode);
16051 })
16052
16053 (define_insn "*f2xm1xf2"
16054   [(set (match_operand:XF 0 "register_operand" "=f")
16055         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16056          UNSPEC_F2XM1))]
16057   "TARGET_USE_FANCY_MATH_387
16058    && flag_unsafe_math_optimizations"
16059   "f2xm1"
16060   [(set_attr "type" "fpspc")
16061    (set_attr "mode" "XF")])
16062
16063 (define_insn "*fscalexf4"
16064   [(set (match_operand:XF 0 "register_operand" "=f")
16065         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16066                     (match_operand:XF 3 "register_operand" "1")]
16067                    UNSPEC_FSCALE_FRACT))
16068    (set (match_operand:XF 1 "register_operand" "=u")
16069         (unspec:XF [(match_dup 2) (match_dup 3)]
16070                    UNSPEC_FSCALE_EXP))]
16071   "TARGET_USE_FANCY_MATH_387
16072    && flag_unsafe_math_optimizations"
16073   "fscale"
16074   [(set_attr "type" "fpspc")
16075    (set_attr "mode" "XF")])
16076
16077 (define_expand "expsf2"
16078   [(set (match_dup 2)
16079         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16080    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16081    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16082    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16083    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16084    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16085    (parallel [(set (match_dup 10)
16086                    (unspec:XF [(match_dup 9) (match_dup 5)]
16087                               UNSPEC_FSCALE_FRACT))
16088               (set (match_dup 11)
16089                    (unspec:XF [(match_dup 9) (match_dup 5)]
16090                               UNSPEC_FSCALE_EXP))])
16091    (set (match_operand:SF 0 "register_operand" "")
16092         (float_truncate:SF (match_dup 10)))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16095    && flag_unsafe_math_optimizations"
16096 {
16097   rtx temp;
16098   int i;
16099
16100   for (i=2; i<12; i++)
16101     operands[i] = gen_reg_rtx (XFmode);
16102   temp = standard_80387_constant_rtx (5); /* fldl2e */
16103   emit_move_insn (operands[3], temp);
16104   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16105 })
16106
16107 (define_expand "expdf2"
16108   [(set (match_dup 2)
16109         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16110    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16111    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16112    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16113    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16114    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16115    (parallel [(set (match_dup 10)
16116                    (unspec:XF [(match_dup 9) (match_dup 5)]
16117                               UNSPEC_FSCALE_FRACT))
16118               (set (match_dup 11)
16119                    (unspec:XF [(match_dup 9) (match_dup 5)]
16120                               UNSPEC_FSCALE_EXP))])
16121    (set (match_operand:DF 0 "register_operand" "")
16122         (float_truncate:DF (match_dup 10)))]
16123   "TARGET_USE_FANCY_MATH_387
16124    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16125    && flag_unsafe_math_optimizations"
16126 {
16127   rtx temp;
16128   int i;
16129
16130   for (i=2; i<12; i++)
16131     operands[i] = gen_reg_rtx (XFmode);
16132   temp = standard_80387_constant_rtx (5); /* fldl2e */
16133   emit_move_insn (operands[3], temp);
16134   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16135 })
16136
16137 (define_expand "expxf2"
16138   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16139                                (match_dup 2)))
16140    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16141    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16142    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16143    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16144    (parallel [(set (match_operand:XF 0 "register_operand" "")
16145                    (unspec:XF [(match_dup 8) (match_dup 4)]
16146                               UNSPEC_FSCALE_FRACT))
16147               (set (match_dup 9)
16148                    (unspec:XF [(match_dup 8) (match_dup 4)]
16149                               UNSPEC_FSCALE_EXP))])]
16150   "TARGET_USE_FANCY_MATH_387
16151    && flag_unsafe_math_optimizations"
16152 {
16153   rtx temp;
16154   int i;
16155
16156   for (i=2; i<10; i++)
16157     operands[i] = gen_reg_rtx (XFmode);
16158   temp = standard_80387_constant_rtx (5); /* fldl2e */
16159   emit_move_insn (operands[2], temp);
16160   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16161 })
16162
16163 (define_expand "exp10sf2"
16164   [(set (match_dup 2)
16165         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16166    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16167    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16168    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16169    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16170    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16171    (parallel [(set (match_dup 10)
16172                    (unspec:XF [(match_dup 9) (match_dup 5)]
16173                               UNSPEC_FSCALE_FRACT))
16174               (set (match_dup 11)
16175                    (unspec:XF [(match_dup 9) (match_dup 5)]
16176                               UNSPEC_FSCALE_EXP))])
16177    (set (match_operand:SF 0 "register_operand" "")
16178         (float_truncate:SF (match_dup 10)))]
16179   "TARGET_USE_FANCY_MATH_387
16180    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16181    && flag_unsafe_math_optimizations"
16182 {
16183   rtx temp;
16184   int i;
16185
16186   for (i=2; i<12; i++)
16187     operands[i] = gen_reg_rtx (XFmode);
16188   temp = standard_80387_constant_rtx (6); /* fldl2t */
16189   emit_move_insn (operands[3], temp);
16190   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16191 })
16192
16193 (define_expand "exp10df2"
16194   [(set (match_dup 2)
16195         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16196    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16197    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16198    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16199    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16200    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16201    (parallel [(set (match_dup 10)
16202                    (unspec:XF [(match_dup 9) (match_dup 5)]
16203                               UNSPEC_FSCALE_FRACT))
16204               (set (match_dup 11)
16205                    (unspec:XF [(match_dup 9) (match_dup 5)]
16206                               UNSPEC_FSCALE_EXP))])
16207    (set (match_operand:DF 0 "register_operand" "")
16208         (float_truncate:DF (match_dup 10)))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211    && flag_unsafe_math_optimizations"
16212 {
16213   rtx temp;
16214   int i;
16215
16216   for (i=2; i<12; i++)
16217     operands[i] = gen_reg_rtx (XFmode);
16218   temp = standard_80387_constant_rtx (6); /* fldl2t */
16219   emit_move_insn (operands[3], temp);
16220   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16221 })
16222
16223 (define_expand "exp10xf2"
16224   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16225                                (match_dup 2)))
16226    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16227    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16228    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16229    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16230    (parallel [(set (match_operand:XF 0 "register_operand" "")
16231                    (unspec:XF [(match_dup 8) (match_dup 4)]
16232                               UNSPEC_FSCALE_FRACT))
16233               (set (match_dup 9)
16234                    (unspec:XF [(match_dup 8) (match_dup 4)]
16235                               UNSPEC_FSCALE_EXP))])]
16236   "TARGET_USE_FANCY_MATH_387
16237    && flag_unsafe_math_optimizations"
16238 {
16239   rtx temp;
16240   int i;
16241
16242   for (i=2; i<10; i++)
16243     operands[i] = gen_reg_rtx (XFmode);
16244   temp = standard_80387_constant_rtx (6); /* fldl2t */
16245   emit_move_insn (operands[2], temp);
16246   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16247 })
16248
16249 (define_expand "exp2sf2"
16250   [(set (match_dup 2)
16251         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16252    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16253    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16254    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16255    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16256    (parallel [(set (match_dup 8)
16257                    (unspec:XF [(match_dup 7) (match_dup 3)]
16258                               UNSPEC_FSCALE_FRACT))
16259               (set (match_dup 9)
16260                    (unspec:XF [(match_dup 7) (match_dup 3)]
16261                               UNSPEC_FSCALE_EXP))])
16262    (set (match_operand:SF 0 "register_operand" "")
16263         (float_truncate:SF (match_dup 8)))]
16264   "TARGET_USE_FANCY_MATH_387
16265    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16266    && flag_unsafe_math_optimizations"
16267 {
16268   int i;
16269
16270   for (i=2; i<10; i++)
16271     operands[i] = gen_reg_rtx (XFmode);
16272   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16273 })
16274
16275 (define_expand "exp2df2"
16276   [(set (match_dup 2)
16277         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16278    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16279    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16280    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16281    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16282    (parallel [(set (match_dup 8)
16283                    (unspec:XF [(match_dup 7) (match_dup 3)]
16284                               UNSPEC_FSCALE_FRACT))
16285               (set (match_dup 9)
16286                    (unspec:XF [(match_dup 7) (match_dup 3)]
16287                               UNSPEC_FSCALE_EXP))])
16288    (set (match_operand:DF 0 "register_operand" "")
16289         (float_truncate:DF (match_dup 8)))]
16290   "TARGET_USE_FANCY_MATH_387
16291    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16292    && flag_unsafe_math_optimizations"
16293 {
16294   int i;
16295
16296   for (i=2; i<10; i++)
16297     operands[i] = gen_reg_rtx (XFmode);
16298   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16299 })
16300
16301 (define_expand "exp2xf2"
16302   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16303    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16304    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16305    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16306    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16307    (parallel [(set (match_operand:XF 0 "register_operand" "")
16308                    (unspec:XF [(match_dup 7) (match_dup 3)]
16309                               UNSPEC_FSCALE_FRACT))
16310               (set (match_dup 8)
16311                    (unspec:XF [(match_dup 7) (match_dup 3)]
16312                               UNSPEC_FSCALE_EXP))])]
16313   "TARGET_USE_FANCY_MATH_387
16314    && flag_unsafe_math_optimizations"
16315 {
16316   int i;
16317
16318   for (i=2; i<9; i++)
16319     operands[i] = gen_reg_rtx (XFmode);
16320   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16321 })
16322
16323 (define_expand "expm1df2"
16324   [(set (match_dup 2)
16325         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16326    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16327    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16328    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16329    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16330    (parallel [(set (match_dup 8)
16331                    (unspec:XF [(match_dup 7) (match_dup 5)]
16332                               UNSPEC_FSCALE_FRACT))
16333                    (set (match_dup 9)
16334                    (unspec:XF [(match_dup 7) (match_dup 5)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (parallel [(set (match_dup 11)
16337                    (unspec:XF [(match_dup 10) (match_dup 9)]
16338                               UNSPEC_FSCALE_FRACT))
16339               (set (match_dup 12)
16340                    (unspec:XF [(match_dup 10) (match_dup 9)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16343    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16344    (set (match_operand:DF 0 "register_operand" "")
16345         (float_truncate:DF (match_dup 14)))]
16346   "TARGET_USE_FANCY_MATH_387
16347    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16348    && flag_unsafe_math_optimizations"
16349 {
16350   rtx temp;
16351   int i;
16352
16353   for (i=2; i<15; i++)
16354     operands[i] = gen_reg_rtx (XFmode);
16355   temp = standard_80387_constant_rtx (5); /* fldl2e */
16356   emit_move_insn (operands[3], temp);
16357   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16358 })
16359
16360 (define_expand "expm1sf2"
16361   [(set (match_dup 2)
16362         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16363    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16364    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16365    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16366    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16367    (parallel [(set (match_dup 8)
16368                    (unspec:XF [(match_dup 7) (match_dup 5)]
16369                               UNSPEC_FSCALE_FRACT))
16370                    (set (match_dup 9)
16371                    (unspec:XF [(match_dup 7) (match_dup 5)]
16372                               UNSPEC_FSCALE_EXP))])
16373    (parallel [(set (match_dup 11)
16374                    (unspec:XF [(match_dup 10) (match_dup 9)]
16375                               UNSPEC_FSCALE_FRACT))
16376               (set (match_dup 12)
16377                    (unspec:XF [(match_dup 10) (match_dup 9)]
16378                               UNSPEC_FSCALE_EXP))])
16379    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16380    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16381    (set (match_operand:SF 0 "register_operand" "")
16382         (float_truncate:SF (match_dup 14)))]
16383   "TARGET_USE_FANCY_MATH_387
16384    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16385    && flag_unsafe_math_optimizations"
16386 {
16387   rtx temp;
16388   int i;
16389
16390   for (i=2; i<15; i++)
16391     operands[i] = gen_reg_rtx (XFmode);
16392   temp = standard_80387_constant_rtx (5); /* fldl2e */
16393   emit_move_insn (operands[3], temp);
16394   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16395 })
16396
16397 (define_expand "expm1xf2"
16398   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16399                                (match_dup 2)))
16400    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16401    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16402    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16403    (parallel [(set (match_dup 7)
16404                    (unspec:XF [(match_dup 6) (match_dup 4)]
16405                               UNSPEC_FSCALE_FRACT))
16406                    (set (match_dup 8)
16407                    (unspec:XF [(match_dup 6) (match_dup 4)]
16408                               UNSPEC_FSCALE_EXP))])
16409    (parallel [(set (match_dup 10)
16410                    (unspec:XF [(match_dup 9) (match_dup 8)]
16411                               UNSPEC_FSCALE_FRACT))
16412               (set (match_dup 11)
16413                    (unspec:XF [(match_dup 9) (match_dup 8)]
16414                               UNSPEC_FSCALE_EXP))])
16415    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16416    (set (match_operand:XF 0 "register_operand" "")
16417         (plus:XF (match_dup 12) (match_dup 7)))]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420 {
16421   rtx temp;
16422   int i;
16423
16424   for (i=2; i<13; i++)
16425     operands[i] = gen_reg_rtx (XFmode);
16426   temp = standard_80387_constant_rtx (5); /* fldl2e */
16427   emit_move_insn (operands[2], temp);
16428   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16429 })
16430
16431 (define_expand "ldexpdf3"
16432   [(set (match_dup 3)
16433         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16434    (set (match_dup 4)
16435         (float:XF (match_operand:SI 2 "register_operand" "")))
16436    (parallel [(set (match_dup 5)
16437                    (unspec:XF [(match_dup 3) (match_dup 4)]
16438                               UNSPEC_FSCALE_FRACT))
16439               (set (match_dup 6)
16440                    (unspec:XF [(match_dup 3) (match_dup 4)]
16441                               UNSPEC_FSCALE_EXP))])
16442    (set (match_operand:DF 0 "register_operand" "")
16443         (float_truncate:DF (match_dup 5)))]
16444   "TARGET_USE_FANCY_MATH_387
16445    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16446    && flag_unsafe_math_optimizations"
16447 {
16448   int i;
16449
16450   for (i=3; i<7; i++)
16451     operands[i] = gen_reg_rtx (XFmode);
16452 })
16453
16454 (define_expand "ldexpsf3"
16455   [(set (match_dup 3)
16456         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16457    (set (match_dup 4)
16458         (float:XF (match_operand:SI 2 "register_operand" "")))
16459    (parallel [(set (match_dup 5)
16460                    (unspec:XF [(match_dup 3) (match_dup 4)]
16461                               UNSPEC_FSCALE_FRACT))
16462               (set (match_dup 6)
16463                    (unspec:XF [(match_dup 3) (match_dup 4)]
16464                               UNSPEC_FSCALE_EXP))])
16465    (set (match_operand:SF 0 "register_operand" "")
16466         (float_truncate:SF (match_dup 5)))]
16467   "TARGET_USE_FANCY_MATH_387
16468    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16469    && flag_unsafe_math_optimizations"
16470 {
16471   int i;
16472
16473   for (i=3; i<7; i++)
16474     operands[i] = gen_reg_rtx (XFmode);
16475 })
16476
16477 (define_expand "ldexpxf3"
16478   [(set (match_dup 3)
16479         (float:XF (match_operand:SI 2 "register_operand" "")))
16480    (parallel [(set (match_operand:XF 0 " register_operand" "")
16481                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16482                                (match_dup 3)]
16483                               UNSPEC_FSCALE_FRACT))
16484               (set (match_dup 4)
16485                    (unspec:XF [(match_dup 1) (match_dup 3)]
16486                               UNSPEC_FSCALE_EXP))])]
16487   "TARGET_USE_FANCY_MATH_387
16488    && flag_unsafe_math_optimizations"
16489 {
16490   int i;
16491
16492   for (i=3; i<5; i++)
16493     operands[i] = gen_reg_rtx (XFmode);
16494 })
16495 \f
16496
16497 (define_insn "frndintxf2"
16498   [(set (match_operand:XF 0 "register_operand" "=f")
16499         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16500          UNSPEC_FRNDINT))]
16501   "TARGET_USE_FANCY_MATH_387
16502    && flag_unsafe_math_optimizations"
16503   "frndint"
16504   [(set_attr "type" "fpspc")
16505    (set_attr "mode" "XF")])
16506
16507 (define_expand "rintdf2"
16508   [(use (match_operand:DF 0 "register_operand" ""))
16509    (use (match_operand:DF 1 "register_operand" ""))]
16510   "TARGET_USE_FANCY_MATH_387
16511    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16512    && flag_unsafe_math_optimizations"
16513 {
16514   rtx op0 = gen_reg_rtx (XFmode);
16515   rtx op1 = gen_reg_rtx (XFmode);
16516
16517   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16518   emit_insn (gen_frndintxf2 (op0, op1));
16519
16520   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16521   DONE;
16522 })
16523
16524 (define_expand "rintsf2"
16525   [(use (match_operand:SF 0 "register_operand" ""))
16526    (use (match_operand:SF 1 "register_operand" ""))]
16527   "TARGET_USE_FANCY_MATH_387
16528    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16529    && flag_unsafe_math_optimizations"
16530 {
16531   rtx op0 = gen_reg_rtx (XFmode);
16532   rtx op1 = gen_reg_rtx (XFmode);
16533
16534   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16535   emit_insn (gen_frndintxf2 (op0, op1));
16536
16537   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16538   DONE;
16539 })
16540
16541 (define_expand "rintxf2"
16542   [(use (match_operand:XF 0 "register_operand" ""))
16543    (use (match_operand:XF 1 "register_operand" ""))]
16544   "TARGET_USE_FANCY_MATH_387
16545    && flag_unsafe_math_optimizations"
16546 {
16547   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16548   DONE;
16549 })
16550
16551 (define_insn_and_split "*fistdi2_1"
16552   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16553         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16554          UNSPEC_FIST))]
16555   "TARGET_USE_FANCY_MATH_387
16556    && flag_unsafe_math_optimizations
16557    && !(reload_completed || reload_in_progress)"
16558   "#"
16559   "&& 1"
16560   [(const_int 0)]
16561 {
16562   if (memory_operand (operands[0], VOIDmode))
16563     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16564   else
16565     {
16566       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16567       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16568                                          operands[2]));
16569     }
16570   DONE;
16571 }
16572   [(set_attr "type" "fpspc")
16573    (set_attr "mode" "DI")])
16574
16575 (define_insn "fistdi2"
16576   [(set (match_operand:DI 0 "memory_operand" "=m")
16577         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16578          UNSPEC_FIST))
16579    (clobber (match_scratch:XF 2 "=&1f"))]
16580   "TARGET_USE_FANCY_MATH_387
16581    && flag_unsafe_math_optimizations"
16582   "* return output_fix_trunc (insn, operands, 0);"
16583   [(set_attr "type" "fpspc")
16584    (set_attr "mode" "DI")])
16585
16586 (define_insn "fistdi2_with_temp"
16587   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16588         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16589          UNSPEC_FIST))
16590    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16591    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16592   "TARGET_USE_FANCY_MATH_387
16593    && flag_unsafe_math_optimizations"
16594   "#"
16595   [(set_attr "type" "fpspc")
16596    (set_attr "mode" "DI")])
16597
16598 (define_split 
16599   [(set (match_operand:DI 0 "register_operand" "")
16600         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16601          UNSPEC_FIST))
16602    (clobber (match_operand:DI 2 "memory_operand" ""))
16603    (clobber (match_scratch 3 ""))]
16604   "reload_completed"
16605   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16606               (clobber (match_dup 3))])
16607    (set (match_dup 0) (match_dup 2))]
16608   "")
16609
16610 (define_split 
16611   [(set (match_operand:DI 0 "memory_operand" "")
16612         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16613          UNSPEC_FIST))
16614    (clobber (match_operand:DI 2 "memory_operand" ""))
16615    (clobber (match_scratch 3 ""))]
16616   "reload_completed"
16617   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16618               (clobber (match_dup 3))])]
16619   "")
16620
16621 (define_insn_and_split "*fist<mode>2_1"
16622   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16623         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16624          UNSPEC_FIST))]
16625   "TARGET_USE_FANCY_MATH_387
16626    && flag_unsafe_math_optimizations
16627    && !(reload_completed || reload_in_progress)"
16628   "#"
16629   "&& 1"
16630   [(const_int 0)]
16631 {
16632   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16633   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16634                                         operands[2]));
16635   DONE;
16636 }
16637   [(set_attr "type" "fpspc")
16638    (set_attr "mode" "<MODE>")])
16639
16640 (define_insn "fist<mode>2"
16641   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16642         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16643          UNSPEC_FIST))]
16644   "TARGET_USE_FANCY_MATH_387
16645    && flag_unsafe_math_optimizations"
16646   "* return output_fix_trunc (insn, operands, 0);"
16647   [(set_attr "type" "fpspc")
16648    (set_attr "mode" "<MODE>")])
16649
16650 (define_insn "fist<mode>2_with_temp"
16651   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16652         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16653          UNSPEC_FIST))
16654    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16655   "TARGET_USE_FANCY_MATH_387
16656    && flag_unsafe_math_optimizations"
16657   "#"
16658   [(set_attr "type" "fpspc")
16659    (set_attr "mode" "<MODE>")])
16660
16661 (define_split 
16662   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16663         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16664          UNSPEC_FIST))
16665    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16666   "reload_completed"
16667   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16668                        UNSPEC_FIST))
16669    (set (match_dup 0) (match_dup 2))]
16670   "")
16671
16672 (define_split 
16673   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16674         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16675          UNSPEC_FIST))
16676    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16677   "reload_completed"
16678   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16679                        UNSPEC_FIST))]
16680   "")
16681
16682 (define_expand "lrint<mode>2"
16683   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16684         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16685          UNSPEC_FIST))]
16686   "TARGET_USE_FANCY_MATH_387
16687    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16688    && flag_unsafe_math_optimizations"
16689   "")
16690
16691 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16692 (define_insn_and_split "frndintxf2_floor"
16693   [(set (match_operand:XF 0 "register_operand" "=f")
16694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16695          UNSPEC_FRNDINT_FLOOR))
16696    (clobber (reg:CC FLAGS_REG))]
16697   "TARGET_USE_FANCY_MATH_387
16698    && flag_unsafe_math_optimizations
16699    && !(reload_completed || reload_in_progress)"
16700   "#"
16701   "&& 1"
16702   [(const_int 0)]
16703 {
16704   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16705
16706   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16707   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16708
16709   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16710                                         operands[2], operands[3]));
16711   DONE;
16712 }
16713   [(set_attr "type" "frndint")
16714    (set_attr "i387_cw" "floor")
16715    (set_attr "mode" "XF")])
16716
16717 (define_insn "frndintxf2_floor_i387"
16718   [(set (match_operand:XF 0 "register_operand" "=f")
16719         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16720          UNSPEC_FRNDINT_FLOOR))
16721    (use (match_operand:HI 2 "memory_operand" "m"))
16722    (use (match_operand:HI 3 "memory_operand" "m"))]
16723   "TARGET_USE_FANCY_MATH_387
16724    && flag_unsafe_math_optimizations"
16725   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16726   [(set_attr "type" "frndint")
16727    (set_attr "i387_cw" "floor")
16728    (set_attr "mode" "XF")])
16729
16730 (define_expand "floorxf2"
16731   [(use (match_operand:XF 0 "register_operand" ""))
16732    (use (match_operand:XF 1 "register_operand" ""))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && flag_unsafe_math_optimizations"
16735 {
16736   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16737   DONE;
16738 })
16739
16740 (define_expand "floordf2"
16741   [(use (match_operand:DF 0 "register_operand" ""))
16742    (use (match_operand:DF 1 "register_operand" ""))]
16743   "TARGET_USE_FANCY_MATH_387
16744    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16745    && flag_unsafe_math_optimizations"
16746 {
16747   rtx op0 = gen_reg_rtx (XFmode);
16748   rtx op1 = gen_reg_rtx (XFmode);
16749
16750   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16751   emit_insn (gen_frndintxf2_floor (op0, op1));
16752
16753   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16754   DONE;
16755 })
16756
16757 (define_expand "floorsf2"
16758   [(use (match_operand:SF 0 "register_operand" ""))
16759    (use (match_operand:SF 1 "register_operand" ""))]
16760   "TARGET_USE_FANCY_MATH_387
16761    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16762    && flag_unsafe_math_optimizations"
16763 {
16764   rtx op0 = gen_reg_rtx (XFmode);
16765   rtx op1 = gen_reg_rtx (XFmode);
16766
16767   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16768   emit_insn (gen_frndintxf2_floor (op0, op1));
16769
16770   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16771   DONE;
16772 })
16773
16774 (define_insn_and_split "*fist<mode>2_floor_1"
16775   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16776         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16777          UNSPEC_FIST_FLOOR))
16778    (clobber (reg:CC FLAGS_REG))]
16779   "TARGET_USE_FANCY_MATH_387
16780    && flag_unsafe_math_optimizations
16781    && !(reload_completed || reload_in_progress)"
16782   "#"
16783   "&& 1"
16784   [(const_int 0)]
16785 {
16786   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16787
16788   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16789   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16790   if (memory_operand (operands[0], VOIDmode))
16791     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16792                                       operands[2], operands[3]));
16793   else
16794     {
16795       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16796       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16797                                                   operands[2], operands[3],
16798                                                   operands[4]));
16799     }
16800   DONE;
16801 }
16802   [(set_attr "type" "fistp")
16803    (set_attr "i387_cw" "floor")
16804    (set_attr "mode" "<MODE>")])
16805
16806 (define_insn "fistdi2_floor"
16807   [(set (match_operand:DI 0 "memory_operand" "=m")
16808         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16809          UNSPEC_FIST_FLOOR))
16810    (use (match_operand:HI 2 "memory_operand" "m"))
16811    (use (match_operand:HI 3 "memory_operand" "m"))
16812    (clobber (match_scratch:XF 4 "=&1f"))]
16813   "TARGET_USE_FANCY_MATH_387
16814    && flag_unsafe_math_optimizations"
16815   "* return output_fix_trunc (insn, operands, 0);"
16816   [(set_attr "type" "fistp")
16817    (set_attr "i387_cw" "floor")
16818    (set_attr "mode" "DI")])
16819
16820 (define_insn "fistdi2_floor_with_temp"
16821   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16822         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16823          UNSPEC_FIST_FLOOR))
16824    (use (match_operand:HI 2 "memory_operand" "m,m"))
16825    (use (match_operand:HI 3 "memory_operand" "m,m"))
16826    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16827    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16828   "TARGET_USE_FANCY_MATH_387
16829    && flag_unsafe_math_optimizations"
16830   "#"
16831   [(set_attr "type" "fistp")
16832    (set_attr "i387_cw" "floor")
16833    (set_attr "mode" "DI")])
16834
16835 (define_split 
16836   [(set (match_operand:DI 0 "register_operand" "")
16837         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16838          UNSPEC_FIST_FLOOR))
16839    (use (match_operand:HI 2 "memory_operand" ""))
16840    (use (match_operand:HI 3 "memory_operand" ""))
16841    (clobber (match_operand:DI 4 "memory_operand" ""))
16842    (clobber (match_scratch 5 ""))]
16843   "reload_completed"
16844   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16845               (use (match_dup 2))
16846               (use (match_dup 3))
16847               (clobber (match_dup 5))])
16848    (set (match_dup 0) (match_dup 4))]
16849   "")
16850
16851 (define_split 
16852   [(set (match_operand:DI 0 "memory_operand" "")
16853         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16854          UNSPEC_FIST_FLOOR))
16855    (use (match_operand:HI 2 "memory_operand" ""))
16856    (use (match_operand:HI 3 "memory_operand" ""))
16857    (clobber (match_operand:DI 4 "memory_operand" ""))
16858    (clobber (match_scratch 5 ""))]
16859   "reload_completed"
16860   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16861               (use (match_dup 2))
16862               (use (match_dup 3))
16863               (clobber (match_dup 5))])]
16864   "")
16865
16866 (define_insn "fist<mode>2_floor"
16867   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16868         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16869          UNSPEC_FIST_FLOOR))
16870    (use (match_operand:HI 2 "memory_operand" "m"))
16871    (use (match_operand:HI 3 "memory_operand" "m"))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations"
16874   "* return output_fix_trunc (insn, operands, 0);"
16875   [(set_attr "type" "fistp")
16876    (set_attr "i387_cw" "floor")
16877    (set_attr "mode" "<MODE>")])
16878
16879 (define_insn "fist<mode>2_floor_with_temp"
16880   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16881         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16882          UNSPEC_FIST_FLOOR))
16883    (use (match_operand:HI 2 "memory_operand" "m,m"))
16884    (use (match_operand:HI 3 "memory_operand" "m,m"))
16885    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16886   "TARGET_USE_FANCY_MATH_387
16887    && flag_unsafe_math_optimizations"
16888   "#"
16889   [(set_attr "type" "fistp")
16890    (set_attr "i387_cw" "floor")
16891    (set_attr "mode" "<MODE>")])
16892
16893 (define_split 
16894   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16895         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16896          UNSPEC_FIST_FLOOR))
16897    (use (match_operand:HI 2 "memory_operand" ""))
16898    (use (match_operand:HI 3 "memory_operand" ""))
16899    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16900   "reload_completed"
16901   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16902                                   UNSPEC_FIST_FLOOR))
16903               (use (match_dup 2))
16904               (use (match_dup 3))])
16905    (set (match_dup 0) (match_dup 4))]
16906   "")
16907
16908 (define_split 
16909   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16910         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16911          UNSPEC_FIST_FLOOR))
16912    (use (match_operand:HI 2 "memory_operand" ""))
16913    (use (match_operand:HI 3 "memory_operand" ""))
16914    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16915   "reload_completed"
16916   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16917                                   UNSPEC_FIST_FLOOR))
16918               (use (match_dup 2))
16919               (use (match_dup 3))])]
16920   "")
16921
16922 (define_expand "lfloor<mode>2"
16923   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16924                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16925                     UNSPEC_FIST_FLOOR))
16926               (clobber (reg:CC FLAGS_REG))])]
16927   "TARGET_USE_FANCY_MATH_387
16928    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16929    && flag_unsafe_math_optimizations"
16930   "")
16931
16932 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16933 (define_insn_and_split "frndintxf2_ceil"
16934   [(set (match_operand:XF 0 "register_operand" "=f")
16935         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16936          UNSPEC_FRNDINT_CEIL))
16937    (clobber (reg:CC FLAGS_REG))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations
16940    && !(reload_completed || reload_in_progress)"
16941   "#"
16942   "&& 1"
16943   [(const_int 0)]
16944 {
16945   ix86_optimize_mode_switching[I387_CEIL] = 1;
16946
16947   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16948   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16949
16950   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16951                                        operands[2], operands[3]));
16952   DONE;
16953 }
16954   [(set_attr "type" "frndint")
16955    (set_attr "i387_cw" "ceil")
16956    (set_attr "mode" "XF")])
16957
16958 (define_insn "frndintxf2_ceil_i387"
16959   [(set (match_operand:XF 0 "register_operand" "=f")
16960         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16961          UNSPEC_FRNDINT_CEIL))
16962    (use (match_operand:HI 2 "memory_operand" "m"))
16963    (use (match_operand:HI 3 "memory_operand" "m"))]
16964   "TARGET_USE_FANCY_MATH_387
16965    && flag_unsafe_math_optimizations"
16966   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16967   [(set_attr "type" "frndint")
16968    (set_attr "i387_cw" "ceil")
16969    (set_attr "mode" "XF")])
16970
16971 (define_expand "ceilxf2"
16972   [(use (match_operand:XF 0 "register_operand" ""))
16973    (use (match_operand:XF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && flag_unsafe_math_optimizations"
16976 {
16977   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16978   DONE;
16979 })
16980
16981 (define_expand "ceildf2"
16982   [(use (match_operand:DF 0 "register_operand" ""))
16983    (use (match_operand:DF 1 "register_operand" ""))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16986    && flag_unsafe_math_optimizations"
16987 {
16988   rtx op0 = gen_reg_rtx (XFmode);
16989   rtx op1 = gen_reg_rtx (XFmode);
16990
16991   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16992   emit_insn (gen_frndintxf2_ceil (op0, op1));
16993
16994   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16995   DONE;
16996 })
16997
16998 (define_expand "ceilsf2"
16999   [(use (match_operand:SF 0 "register_operand" ""))
17000    (use (match_operand:SF 1 "register_operand" ""))]
17001   "TARGET_USE_FANCY_MATH_387
17002    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17003    && flag_unsafe_math_optimizations"
17004 {
17005   rtx op0 = gen_reg_rtx (XFmode);
17006   rtx op1 = gen_reg_rtx (XFmode);
17007
17008   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17009   emit_insn (gen_frndintxf2_ceil (op0, op1));
17010
17011   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17012   DONE;
17013 })
17014
17015 (define_insn_and_split "*fist<mode>2_ceil_1"
17016   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17017         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17018          UNSPEC_FIST_CEIL))
17019    (clobber (reg:CC FLAGS_REG))]
17020   "TARGET_USE_FANCY_MATH_387
17021    && flag_unsafe_math_optimizations
17022    && !(reload_completed || reload_in_progress)"
17023   "#"
17024   "&& 1"
17025   [(const_int 0)]
17026 {
17027   ix86_optimize_mode_switching[I387_CEIL] = 1;
17028
17029   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17030   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17031   if (memory_operand (operands[0], VOIDmode))
17032     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17033                                      operands[2], operands[3]));
17034   else
17035     {
17036       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17037       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17038                                                  operands[2], operands[3],
17039                                                  operands[4]));
17040     }
17041   DONE;
17042 }
17043   [(set_attr "type" "fistp")
17044    (set_attr "i387_cw" "ceil")
17045    (set_attr "mode" "<MODE>")])
17046
17047 (define_insn "fistdi2_ceil"
17048   [(set (match_operand:DI 0 "memory_operand" "=m")
17049         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17050          UNSPEC_FIST_CEIL))
17051    (use (match_operand:HI 2 "memory_operand" "m"))
17052    (use (match_operand:HI 3 "memory_operand" "m"))
17053    (clobber (match_scratch:XF 4 "=&1f"))]
17054   "TARGET_USE_FANCY_MATH_387
17055    && flag_unsafe_math_optimizations"
17056   "* return output_fix_trunc (insn, operands, 0);"
17057   [(set_attr "type" "fistp")
17058    (set_attr "i387_cw" "ceil")
17059    (set_attr "mode" "DI")])
17060
17061 (define_insn "fistdi2_ceil_with_temp"
17062   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17063         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17064          UNSPEC_FIST_CEIL))
17065    (use (match_operand:HI 2 "memory_operand" "m,m"))
17066    (use (match_operand:HI 3 "memory_operand" "m,m"))
17067    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17068    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && flag_unsafe_math_optimizations"
17071   "#"
17072   [(set_attr "type" "fistp")
17073    (set_attr "i387_cw" "ceil")
17074    (set_attr "mode" "DI")])
17075
17076 (define_split 
17077   [(set (match_operand:DI 0 "register_operand" "")
17078         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17079          UNSPEC_FIST_CEIL))
17080    (use (match_operand:HI 2 "memory_operand" ""))
17081    (use (match_operand:HI 3 "memory_operand" ""))
17082    (clobber (match_operand:DI 4 "memory_operand" ""))
17083    (clobber (match_scratch 5 ""))]
17084   "reload_completed"
17085   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17086               (use (match_dup 2))
17087               (use (match_dup 3))
17088               (clobber (match_dup 5))])
17089    (set (match_dup 0) (match_dup 4))]
17090   "")
17091
17092 (define_split 
17093   [(set (match_operand:DI 0 "memory_operand" "")
17094         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17095          UNSPEC_FIST_CEIL))
17096    (use (match_operand:HI 2 "memory_operand" ""))
17097    (use (match_operand:HI 3 "memory_operand" ""))
17098    (clobber (match_operand:DI 4 "memory_operand" ""))
17099    (clobber (match_scratch 5 ""))]
17100   "reload_completed"
17101   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17102               (use (match_dup 2))
17103               (use (match_dup 3))
17104               (clobber (match_dup 5))])]
17105   "")
17106
17107 (define_insn "fist<mode>2_ceil"
17108   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17109         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17110          UNSPEC_FIST_CEIL))
17111    (use (match_operand:HI 2 "memory_operand" "m"))
17112    (use (match_operand:HI 3 "memory_operand" "m"))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && flag_unsafe_math_optimizations"
17115   "* return output_fix_trunc (insn, operands, 0);"
17116   [(set_attr "type" "fistp")
17117    (set_attr "i387_cw" "ceil")
17118    (set_attr "mode" "<MODE>")])
17119
17120 (define_insn "fist<mode>2_ceil_with_temp"
17121   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17122         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17123          UNSPEC_FIST_CEIL))
17124    (use (match_operand:HI 2 "memory_operand" "m,m"))
17125    (use (match_operand:HI 3 "memory_operand" "m,m"))
17126    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17127   "TARGET_USE_FANCY_MATH_387
17128    && flag_unsafe_math_optimizations"
17129   "#"
17130   [(set_attr "type" "fistp")
17131    (set_attr "i387_cw" "ceil")
17132    (set_attr "mode" "<MODE>")])
17133
17134 (define_split 
17135   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17136         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17137          UNSPEC_FIST_CEIL))
17138    (use (match_operand:HI 2 "memory_operand" ""))
17139    (use (match_operand:HI 3 "memory_operand" ""))
17140    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17141   "reload_completed"
17142   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17143                                   UNSPEC_FIST_CEIL))
17144               (use (match_dup 2))
17145               (use (match_dup 3))])
17146    (set (match_dup 0) (match_dup 4))]
17147   "")
17148
17149 (define_split 
17150   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17151         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17152          UNSPEC_FIST_CEIL))
17153    (use (match_operand:HI 2 "memory_operand" ""))
17154    (use (match_operand:HI 3 "memory_operand" ""))
17155    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17156   "reload_completed"
17157   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17158                                   UNSPEC_FIST_CEIL))
17159               (use (match_dup 2))
17160               (use (match_dup 3))])]
17161   "")
17162
17163 (define_expand "lceil<mode>2"
17164   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17165                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17166                     UNSPEC_FIST_CEIL))
17167               (clobber (reg:CC FLAGS_REG))])]
17168   "TARGET_USE_FANCY_MATH_387
17169    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17170    && flag_unsafe_math_optimizations"
17171   "")
17172
17173 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17174 (define_insn_and_split "frndintxf2_trunc"
17175   [(set (match_operand:XF 0 "register_operand" "=f")
17176         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17177          UNSPEC_FRNDINT_TRUNC))
17178    (clobber (reg:CC FLAGS_REG))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && flag_unsafe_math_optimizations
17181    && !(reload_completed || reload_in_progress)"
17182   "#"
17183   "&& 1"
17184   [(const_int 0)]
17185 {
17186   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17187
17188   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17189   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17190
17191   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17192                                         operands[2], operands[3]));
17193   DONE;
17194 }
17195   [(set_attr "type" "frndint")
17196    (set_attr "i387_cw" "trunc")
17197    (set_attr "mode" "XF")])
17198
17199 (define_insn "frndintxf2_trunc_i387"
17200   [(set (match_operand:XF 0 "register_operand" "=f")
17201         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17202          UNSPEC_FRNDINT_TRUNC))
17203    (use (match_operand:HI 2 "memory_operand" "m"))
17204    (use (match_operand:HI 3 "memory_operand" "m"))]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations"
17207   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17208   [(set_attr "type" "frndint")
17209    (set_attr "i387_cw" "trunc")
17210    (set_attr "mode" "XF")])
17211
17212 (define_expand "btruncxf2"
17213   [(use (match_operand:XF 0 "register_operand" ""))
17214    (use (match_operand:XF 1 "register_operand" ""))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && flag_unsafe_math_optimizations"
17217 {
17218   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17219   DONE;
17220 })
17221
17222 (define_expand "btruncdf2"
17223   [(use (match_operand:DF 0 "register_operand" ""))
17224    (use (match_operand:DF 1 "register_operand" ""))]
17225   "TARGET_USE_FANCY_MATH_387
17226    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17227    && flag_unsafe_math_optimizations"
17228 {
17229   rtx op0 = gen_reg_rtx (XFmode);
17230   rtx op1 = gen_reg_rtx (XFmode);
17231
17232   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17233   emit_insn (gen_frndintxf2_trunc (op0, op1));
17234
17235   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17236   DONE;
17237 })
17238
17239 (define_expand "btruncsf2"
17240   [(use (match_operand:SF 0 "register_operand" ""))
17241    (use (match_operand:SF 1 "register_operand" ""))]
17242   "TARGET_USE_FANCY_MATH_387
17243    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17244    && flag_unsafe_math_optimizations"
17245 {
17246   rtx op0 = gen_reg_rtx (XFmode);
17247   rtx op1 = gen_reg_rtx (XFmode);
17248
17249   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17250   emit_insn (gen_frndintxf2_trunc (op0, op1));
17251
17252   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17253   DONE;
17254 })
17255
17256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17257 (define_insn_and_split "frndintxf2_mask_pm"
17258   [(set (match_operand:XF 0 "register_operand" "=f")
17259         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17260          UNSPEC_FRNDINT_MASK_PM))
17261    (clobber (reg:CC FLAGS_REG))]
17262   "TARGET_USE_FANCY_MATH_387
17263    && flag_unsafe_math_optimizations
17264    && !(reload_completed || reload_in_progress)"
17265   "#"
17266   "&& 1"
17267   [(const_int 0)]
17268 {
17269   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17270
17271   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17272   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17273
17274   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17275                                           operands[2], operands[3]));
17276   DONE;
17277 }
17278   [(set_attr "type" "frndint")
17279    (set_attr "i387_cw" "mask_pm")
17280    (set_attr "mode" "XF")])
17281
17282 (define_insn "frndintxf2_mask_pm_i387"
17283   [(set (match_operand:XF 0 "register_operand" "=f")
17284         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17285          UNSPEC_FRNDINT_MASK_PM))
17286    (use (match_operand:HI 2 "memory_operand" "m"))
17287    (use (match_operand:HI 3 "memory_operand" "m"))]
17288   "TARGET_USE_FANCY_MATH_387
17289    && flag_unsafe_math_optimizations"
17290   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17291   [(set_attr "type" "frndint")
17292    (set_attr "i387_cw" "mask_pm")
17293    (set_attr "mode" "XF")])
17294
17295 (define_expand "nearbyintxf2"
17296   [(use (match_operand:XF 0 "register_operand" ""))
17297    (use (match_operand:XF 1 "register_operand" ""))]
17298   "TARGET_USE_FANCY_MATH_387
17299    && flag_unsafe_math_optimizations"
17300 {
17301   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17302
17303   DONE;
17304 })
17305
17306 (define_expand "nearbyintdf2"
17307   [(use (match_operand:DF 0 "register_operand" ""))
17308    (use (match_operand:DF 1 "register_operand" ""))]
17309   "TARGET_USE_FANCY_MATH_387
17310    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17311    && flag_unsafe_math_optimizations"
17312 {
17313   rtx op0 = gen_reg_rtx (XFmode);
17314   rtx op1 = gen_reg_rtx (XFmode);
17315
17316   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17317   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17318
17319   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17320   DONE;
17321 })
17322
17323 (define_expand "nearbyintsf2"
17324   [(use (match_operand:SF 0 "register_operand" ""))
17325    (use (match_operand:SF 1 "register_operand" ""))]
17326   "TARGET_USE_FANCY_MATH_387
17327    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17328    && flag_unsafe_math_optimizations"
17329 {
17330   rtx op0 = gen_reg_rtx (XFmode);
17331   rtx op1 = gen_reg_rtx (XFmode);
17332
17333   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17334   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17335
17336   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17337   DONE;
17338 })
17339
17340 \f
17341 ;; Block operation instructions
17342
17343 (define_insn "cld"
17344  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17345  ""
17346  "cld"
17347   [(set_attr "type" "cld")])
17348
17349 (define_expand "movmemsi"
17350   [(use (match_operand:BLK 0 "memory_operand" ""))
17351    (use (match_operand:BLK 1 "memory_operand" ""))
17352    (use (match_operand:SI 2 "nonmemory_operand" ""))
17353    (use (match_operand:SI 3 "const_int_operand" ""))]
17354   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17355 {
17356  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17357    DONE;
17358  else
17359    FAIL;
17360 })
17361
17362 (define_expand "movmemdi"
17363   [(use (match_operand:BLK 0 "memory_operand" ""))
17364    (use (match_operand:BLK 1 "memory_operand" ""))
17365    (use (match_operand:DI 2 "nonmemory_operand" ""))
17366    (use (match_operand:DI 3 "const_int_operand" ""))]
17367   "TARGET_64BIT"
17368 {
17369  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17370    DONE;
17371  else
17372    FAIL;
17373 })
17374
17375 ;; Most CPUs don't like single string operations
17376 ;; Handle this case here to simplify previous expander.
17377
17378 (define_expand "strmov"
17379   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17380    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17381    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17382               (clobber (reg:CC FLAGS_REG))])
17383    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17384               (clobber (reg:CC FLAGS_REG))])]
17385   ""
17386 {
17387   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17388
17389   /* If .md ever supports :P for Pmode, these can be directly
17390      in the pattern above.  */
17391   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17392   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17393
17394   if (TARGET_SINGLE_STRINGOP || optimize_size)
17395     {
17396       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17397                                       operands[2], operands[3],
17398                                       operands[5], operands[6]));
17399       DONE;
17400     }
17401
17402   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17403 })
17404
17405 (define_expand "strmov_singleop"
17406   [(parallel [(set (match_operand 1 "memory_operand" "")
17407                    (match_operand 3 "memory_operand" ""))
17408               (set (match_operand 0 "register_operand" "")
17409                    (match_operand 4 "" ""))
17410               (set (match_operand 2 "register_operand" "")
17411                    (match_operand 5 "" ""))
17412               (use (reg:SI DIRFLAG_REG))])]
17413   "TARGET_SINGLE_STRINGOP || optimize_size"
17414   "")
17415
17416 (define_insn "*strmovdi_rex_1"
17417   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17418         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17419    (set (match_operand:DI 0 "register_operand" "=D")
17420         (plus:DI (match_dup 2)
17421                  (const_int 8)))
17422    (set (match_operand:DI 1 "register_operand" "=S")
17423         (plus:DI (match_dup 3)
17424                  (const_int 8)))
17425    (use (reg:SI DIRFLAG_REG))]
17426   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17427   "movsq"
17428   [(set_attr "type" "str")
17429    (set_attr "mode" "DI")
17430    (set_attr "memory" "both")])
17431
17432 (define_insn "*strmovsi_1"
17433   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17434         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17435    (set (match_operand:SI 0 "register_operand" "=D")
17436         (plus:SI (match_dup 2)
17437                  (const_int 4)))
17438    (set (match_operand:SI 1 "register_operand" "=S")
17439         (plus:SI (match_dup 3)
17440                  (const_int 4)))
17441    (use (reg:SI DIRFLAG_REG))]
17442   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17443   "{movsl|movsd}"
17444   [(set_attr "type" "str")
17445    (set_attr "mode" "SI")
17446    (set_attr "memory" "both")])
17447
17448 (define_insn "*strmovsi_rex_1"
17449   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17450         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17451    (set (match_operand:DI 0 "register_operand" "=D")
17452         (plus:DI (match_dup 2)
17453                  (const_int 4)))
17454    (set (match_operand:DI 1 "register_operand" "=S")
17455         (plus:DI (match_dup 3)
17456                  (const_int 4)))
17457    (use (reg:SI DIRFLAG_REG))]
17458   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17459   "{movsl|movsd}"
17460   [(set_attr "type" "str")
17461    (set_attr "mode" "SI")
17462    (set_attr "memory" "both")])
17463
17464 (define_insn "*strmovhi_1"
17465   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17466         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17467    (set (match_operand:SI 0 "register_operand" "=D")
17468         (plus:SI (match_dup 2)
17469                  (const_int 2)))
17470    (set (match_operand:SI 1 "register_operand" "=S")
17471         (plus:SI (match_dup 3)
17472                  (const_int 2)))
17473    (use (reg:SI DIRFLAG_REG))]
17474   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17475   "movsw"
17476   [(set_attr "type" "str")
17477    (set_attr "memory" "both")
17478    (set_attr "mode" "HI")])
17479
17480 (define_insn "*strmovhi_rex_1"
17481   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17482         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17483    (set (match_operand:DI 0 "register_operand" "=D")
17484         (plus:DI (match_dup 2)
17485                  (const_int 2)))
17486    (set (match_operand:DI 1 "register_operand" "=S")
17487         (plus:DI (match_dup 3)
17488                  (const_int 2)))
17489    (use (reg:SI DIRFLAG_REG))]
17490   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17491   "movsw"
17492   [(set_attr "type" "str")
17493    (set_attr "memory" "both")
17494    (set_attr "mode" "HI")])
17495
17496 (define_insn "*strmovqi_1"
17497   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17498         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17499    (set (match_operand:SI 0 "register_operand" "=D")
17500         (plus:SI (match_dup 2)
17501                  (const_int 1)))
17502    (set (match_operand:SI 1 "register_operand" "=S")
17503         (plus:SI (match_dup 3)
17504                  (const_int 1)))
17505    (use (reg:SI DIRFLAG_REG))]
17506   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17507   "movsb"
17508   [(set_attr "type" "str")
17509    (set_attr "memory" "both")
17510    (set_attr "mode" "QI")])
17511
17512 (define_insn "*strmovqi_rex_1"
17513   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17514         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17515    (set (match_operand:DI 0 "register_operand" "=D")
17516         (plus:DI (match_dup 2)
17517                  (const_int 1)))
17518    (set (match_operand:DI 1 "register_operand" "=S")
17519         (plus:DI (match_dup 3)
17520                  (const_int 1)))
17521    (use (reg:SI DIRFLAG_REG))]
17522   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17523   "movsb"
17524   [(set_attr "type" "str")
17525    (set_attr "memory" "both")
17526    (set_attr "mode" "QI")])
17527
17528 (define_expand "rep_mov"
17529   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17530               (set (match_operand 0 "register_operand" "")
17531                    (match_operand 5 "" ""))
17532               (set (match_operand 2 "register_operand" "")
17533                    (match_operand 6 "" ""))
17534               (set (match_operand 1 "memory_operand" "")
17535                    (match_operand 3 "memory_operand" ""))
17536               (use (match_dup 4))
17537               (use (reg:SI DIRFLAG_REG))])]
17538   ""
17539   "")
17540
17541 (define_insn "*rep_movdi_rex64"
17542   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17543    (set (match_operand:DI 0 "register_operand" "=D") 
17544         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17545                             (const_int 3))
17546                  (match_operand:DI 3 "register_operand" "0")))
17547    (set (match_operand:DI 1 "register_operand" "=S") 
17548         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17549                  (match_operand:DI 4 "register_operand" "1")))
17550    (set (mem:BLK (match_dup 3))
17551         (mem:BLK (match_dup 4)))
17552    (use (match_dup 5))
17553    (use (reg:SI DIRFLAG_REG))]
17554   "TARGET_64BIT"
17555   "{rep\;movsq|rep movsq}"
17556   [(set_attr "type" "str")
17557    (set_attr "prefix_rep" "1")
17558    (set_attr "memory" "both")
17559    (set_attr "mode" "DI")])
17560
17561 (define_insn "*rep_movsi"
17562   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17563    (set (match_operand:SI 0 "register_operand" "=D") 
17564         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17565                             (const_int 2))
17566                  (match_operand:SI 3 "register_operand" "0")))
17567    (set (match_operand:SI 1 "register_operand" "=S") 
17568         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17569                  (match_operand:SI 4 "register_operand" "1")))
17570    (set (mem:BLK (match_dup 3))
17571         (mem:BLK (match_dup 4)))
17572    (use (match_dup 5))
17573    (use (reg:SI DIRFLAG_REG))]
17574   "!TARGET_64BIT"
17575   "{rep\;movsl|rep movsd}"
17576   [(set_attr "type" "str")
17577    (set_attr "prefix_rep" "1")
17578    (set_attr "memory" "both")
17579    (set_attr "mode" "SI")])
17580
17581 (define_insn "*rep_movsi_rex64"
17582   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17583    (set (match_operand:DI 0 "register_operand" "=D") 
17584         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17585                             (const_int 2))
17586                  (match_operand:DI 3 "register_operand" "0")))
17587    (set (match_operand:DI 1 "register_operand" "=S") 
17588         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17589                  (match_operand:DI 4 "register_operand" "1")))
17590    (set (mem:BLK (match_dup 3))
17591         (mem:BLK (match_dup 4)))
17592    (use (match_dup 5))
17593    (use (reg:SI DIRFLAG_REG))]
17594   "TARGET_64BIT"
17595   "{rep\;movsl|rep movsd}"
17596   [(set_attr "type" "str")
17597    (set_attr "prefix_rep" "1")
17598    (set_attr "memory" "both")
17599    (set_attr "mode" "SI")])
17600
17601 (define_insn "*rep_movqi"
17602   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17603    (set (match_operand:SI 0 "register_operand" "=D") 
17604         (plus:SI (match_operand:SI 3 "register_operand" "0")
17605                  (match_operand:SI 5 "register_operand" "2")))
17606    (set (match_operand:SI 1 "register_operand" "=S") 
17607         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17608    (set (mem:BLK (match_dup 3))
17609         (mem:BLK (match_dup 4)))
17610    (use (match_dup 5))
17611    (use (reg:SI DIRFLAG_REG))]
17612   "!TARGET_64BIT"
17613   "{rep\;movsb|rep movsb}"
17614   [(set_attr "type" "str")
17615    (set_attr "prefix_rep" "1")
17616    (set_attr "memory" "both")
17617    (set_attr "mode" "SI")])
17618
17619 (define_insn "*rep_movqi_rex64"
17620   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17621    (set (match_operand:DI 0 "register_operand" "=D") 
17622         (plus:DI (match_operand:DI 3 "register_operand" "0")
17623                  (match_operand:DI 5 "register_operand" "2")))
17624    (set (match_operand:DI 1 "register_operand" "=S") 
17625         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17626    (set (mem:BLK (match_dup 3))
17627         (mem:BLK (match_dup 4)))
17628    (use (match_dup 5))
17629    (use (reg:SI DIRFLAG_REG))]
17630   "TARGET_64BIT"
17631   "{rep\;movsb|rep movsb}"
17632   [(set_attr "type" "str")
17633    (set_attr "prefix_rep" "1")
17634    (set_attr "memory" "both")
17635    (set_attr "mode" "SI")])
17636
17637 (define_expand "setmemsi"
17638    [(use (match_operand:BLK 0 "memory_operand" ""))
17639     (use (match_operand:SI 1 "nonmemory_operand" ""))
17640     (use (match_operand 2 "const_int_operand" ""))
17641     (use (match_operand 3 "const_int_operand" ""))]
17642   ""
17643 {
17644  /* If value to set is not zero, use the library routine.  */
17645  if (operands[2] != const0_rtx)
17646    FAIL;
17647
17648  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17649    DONE;
17650  else
17651    FAIL;
17652 })
17653
17654 (define_expand "setmemdi"
17655    [(use (match_operand:BLK 0 "memory_operand" ""))
17656     (use (match_operand:DI 1 "nonmemory_operand" ""))
17657     (use (match_operand 2 "const_int_operand" ""))
17658     (use (match_operand 3 "const_int_operand" ""))]
17659   "TARGET_64BIT"
17660 {
17661  /* If value to set is not zero, use the library routine.  */
17662  if (operands[2] != const0_rtx)
17663    FAIL;
17664
17665  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17666    DONE;
17667  else
17668    FAIL;
17669 })
17670
17671 ;; Most CPUs don't like single string operations
17672 ;; Handle this case here to simplify previous expander.
17673
17674 (define_expand "strset"
17675   [(set (match_operand 1 "memory_operand" "")
17676         (match_operand 2 "register_operand" ""))
17677    (parallel [(set (match_operand 0 "register_operand" "")
17678                    (match_dup 3))
17679               (clobber (reg:CC FLAGS_REG))])]
17680   ""
17681 {
17682   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17683     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17684
17685   /* If .md ever supports :P for Pmode, this can be directly
17686      in the pattern above.  */
17687   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17688                               GEN_INT (GET_MODE_SIZE (GET_MODE
17689                                                       (operands[2]))));
17690   if (TARGET_SINGLE_STRINGOP || optimize_size)
17691     {
17692       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17693                                       operands[3]));
17694       DONE;
17695     }
17696 })
17697
17698 (define_expand "strset_singleop"
17699   [(parallel [(set (match_operand 1 "memory_operand" "")
17700                    (match_operand 2 "register_operand" ""))
17701               (set (match_operand 0 "register_operand" "")
17702                    (match_operand 3 "" ""))
17703               (use (reg:SI DIRFLAG_REG))])]
17704   "TARGET_SINGLE_STRINGOP || optimize_size"
17705   "")
17706
17707 (define_insn "*strsetdi_rex_1"
17708   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17709         (match_operand:DI 2 "register_operand" "a"))
17710    (set (match_operand:DI 0 "register_operand" "=D")
17711         (plus:DI (match_dup 1)
17712                  (const_int 8)))
17713    (use (reg:SI DIRFLAG_REG))]
17714   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17715   "stosq"
17716   [(set_attr "type" "str")
17717    (set_attr "memory" "store")
17718    (set_attr "mode" "DI")])
17719
17720 (define_insn "*strsetsi_1"
17721   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17722         (match_operand:SI 2 "register_operand" "a"))
17723    (set (match_operand:SI 0 "register_operand" "=D")
17724         (plus:SI (match_dup 1)
17725                  (const_int 4)))
17726    (use (reg:SI DIRFLAG_REG))]
17727   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17728   "{stosl|stosd}"
17729   [(set_attr "type" "str")
17730    (set_attr "memory" "store")
17731    (set_attr "mode" "SI")])
17732
17733 (define_insn "*strsetsi_rex_1"
17734   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17735         (match_operand:SI 2 "register_operand" "a"))
17736    (set (match_operand:DI 0 "register_operand" "=D")
17737         (plus:DI (match_dup 1)
17738                  (const_int 4)))
17739    (use (reg:SI DIRFLAG_REG))]
17740   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17741   "{stosl|stosd}"
17742   [(set_attr "type" "str")
17743    (set_attr "memory" "store")
17744    (set_attr "mode" "SI")])
17745
17746 (define_insn "*strsethi_1"
17747   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17748         (match_operand:HI 2 "register_operand" "a"))
17749    (set (match_operand:SI 0 "register_operand" "=D")
17750         (plus:SI (match_dup 1)
17751                  (const_int 2)))
17752    (use (reg:SI DIRFLAG_REG))]
17753   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17754   "stosw"
17755   [(set_attr "type" "str")
17756    (set_attr "memory" "store")
17757    (set_attr "mode" "HI")])
17758
17759 (define_insn "*strsethi_rex_1"
17760   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17761         (match_operand:HI 2 "register_operand" "a"))
17762    (set (match_operand:DI 0 "register_operand" "=D")
17763         (plus:DI (match_dup 1)
17764                  (const_int 2)))
17765    (use (reg:SI DIRFLAG_REG))]
17766   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17767   "stosw"
17768   [(set_attr "type" "str")
17769    (set_attr "memory" "store")
17770    (set_attr "mode" "HI")])
17771
17772 (define_insn "*strsetqi_1"
17773   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17774         (match_operand:QI 2 "register_operand" "a"))
17775    (set (match_operand:SI 0 "register_operand" "=D")
17776         (plus:SI (match_dup 1)
17777                  (const_int 1)))
17778    (use (reg:SI DIRFLAG_REG))]
17779   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17780   "stosb"
17781   [(set_attr "type" "str")
17782    (set_attr "memory" "store")
17783    (set_attr "mode" "QI")])
17784
17785 (define_insn "*strsetqi_rex_1"
17786   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17787         (match_operand:QI 2 "register_operand" "a"))
17788    (set (match_operand:DI 0 "register_operand" "=D")
17789         (plus:DI (match_dup 1)
17790                  (const_int 1)))
17791    (use (reg:SI DIRFLAG_REG))]
17792   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17793   "stosb"
17794   [(set_attr "type" "str")
17795    (set_attr "memory" "store")
17796    (set_attr "mode" "QI")])
17797
17798 (define_expand "rep_stos"
17799   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17800               (set (match_operand 0 "register_operand" "")
17801                    (match_operand 4 "" ""))
17802               (set (match_operand 2 "memory_operand" "") (const_int 0))
17803               (use (match_operand 3 "register_operand" ""))
17804               (use (match_dup 1))
17805               (use (reg:SI DIRFLAG_REG))])]
17806   ""
17807   "")
17808
17809 (define_insn "*rep_stosdi_rex64"
17810   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17811    (set (match_operand:DI 0 "register_operand" "=D") 
17812         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17813                             (const_int 3))
17814                  (match_operand:DI 3 "register_operand" "0")))
17815    (set (mem:BLK (match_dup 3))
17816         (const_int 0))
17817    (use (match_operand:DI 2 "register_operand" "a"))
17818    (use (match_dup 4))
17819    (use (reg:SI DIRFLAG_REG))]
17820   "TARGET_64BIT"
17821   "{rep\;stosq|rep stosq}"
17822   [(set_attr "type" "str")
17823    (set_attr "prefix_rep" "1")
17824    (set_attr "memory" "store")
17825    (set_attr "mode" "DI")])
17826
17827 (define_insn "*rep_stossi"
17828   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17829    (set (match_operand:SI 0 "register_operand" "=D") 
17830         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17831                             (const_int 2))
17832                  (match_operand:SI 3 "register_operand" "0")))
17833    (set (mem:BLK (match_dup 3))
17834         (const_int 0))
17835    (use (match_operand:SI 2 "register_operand" "a"))
17836    (use (match_dup 4))
17837    (use (reg:SI DIRFLAG_REG))]
17838   "!TARGET_64BIT"
17839   "{rep\;stosl|rep stosd}"
17840   [(set_attr "type" "str")
17841    (set_attr "prefix_rep" "1")
17842    (set_attr "memory" "store")
17843    (set_attr "mode" "SI")])
17844
17845 (define_insn "*rep_stossi_rex64"
17846   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17847    (set (match_operand:DI 0 "register_operand" "=D") 
17848         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17849                             (const_int 2))
17850                  (match_operand:DI 3 "register_operand" "0")))
17851    (set (mem:BLK (match_dup 3))
17852         (const_int 0))
17853    (use (match_operand:SI 2 "register_operand" "a"))
17854    (use (match_dup 4))
17855    (use (reg:SI DIRFLAG_REG))]
17856   "TARGET_64BIT"
17857   "{rep\;stosl|rep stosd}"
17858   [(set_attr "type" "str")
17859    (set_attr "prefix_rep" "1")
17860    (set_attr "memory" "store")
17861    (set_attr "mode" "SI")])
17862
17863 (define_insn "*rep_stosqi"
17864   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17865    (set (match_operand:SI 0 "register_operand" "=D") 
17866         (plus:SI (match_operand:SI 3 "register_operand" "0")
17867                  (match_operand:SI 4 "register_operand" "1")))
17868    (set (mem:BLK (match_dup 3))
17869         (const_int 0))
17870    (use (match_operand:QI 2 "register_operand" "a"))
17871    (use (match_dup 4))
17872    (use (reg:SI DIRFLAG_REG))]
17873   "!TARGET_64BIT"
17874   "{rep\;stosb|rep stosb}"
17875   [(set_attr "type" "str")
17876    (set_attr "prefix_rep" "1")
17877    (set_attr "memory" "store")
17878    (set_attr "mode" "QI")])
17879
17880 (define_insn "*rep_stosqi_rex64"
17881   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17882    (set (match_operand:DI 0 "register_operand" "=D") 
17883         (plus:DI (match_operand:DI 3 "register_operand" "0")
17884                  (match_operand:DI 4 "register_operand" "1")))
17885    (set (mem:BLK (match_dup 3))
17886         (const_int 0))
17887    (use (match_operand:QI 2 "register_operand" "a"))
17888    (use (match_dup 4))
17889    (use (reg:SI DIRFLAG_REG))]
17890   "TARGET_64BIT"
17891   "{rep\;stosb|rep stosb}"
17892   [(set_attr "type" "str")
17893    (set_attr "prefix_rep" "1")
17894    (set_attr "memory" "store")
17895    (set_attr "mode" "QI")])
17896
17897 (define_expand "cmpstrnsi"
17898   [(set (match_operand:SI 0 "register_operand" "")
17899         (compare:SI (match_operand:BLK 1 "general_operand" "")
17900                     (match_operand:BLK 2 "general_operand" "")))
17901    (use (match_operand 3 "general_operand" ""))
17902    (use (match_operand 4 "immediate_operand" ""))]
17903   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17904 {
17905   rtx addr1, addr2, out, outlow, count, countreg, align;
17906
17907   /* Can't use this if the user has appropriated esi or edi.  */
17908   if (global_regs[4] || global_regs[5])
17909     FAIL;
17910
17911   out = operands[0];
17912   if (GET_CODE (out) != REG)
17913     out = gen_reg_rtx (SImode);
17914
17915   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17916   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17917   if (addr1 != XEXP (operands[1], 0))
17918     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17919   if (addr2 != XEXP (operands[2], 0))
17920     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17921
17922   count = operands[3];
17923   countreg = ix86_zero_extend_to_Pmode (count);
17924
17925   /* %%% Iff we are testing strict equality, we can use known alignment
17926      to good advantage.  This may be possible with combine, particularly
17927      once cc0 is dead.  */
17928   align = operands[4];
17929
17930   emit_insn (gen_cld ());
17931   if (GET_CODE (count) == CONST_INT)
17932     {
17933       if (INTVAL (count) == 0)
17934         {
17935           emit_move_insn (operands[0], const0_rtx);
17936           DONE;
17937         }
17938       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17939                                      operands[1], operands[2]));
17940     }
17941   else
17942     {
17943       if (TARGET_64BIT)
17944         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17945       else
17946         emit_insn (gen_cmpsi_1 (countreg, countreg));
17947       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17948                                   operands[1], operands[2]));
17949     }
17950
17951   outlow = gen_lowpart (QImode, out);
17952   emit_insn (gen_cmpintqi (outlow));
17953   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17954
17955   if (operands[0] != out)
17956     emit_move_insn (operands[0], out);
17957
17958   DONE;
17959 })
17960
17961 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17962
17963 (define_expand "cmpintqi"
17964   [(set (match_dup 1)
17965         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17966    (set (match_dup 2)
17967         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17968    (parallel [(set (match_operand:QI 0 "register_operand" "")
17969                    (minus:QI (match_dup 1)
17970                              (match_dup 2)))
17971               (clobber (reg:CC FLAGS_REG))])]
17972   ""
17973   "operands[1] = gen_reg_rtx (QImode);
17974    operands[2] = gen_reg_rtx (QImode);")
17975
17976 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17977 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17978
17979 (define_expand "cmpstrnqi_nz_1"
17980   [(parallel [(set (reg:CC FLAGS_REG)
17981                    (compare:CC (match_operand 4 "memory_operand" "")
17982                                (match_operand 5 "memory_operand" "")))
17983               (use (match_operand 2 "register_operand" ""))
17984               (use (match_operand:SI 3 "immediate_operand" ""))
17985               (use (reg:SI DIRFLAG_REG))
17986               (clobber (match_operand 0 "register_operand" ""))
17987               (clobber (match_operand 1 "register_operand" ""))
17988               (clobber (match_dup 2))])]
17989   ""
17990   "")
17991
17992 (define_insn "*cmpstrnqi_nz_1"
17993   [(set (reg:CC FLAGS_REG)
17994         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17995                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17996    (use (match_operand:SI 6 "register_operand" "2"))
17997    (use (match_operand:SI 3 "immediate_operand" "i"))
17998    (use (reg:SI DIRFLAG_REG))
17999    (clobber (match_operand:SI 0 "register_operand" "=S"))
18000    (clobber (match_operand:SI 1 "register_operand" "=D"))
18001    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18002   "!TARGET_64BIT"
18003   "repz{\;| }cmpsb"
18004   [(set_attr "type" "str")
18005    (set_attr "mode" "QI")
18006    (set_attr "prefix_rep" "1")])
18007
18008 (define_insn "*cmpstrnqi_nz_rex_1"
18009   [(set (reg:CC FLAGS_REG)
18010         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18011                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18012    (use (match_operand:DI 6 "register_operand" "2"))
18013    (use (match_operand:SI 3 "immediate_operand" "i"))
18014    (use (reg:SI DIRFLAG_REG))
18015    (clobber (match_operand:DI 0 "register_operand" "=S"))
18016    (clobber (match_operand:DI 1 "register_operand" "=D"))
18017    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18018   "TARGET_64BIT"
18019   "repz{\;| }cmpsb"
18020   [(set_attr "type" "str")
18021    (set_attr "mode" "QI")
18022    (set_attr "prefix_rep" "1")])
18023
18024 ;; The same, but the count is not known to not be zero.
18025
18026 (define_expand "cmpstrnqi_1"
18027   [(parallel [(set (reg:CC FLAGS_REG)
18028                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18029                                      (const_int 0))
18030                   (compare:CC (match_operand 4 "memory_operand" "")
18031                               (match_operand 5 "memory_operand" ""))
18032                   (const_int 0)))
18033               (use (match_operand:SI 3 "immediate_operand" ""))
18034               (use (reg:CC FLAGS_REG))
18035               (use (reg:SI DIRFLAG_REG))
18036               (clobber (match_operand 0 "register_operand" ""))
18037               (clobber (match_operand 1 "register_operand" ""))
18038               (clobber (match_dup 2))])]
18039   ""
18040   "")
18041
18042 (define_insn "*cmpstrnqi_1"
18043   [(set (reg:CC FLAGS_REG)
18044         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18045                              (const_int 0))
18046           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18047                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18048           (const_int 0)))
18049    (use (match_operand:SI 3 "immediate_operand" "i"))
18050    (use (reg:CC FLAGS_REG))
18051    (use (reg:SI DIRFLAG_REG))
18052    (clobber (match_operand:SI 0 "register_operand" "=S"))
18053    (clobber (match_operand:SI 1 "register_operand" "=D"))
18054    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18055   "!TARGET_64BIT"
18056   "repz{\;| }cmpsb"
18057   [(set_attr "type" "str")
18058    (set_attr "mode" "QI")
18059    (set_attr "prefix_rep" "1")])
18060
18061 (define_insn "*cmpstrnqi_rex_1"
18062   [(set (reg:CC FLAGS_REG)
18063         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18064                              (const_int 0))
18065           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18066                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18067           (const_int 0)))
18068    (use (match_operand:SI 3 "immediate_operand" "i"))
18069    (use (reg:CC FLAGS_REG))
18070    (use (reg:SI DIRFLAG_REG))
18071    (clobber (match_operand:DI 0 "register_operand" "=S"))
18072    (clobber (match_operand:DI 1 "register_operand" "=D"))
18073    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18074   "TARGET_64BIT"
18075   "repz{\;| }cmpsb"
18076   [(set_attr "type" "str")
18077    (set_attr "mode" "QI")
18078    (set_attr "prefix_rep" "1")])
18079
18080 (define_expand "strlensi"
18081   [(set (match_operand:SI 0 "register_operand" "")
18082         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18083                     (match_operand:QI 2 "immediate_operand" "")
18084                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18085   ""
18086 {
18087  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18088    DONE;
18089  else
18090    FAIL;
18091 })
18092
18093 (define_expand "strlendi"
18094   [(set (match_operand:DI 0 "register_operand" "")
18095         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18096                     (match_operand:QI 2 "immediate_operand" "")
18097                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18098   ""
18099 {
18100  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18101    DONE;
18102  else
18103    FAIL;
18104 })
18105
18106 (define_expand "strlenqi_1"
18107   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18108               (use (reg:SI DIRFLAG_REG))
18109               (clobber (match_operand 1 "register_operand" ""))
18110               (clobber (reg:CC FLAGS_REG))])]
18111   ""
18112   "")
18113
18114 (define_insn "*strlenqi_1"
18115   [(set (match_operand:SI 0 "register_operand" "=&c")
18116         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18117                     (match_operand:QI 2 "register_operand" "a")
18118                     (match_operand:SI 3 "immediate_operand" "i")
18119                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18120    (use (reg:SI DIRFLAG_REG))
18121    (clobber (match_operand:SI 1 "register_operand" "=D"))
18122    (clobber (reg:CC FLAGS_REG))]
18123   "!TARGET_64BIT"
18124   "repnz{\;| }scasb"
18125   [(set_attr "type" "str")
18126    (set_attr "mode" "QI")
18127    (set_attr "prefix_rep" "1")])
18128
18129 (define_insn "*strlenqi_rex_1"
18130   [(set (match_operand:DI 0 "register_operand" "=&c")
18131         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18132                     (match_operand:QI 2 "register_operand" "a")
18133                     (match_operand:DI 3 "immediate_operand" "i")
18134                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18135    (use (reg:SI DIRFLAG_REG))
18136    (clobber (match_operand:DI 1 "register_operand" "=D"))
18137    (clobber (reg:CC FLAGS_REG))]
18138   "TARGET_64BIT"
18139   "repnz{\;| }scasb"
18140   [(set_attr "type" "str")
18141    (set_attr "mode" "QI")
18142    (set_attr "prefix_rep" "1")])
18143
18144 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18145 ;; handled in combine, but it is not currently up to the task.
18146 ;; When used for their truth value, the cmpstrn* expanders generate
18147 ;; code like this:
18148 ;;
18149 ;;   repz cmpsb
18150 ;;   seta       %al
18151 ;;   setb       %dl
18152 ;;   cmpb       %al, %dl
18153 ;;   jcc        label
18154 ;;
18155 ;; The intermediate three instructions are unnecessary.
18156
18157 ;; This one handles cmpstrn*_nz_1...
18158 (define_peephole2
18159   [(parallel[
18160      (set (reg:CC FLAGS_REG)
18161           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18162                       (mem:BLK (match_operand 5 "register_operand" ""))))
18163      (use (match_operand 6 "register_operand" ""))
18164      (use (match_operand:SI 3 "immediate_operand" ""))
18165      (use (reg:SI DIRFLAG_REG))
18166      (clobber (match_operand 0 "register_operand" ""))
18167      (clobber (match_operand 1 "register_operand" ""))
18168      (clobber (match_operand 2 "register_operand" ""))])
18169    (set (match_operand:QI 7 "register_operand" "")
18170         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18171    (set (match_operand:QI 8 "register_operand" "")
18172         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18173    (set (reg FLAGS_REG)
18174         (compare (match_dup 7) (match_dup 8)))
18175   ]
18176   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18177   [(parallel[
18178      (set (reg:CC FLAGS_REG)
18179           (compare:CC (mem:BLK (match_dup 4))
18180                       (mem:BLK (match_dup 5))))
18181      (use (match_dup 6))
18182      (use (match_dup 3))
18183      (use (reg:SI DIRFLAG_REG))
18184      (clobber (match_dup 0))
18185      (clobber (match_dup 1))
18186      (clobber (match_dup 2))])]
18187   "")
18188
18189 ;; ...and this one handles cmpstrn*_1.
18190 (define_peephole2
18191   [(parallel[
18192      (set (reg:CC FLAGS_REG)
18193           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18194                                (const_int 0))
18195             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18196                         (mem:BLK (match_operand 5 "register_operand" "")))
18197             (const_int 0)))
18198      (use (match_operand:SI 3 "immediate_operand" ""))
18199      (use (reg:CC FLAGS_REG))
18200      (use (reg:SI DIRFLAG_REG))
18201      (clobber (match_operand 0 "register_operand" ""))
18202      (clobber (match_operand 1 "register_operand" ""))
18203      (clobber (match_operand 2 "register_operand" ""))])
18204    (set (match_operand:QI 7 "register_operand" "")
18205         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18206    (set (match_operand:QI 8 "register_operand" "")
18207         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18208    (set (reg FLAGS_REG)
18209         (compare (match_dup 7) (match_dup 8)))
18210   ]
18211   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18212   [(parallel[
18213      (set (reg:CC FLAGS_REG)
18214           (if_then_else:CC (ne (match_dup 6)
18215                                (const_int 0))
18216             (compare:CC (mem:BLK (match_dup 4))
18217                         (mem:BLK (match_dup 5)))
18218             (const_int 0)))
18219      (use (match_dup 3))
18220      (use (reg:CC FLAGS_REG))
18221      (use (reg:SI DIRFLAG_REG))
18222      (clobber (match_dup 0))
18223      (clobber (match_dup 1))
18224      (clobber (match_dup 2))])]
18225   "")
18226
18227
18228 \f
18229 ;; Conditional move instructions.
18230
18231 (define_expand "movdicc"
18232   [(set (match_operand:DI 0 "register_operand" "")
18233         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18234                          (match_operand:DI 2 "general_operand" "")
18235                          (match_operand:DI 3 "general_operand" "")))]
18236   "TARGET_64BIT"
18237   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18238
18239 (define_insn "x86_movdicc_0_m1_rex64"
18240   [(set (match_operand:DI 0 "register_operand" "=r")
18241         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18242           (const_int -1)
18243           (const_int 0)))
18244    (clobber (reg:CC FLAGS_REG))]
18245   "TARGET_64BIT"
18246   "sbb{q}\t%0, %0"
18247   ; Since we don't have the proper number of operands for an alu insn,
18248   ; fill in all the blanks.
18249   [(set_attr "type" "alu")
18250    (set_attr "pent_pair" "pu")
18251    (set_attr "memory" "none")
18252    (set_attr "imm_disp" "false")
18253    (set_attr "mode" "DI")
18254    (set_attr "length_immediate" "0")])
18255
18256 (define_insn "*movdicc_c_rex64"
18257   [(set (match_operand:DI 0 "register_operand" "=r,r")
18258         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18259                                 [(reg FLAGS_REG) (const_int 0)])
18260                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18261                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18262   "TARGET_64BIT && TARGET_CMOVE
18263    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18264   "@
18265    cmov%O2%C1\t{%2, %0|%0, %2}
18266    cmov%O2%c1\t{%3, %0|%0, %3}"
18267   [(set_attr "type" "icmov")
18268    (set_attr "mode" "DI")])
18269
18270 (define_expand "movsicc"
18271   [(set (match_operand:SI 0 "register_operand" "")
18272         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18273                          (match_operand:SI 2 "general_operand" "")
18274                          (match_operand:SI 3 "general_operand" "")))]
18275   ""
18276   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18277
18278 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18279 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18280 ;; So just document what we're doing explicitly.
18281
18282 (define_insn "x86_movsicc_0_m1"
18283   [(set (match_operand:SI 0 "register_operand" "=r")
18284         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18285           (const_int -1)
18286           (const_int 0)))
18287    (clobber (reg:CC FLAGS_REG))]
18288   ""
18289   "sbb{l}\t%0, %0"
18290   ; Since we don't have the proper number of operands for an alu insn,
18291   ; fill in all the blanks.
18292   [(set_attr "type" "alu")
18293    (set_attr "pent_pair" "pu")
18294    (set_attr "memory" "none")
18295    (set_attr "imm_disp" "false")
18296    (set_attr "mode" "SI")
18297    (set_attr "length_immediate" "0")])
18298
18299 (define_insn "*movsicc_noc"
18300   [(set (match_operand:SI 0 "register_operand" "=r,r")
18301         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18302                                 [(reg FLAGS_REG) (const_int 0)])
18303                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18304                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18305   "TARGET_CMOVE
18306    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18307   "@
18308    cmov%O2%C1\t{%2, %0|%0, %2}
18309    cmov%O2%c1\t{%3, %0|%0, %3}"
18310   [(set_attr "type" "icmov")
18311    (set_attr "mode" "SI")])
18312
18313 (define_expand "movhicc"
18314   [(set (match_operand:HI 0 "register_operand" "")
18315         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18316                          (match_operand:HI 2 "general_operand" "")
18317                          (match_operand:HI 3 "general_operand" "")))]
18318   "TARGET_HIMODE_MATH"
18319   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18320
18321 (define_insn "*movhicc_noc"
18322   [(set (match_operand:HI 0 "register_operand" "=r,r")
18323         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18324                                 [(reg FLAGS_REG) (const_int 0)])
18325                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18326                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18327   "TARGET_CMOVE
18328    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18329   "@
18330    cmov%O2%C1\t{%2, %0|%0, %2}
18331    cmov%O2%c1\t{%3, %0|%0, %3}"
18332   [(set_attr "type" "icmov")
18333    (set_attr "mode" "HI")])
18334
18335 (define_expand "movqicc"
18336   [(set (match_operand:QI 0 "register_operand" "")
18337         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18338                          (match_operand:QI 2 "general_operand" "")
18339                          (match_operand:QI 3 "general_operand" "")))]
18340   "TARGET_QIMODE_MATH"
18341   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18342
18343 (define_insn_and_split "*movqicc_noc"
18344   [(set (match_operand:QI 0 "register_operand" "=r,r")
18345         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18346                                 [(match_operand 4 "flags_reg_operand" "")
18347                                  (const_int 0)])
18348                       (match_operand:QI 2 "register_operand" "r,0")
18349                       (match_operand:QI 3 "register_operand" "0,r")))]
18350   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18351   "#"
18352   "&& reload_completed"
18353   [(set (match_dup 0)
18354         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18355                       (match_dup 2)
18356                       (match_dup 3)))]
18357   "operands[0] = gen_lowpart (SImode, operands[0]);
18358    operands[2] = gen_lowpart (SImode, operands[2]);
18359    operands[3] = gen_lowpart (SImode, operands[3]);"
18360   [(set_attr "type" "icmov")
18361    (set_attr "mode" "SI")])
18362
18363 (define_expand "movsfcc"
18364   [(set (match_operand:SF 0 "register_operand" "")
18365         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18366                          (match_operand:SF 2 "register_operand" "")
18367                          (match_operand:SF 3 "register_operand" "")))]
18368   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18369   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18370
18371 (define_insn "*movsfcc_1_387"
18372   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18373         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18374                                 [(reg FLAGS_REG) (const_int 0)])
18375                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18376                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18377   "TARGET_80387 && TARGET_CMOVE
18378    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18379   "@
18380    fcmov%F1\t{%2, %0|%0, %2}
18381    fcmov%f1\t{%3, %0|%0, %3}
18382    cmov%O2%C1\t{%2, %0|%0, %2}
18383    cmov%O2%c1\t{%3, %0|%0, %3}"
18384   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18385    (set_attr "mode" "SF,SF,SI,SI")])
18386
18387 (define_expand "movdfcc"
18388   [(set (match_operand:DF 0 "register_operand" "")
18389         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18390                          (match_operand:DF 2 "register_operand" "")
18391                          (match_operand:DF 3 "register_operand" "")))]
18392   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18393   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18394
18395 (define_insn "*movdfcc_1"
18396   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18397         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18398                                 [(reg FLAGS_REG) (const_int 0)])
18399                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18400                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18401   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18402    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18403   "@
18404    fcmov%F1\t{%2, %0|%0, %2}
18405    fcmov%f1\t{%3, %0|%0, %3}
18406    #
18407    #"
18408   [(set_attr "type" "fcmov,fcmov,multi,multi")
18409    (set_attr "mode" "DF")])
18410
18411 (define_insn "*movdfcc_1_rex64"
18412   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18413         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18414                                 [(reg FLAGS_REG) (const_int 0)])
18415                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18416                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18417   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18418    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18419   "@
18420    fcmov%F1\t{%2, %0|%0, %2}
18421    fcmov%f1\t{%3, %0|%0, %3}
18422    cmov%O2%C1\t{%2, %0|%0, %2}
18423    cmov%O2%c1\t{%3, %0|%0, %3}"
18424   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18425    (set_attr "mode" "DF")])
18426
18427 (define_split
18428   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18429         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18430                                 [(match_operand 4 "flags_reg_operand" "")
18431                                  (const_int 0)])
18432                       (match_operand:DF 2 "nonimmediate_operand" "")
18433                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18434   "!TARGET_64BIT && reload_completed"
18435   [(set (match_dup 2)
18436         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18437                       (match_dup 5)
18438                       (match_dup 7)))
18439    (set (match_dup 3)
18440         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18441                       (match_dup 6)
18442                       (match_dup 8)))]
18443   "split_di (operands+2, 1, operands+5, operands+6);
18444    split_di (operands+3, 1, operands+7, operands+8);
18445    split_di (operands, 1, operands+2, operands+3);")
18446
18447 (define_expand "movxfcc"
18448   [(set (match_operand:XF 0 "register_operand" "")
18449         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18450                          (match_operand:XF 2 "register_operand" "")
18451                          (match_operand:XF 3 "register_operand" "")))]
18452   "TARGET_80387 && TARGET_CMOVE"
18453   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18454
18455 (define_insn "*movxfcc_1"
18456   [(set (match_operand:XF 0 "register_operand" "=f,f")
18457         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18458                                 [(reg FLAGS_REG) (const_int 0)])
18459                       (match_operand:XF 2 "register_operand" "f,0")
18460                       (match_operand:XF 3 "register_operand" "0,f")))]
18461   "TARGET_80387 && TARGET_CMOVE"
18462   "@
18463    fcmov%F1\t{%2, %0|%0, %2}
18464    fcmov%f1\t{%3, %0|%0, %3}"
18465   [(set_attr "type" "fcmov")
18466    (set_attr "mode" "XF")])
18467
18468 ;; These versions of the min/max patterns are intentionally ignorant of
18469 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18470 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18471 ;; are undefined in this condition, we're certain this is correct.
18472
18473 (define_insn "sminsf3"
18474   [(set (match_operand:SF 0 "register_operand" "=x")
18475         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18476                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18477   "TARGET_SSE_MATH"
18478   "minss\t{%2, %0|%0, %2}"
18479   [(set_attr "type" "sseadd")
18480    (set_attr "mode" "SF")])
18481
18482 (define_insn "smaxsf3"
18483   [(set (match_operand:SF 0 "register_operand" "=x")
18484         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18485                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18486   "TARGET_SSE_MATH"
18487   "maxss\t{%2, %0|%0, %2}"
18488   [(set_attr "type" "sseadd")
18489    (set_attr "mode" "SF")])
18490
18491 (define_insn "smindf3"
18492   [(set (match_operand:DF 0 "register_operand" "=x")
18493         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18494                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18495   "TARGET_SSE2 && TARGET_SSE_MATH"
18496   "minsd\t{%2, %0|%0, %2}"
18497   [(set_attr "type" "sseadd")
18498    (set_attr "mode" "DF")])
18499
18500 (define_insn "smaxdf3"
18501   [(set (match_operand:DF 0 "register_operand" "=x")
18502         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18503                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18504   "TARGET_SSE2 && TARGET_SSE_MATH"
18505   "maxsd\t{%2, %0|%0, %2}"
18506   [(set_attr "type" "sseadd")
18507    (set_attr "mode" "DF")])
18508
18509 ;; These versions of the min/max patterns implement exactly the operations
18510 ;;   min = (op1 < op2 ? op1 : op2)
18511 ;;   max = (!(op1 < op2) ? op1 : op2)
18512 ;; Their operands are not commutative, and thus they may be used in the
18513 ;; presence of -0.0 and NaN.
18514
18515 (define_insn "*ieee_sminsf3"
18516   [(set (match_operand:SF 0 "register_operand" "=x")
18517         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18518                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18519                    UNSPEC_IEEE_MIN))]
18520   "TARGET_SSE_MATH"
18521   "minss\t{%2, %0|%0, %2}"
18522   [(set_attr "type" "sseadd")
18523    (set_attr "mode" "SF")])
18524
18525 (define_insn "*ieee_smaxsf3"
18526   [(set (match_operand:SF 0 "register_operand" "=x")
18527         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18528                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18529                    UNSPEC_IEEE_MAX))]
18530   "TARGET_SSE_MATH"
18531   "maxss\t{%2, %0|%0, %2}"
18532   [(set_attr "type" "sseadd")
18533    (set_attr "mode" "SF")])
18534
18535 (define_insn "*ieee_smindf3"
18536   [(set (match_operand:DF 0 "register_operand" "=x")
18537         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18538                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18539                    UNSPEC_IEEE_MIN))]
18540   "TARGET_SSE2 && TARGET_SSE_MATH"
18541   "minsd\t{%2, %0|%0, %2}"
18542   [(set_attr "type" "sseadd")
18543    (set_attr "mode" "DF")])
18544
18545 (define_insn "*ieee_smaxdf3"
18546   [(set (match_operand:DF 0 "register_operand" "=x")
18547         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18548                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18549                    UNSPEC_IEEE_MAX))]
18550   "TARGET_SSE2 && TARGET_SSE_MATH"
18551   "maxsd\t{%2, %0|%0, %2}"
18552   [(set_attr "type" "sseadd")
18553    (set_attr "mode" "DF")])
18554
18555 ;; Conditional addition patterns
18556 (define_expand "addqicc"
18557   [(match_operand:QI 0 "register_operand" "")
18558    (match_operand 1 "comparison_operator" "")
18559    (match_operand:QI 2 "register_operand" "")
18560    (match_operand:QI 3 "const_int_operand" "")]
18561   ""
18562   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18563
18564 (define_expand "addhicc"
18565   [(match_operand:HI 0 "register_operand" "")
18566    (match_operand 1 "comparison_operator" "")
18567    (match_operand:HI 2 "register_operand" "")
18568    (match_operand:HI 3 "const_int_operand" "")]
18569   ""
18570   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18571
18572 (define_expand "addsicc"
18573   [(match_operand:SI 0 "register_operand" "")
18574    (match_operand 1 "comparison_operator" "")
18575    (match_operand:SI 2 "register_operand" "")
18576    (match_operand:SI 3 "const_int_operand" "")]
18577   ""
18578   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18579
18580 (define_expand "adddicc"
18581   [(match_operand:DI 0 "register_operand" "")
18582    (match_operand 1 "comparison_operator" "")
18583    (match_operand:DI 2 "register_operand" "")
18584    (match_operand:DI 3 "const_int_operand" "")]
18585   "TARGET_64BIT"
18586   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18587
18588 \f
18589 ;; Misc patterns (?)
18590
18591 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18592 ;; Otherwise there will be nothing to keep
18593 ;; 
18594 ;; [(set (reg ebp) (reg esp))]
18595 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18596 ;;  (clobber (eflags)]
18597 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18598 ;;
18599 ;; in proper program order.
18600 (define_insn "pro_epilogue_adjust_stack_1"
18601   [(set (match_operand:SI 0 "register_operand" "=r,r")
18602         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18603                  (match_operand:SI 2 "immediate_operand" "i,i")))
18604    (clobber (reg:CC FLAGS_REG))
18605    (clobber (mem:BLK (scratch)))]
18606   "!TARGET_64BIT"
18607 {
18608   switch (get_attr_type (insn))
18609     {
18610     case TYPE_IMOV:
18611       return "mov{l}\t{%1, %0|%0, %1}";
18612
18613     case TYPE_ALU:
18614       if (GET_CODE (operands[2]) == CONST_INT
18615           && (INTVAL (operands[2]) == 128
18616               || (INTVAL (operands[2]) < 0
18617                   && INTVAL (operands[2]) != -128)))
18618         {
18619           operands[2] = GEN_INT (-INTVAL (operands[2]));
18620           return "sub{l}\t{%2, %0|%0, %2}";
18621         }
18622       return "add{l}\t{%2, %0|%0, %2}";
18623
18624     case TYPE_LEA:
18625       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18626       return "lea{l}\t{%a2, %0|%0, %a2}";
18627
18628     default:
18629       gcc_unreachable ();
18630     }
18631 }
18632   [(set (attr "type")
18633         (cond [(eq_attr "alternative" "0")
18634                  (const_string "alu")
18635                (match_operand:SI 2 "const0_operand" "")
18636                  (const_string "imov")
18637               ]
18638               (const_string "lea")))
18639    (set_attr "mode" "SI")])
18640
18641 (define_insn "pro_epilogue_adjust_stack_rex64"
18642   [(set (match_operand:DI 0 "register_operand" "=r,r")
18643         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18644                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18645    (clobber (reg:CC FLAGS_REG))
18646    (clobber (mem:BLK (scratch)))]
18647   "TARGET_64BIT"
18648 {
18649   switch (get_attr_type (insn))
18650     {
18651     case TYPE_IMOV:
18652       return "mov{q}\t{%1, %0|%0, %1}";
18653
18654     case TYPE_ALU:
18655       if (GET_CODE (operands[2]) == CONST_INT
18656           /* Avoid overflows.  */
18657           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18658           && (INTVAL (operands[2]) == 128
18659               || (INTVAL (operands[2]) < 0
18660                   && INTVAL (operands[2]) != -128)))
18661         {
18662           operands[2] = GEN_INT (-INTVAL (operands[2]));
18663           return "sub{q}\t{%2, %0|%0, %2}";
18664         }
18665       return "add{q}\t{%2, %0|%0, %2}";
18666
18667     case TYPE_LEA:
18668       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18669       return "lea{q}\t{%a2, %0|%0, %a2}";
18670
18671     default:
18672       gcc_unreachable ();
18673     }
18674 }
18675   [(set (attr "type")
18676         (cond [(eq_attr "alternative" "0")
18677                  (const_string "alu")
18678                (match_operand:DI 2 "const0_operand" "")
18679                  (const_string "imov")
18680               ]
18681               (const_string "lea")))
18682    (set_attr "mode" "DI")])
18683
18684 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18685   [(set (match_operand:DI 0 "register_operand" "=r,r")
18686         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18687                  (match_operand:DI 3 "immediate_operand" "i,i")))
18688    (use (match_operand:DI 2 "register_operand" "r,r"))
18689    (clobber (reg:CC FLAGS_REG))
18690    (clobber (mem:BLK (scratch)))]
18691   "TARGET_64BIT"
18692 {
18693   switch (get_attr_type (insn))
18694     {
18695     case TYPE_ALU:
18696       return "add{q}\t{%2, %0|%0, %2}";
18697
18698     case TYPE_LEA:
18699       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18700       return "lea{q}\t{%a2, %0|%0, %a2}";
18701
18702     default:
18703       gcc_unreachable ();
18704     }
18705 }
18706   [(set_attr "type" "alu,lea")
18707    (set_attr "mode" "DI")])
18708
18709 (define_expand "allocate_stack_worker"
18710   [(match_operand:SI 0 "register_operand" "")]
18711   "TARGET_STACK_PROBE"
18712 {
18713   if (reload_completed)
18714     {
18715       if (TARGET_64BIT)
18716         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18717       else
18718         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18719     }
18720   else
18721     {
18722       if (TARGET_64BIT)
18723         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18724       else
18725         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18726     }
18727   DONE;
18728 })
18729
18730 (define_insn "allocate_stack_worker_1"
18731   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18732     UNSPECV_STACK_PROBE)
18733    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18734    (clobber (match_scratch:SI 1 "=0"))
18735    (clobber (reg:CC FLAGS_REG))]
18736   "!TARGET_64BIT && TARGET_STACK_PROBE"
18737   "call\t__alloca"
18738   [(set_attr "type" "multi")
18739    (set_attr "length" "5")])
18740
18741 (define_expand "allocate_stack_worker_postreload"
18742   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18743                                     UNSPECV_STACK_PROBE)
18744               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18745               (clobber (match_dup 0))
18746               (clobber (reg:CC FLAGS_REG))])]
18747   ""
18748   "")
18749
18750 (define_insn "allocate_stack_worker_rex64"
18751   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18752     UNSPECV_STACK_PROBE)
18753    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18754    (clobber (match_scratch:DI 1 "=0"))
18755    (clobber (reg:CC FLAGS_REG))]
18756   "TARGET_64BIT && TARGET_STACK_PROBE"
18757   "call\t__alloca"
18758   [(set_attr "type" "multi")
18759    (set_attr "length" "5")])
18760
18761 (define_expand "allocate_stack_worker_rex64_postreload"
18762   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18763                                     UNSPECV_STACK_PROBE)
18764               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18765               (clobber (match_dup 0))
18766               (clobber (reg:CC FLAGS_REG))])]
18767   ""
18768   "")
18769
18770 (define_expand "allocate_stack"
18771   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18772                    (minus:SI (reg:SI SP_REG)
18773                              (match_operand:SI 1 "general_operand" "")))
18774               (clobber (reg:CC FLAGS_REG))])
18775    (parallel [(set (reg:SI SP_REG)
18776                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18777               (clobber (reg:CC FLAGS_REG))])]
18778   "TARGET_STACK_PROBE"
18779 {
18780 #ifdef CHECK_STACK_LIMIT
18781   if (GET_CODE (operands[1]) == CONST_INT
18782       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18783     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18784                            operands[1]));
18785   else 
18786 #endif
18787     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18788                                                             operands[1])));
18789
18790   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18791   DONE;
18792 })
18793
18794 (define_expand "builtin_setjmp_receiver"
18795   [(label_ref (match_operand 0 "" ""))]
18796   "!TARGET_64BIT && flag_pic"
18797 {
18798   emit_insn (gen_set_got (pic_offset_table_rtx));
18799   DONE;
18800 })
18801 \f
18802 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18803
18804 (define_split
18805   [(set (match_operand 0 "register_operand" "")
18806         (match_operator 3 "promotable_binary_operator"
18807            [(match_operand 1 "register_operand" "")
18808             (match_operand 2 "aligned_operand" "")]))
18809    (clobber (reg:CC FLAGS_REG))]
18810   "! TARGET_PARTIAL_REG_STALL && reload_completed
18811    && ((GET_MODE (operands[0]) == HImode 
18812         && ((!optimize_size && !TARGET_FAST_PREFIX)
18813             || GET_CODE (operands[2]) != CONST_INT
18814             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18815        || (GET_MODE (operands[0]) == QImode 
18816            && (TARGET_PROMOTE_QImode || optimize_size)))"
18817   [(parallel [(set (match_dup 0)
18818                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18819               (clobber (reg:CC FLAGS_REG))])]
18820   "operands[0] = gen_lowpart (SImode, operands[0]);
18821    operands[1] = gen_lowpart (SImode, operands[1]);
18822    if (GET_CODE (operands[3]) != ASHIFT)
18823      operands[2] = gen_lowpart (SImode, operands[2]);
18824    PUT_MODE (operands[3], SImode);")
18825
18826 ; Promote the QImode tests, as i386 has encoding of the AND
18827 ; instruction with 32-bit sign-extended immediate and thus the
18828 ; instruction size is unchanged, except in the %eax case for
18829 ; which it is increased by one byte, hence the ! optimize_size.
18830 (define_split
18831   [(set (match_operand 0 "flags_reg_operand" "")
18832         (match_operator 2 "compare_operator"
18833           [(and (match_operand 3 "aligned_operand" "")
18834                 (match_operand 4 "const_int_operand" ""))
18835            (const_int 0)]))
18836    (set (match_operand 1 "register_operand" "")
18837         (and (match_dup 3) (match_dup 4)))]
18838   "! TARGET_PARTIAL_REG_STALL && reload_completed
18839    /* Ensure that the operand will remain sign-extended immediate.  */
18840    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18841    && ! optimize_size
18842    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18843        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18844   [(parallel [(set (match_dup 0)
18845                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18846                                     (const_int 0)]))
18847               (set (match_dup 1)
18848                    (and:SI (match_dup 3) (match_dup 4)))])]
18849 {
18850   operands[4]
18851     = gen_int_mode (INTVAL (operands[4])
18852                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18853   operands[1] = gen_lowpart (SImode, operands[1]);
18854   operands[3] = gen_lowpart (SImode, operands[3]);
18855 })
18856
18857 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18858 ; the TEST instruction with 32-bit sign-extended immediate and thus
18859 ; the instruction size would at least double, which is not what we
18860 ; want even with ! optimize_size.
18861 (define_split
18862   [(set (match_operand 0 "flags_reg_operand" "")
18863         (match_operator 1 "compare_operator"
18864           [(and (match_operand:HI 2 "aligned_operand" "")
18865                 (match_operand:HI 3 "const_int_operand" ""))
18866            (const_int 0)]))]
18867   "! TARGET_PARTIAL_REG_STALL && reload_completed
18868    /* Ensure that the operand will remain sign-extended immediate.  */
18869    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18870    && ! TARGET_FAST_PREFIX
18871    && ! optimize_size"
18872   [(set (match_dup 0)
18873         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18874                          (const_int 0)]))]
18875 {
18876   operands[3]
18877     = gen_int_mode (INTVAL (operands[3])
18878                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18879   operands[2] = gen_lowpart (SImode, operands[2]);
18880 })
18881
18882 (define_split
18883   [(set (match_operand 0 "register_operand" "")
18884         (neg (match_operand 1 "register_operand" "")))
18885    (clobber (reg:CC FLAGS_REG))]
18886   "! TARGET_PARTIAL_REG_STALL && reload_completed
18887    && (GET_MODE (operands[0]) == HImode
18888        || (GET_MODE (operands[0]) == QImode 
18889            && (TARGET_PROMOTE_QImode || optimize_size)))"
18890   [(parallel [(set (match_dup 0)
18891                    (neg:SI (match_dup 1)))
18892               (clobber (reg:CC FLAGS_REG))])]
18893   "operands[0] = gen_lowpart (SImode, operands[0]);
18894    operands[1] = gen_lowpart (SImode, operands[1]);")
18895
18896 (define_split
18897   [(set (match_operand 0 "register_operand" "")
18898         (not (match_operand 1 "register_operand" "")))]
18899   "! TARGET_PARTIAL_REG_STALL && reload_completed
18900    && (GET_MODE (operands[0]) == HImode
18901        || (GET_MODE (operands[0]) == QImode 
18902            && (TARGET_PROMOTE_QImode || optimize_size)))"
18903   [(set (match_dup 0)
18904         (not:SI (match_dup 1)))]
18905   "operands[0] = gen_lowpart (SImode, operands[0]);
18906    operands[1] = gen_lowpart (SImode, operands[1]);")
18907
18908 (define_split 
18909   [(set (match_operand 0 "register_operand" "")
18910         (if_then_else (match_operator 1 "comparison_operator" 
18911                                 [(reg FLAGS_REG) (const_int 0)])
18912                       (match_operand 2 "register_operand" "")
18913                       (match_operand 3 "register_operand" "")))]
18914   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18915    && (GET_MODE (operands[0]) == HImode
18916        || (GET_MODE (operands[0]) == QImode 
18917            && (TARGET_PROMOTE_QImode || optimize_size)))"
18918   [(set (match_dup 0)
18919         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18920   "operands[0] = gen_lowpart (SImode, operands[0]);
18921    operands[2] = gen_lowpart (SImode, operands[2]);
18922    operands[3] = gen_lowpart (SImode, operands[3]);")
18923                         
18924 \f
18925 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18926 ;; transform a complex memory operation into two memory to register operations.
18927
18928 ;; Don't push memory operands
18929 (define_peephole2
18930   [(set (match_operand:SI 0 "push_operand" "")
18931         (match_operand:SI 1 "memory_operand" ""))
18932    (match_scratch:SI 2 "r")]
18933   "!optimize_size && !TARGET_PUSH_MEMORY
18934    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18935   [(set (match_dup 2) (match_dup 1))
18936    (set (match_dup 0) (match_dup 2))]
18937   "")
18938
18939 (define_peephole2
18940   [(set (match_operand:DI 0 "push_operand" "")
18941         (match_operand:DI 1 "memory_operand" ""))
18942    (match_scratch:DI 2 "r")]
18943   "!optimize_size && !TARGET_PUSH_MEMORY
18944    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18945   [(set (match_dup 2) (match_dup 1))
18946    (set (match_dup 0) (match_dup 2))]
18947   "")
18948
18949 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18950 ;; SImode pushes.
18951 (define_peephole2
18952   [(set (match_operand:SF 0 "push_operand" "")
18953         (match_operand:SF 1 "memory_operand" ""))
18954    (match_scratch:SF 2 "r")]
18955   "!optimize_size && !TARGET_PUSH_MEMORY
18956    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18957   [(set (match_dup 2) (match_dup 1))
18958    (set (match_dup 0) (match_dup 2))]
18959   "")
18960
18961 (define_peephole2
18962   [(set (match_operand:HI 0 "push_operand" "")
18963         (match_operand:HI 1 "memory_operand" ""))
18964    (match_scratch:HI 2 "r")]
18965   "!optimize_size && !TARGET_PUSH_MEMORY
18966    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18967   [(set (match_dup 2) (match_dup 1))
18968    (set (match_dup 0) (match_dup 2))]
18969   "")
18970
18971 (define_peephole2
18972   [(set (match_operand:QI 0 "push_operand" "")
18973         (match_operand:QI 1 "memory_operand" ""))
18974    (match_scratch:QI 2 "q")]
18975   "!optimize_size && !TARGET_PUSH_MEMORY
18976    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18977   [(set (match_dup 2) (match_dup 1))
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18980
18981 ;; Don't move an immediate directly to memory when the instruction
18982 ;; gets too big.
18983 (define_peephole2
18984   [(match_scratch:SI 1 "r")
18985    (set (match_operand:SI 0 "memory_operand" "")
18986         (const_int 0))]
18987   "! optimize_size
18988    && ! TARGET_USE_MOV0
18989    && TARGET_SPLIT_LONG_MOVES
18990    && get_attr_length (insn) >= ix86_cost->large_insn
18991    && peep2_regno_dead_p (0, FLAGS_REG)"
18992   [(parallel [(set (match_dup 1) (const_int 0))
18993               (clobber (reg:CC FLAGS_REG))])
18994    (set (match_dup 0) (match_dup 1))]
18995   "")
18996
18997 (define_peephole2
18998   [(match_scratch:HI 1 "r")
18999    (set (match_operand:HI 0 "memory_operand" "")
19000         (const_int 0))]
19001   "! optimize_size
19002    && ! TARGET_USE_MOV0
19003    && TARGET_SPLIT_LONG_MOVES
19004    && get_attr_length (insn) >= ix86_cost->large_insn
19005    && peep2_regno_dead_p (0, FLAGS_REG)"
19006   [(parallel [(set (match_dup 2) (const_int 0))
19007               (clobber (reg:CC FLAGS_REG))])
19008    (set (match_dup 0) (match_dup 1))]
19009   "operands[2] = gen_lowpart (SImode, operands[1]);")
19010
19011 (define_peephole2
19012   [(match_scratch:QI 1 "q")
19013    (set (match_operand:QI 0 "memory_operand" "")
19014         (const_int 0))]
19015   "! optimize_size
19016    && ! TARGET_USE_MOV0
19017    && TARGET_SPLIT_LONG_MOVES
19018    && get_attr_length (insn) >= ix86_cost->large_insn
19019    && peep2_regno_dead_p (0, FLAGS_REG)"
19020   [(parallel [(set (match_dup 2) (const_int 0))
19021               (clobber (reg:CC FLAGS_REG))])
19022    (set (match_dup 0) (match_dup 1))]
19023   "operands[2] = gen_lowpart (SImode, operands[1]);")
19024
19025 (define_peephole2
19026   [(match_scratch:SI 2 "r")
19027    (set (match_operand:SI 0 "memory_operand" "")
19028         (match_operand:SI 1 "immediate_operand" ""))]
19029   "! optimize_size
19030    && get_attr_length (insn) >= ix86_cost->large_insn
19031    && TARGET_SPLIT_LONG_MOVES"
19032   [(set (match_dup 2) (match_dup 1))
19033    (set (match_dup 0) (match_dup 2))]
19034   "")
19035
19036 (define_peephole2
19037   [(match_scratch:HI 2 "r")
19038    (set (match_operand:HI 0 "memory_operand" "")
19039         (match_operand:HI 1 "immediate_operand" ""))]
19040   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19041   && TARGET_SPLIT_LONG_MOVES"
19042   [(set (match_dup 2) (match_dup 1))
19043    (set (match_dup 0) (match_dup 2))]
19044   "")
19045
19046 (define_peephole2
19047   [(match_scratch:QI 2 "q")
19048    (set (match_operand:QI 0 "memory_operand" "")
19049         (match_operand:QI 1 "immediate_operand" ""))]
19050   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19051   && TARGET_SPLIT_LONG_MOVES"
19052   [(set (match_dup 2) (match_dup 1))
19053    (set (match_dup 0) (match_dup 2))]
19054   "")
19055
19056 ;; Don't compare memory with zero, load and use a test instead.
19057 (define_peephole2
19058   [(set (match_operand 0 "flags_reg_operand" "")
19059         (match_operator 1 "compare_operator"
19060           [(match_operand:SI 2 "memory_operand" "")
19061            (const_int 0)]))
19062    (match_scratch:SI 3 "r")]
19063   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19064   [(set (match_dup 3) (match_dup 2))
19065    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19066   "")
19067
19068 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19069 ;; Don't split NOTs with a displacement operand, because resulting XOR
19070 ;; will not be pairable anyway.
19071 ;;
19072 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19073 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19074 ;; so this split helps here as well.
19075 ;;
19076 ;; Note: Can't do this as a regular split because we can't get proper
19077 ;; lifetime information then.
19078
19079 (define_peephole2
19080   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19081         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19082   "!optimize_size
19083    && peep2_regno_dead_p (0, FLAGS_REG)
19084    && ((TARGET_PENTIUM 
19085         && (GET_CODE (operands[0]) != MEM
19086             || !memory_displacement_operand (operands[0], SImode)))
19087        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19088   [(parallel [(set (match_dup 0)
19089                    (xor:SI (match_dup 1) (const_int -1)))
19090               (clobber (reg:CC FLAGS_REG))])]
19091   "")
19092
19093 (define_peephole2
19094   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19095         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19096   "!optimize_size
19097    && peep2_regno_dead_p (0, FLAGS_REG)
19098    && ((TARGET_PENTIUM 
19099         && (GET_CODE (operands[0]) != MEM
19100             || !memory_displacement_operand (operands[0], HImode)))
19101        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19102   [(parallel [(set (match_dup 0)
19103                    (xor:HI (match_dup 1) (const_int -1)))
19104               (clobber (reg:CC FLAGS_REG))])]
19105   "")
19106
19107 (define_peephole2
19108   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19109         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19110   "!optimize_size
19111    && peep2_regno_dead_p (0, FLAGS_REG)
19112    && ((TARGET_PENTIUM 
19113         && (GET_CODE (operands[0]) != MEM
19114             || !memory_displacement_operand (operands[0], QImode)))
19115        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19116   [(parallel [(set (match_dup 0)
19117                    (xor:QI (match_dup 1) (const_int -1)))
19118               (clobber (reg:CC FLAGS_REG))])]
19119   "")
19120
19121 ;; Non pairable "test imm, reg" instructions can be translated to
19122 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19123 ;; byte opcode instead of two, have a short form for byte operands),
19124 ;; so do it for other CPUs as well.  Given that the value was dead,
19125 ;; this should not create any new dependencies.  Pass on the sub-word
19126 ;; versions if we're concerned about partial register stalls.
19127
19128 (define_peephole2
19129   [(set (match_operand 0 "flags_reg_operand" "")
19130         (match_operator 1 "compare_operator"
19131           [(and:SI (match_operand:SI 2 "register_operand" "")
19132                    (match_operand:SI 3 "immediate_operand" ""))
19133            (const_int 0)]))]
19134   "ix86_match_ccmode (insn, CCNOmode)
19135    && (true_regnum (operands[2]) != 0
19136        || (GET_CODE (operands[3]) == CONST_INT
19137            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19138    && peep2_reg_dead_p (1, operands[2])"
19139   [(parallel
19140      [(set (match_dup 0)
19141            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19142                             (const_int 0)]))
19143       (set (match_dup 2)
19144            (and:SI (match_dup 2) (match_dup 3)))])]
19145   "")
19146
19147 ;; We don't need to handle HImode case, because it will be promoted to SImode
19148 ;; on ! TARGET_PARTIAL_REG_STALL
19149
19150 (define_peephole2
19151   [(set (match_operand 0 "flags_reg_operand" "")
19152         (match_operator 1 "compare_operator"
19153           [(and:QI (match_operand:QI 2 "register_operand" "")
19154                    (match_operand:QI 3 "immediate_operand" ""))
19155            (const_int 0)]))]
19156   "! TARGET_PARTIAL_REG_STALL
19157    && ix86_match_ccmode (insn, CCNOmode)
19158    && true_regnum (operands[2]) != 0
19159    && peep2_reg_dead_p (1, operands[2])"
19160   [(parallel
19161      [(set (match_dup 0)
19162            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19163                             (const_int 0)]))
19164       (set (match_dup 2)
19165            (and:QI (match_dup 2) (match_dup 3)))])]
19166   "")
19167
19168 (define_peephole2
19169   [(set (match_operand 0 "flags_reg_operand" "")
19170         (match_operator 1 "compare_operator"
19171           [(and:SI
19172              (zero_extract:SI
19173                (match_operand 2 "ext_register_operand" "")
19174                (const_int 8)
19175                (const_int 8))
19176              (match_operand 3 "const_int_operand" ""))
19177            (const_int 0)]))]
19178   "! TARGET_PARTIAL_REG_STALL
19179    && ix86_match_ccmode (insn, CCNOmode)
19180    && true_regnum (operands[2]) != 0
19181    && peep2_reg_dead_p (1, operands[2])"
19182   [(parallel [(set (match_dup 0)
19183                    (match_op_dup 1
19184                      [(and:SI
19185                         (zero_extract:SI
19186                           (match_dup 2)
19187                           (const_int 8)
19188                           (const_int 8))
19189                         (match_dup 3))
19190                       (const_int 0)]))
19191               (set (zero_extract:SI (match_dup 2)
19192                                     (const_int 8)
19193                                     (const_int 8))
19194                    (and:SI 
19195                      (zero_extract:SI
19196                        (match_dup 2)
19197                        (const_int 8)
19198                        (const_int 8))
19199                      (match_dup 3)))])]
19200   "")
19201
19202 ;; Don't do logical operations with memory inputs.
19203 (define_peephole2
19204   [(match_scratch:SI 2 "r")
19205    (parallel [(set (match_operand:SI 0 "register_operand" "")
19206                    (match_operator:SI 3 "arith_or_logical_operator"
19207                      [(match_dup 0)
19208                       (match_operand:SI 1 "memory_operand" "")]))
19209               (clobber (reg:CC FLAGS_REG))])]
19210   "! optimize_size && ! TARGET_READ_MODIFY"
19211   [(set (match_dup 2) (match_dup 1))
19212    (parallel [(set (match_dup 0)
19213                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19214               (clobber (reg:CC FLAGS_REG))])]
19215   "")
19216
19217 (define_peephole2
19218   [(match_scratch:SI 2 "r")
19219    (parallel [(set (match_operand:SI 0 "register_operand" "")
19220                    (match_operator:SI 3 "arith_or_logical_operator"
19221                      [(match_operand:SI 1 "memory_operand" "")
19222                       (match_dup 0)]))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   "! optimize_size && ! TARGET_READ_MODIFY"
19225   [(set (match_dup 2) (match_dup 1))
19226    (parallel [(set (match_dup 0)
19227                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19228               (clobber (reg:CC FLAGS_REG))])]
19229   "")
19230
19231 ; Don't do logical operations with memory outputs
19232 ;
19233 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19234 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19235 ; the same decoder scheduling characteristics as the original.
19236
19237 (define_peephole2
19238   [(match_scratch:SI 2 "r")
19239    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19240                    (match_operator:SI 3 "arith_or_logical_operator"
19241                      [(match_dup 0)
19242                       (match_operand:SI 1 "nonmemory_operand" "")]))
19243               (clobber (reg:CC FLAGS_REG))])]
19244   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19245   [(set (match_dup 2) (match_dup 0))
19246    (parallel [(set (match_dup 2)
19247                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19248               (clobber (reg:CC FLAGS_REG))])
19249    (set (match_dup 0) (match_dup 2))]
19250   "")
19251
19252 (define_peephole2
19253   [(match_scratch:SI 2 "r")
19254    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19255                    (match_operator:SI 3 "arith_or_logical_operator"
19256                      [(match_operand:SI 1 "nonmemory_operand" "")
19257                       (match_dup 0)]))
19258               (clobber (reg:CC FLAGS_REG))])]
19259   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19260   [(set (match_dup 2) (match_dup 0))
19261    (parallel [(set (match_dup 2)
19262                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19263               (clobber (reg:CC FLAGS_REG))])
19264    (set (match_dup 0) (match_dup 2))]
19265   "")
19266
19267 ;; Attempt to always use XOR for zeroing registers.
19268 (define_peephole2
19269   [(set (match_operand 0 "register_operand" "")
19270         (match_operand 1 "const0_operand" ""))]
19271   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19272    && (! TARGET_USE_MOV0 || optimize_size)
19273    && GENERAL_REG_P (operands[0])
19274    && peep2_regno_dead_p (0, FLAGS_REG)"
19275   [(parallel [(set (match_dup 0) (const_int 0))
19276               (clobber (reg:CC FLAGS_REG))])]
19277 {
19278   operands[0] = gen_lowpart (word_mode, operands[0]);
19279 })
19280
19281 (define_peephole2
19282   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19283         (const_int 0))]
19284   "(GET_MODE (operands[0]) == QImode
19285     || GET_MODE (operands[0]) == HImode)
19286    && (! TARGET_USE_MOV0 || optimize_size)
19287    && peep2_regno_dead_p (0, FLAGS_REG)"
19288   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19289               (clobber (reg:CC FLAGS_REG))])])
19290
19291 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19292 (define_peephole2
19293   [(set (match_operand 0 "register_operand" "")
19294         (const_int -1))]
19295   "(GET_MODE (operands[0]) == HImode
19296     || GET_MODE (operands[0]) == SImode 
19297     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19298    && (optimize_size || TARGET_PENTIUM)
19299    && peep2_regno_dead_p (0, FLAGS_REG)"
19300   [(parallel [(set (match_dup 0) (const_int -1))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19303                               operands[0]);")
19304
19305 ;; Attempt to convert simple leas to adds. These can be created by
19306 ;; move expanders.
19307 (define_peephole2
19308   [(set (match_operand:SI 0 "register_operand" "")
19309         (plus:SI (match_dup 0)
19310                  (match_operand:SI 1 "nonmemory_operand" "")))]
19311   "peep2_regno_dead_p (0, FLAGS_REG)"
19312   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19313               (clobber (reg:CC FLAGS_REG))])]
19314   "")
19315
19316 (define_peephole2
19317   [(set (match_operand:SI 0 "register_operand" "")
19318         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19319                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19320   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19321   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19322               (clobber (reg:CC FLAGS_REG))])]
19323   "operands[2] = gen_lowpart (SImode, operands[2]);")
19324
19325 (define_peephole2
19326   [(set (match_operand:DI 0 "register_operand" "")
19327         (plus:DI (match_dup 0)
19328                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19329   "peep2_regno_dead_p (0, FLAGS_REG)"
19330   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "")
19333
19334 (define_peephole2
19335   [(set (match_operand:SI 0 "register_operand" "")
19336         (mult:SI (match_dup 0)
19337                  (match_operand:SI 1 "const_int_operand" "")))]
19338   "exact_log2 (INTVAL (operands[1])) >= 0
19339    && peep2_regno_dead_p (0, FLAGS_REG)"
19340   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19341               (clobber (reg:CC FLAGS_REG))])]
19342   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19343
19344 (define_peephole2
19345   [(set (match_operand:DI 0 "register_operand" "")
19346         (mult:DI (match_dup 0)
19347                  (match_operand:DI 1 "const_int_operand" "")))]
19348   "exact_log2 (INTVAL (operands[1])) >= 0
19349    && peep2_regno_dead_p (0, FLAGS_REG)"
19350   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19351               (clobber (reg:CC FLAGS_REG))])]
19352   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19353
19354 (define_peephole2
19355   [(set (match_operand:SI 0 "register_operand" "")
19356         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19357                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19358   "exact_log2 (INTVAL (operands[2])) >= 0
19359    && REGNO (operands[0]) == REGNO (operands[1])
19360    && peep2_regno_dead_p (0, FLAGS_REG)"
19361   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19362               (clobber (reg:CC FLAGS_REG))])]
19363   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19364
19365 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19366 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19367 ;; many CPUs it is also faster, since special hardware to avoid esp
19368 ;; dependencies is present.
19369
19370 ;; While some of these conversions may be done using splitters, we use peepholes
19371 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19372
19373 ;; Convert prologue esp subtractions to push.
19374 ;; We need register to push.  In order to keep verify_flow_info happy we have
19375 ;; two choices
19376 ;; - use scratch and clobber it in order to avoid dependencies
19377 ;; - use already live register
19378 ;; We can't use the second way right now, since there is no reliable way how to
19379 ;; verify that given register is live.  First choice will also most likely in
19380 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19381 ;; call clobbered registers are dead.  We may want to use base pointer as an
19382 ;; alternative when no register is available later.
19383
19384 (define_peephole2
19385   [(match_scratch:SI 0 "r")
19386    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19387               (clobber (reg:CC FLAGS_REG))
19388               (clobber (mem:BLK (scratch)))])]
19389   "optimize_size || !TARGET_SUB_ESP_4"
19390   [(clobber (match_dup 0))
19391    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19392               (clobber (mem:BLK (scratch)))])])
19393
19394 (define_peephole2
19395   [(match_scratch:SI 0 "r")
19396    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19397               (clobber (reg:CC FLAGS_REG))
19398               (clobber (mem:BLK (scratch)))])]
19399   "optimize_size || !TARGET_SUB_ESP_8"
19400   [(clobber (match_dup 0))
19401    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19402    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19403               (clobber (mem:BLK (scratch)))])])
19404
19405 ;; Convert esp subtractions to push.
19406 (define_peephole2
19407   [(match_scratch:SI 0 "r")
19408    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19409               (clobber (reg:CC FLAGS_REG))])]
19410   "optimize_size || !TARGET_SUB_ESP_4"
19411   [(clobber (match_dup 0))
19412    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19413
19414 (define_peephole2
19415   [(match_scratch:SI 0 "r")
19416    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19417               (clobber (reg:CC FLAGS_REG))])]
19418   "optimize_size || !TARGET_SUB_ESP_8"
19419   [(clobber (match_dup 0))
19420    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19421    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19422
19423 ;; Convert epilogue deallocator to pop.
19424 (define_peephole2
19425   [(match_scratch:SI 0 "r")
19426    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19427               (clobber (reg:CC FLAGS_REG))
19428               (clobber (mem:BLK (scratch)))])]
19429   "optimize_size || !TARGET_ADD_ESP_4"
19430   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19431               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19432               (clobber (mem:BLK (scratch)))])]
19433   "")
19434
19435 ;; Two pops case is tricky, since pop causes dependency on destination register.
19436 ;; We use two registers if available.
19437 (define_peephole2
19438   [(match_scratch:SI 0 "r")
19439    (match_scratch:SI 1 "r")
19440    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19441               (clobber (reg:CC FLAGS_REG))
19442               (clobber (mem:BLK (scratch)))])]
19443   "optimize_size || !TARGET_ADD_ESP_8"
19444   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19445               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19446               (clobber (mem:BLK (scratch)))])
19447    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19448               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19449   "")
19450
19451 (define_peephole2
19452   [(match_scratch:SI 0 "r")
19453    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19454               (clobber (reg:CC FLAGS_REG))
19455               (clobber (mem:BLK (scratch)))])]
19456   "optimize_size"
19457   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19458               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19459               (clobber (mem:BLK (scratch)))])
19460    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19461               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19462   "")
19463
19464 ;; Convert esp additions to pop.
19465 (define_peephole2
19466   [(match_scratch:SI 0 "r")
19467    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19468               (clobber (reg:CC FLAGS_REG))])]
19469   ""
19470   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19471               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19472   "")
19473
19474 ;; Two pops case is tricky, since pop causes dependency on destination register.
19475 ;; We use two registers if available.
19476 (define_peephole2
19477   [(match_scratch:SI 0 "r")
19478    (match_scratch:SI 1 "r")
19479    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19480               (clobber (reg:CC FLAGS_REG))])]
19481   ""
19482   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19483               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19484    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19485               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19486   "")
19487
19488 (define_peephole2
19489   [(match_scratch:SI 0 "r")
19490    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19491               (clobber (reg:CC FLAGS_REG))])]
19492   "optimize_size"
19493   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19494               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19495    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19496               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19497   "")
19498 \f
19499 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19500 ;; required and register dies.  Similarly for 128 to plus -128.
19501 (define_peephole2
19502   [(set (match_operand 0 "flags_reg_operand" "")
19503         (match_operator 1 "compare_operator"
19504           [(match_operand 2 "register_operand" "")
19505            (match_operand 3 "const_int_operand" "")]))]
19506   "(INTVAL (operands[3]) == -1
19507     || INTVAL (operands[3]) == 1
19508     || INTVAL (operands[3]) == 128)
19509    && ix86_match_ccmode (insn, CCGCmode)
19510    && peep2_reg_dead_p (1, operands[2])"
19511   [(parallel [(set (match_dup 0)
19512                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19513               (clobber (match_dup 2))])]
19514   "")
19515 \f
19516 (define_peephole2
19517   [(match_scratch:DI 0 "r")
19518    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19519               (clobber (reg:CC FLAGS_REG))
19520               (clobber (mem:BLK (scratch)))])]
19521   "optimize_size || !TARGET_SUB_ESP_4"
19522   [(clobber (match_dup 0))
19523    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19524               (clobber (mem:BLK (scratch)))])])
19525
19526 (define_peephole2
19527   [(match_scratch:DI 0 "r")
19528    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19529               (clobber (reg:CC FLAGS_REG))
19530               (clobber (mem:BLK (scratch)))])]
19531   "optimize_size || !TARGET_SUB_ESP_8"
19532   [(clobber (match_dup 0))
19533    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19534    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19535               (clobber (mem:BLK (scratch)))])])
19536
19537 ;; Convert esp subtractions to push.
19538 (define_peephole2
19539   [(match_scratch:DI 0 "r")
19540    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19541               (clobber (reg:CC FLAGS_REG))])]
19542   "optimize_size || !TARGET_SUB_ESP_4"
19543   [(clobber (match_dup 0))
19544    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19545
19546 (define_peephole2
19547   [(match_scratch:DI 0 "r")
19548    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19549               (clobber (reg:CC FLAGS_REG))])]
19550   "optimize_size || !TARGET_SUB_ESP_8"
19551   [(clobber (match_dup 0))
19552    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19553    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19554
19555 ;; Convert epilogue deallocator to pop.
19556 (define_peephole2
19557   [(match_scratch:DI 0 "r")
19558    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19559               (clobber (reg:CC FLAGS_REG))
19560               (clobber (mem:BLK (scratch)))])]
19561   "optimize_size || !TARGET_ADD_ESP_4"
19562   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19563               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19564               (clobber (mem:BLK (scratch)))])]
19565   "")
19566
19567 ;; Two pops case is tricky, since pop causes dependency on destination register.
19568 ;; We use two registers if available.
19569 (define_peephole2
19570   [(match_scratch:DI 0 "r")
19571    (match_scratch:DI 1 "r")
19572    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19573               (clobber (reg:CC FLAGS_REG))
19574               (clobber (mem:BLK (scratch)))])]
19575   "optimize_size || !TARGET_ADD_ESP_8"
19576   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19577               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19578               (clobber (mem:BLK (scratch)))])
19579    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19580               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19581   "")
19582
19583 (define_peephole2
19584   [(match_scratch:DI 0 "r")
19585    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19586               (clobber (reg:CC FLAGS_REG))
19587               (clobber (mem:BLK (scratch)))])]
19588   "optimize_size"
19589   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19590               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19591               (clobber (mem:BLK (scratch)))])
19592    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19593               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19594   "")
19595
19596 ;; Convert esp additions to pop.
19597 (define_peephole2
19598   [(match_scratch:DI 0 "r")
19599    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19600               (clobber (reg:CC FLAGS_REG))])]
19601   ""
19602   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19603               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19604   "")
19605
19606 ;; Two pops case is tricky, since pop causes dependency on destination register.
19607 ;; We use two registers if available.
19608 (define_peephole2
19609   [(match_scratch:DI 0 "r")
19610    (match_scratch:DI 1 "r")
19611    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19612               (clobber (reg:CC FLAGS_REG))])]
19613   ""
19614   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19615               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19616    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19617               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19618   "")
19619
19620 (define_peephole2
19621   [(match_scratch:DI 0 "r")
19622    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19623               (clobber (reg:CC FLAGS_REG))])]
19624   "optimize_size"
19625   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19626               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19627    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19628               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19629   "")
19630 \f
19631 ;; Convert imul by three, five and nine into lea
19632 (define_peephole2
19633   [(parallel
19634     [(set (match_operand:SI 0 "register_operand" "")
19635           (mult:SI (match_operand:SI 1 "register_operand" "")
19636                    (match_operand:SI 2 "const_int_operand" "")))
19637      (clobber (reg:CC FLAGS_REG))])]
19638   "INTVAL (operands[2]) == 3
19639    || INTVAL (operands[2]) == 5
19640    || INTVAL (operands[2]) == 9"
19641   [(set (match_dup 0)
19642         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19643                  (match_dup 1)))]
19644   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19645
19646 (define_peephole2
19647   [(parallel
19648     [(set (match_operand:SI 0 "register_operand" "")
19649           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19650                    (match_operand:SI 2 "const_int_operand" "")))
19651      (clobber (reg:CC FLAGS_REG))])]
19652   "!optimize_size 
19653    && (INTVAL (operands[2]) == 3
19654        || INTVAL (operands[2]) == 5
19655        || INTVAL (operands[2]) == 9)"
19656   [(set (match_dup 0) (match_dup 1))
19657    (set (match_dup 0)
19658         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19659                  (match_dup 0)))]
19660   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19661
19662 (define_peephole2
19663   [(parallel
19664     [(set (match_operand:DI 0 "register_operand" "")
19665           (mult:DI (match_operand:DI 1 "register_operand" "")
19666                    (match_operand:DI 2 "const_int_operand" "")))
19667      (clobber (reg:CC FLAGS_REG))])]
19668   "TARGET_64BIT
19669    && (INTVAL (operands[2]) == 3
19670        || INTVAL (operands[2]) == 5
19671        || INTVAL (operands[2]) == 9)"
19672   [(set (match_dup 0)
19673         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19674                  (match_dup 1)))]
19675   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19676
19677 (define_peephole2
19678   [(parallel
19679     [(set (match_operand:DI 0 "register_operand" "")
19680           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19681                    (match_operand:DI 2 "const_int_operand" "")))
19682      (clobber (reg:CC FLAGS_REG))])]
19683   "TARGET_64BIT
19684    && !optimize_size 
19685    && (INTVAL (operands[2]) == 3
19686        || INTVAL (operands[2]) == 5
19687        || INTVAL (operands[2]) == 9)"
19688   [(set (match_dup 0) (match_dup 1))
19689    (set (match_dup 0)
19690         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19691                  (match_dup 0)))]
19692   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19693
19694 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19695 ;; imul $32bit_imm, reg, reg is direct decoded.
19696 (define_peephole2
19697   [(match_scratch:DI 3 "r")
19698    (parallel [(set (match_operand:DI 0 "register_operand" "")
19699                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19700                             (match_operand:DI 2 "immediate_operand" "")))
19701               (clobber (reg:CC FLAGS_REG))])]
19702   "TARGET_K8 && !optimize_size
19703    && (GET_CODE (operands[2]) != CONST_INT
19704        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19705   [(set (match_dup 3) (match_dup 1))
19706    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19707               (clobber (reg:CC FLAGS_REG))])]
19708 "")
19709
19710 (define_peephole2
19711   [(match_scratch:SI 3 "r")
19712    (parallel [(set (match_operand:SI 0 "register_operand" "")
19713                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19714                             (match_operand:SI 2 "immediate_operand" "")))
19715               (clobber (reg:CC FLAGS_REG))])]
19716   "TARGET_K8 && !optimize_size
19717    && (GET_CODE (operands[2]) != CONST_INT
19718        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19719   [(set (match_dup 3) (match_dup 1))
19720    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19721               (clobber (reg:CC FLAGS_REG))])]
19722 "")
19723
19724 (define_peephole2
19725   [(match_scratch:SI 3 "r")
19726    (parallel [(set (match_operand:DI 0 "register_operand" "")
19727                    (zero_extend:DI
19728                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19729                               (match_operand:SI 2 "immediate_operand" ""))))
19730               (clobber (reg:CC FLAGS_REG))])]
19731   "TARGET_K8 && !optimize_size
19732    && (GET_CODE (operands[2]) != CONST_INT
19733        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19734   [(set (match_dup 3) (match_dup 1))
19735    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19736               (clobber (reg:CC FLAGS_REG))])]
19737 "")
19738
19739 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19740 ;; Convert it into imul reg, reg
19741 ;; It would be better to force assembler to encode instruction using long
19742 ;; immediate, but there is apparently no way to do so.
19743 (define_peephole2
19744   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19745                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19746                             (match_operand:DI 2 "const_int_operand" "")))
19747               (clobber (reg:CC FLAGS_REG))])
19748    (match_scratch:DI 3 "r")]
19749   "TARGET_K8 && !optimize_size
19750    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19751   [(set (match_dup 3) (match_dup 2))
19752    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19753               (clobber (reg:CC FLAGS_REG))])]
19754 {
19755   if (!rtx_equal_p (operands[0], operands[1]))
19756     emit_move_insn (operands[0], operands[1]);
19757 })
19758
19759 (define_peephole2
19760   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19761                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19762                             (match_operand:SI 2 "const_int_operand" "")))
19763               (clobber (reg:CC FLAGS_REG))])
19764    (match_scratch:SI 3 "r")]
19765   "TARGET_K8 && !optimize_size
19766    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19767   [(set (match_dup 3) (match_dup 2))
19768    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19769               (clobber (reg:CC FLAGS_REG))])]
19770 {
19771   if (!rtx_equal_p (operands[0], operands[1]))
19772     emit_move_insn (operands[0], operands[1]);
19773 })
19774
19775 (define_peephole2
19776   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19777                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19778                             (match_operand:HI 2 "immediate_operand" "")))
19779               (clobber (reg:CC FLAGS_REG))])
19780    (match_scratch:HI 3 "r")]
19781   "TARGET_K8 && !optimize_size"
19782   [(set (match_dup 3) (match_dup 2))
19783    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19784               (clobber (reg:CC FLAGS_REG))])]
19785 {
19786   if (!rtx_equal_p (operands[0], operands[1]))
19787     emit_move_insn (operands[0], operands[1]);
19788 })
19789
19790 ;; After splitting up read-modify operations, array accesses with memory
19791 ;; operands might end up in form:
19792 ;;  sall    $2, %eax
19793 ;;  movl    4(%esp), %edx
19794 ;;  addl    %edx, %eax
19795 ;; instead of pre-splitting:
19796 ;;  sall    $2, %eax
19797 ;;  addl    4(%esp), %eax
19798 ;; Turn it into:
19799 ;;  movl    4(%esp), %edx
19800 ;;  leal    (%edx,%eax,4), %eax
19801
19802 (define_peephole2
19803   [(parallel [(set (match_operand 0 "register_operand" "")
19804                    (ashift (match_operand 1 "register_operand" "")
19805                            (match_operand 2 "const_int_operand" "")))
19806                (clobber (reg:CC FLAGS_REG))])
19807    (set (match_operand 3 "register_operand")
19808         (match_operand 4 "x86_64_general_operand" ""))
19809    (parallel [(set (match_operand 5 "register_operand" "")
19810                    (plus (match_operand 6 "register_operand" "")
19811                          (match_operand 7 "register_operand" "")))
19812                    (clobber (reg:CC FLAGS_REG))])]
19813   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19814    /* Validate MODE for lea.  */
19815    && ((!TARGET_PARTIAL_REG_STALL
19816         && (GET_MODE (operands[0]) == QImode
19817             || GET_MODE (operands[0]) == HImode))
19818        || GET_MODE (operands[0]) == SImode 
19819        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19820    /* We reorder load and the shift.  */
19821    && !rtx_equal_p (operands[1], operands[3])
19822    && !reg_overlap_mentioned_p (operands[0], operands[4])
19823    /* Last PLUS must consist of operand 0 and 3.  */
19824    && !rtx_equal_p (operands[0], operands[3])
19825    && (rtx_equal_p (operands[3], operands[6])
19826        || rtx_equal_p (operands[3], operands[7]))
19827    && (rtx_equal_p (operands[0], operands[6])
19828        || rtx_equal_p (operands[0], operands[7]))
19829    /* The intermediate operand 0 must die or be same as output.  */
19830    && (rtx_equal_p (operands[0], operands[5])
19831        || peep2_reg_dead_p (3, operands[0]))"
19832   [(set (match_dup 3) (match_dup 4))
19833    (set (match_dup 0) (match_dup 1))]
19834 {
19835   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19836   int scale = 1 << INTVAL (operands[2]);
19837   rtx index = gen_lowpart (Pmode, operands[1]);
19838   rtx base = gen_lowpart (Pmode, operands[3]);
19839   rtx dest = gen_lowpart (mode, operands[5]);
19840
19841   operands[1] = gen_rtx_PLUS (Pmode, base,
19842                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19843   if (mode != Pmode)
19844     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19845   operands[0] = dest;
19846 })
19847 \f
19848 ;; Call-value patterns last so that the wildcard operand does not
19849 ;; disrupt insn-recog's switch tables.
19850
19851 (define_insn "*call_value_pop_0"
19852   [(set (match_operand 0 "" "")
19853         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19854               (match_operand:SI 2 "" "")))
19855    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19856                             (match_operand:SI 3 "immediate_operand" "")))]
19857   "!TARGET_64BIT"
19858 {
19859   if (SIBLING_CALL_P (insn))
19860     return "jmp\t%P1";
19861   else
19862     return "call\t%P1";
19863 }
19864   [(set_attr "type" "callv")])
19865
19866 (define_insn "*call_value_pop_1"
19867   [(set (match_operand 0 "" "")
19868         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19869               (match_operand:SI 2 "" "")))
19870    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19871                             (match_operand:SI 3 "immediate_operand" "i")))]
19872   "!TARGET_64BIT"
19873 {
19874   if (constant_call_address_operand (operands[1], Pmode))
19875     {
19876       if (SIBLING_CALL_P (insn))
19877         return "jmp\t%P1";
19878       else
19879         return "call\t%P1";
19880     }
19881   if (SIBLING_CALL_P (insn))
19882     return "jmp\t%A1";
19883   else
19884     return "call\t%A1";
19885 }
19886   [(set_attr "type" "callv")])
19887
19888 (define_insn "*call_value_0"
19889   [(set (match_operand 0 "" "")
19890         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19891               (match_operand:SI 2 "" "")))]
19892   "!TARGET_64BIT"
19893 {
19894   if (SIBLING_CALL_P (insn))
19895     return "jmp\t%P1";
19896   else
19897     return "call\t%P1";
19898 }
19899   [(set_attr "type" "callv")])
19900
19901 (define_insn "*call_value_0_rex64"
19902   [(set (match_operand 0 "" "")
19903         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19904               (match_operand:DI 2 "const_int_operand" "")))]
19905   "TARGET_64BIT"
19906 {
19907   if (SIBLING_CALL_P (insn))
19908     return "jmp\t%P1";
19909   else
19910     return "call\t%P1";
19911 }
19912   [(set_attr "type" "callv")])
19913
19914 (define_insn "*call_value_1"
19915   [(set (match_operand 0 "" "")
19916         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19917               (match_operand:SI 2 "" "")))]
19918   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19919 {
19920   if (constant_call_address_operand (operands[1], Pmode))
19921     return "call\t%P1";
19922   return "call\t%A1";
19923 }
19924   [(set_attr "type" "callv")])
19925
19926 (define_insn "*sibcall_value_1"
19927   [(set (match_operand 0 "" "")
19928         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19929               (match_operand:SI 2 "" "")))]
19930   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19931 {
19932   if (constant_call_address_operand (operands[1], Pmode))
19933     return "jmp\t%P1";
19934   return "jmp\t%A1";
19935 }
19936   [(set_attr "type" "callv")])
19937
19938 (define_insn "*call_value_1_rex64"
19939   [(set (match_operand 0 "" "")
19940         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19941               (match_operand:DI 2 "" "")))]
19942   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19943 {
19944   if (constant_call_address_operand (operands[1], Pmode))
19945     return "call\t%P1";
19946   return "call\t%A1";
19947 }
19948   [(set_attr "type" "callv")])
19949
19950 (define_insn "*sibcall_value_1_rex64"
19951   [(set (match_operand 0 "" "")
19952         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19953               (match_operand:DI 2 "" "")))]
19954   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19955   "jmp\t%P1"
19956   [(set_attr "type" "callv")])
19957
19958 (define_insn "*sibcall_value_1_rex64_v"
19959   [(set (match_operand 0 "" "")
19960         (call (mem:QI (reg:DI 40))
19961               (match_operand:DI 1 "" "")))]
19962   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19963   "jmp\t*%%r11"
19964   [(set_attr "type" "callv")])
19965 \f
19966 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19967 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19968 ;; caught for use by garbage collectors and the like.  Using an insn that
19969 ;; maps to SIGILL makes it more likely the program will rightfully die.
19970 ;; Keeping with tradition, "6" is in honor of #UD.
19971 (define_insn "trap"
19972   [(trap_if (const_int 1) (const_int 6))]
19973   ""
19974   ".word\t0x0b0f"
19975   [(set_attr "length" "2")])
19976
19977 (define_expand "sse_prologue_save"
19978   [(parallel [(set (match_operand:BLK 0 "" "")
19979                    (unspec:BLK [(reg:DI 21)
19980                                 (reg:DI 22)
19981                                 (reg:DI 23)
19982                                 (reg:DI 24)
19983                                 (reg:DI 25)
19984                                 (reg:DI 26)
19985                                 (reg:DI 27)
19986                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19987               (use (match_operand:DI 1 "register_operand" ""))
19988               (use (match_operand:DI 2 "immediate_operand" ""))
19989               (use (label_ref:DI (match_operand 3 "" "")))])]
19990   "TARGET_64BIT"
19991   "")
19992
19993 (define_insn "*sse_prologue_save_insn"
19994   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19995                           (match_operand:DI 4 "const_int_operand" "n")))
19996         (unspec:BLK [(reg:DI 21)
19997                      (reg:DI 22)
19998                      (reg:DI 23)
19999                      (reg:DI 24)
20000                      (reg:DI 25)
20001                      (reg:DI 26)
20002                      (reg:DI 27)
20003                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20004    (use (match_operand:DI 1 "register_operand" "r"))
20005    (use (match_operand:DI 2 "const_int_operand" "i"))
20006    (use (label_ref:DI (match_operand 3 "" "X")))]
20007   "TARGET_64BIT
20008    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20009    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20010   "*
20011 {
20012   int i;
20013   operands[0] = gen_rtx_MEM (Pmode,
20014                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20015   output_asm_insn (\"jmp\\t%A1\", operands);
20016   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20017     {
20018       operands[4] = adjust_address (operands[0], DImode, i*16);
20019       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20020       PUT_MODE (operands[4], TImode);
20021       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20022         output_asm_insn (\"rex\", operands);
20023       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20024     }
20025   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20026                              CODE_LABEL_NUMBER (operands[3]));
20027   RET;
20028 }
20029   "
20030   [(set_attr "type" "other")
20031    (set_attr "length_immediate" "0")
20032    (set_attr "length_address" "0")
20033    (set_attr "length" "135")
20034    (set_attr "memory" "store")
20035    (set_attr "modrm" "0")
20036    (set_attr "mode" "DI")])
20037
20038 (define_expand "prefetch"
20039   [(prefetch (match_operand 0 "address_operand" "")
20040              (match_operand:SI 1 "const_int_operand" "")
20041              (match_operand:SI 2 "const_int_operand" ""))]
20042   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20043 {
20044   int rw = INTVAL (operands[1]);
20045   int locality = INTVAL (operands[2]);
20046
20047   gcc_assert (rw == 0 || rw == 1);
20048   gcc_assert (locality >= 0 && locality <= 3);
20049   gcc_assert (GET_MODE (operands[0]) == Pmode
20050               || GET_MODE (operands[0]) == VOIDmode);
20051
20052   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20053      supported by SSE counterpart or the SSE prefetch is not available
20054      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20055      of locality.  */
20056   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20057     operands[2] = GEN_INT (3);
20058   else
20059     operands[1] = const0_rtx;
20060 })
20061
20062 (define_insn "*prefetch_sse"
20063   [(prefetch (match_operand:SI 0 "address_operand" "p")
20064              (const_int 0)
20065              (match_operand:SI 1 "const_int_operand" ""))]
20066   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20067 {
20068   static const char * const patterns[4] = {
20069    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20070   };
20071
20072   int locality = INTVAL (operands[1]);
20073   gcc_assert (locality >= 0 && locality <= 3);
20074
20075   return patterns[locality];  
20076 }
20077   [(set_attr "type" "sse")
20078    (set_attr "memory" "none")])
20079
20080 (define_insn "*prefetch_sse_rex"
20081   [(prefetch (match_operand:DI 0 "address_operand" "p")
20082              (const_int 0)
20083              (match_operand:SI 1 "const_int_operand" ""))]
20084   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20085 {
20086   static const char * const patterns[4] = {
20087    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20088   };
20089
20090   int locality = INTVAL (operands[1]);
20091   gcc_assert (locality >= 0 && locality <= 3);
20092
20093   return patterns[locality];  
20094 }
20095   [(set_attr "type" "sse")
20096    (set_attr "memory" "none")])
20097
20098 (define_insn "*prefetch_3dnow"
20099   [(prefetch (match_operand:SI 0 "address_operand" "p")
20100              (match_operand:SI 1 "const_int_operand" "n")
20101              (const_int 3))]
20102   "TARGET_3DNOW && !TARGET_64BIT"
20103 {
20104   if (INTVAL (operands[1]) == 0)
20105     return "prefetch\t%a0";
20106   else
20107     return "prefetchw\t%a0";
20108 }
20109   [(set_attr "type" "mmx")
20110    (set_attr "memory" "none")])
20111
20112 (define_insn "*prefetch_3dnow_rex"
20113   [(prefetch (match_operand:DI 0 "address_operand" "p")
20114              (match_operand:SI 1 "const_int_operand" "n")
20115              (const_int 3))]
20116   "TARGET_3DNOW && TARGET_64BIT"
20117 {
20118   if (INTVAL (operands[1]) == 0)
20119     return "prefetch\t%a0";
20120   else
20121     return "prefetchw\t%a0";
20122 }
20123   [(set_attr "type" "mmx")
20124    (set_attr "memory" "none")])
20125
20126 (define_expand "stack_protect_set"
20127   [(match_operand 0 "memory_operand" "")
20128    (match_operand 1 "memory_operand" "")]
20129   ""
20130 {
20131 #ifdef TARGET_THREAD_SSP_OFFSET
20132   if (TARGET_64BIT)
20133     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20134                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20135   else
20136     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20137                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20138 #else
20139   if (TARGET_64BIT)
20140     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20141   else
20142     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20143 #endif
20144   DONE;
20145 })
20146
20147 (define_insn "stack_protect_set_si"
20148   [(set (match_operand:SI 0 "memory_operand" "=m")
20149         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20150    (set (match_scratch:SI 2 "=&r") (const_int 0))
20151    (clobber (reg:CC FLAGS_REG))]
20152   ""
20153   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20154   [(set_attr "type" "multi")])
20155
20156 (define_insn "stack_protect_set_di"
20157   [(set (match_operand:DI 0 "memory_operand" "=m")
20158         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20159    (set (match_scratch:DI 2 "=&r") (const_int 0))
20160    (clobber (reg:CC FLAGS_REG))]
20161   "TARGET_64BIT"
20162   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20163   [(set_attr "type" "multi")])
20164
20165 (define_insn "stack_tls_protect_set_si"
20166   [(set (match_operand:SI 0 "memory_operand" "=m")
20167         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20168    (set (match_scratch:SI 2 "=&r") (const_int 0))
20169    (clobber (reg:CC FLAGS_REG))]
20170   ""
20171   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20172   [(set_attr "type" "multi")])
20173
20174 (define_insn "stack_tls_protect_set_di"
20175   [(set (match_operand:DI 0 "memory_operand" "=m")
20176         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20177    (set (match_scratch:DI 2 "=&r") (const_int 0))
20178    (clobber (reg:CC FLAGS_REG))]
20179   "TARGET_64BIT"
20180   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20181   [(set_attr "type" "multi")])
20182
20183 (define_expand "stack_protect_test"
20184   [(match_operand 0 "memory_operand" "")
20185    (match_operand 1 "memory_operand" "")
20186    (match_operand 2 "" "")]
20187   ""
20188 {
20189   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20190   ix86_compare_op0 = operands[0];
20191   ix86_compare_op1 = operands[1];
20192   ix86_compare_emitted = flags;
20193
20194 #ifdef TARGET_THREAD_SSP_OFFSET
20195   if (TARGET_64BIT)
20196     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20197                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20198   else
20199     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20200                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20201 #else
20202   if (TARGET_64BIT)
20203     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20204   else
20205     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20206 #endif
20207   emit_jump_insn (gen_beq (operands[2]));
20208   DONE;
20209 })
20210
20211 (define_insn "stack_protect_test_si"
20212   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20213         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20214                      (match_operand:SI 2 "memory_operand" "m")]
20215                     UNSPEC_SP_TEST))
20216    (clobber (match_scratch:SI 3 "=&r"))]
20217   ""
20218   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20219   [(set_attr "type" "multi")])
20220
20221 (define_insn "stack_protect_test_di"
20222   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20223         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20224                      (match_operand:DI 2 "memory_operand" "m")]
20225                     UNSPEC_SP_TEST))
20226    (clobber (match_scratch:DI 3 "=&r"))]
20227   "TARGET_64BIT"
20228   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20229   [(set_attr "type" "multi")])
20230
20231 (define_insn "stack_tls_protect_test_si"
20232   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20233         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20234                      (match_operand:SI 2 "const_int_operand" "i")]
20235                     UNSPEC_SP_TLS_TEST))
20236    (clobber (match_scratch:SI 3 "=r"))]
20237   ""
20238   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20239   [(set_attr "type" "multi")])
20240
20241 (define_insn "stack_tls_protect_test_di"
20242   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20243         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20244                      (match_operand:DI 2 "const_int_operand" "i")]
20245                     UNSPEC_SP_TLS_TEST))
20246    (clobber (match_scratch:DI 3 "=r"))]
20247   "TARGET_64BIT"
20248   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20249   [(set_attr "type" "multi")])
20250
20251 (include "sse.md")
20252 (include "mmx.md")
20253 (include "sync.md")