OSDN Git Service

afcecdea930d20ee123dcf738b17b753d5b1f165
[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" "=<,<")
1278         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279   "!TARGET_64BIT"
1280   "@
1281    push{w}\t{|WORD PTR }%1
1282    push{w}\t%1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X,X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444   "!TARGET_64BIT"
1445   "@
1446    push{w}\t{|word ptr }%1
1447    push{w}\t%w1"
1448   [(set_attr "type" "push")
1449    (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453   [(set (match_operand:QI 0 "push_operand" "=X")
1454         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455   "TARGET_64BIT"
1456   "push{q}\t%q1"
1457   [(set_attr "type" "push")
1458    (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there.  Then we use movzx.
1470 (define_insn "*movqi_1"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1473   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475   switch (get_attr_type (insn))
1476     {
1477     case TYPE_IMOVX:
1478       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480     default:
1481       if (get_attr_mode (insn) == MODE_SI)
1482         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483       else
1484         return "mov{b}\t{%1, %0|%0, %1}";
1485     }
1486 }
1487   [(set (attr "type")
1488      (cond [(and (eq_attr "alternative" "5")
1489                  (not (match_operand:QI 1 "aligned_operand" "")))
1490               (const_string "imovx")
1491             (ne (symbol_ref "optimize_size") (const_int 0))
1492               (const_string "imov")
1493             (and (eq_attr "alternative" "3")
1494                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495                           (const_int 0))
1496                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1497                           (const_int 0))))
1498               (const_string "imov")
1499             (eq_attr "alternative" "3,5")
1500               (const_string "imovx")
1501             (and (ne (symbol_ref "TARGET_MOVX")
1502                      (const_int 0))
1503                  (eq_attr "alternative" "2"))
1504               (const_string "imovx")
1505            ]
1506            (const_string "imov")))
1507    (set (attr "mode")
1508       (cond [(eq_attr "alternative" "3,4,5")
1509                (const_string "SI")
1510              (eq_attr "alternative" "6")
1511                (const_string "QI")
1512              (eq_attr "type" "imovx")
1513                (const_string "SI")
1514              (and (eq_attr "type" "imov")
1515                   (and (eq_attr "alternative" "0,1")
1516                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517                            (const_int 0))))
1518                (const_string "SI")
1519              ;; Avoid partial register stalls when not using QImode arithmetic
1520              (and (eq_attr "type" "imov")
1521                   (and (eq_attr "alternative" "0,1")
1522                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1523                                 (const_int 0))
1524                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1525                                 (const_int 0)))))
1526                (const_string "SI")
1527            ]
1528            (const_string "QI")))])
1529
1530 (define_expand "reload_outqi"
1531   [(parallel [(match_operand:QI 0 "" "=m")
1532               (match_operand:QI 1 "register_operand" "r")
1533               (match_operand:QI 2 "register_operand" "=&q")])]
1534   ""
1535 {
1536   rtx op0, op1, op2;
1537   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1538
1539   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1540   if (! q_regs_operand (op1, QImode))
1541     {
1542       emit_insn (gen_movqi (op2, op1));
1543       op1 = op2;
1544     }
1545   emit_insn (gen_movqi (op0, op1));
1546   DONE;
1547 })
1548
1549 (define_insn "*swapqi_1"
1550   [(set (match_operand:QI 0 "register_operand" "+r")
1551         (match_operand:QI 1 "register_operand" "+r"))
1552    (set (match_dup 1)
1553         (match_dup 0))]
1554   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1555   "xchg{l}\t%k1, %k0"
1556   [(set_attr "type" "imov")
1557    (set_attr "mode" "SI")
1558    (set_attr "pent_pair" "np")
1559    (set_attr "athlon_decode" "vector")])
1560
1561 (define_insn "*swapqi_2"
1562   [(set (match_operand:QI 0 "register_operand" "+q")
1563         (match_operand:QI 1 "register_operand" "+q"))
1564    (set (match_dup 1)
1565         (match_dup 0))]
1566   "TARGET_PARTIAL_REG_STALL"
1567   "xchg{b}\t%1, %0"
1568   [(set_attr "type" "imov")
1569    (set_attr "mode" "QI")
1570    (set_attr "pent_pair" "np")
1571    (set_attr "athlon_decode" "vector")])
1572
1573 (define_expand "movstrictqi"
1574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1575         (match_operand:QI 1 "general_operand" ""))]
1576   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1577 {
1578   /* Don't generate memory->memory moves, go through a register.  */
1579   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1580     operands[1] = force_reg (QImode, operands[1]);
1581 })
1582
1583 (define_insn "*movstrictqi_1"
1584   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1585         (match_operand:QI 1 "general_operand" "*qn,m"))]
1586   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1588   "mov{b}\t{%1, %0|%0, %1}"
1589   [(set_attr "type" "imov")
1590    (set_attr "mode" "QI")])
1591
1592 (define_insn "*movstrictqi_xor"
1593   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1594         (match_operand:QI 1 "const0_operand" "i"))
1595    (clobber (reg:CC FLAGS_REG))]
1596   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1597   "xor{b}\t{%0, %0|%0, %0}"
1598   [(set_attr "type" "alu1")
1599    (set_attr "mode" "QI")
1600    (set_attr "length_immediate" "0")])
1601
1602 (define_insn "*movsi_extv_1"
1603   [(set (match_operand:SI 0 "register_operand" "=R")
1604         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1605                          (const_int 8)
1606                          (const_int 8)))]
1607   ""
1608   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1609   [(set_attr "type" "imovx")
1610    (set_attr "mode" "SI")])
1611
1612 (define_insn "*movhi_extv_1"
1613   [(set (match_operand:HI 0 "register_operand" "=R")
1614         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   ""
1618   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1619   [(set_attr "type" "imovx")
1620    (set_attr "mode" "SI")])
1621
1622 (define_insn "*movqi_extv_1"
1623   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1624         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1625                          (const_int 8)
1626                          (const_int 8)))]
1627   "!TARGET_64BIT"
1628 {
1629   switch (get_attr_type (insn))
1630     {
1631     case TYPE_IMOVX:
1632       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1633     default:
1634       return "mov{b}\t{%h1, %0|%0, %h1}";
1635     }
1636 }
1637   [(set (attr "type")
1638      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640                              (ne (symbol_ref "TARGET_MOVX")
1641                                  (const_int 0))))
1642         (const_string "imovx")
1643         (const_string "imov")))
1644    (set (attr "mode")
1645      (if_then_else (eq_attr "type" "imovx")
1646         (const_string "SI")
1647         (const_string "QI")))])
1648
1649 (define_insn "*movqi_extv_1_rex64"
1650   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1651         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1652                          (const_int 8)
1653                          (const_int 8)))]
1654   "TARGET_64BIT"
1655 {
1656   switch (get_attr_type (insn))
1657     {
1658     case TYPE_IMOVX:
1659       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1660     default:
1661       return "mov{b}\t{%h1, %0|%0, %h1}";
1662     }
1663 }
1664   [(set (attr "type")
1665      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1666                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1667                              (ne (symbol_ref "TARGET_MOVX")
1668                                  (const_int 0))))
1669         (const_string "imovx")
1670         (const_string "imov")))
1671    (set (attr "mode")
1672      (if_then_else (eq_attr "type" "imovx")
1673         (const_string "SI")
1674         (const_string "QI")))])
1675
1676 ;; Stores and loads of ax to arbitrary constant address.
1677 ;; We fake an second form of instruction to force reload to load address
1678 ;; into register when rax is not available
1679 (define_insn "*movabsqi_1_rex64"
1680   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1681         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1682   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1683   "@
1684    movabs{b}\t{%1, %P0|%P0, %1}
1685    mov{b}\t{%1, %a0|%a0, %1}"
1686   [(set_attr "type" "imov")
1687    (set_attr "modrm" "0,*")
1688    (set_attr "length_address" "8,0")
1689    (set_attr "length_immediate" "0,*")
1690    (set_attr "memory" "store")
1691    (set_attr "mode" "QI")])
1692
1693 (define_insn "*movabsqi_2_rex64"
1694   [(set (match_operand:QI 0 "register_operand" "=a,r")
1695         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1696   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1697   "@
1698    movabs{b}\t{%P1, %0|%0, %P1}
1699    mov{b}\t{%a1, %0|%0, %a1}"
1700   [(set_attr "type" "imov")
1701    (set_attr "modrm" "0,*")
1702    (set_attr "length_address" "8,0")
1703    (set_attr "length_immediate" "0")
1704    (set_attr "memory" "load")
1705    (set_attr "mode" "QI")])
1706
1707 (define_insn "*movdi_extzv_1"
1708   [(set (match_operand:DI 0 "register_operand" "=R")
1709         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1710                          (const_int 8)
1711                          (const_int 8)))]
1712   "TARGET_64BIT"
1713   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1714   [(set_attr "type" "imovx")
1715    (set_attr "mode" "DI")])
1716
1717 (define_insn "*movsi_extzv_1"
1718   [(set (match_operand:SI 0 "register_operand" "=R")
1719         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1720                          (const_int 8)
1721                          (const_int 8)))]
1722   ""
1723   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1724   [(set_attr "type" "imovx")
1725    (set_attr "mode" "SI")])
1726
1727 (define_insn "*movqi_extzv_2"
1728   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1729         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1730                                     (const_int 8)
1731                                     (const_int 8)) 0))]
1732   "!TARGET_64BIT"
1733 {
1734   switch (get_attr_type (insn))
1735     {
1736     case TYPE_IMOVX:
1737       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1738     default:
1739       return "mov{b}\t{%h1, %0|%0, %h1}";
1740     }
1741 }
1742   [(set (attr "type")
1743      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1744                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1745                              (ne (symbol_ref "TARGET_MOVX")
1746                                  (const_int 0))))
1747         (const_string "imovx")
1748         (const_string "imov")))
1749    (set (attr "mode")
1750      (if_then_else (eq_attr "type" "imovx")
1751         (const_string "SI")
1752         (const_string "QI")))])
1753
1754 (define_insn "*movqi_extzv_2_rex64"
1755   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1756         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1757                                     (const_int 8)
1758                                     (const_int 8)) 0))]
1759   "TARGET_64BIT"
1760 {
1761   switch (get_attr_type (insn))
1762     {
1763     case TYPE_IMOVX:
1764       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1765     default:
1766       return "mov{b}\t{%h1, %0|%0, %h1}";
1767     }
1768 }
1769   [(set (attr "type")
1770      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1771                         (ne (symbol_ref "TARGET_MOVX")
1772                             (const_int 0)))
1773         (const_string "imovx")
1774         (const_string "imov")))
1775    (set (attr "mode")
1776      (if_then_else (eq_attr "type" "imovx")
1777         (const_string "SI")
1778         (const_string "QI")))])
1779
1780 (define_insn "movsi_insv_1"
1781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1782                          (const_int 8)
1783                          (const_int 8))
1784         (match_operand:SI 1 "general_operand" "Qmn"))]
1785   "!TARGET_64BIT"
1786   "mov{b}\t{%b1, %h0|%h0, %b1}"
1787   [(set_attr "type" "imov")
1788    (set_attr "mode" "QI")])
1789
1790 (define_insn "movdi_insv_1_rex64"
1791   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1792                          (const_int 8)
1793                          (const_int 8))
1794         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1795   "TARGET_64BIT"
1796   "mov{b}\t{%b1, %h0|%h0, %b1}"
1797   [(set_attr "type" "imov")
1798    (set_attr "mode" "QI")])
1799
1800 (define_insn "*movqi_insv_2"
1801   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802                          (const_int 8)
1803                          (const_int 8))
1804         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1805                      (const_int 8)))]
1806   ""
1807   "mov{b}\t{%h1, %h0|%h0, %h1}"
1808   [(set_attr "type" "imov")
1809    (set_attr "mode" "QI")])
1810
1811 (define_expand "movdi"
1812   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1813         (match_operand:DI 1 "general_operand" ""))]
1814   ""
1815   "ix86_expand_move (DImode, operands); DONE;")
1816
1817 (define_insn "*pushdi"
1818   [(set (match_operand:DI 0 "push_operand" "=<")
1819         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1820   "!TARGET_64BIT"
1821   "#")
1822
1823 (define_insn "*pushdi2_rex64"
1824   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1825         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1826   "TARGET_64BIT"
1827   "@
1828    push{q}\t%1
1829    #"
1830   [(set_attr "type" "push,multi")
1831    (set_attr "mode" "DI")])
1832
1833 ;; Convert impossible pushes of immediate to existing instructions.
1834 ;; First try to get scratch register and go through it.  In case this
1835 ;; fails, push sign extended lower part first and then overwrite
1836 ;; upper part by 32bit move.
1837 (define_peephole2
1838   [(match_scratch:DI 2 "r")
1839    (set (match_operand:DI 0 "push_operand" "")
1840         (match_operand:DI 1 "immediate_operand" ""))]
1841   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1842    && !x86_64_immediate_operand (operands[1], DImode)"
1843   [(set (match_dup 2) (match_dup 1))
1844    (set (match_dup 0) (match_dup 2))]
1845   "")
1846
1847 ;; We need to define this as both peepholer and splitter for case
1848 ;; peephole2 pass is not run.
1849 ;; "&& 1" is needed to keep it from matching the previous pattern.
1850 (define_peephole2
1851   [(set (match_operand:DI 0 "push_operand" "")
1852         (match_operand:DI 1 "immediate_operand" ""))]
1853   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1854    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1855   [(set (match_dup 0) (match_dup 1))
1856    (set (match_dup 2) (match_dup 3))]
1857   "split_di (operands + 1, 1, operands + 2, operands + 3);
1858    operands[1] = gen_lowpart (DImode, operands[2]);
1859    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1860                                                     GEN_INT (4)));
1861   ")
1862
1863 (define_split
1864   [(set (match_operand:DI 0 "push_operand" "")
1865         (match_operand:DI 1 "immediate_operand" ""))]
1866   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1867                     ? flow2_completed : reload_completed)
1868    && !symbolic_operand (operands[1], DImode)
1869    && !x86_64_immediate_operand (operands[1], DImode)"
1870   [(set (match_dup 0) (match_dup 1))
1871    (set (match_dup 2) (match_dup 3))]
1872   "split_di (operands + 1, 1, operands + 2, operands + 3);
1873    operands[1] = gen_lowpart (DImode, operands[2]);
1874    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1875                                                     GEN_INT (4)));
1876   ")
1877
1878 (define_insn "*pushdi2_prologue_rex64"
1879   [(set (match_operand:DI 0 "push_operand" "=<")
1880         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1881    (clobber (mem:BLK (scratch)))]
1882   "TARGET_64BIT"
1883   "push{q}\t%1"
1884   [(set_attr "type" "push")
1885    (set_attr "mode" "DI")])
1886
1887 (define_insn "*popdi1_epilogue_rex64"
1888   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1889         (mem:DI (reg:DI SP_REG)))
1890    (set (reg:DI SP_REG)
1891         (plus:DI (reg:DI SP_REG) (const_int 8)))
1892    (clobber (mem:BLK (scratch)))]
1893   "TARGET_64BIT"
1894   "pop{q}\t%0"
1895   [(set_attr "type" "pop")
1896    (set_attr "mode" "DI")])
1897
1898 (define_insn "popdi1"
1899   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900         (mem:DI (reg:DI SP_REG)))
1901    (set (reg:DI SP_REG)
1902         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1903   "TARGET_64BIT"
1904   "pop{q}\t%0"
1905   [(set_attr "type" "pop")
1906    (set_attr "mode" "DI")])
1907
1908 (define_insn "*movdi_xor_rex64"
1909   [(set (match_operand:DI 0 "register_operand" "=r")
1910         (match_operand:DI 1 "const0_operand" "i"))
1911    (clobber (reg:CC FLAGS_REG))]
1912   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1913    && reload_completed"
1914   "xor{l}\t{%k0, %k0|%k0, %k0}"
1915   [(set_attr "type" "alu1")
1916    (set_attr "mode" "SI")
1917    (set_attr "length_immediate" "0")])
1918
1919 (define_insn "*movdi_or_rex64"
1920   [(set (match_operand:DI 0 "register_operand" "=r")
1921         (match_operand:DI 1 "const_int_operand" "i"))
1922    (clobber (reg:CC FLAGS_REG))]
1923   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1924    && reload_completed
1925    && operands[1] == constm1_rtx"
1926 {
1927   operands[1] = constm1_rtx;
1928   return "or{q}\t{%1, %0|%0, %1}";
1929 }
1930   [(set_attr "type" "alu1")
1931    (set_attr "mode" "DI")
1932    (set_attr "length_immediate" "1")])
1933
1934 (define_insn "*movdi_2"
1935   [(set (match_operand:DI 0 "nonimmediate_operand"
1936                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1937         (match_operand:DI 1 "general_operand"
1938                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1939   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1940   "@
1941    #
1942    #
1943    pxor\t%0, %0
1944    movq\t{%1, %0|%0, %1}
1945    movq\t{%1, %0|%0, %1}
1946    pxor\t%0, %0
1947    movq\t{%1, %0|%0, %1}
1948    movdqa\t{%1, %0|%0, %1}
1949    movq\t{%1, %0|%0, %1}
1950    xorps\t%0, %0
1951    movlps\t{%1, %0|%0, %1}
1952    movaps\t{%1, %0|%0, %1}
1953    movlps\t{%1, %0|%0, %1}"
1954   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1955    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1956
1957 (define_split
1958   [(set (match_operand:DI 0 "push_operand" "")
1959         (match_operand:DI 1 "general_operand" ""))]
1960   "!TARGET_64BIT && reload_completed
1961    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1962   [(const_int 0)]
1963   "ix86_split_long_move (operands); DONE;")
1964
1965 ;; %%% This multiword shite has got to go.
1966 (define_split
1967   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1968         (match_operand:DI 1 "general_operand" ""))]
1969   "!TARGET_64BIT && reload_completed
1970    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1971    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1972   [(const_int 0)]
1973   "ix86_split_long_move (operands); DONE;")
1974
1975 (define_insn "*movdi_1_rex64"
1976   [(set (match_operand:DI 0 "nonimmediate_operand"
1977                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1978         (match_operand:DI 1 "general_operand"
1979                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1980   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1981 {
1982   switch (get_attr_type (insn))
1983     {
1984     case TYPE_SSECVT:
1985       if (which_alternative == 13)
1986         return "movq2dq\t{%1, %0|%0, %1}";
1987       else
1988         return "movdq2q\t{%1, %0|%0, %1}";
1989     case TYPE_SSEMOV:
1990       if (get_attr_mode (insn) == MODE_TI)
1991           return "movdqa\t{%1, %0|%0, %1}";
1992       /* FALLTHRU */
1993     case TYPE_MMXMOV:
1994       /* Moves from and into integer register is done using movd opcode with
1995          REX prefix.  */
1996       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997           return "movd\t{%1, %0|%0, %1}";
1998       return "movq\t{%1, %0|%0, %1}";
1999     case TYPE_SSELOG1:
2000     case TYPE_MMXADD:
2001       return "pxor\t%0, %0";
2002     case TYPE_MULTI:
2003       return "#";
2004     case TYPE_LEA:
2005       return "lea{q}\t{%a1, %0|%0, %a1}";
2006     default:
2007       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2008       if (get_attr_mode (insn) == MODE_SI)
2009         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010       else if (which_alternative == 2)
2011         return "movabs{q}\t{%1, %0|%0, %1}";
2012       else
2013         return "mov{q}\t{%1, %0|%0, %1}";
2014     }
2015 }
2016   [(set (attr "type")
2017      (cond [(eq_attr "alternative" "5")
2018               (const_string "mmxadd")
2019             (eq_attr "alternative" "6,7,8")
2020               (const_string "mmxmov")
2021             (eq_attr "alternative" "9")
2022               (const_string "sselog1")
2023             (eq_attr "alternative" "10,11,12")
2024               (const_string "ssemov")
2025             (eq_attr "alternative" "13,14")
2026               (const_string "ssecvt")
2027             (eq_attr "alternative" "4")
2028               (const_string "multi")
2029             (match_operand:DI 1 "pic_32bit_operand" "")
2030               (const_string "lea")
2031            ]
2032            (const_string "imov")))
2033    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2034    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2035    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2036
2037 ;; Stores and loads of ax to arbitrary constant address.
2038 ;; We fake an second form of instruction to force reload to load address
2039 ;; into register when rax is not available
2040 (define_insn "*movabsdi_1_rex64"
2041   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2042         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2044   "@
2045    movabs{q}\t{%1, %P0|%P0, %1}
2046    mov{q}\t{%1, %a0|%a0, %1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0,*")
2051    (set_attr "memory" "store")
2052    (set_attr "mode" "DI")])
2053
2054 (define_insn "*movabsdi_2_rex64"
2055   [(set (match_operand:DI 0 "register_operand" "=a,r")
2056         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2057   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2058   "@
2059    movabs{q}\t{%P1, %0|%0, %P1}
2060    mov{q}\t{%a1, %0|%0, %a1}"
2061   [(set_attr "type" "imov")
2062    (set_attr "modrm" "0,*")
2063    (set_attr "length_address" "8,0")
2064    (set_attr "length_immediate" "0")
2065    (set_attr "memory" "load")
2066    (set_attr "mode" "DI")])
2067
2068 ;; Convert impossible stores of immediate to existing instructions.
2069 ;; First try to get scratch register and go through it.  In case this
2070 ;; fails, move by 32bit parts.
2071 (define_peephole2
2072   [(match_scratch:DI 2 "r")
2073    (set (match_operand:DI 0 "memory_operand" "")
2074         (match_operand:DI 1 "immediate_operand" ""))]
2075   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076    && !x86_64_immediate_operand (operands[1], DImode)"
2077   [(set (match_dup 2) (match_dup 1))
2078    (set (match_dup 0) (match_dup 2))]
2079   "")
2080
2081 ;; We need to define this as both peepholer and splitter for case
2082 ;; peephole2 pass is not run.
2083 ;; "&& 1" is needed to keep it from matching the previous pattern.
2084 (define_peephole2
2085   [(set (match_operand:DI 0 "memory_operand" "")
2086         (match_operand:DI 1 "immediate_operand" ""))]
2087   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089   [(set (match_dup 2) (match_dup 3))
2090    (set (match_dup 4) (match_dup 5))]
2091   "split_di (operands, 2, operands + 2, operands + 4);")
2092
2093 (define_split
2094   [(set (match_operand:DI 0 "memory_operand" "")
2095         (match_operand:DI 1 "immediate_operand" ""))]
2096   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097                     ? flow2_completed : reload_completed)
2098    && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode)"
2100   [(set (match_dup 2) (match_dup 3))
2101    (set (match_dup 4) (match_dup 5))]
2102   "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_insn "*swapdi_rex64"
2105   [(set (match_operand:DI 0 "register_operand" "+r")
2106         (match_operand:DI 1 "register_operand" "+r"))
2107    (set (match_dup 1)
2108         (match_dup 0))]
2109   "TARGET_64BIT"
2110   "xchg{q}\t%1, %0"
2111   [(set_attr "type" "imov")
2112    (set_attr "mode" "DI")
2113    (set_attr "pent_pair" "np")
2114    (set_attr "athlon_decode" "vector")])
2115
2116 (define_expand "movti"
2117   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2118         (match_operand:TI 1 "nonimmediate_operand" ""))]
2119   "TARGET_SSE || TARGET_64BIT"
2120 {
2121   if (TARGET_64BIT)
2122     ix86_expand_move (TImode, operands);
2123   else
2124     ix86_expand_vector_move (TImode, operands);
2125   DONE;
2126 })
2127
2128 (define_insn "*movti_internal"
2129   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2130         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2131   "TARGET_SSE && !TARGET_64BIT
2132    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2133 {
2134   switch (which_alternative)
2135     {
2136     case 0:
2137       if (get_attr_mode (insn) == MODE_V4SF)
2138         return "xorps\t%0, %0";
2139       else
2140         return "pxor\t%0, %0";
2141     case 1:
2142     case 2:
2143       if (get_attr_mode (insn) == MODE_V4SF)
2144         return "movaps\t{%1, %0|%0, %1}";
2145       else
2146         return "movdqa\t{%1, %0|%0, %1}";
2147     default:
2148       gcc_unreachable ();
2149     }
2150 }
2151   [(set_attr "type" "ssemov,ssemov,ssemov")
2152    (set (attr "mode")
2153         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2154                  (const_string "V4SF")
2155
2156                (eq_attr "alternative" "0,1")
2157                  (if_then_else
2158                    (ne (symbol_ref "optimize_size")
2159                        (const_int 0))
2160                    (const_string "V4SF")
2161                    (const_string "TI"))
2162                (eq_attr "alternative" "2")
2163                  (if_then_else
2164                    (ne (symbol_ref "optimize_size")
2165                        (const_int 0))
2166                    (const_string "V4SF")
2167                    (const_string "TI"))]
2168                (const_string "TI")))])
2169
2170 (define_insn "*movti_rex64"
2171   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2172         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2173   "TARGET_64BIT
2174    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175 {
2176   switch (which_alternative)
2177     {
2178     case 0:
2179     case 1:
2180       return "#";
2181     case 2:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "xorps\t%0, %0";
2184       else
2185         return "pxor\t%0, %0";
2186     case 3:
2187     case 4:
2188       if (get_attr_mode (insn) == MODE_V4SF)
2189         return "movaps\t{%1, %0|%0, %1}";
2190       else
2191         return "movdqa\t{%1, %0|%0, %1}";
2192     default:
2193       gcc_unreachable ();
2194     }
2195 }
2196   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2197    (set (attr "mode")
2198         (cond [(eq_attr "alternative" "2,3")
2199                  (if_then_else
2200                    (ne (symbol_ref "optimize_size")
2201                        (const_int 0))
2202                    (const_string "V4SF")
2203                    (const_string "TI"))
2204                (eq_attr "alternative" "4")
2205                  (if_then_else
2206                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207                             (const_int 0))
2208                         (ne (symbol_ref "optimize_size")
2209                             (const_int 0)))
2210                    (const_string "V4SF")
2211                    (const_string "TI"))]
2212                (const_string "DI")))])
2213
2214 (define_split
2215   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2216         (match_operand:TI 1 "general_operand" ""))]
2217   "reload_completed && !SSE_REG_P (operands[0])
2218    && !SSE_REG_P (operands[1])"
2219   [(const_int 0)]
2220   "ix86_split_long_move (operands); DONE;")
2221
2222 (define_expand "movsf"
2223   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2224         (match_operand:SF 1 "general_operand" ""))]
2225   ""
2226   "ix86_expand_move (SFmode, operands); DONE;")
2227
2228 (define_insn "*pushsf"
2229   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2230         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2231   "!TARGET_64BIT"
2232 {
2233   /* Anything else should be already split before reg-stack.  */
2234   gcc_assert (which_alternative == 1);
2235   return "push{l}\t%1";
2236 }
2237   [(set_attr "type" "multi,push,multi")
2238    (set_attr "unit" "i387,*,*")
2239    (set_attr "mode" "SF,SI,SF")])
2240
2241 (define_insn "*pushsf_rex64"
2242   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2243         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2244   "TARGET_64BIT"
2245 {
2246   /* Anything else should be already split before reg-stack.  */
2247   gcc_assert (which_alternative == 1);
2248   return "push{q}\t%q1";
2249 }
2250   [(set_attr "type" "multi,push,multi")
2251    (set_attr "unit" "i387,*,*")
2252    (set_attr "mode" "SF,DI,SF")])
2253
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "memory_operand" ""))]
2257   "reload_completed
2258    && GET_CODE (operands[1]) == MEM
2259    && constant_pool_reference_p (operands[1])"
2260   [(set (match_dup 0)
2261         (match_dup 1))]
2262   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2263
2264
2265 ;; %%% Kill this when call knows how to work this out.
2266 (define_split
2267   [(set (match_operand:SF 0 "push_operand" "")
2268         (match_operand:SF 1 "any_fp_register_operand" ""))]
2269   "!TARGET_64BIT"
2270   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2271    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2272
2273 (define_split
2274   [(set (match_operand:SF 0 "push_operand" "")
2275         (match_operand:SF 1 "any_fp_register_operand" ""))]
2276   "TARGET_64BIT"
2277   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2278    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279
2280 (define_insn "*movsf_1"
2281   [(set (match_operand:SF 0 "nonimmediate_operand"
2282           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2283         (match_operand:SF 1 "general_operand"
2284           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2285   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       gcc_unreachable ();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
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,SI,DF")])
2406
2407 (define_insn "*pushdf_integer"
2408   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2409         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2410   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412   /* This insn should be already split before reg-stack.  */
2413   gcc_unreachable ();
2414 }
2415   [(set_attr "type" "multi")
2416    (set_attr "unit" "i387,*,*")
2417    (set_attr "mode" "DF,SI,DF")])
2418
2419 ;; %%% Kill this when call knows how to work this out.
2420 (define_split
2421   [(set (match_operand:DF 0 "push_operand" "")
2422         (match_operand:DF 1 "any_fp_register_operand" ""))]
2423   "!TARGET_64BIT && reload_completed"
2424   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2425    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2426   "")
2427
2428 (define_split
2429   [(set (match_operand:DF 0 "push_operand" "")
2430         (match_operand:DF 1 "any_fp_register_operand" ""))]
2431   "TARGET_64BIT && reload_completed"
2432   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2433    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2434   "")
2435
2436 (define_split
2437   [(set (match_operand:DF 0 "push_operand" "")
2438         (match_operand:DF 1 "general_operand" ""))]
2439   "reload_completed"
2440   [(const_int 0)]
2441   "ix86_split_long_move (operands); DONE;")
2442
2443 ;; Moving is usually shorter when only FP registers are used. This separate
2444 ;; movdf pattern avoids the use of integer registers for FP operations
2445 ;; when optimizing for size.
2446
2447 (define_insn "*movdf_nointeger"
2448   [(set (match_operand:DF 0 "nonimmediate_operand"
2449                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2450         (match_operand:DF 1 "general_operand"
2451                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2452   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2453    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2454    && (reload_in_progress || reload_completed
2455        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2456        || GET_CODE (operands[1]) != CONST_DOUBLE
2457        || memory_operand (operands[0], DFmode))" 
2458 {
2459   switch (which_alternative)
2460     {
2461     case 0:
2462       return output_387_reg_move (insn, operands);
2463
2464     case 1:
2465       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2466         return "fstp%z0\t%y0";
2467       else
2468         return "fst%z0\t%y0";
2469
2470     case 2:
2471       return standard_80387_constant_opcode (operands[1]);
2472
2473     case 3:
2474     case 4:
2475       return "#";
2476     case 5:
2477       switch (get_attr_mode (insn))
2478         {
2479         case MODE_V4SF:
2480           return "xorps\t%0, %0";
2481         case MODE_V2DF:
2482           return "xorpd\t%0, %0";
2483         case MODE_TI:
2484           return "pxor\t%0, %0";
2485         default:
2486           gcc_unreachable ();
2487         }
2488     case 6:
2489     case 7:
2490     case 8:
2491       switch (get_attr_mode (insn))
2492         {
2493         case MODE_V4SF:
2494           return "movaps\t{%1, %0|%0, %1}";
2495         case MODE_V2DF:
2496           return "movapd\t{%1, %0|%0, %1}";
2497         case MODE_TI:
2498           return "movdqa\t{%1, %0|%0, %1}";
2499         case MODE_DI:
2500           return "movq\t{%1, %0|%0, %1}";
2501         case MODE_DF:
2502           return "movsd\t{%1, %0|%0, %1}";
2503         case MODE_V1DF:
2504           return "movlpd\t{%1, %0|%0, %1}";
2505         case MODE_V2SF:
2506           return "movlps\t{%1, %0|%0, %1}";
2507         default:
2508           gcc_unreachable ();
2509         }
2510
2511     default:
2512       gcc_unreachable ();
2513     }
2514 }
2515   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2516    (set (attr "mode")
2517         (cond [(eq_attr "alternative" "0,1,2")
2518                  (const_string "DF")
2519                (eq_attr "alternative" "3,4")
2520                  (const_string "SI")
2521
2522                /* For SSE1, we have many fewer alternatives.  */
2523                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2524                  (cond [(eq_attr "alternative" "5,6")
2525                           (const_string "V4SF")
2526                        ]
2527                    (const_string "V2SF"))
2528
2529                /* xorps is one byte shorter.  */
2530                (eq_attr "alternative" "5")
2531                  (cond [(ne (symbol_ref "optimize_size")
2532                             (const_int 0))
2533                           (const_string "V4SF")
2534                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2535                             (const_int 0))
2536                           (const_string "TI")
2537                        ]
2538                        (const_string "V2DF"))
2539
2540                /* For architectures resolving dependencies on
2541                   whole SSE registers use APD move to break dependency
2542                   chains, otherwise use short move to avoid extra work.
2543
2544                   movaps encodes one byte shorter.  */
2545                (eq_attr "alternative" "6")
2546                  (cond
2547                    [(ne (symbol_ref "optimize_size")
2548                         (const_int 0))
2549                       (const_string "V4SF")
2550                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551                         (const_int 0))
2552                       (const_string "V2DF")
2553                    ]
2554                    (const_string "DF"))
2555                /* For architectures resolving dependencies on register
2556                   parts we may avoid extra work to zero out upper part
2557                   of register.  */
2558                (eq_attr "alternative" "7")
2559                  (if_then_else
2560                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2561                        (const_int 0))
2562                    (const_string "V1DF")
2563                    (const_string "DF"))
2564               ]
2565               (const_string "DF")))])
2566
2567 (define_insn "*movdf_integer"
2568   [(set (match_operand:DF 0 "nonimmediate_operand"
2569                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2570         (match_operand:DF 1 "general_operand"
2571                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2578 {
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       return output_387_reg_move (insn, operands);
2583
2584     case 1:
2585       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586         return "fstp%z0\t%y0";
2587       else
2588         return "fst%z0\t%y0";
2589
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2592
2593     case 3:
2594     case 4:
2595       return "#";
2596
2597     case 5:
2598       switch (get_attr_mode (insn))
2599         {
2600         case MODE_V4SF:
2601           return "xorps\t%0, %0";
2602         case MODE_V2DF:
2603           return "xorpd\t%0, %0";
2604         case MODE_TI:
2605           return "pxor\t%0, %0";
2606         default:
2607           gcc_unreachable ();
2608         }
2609     case 6:
2610     case 7:
2611     case 8:
2612       switch (get_attr_mode (insn))
2613         {
2614         case MODE_V4SF:
2615           return "movaps\t{%1, %0|%0, %1}";
2616         case MODE_V2DF:
2617           return "movapd\t{%1, %0|%0, %1}";
2618         case MODE_TI:
2619           return "movdqa\t{%1, %0|%0, %1}";
2620         case MODE_DI:
2621           return "movq\t{%1, %0|%0, %1}";
2622         case MODE_DF:
2623           return "movsd\t{%1, %0|%0, %1}";
2624         case MODE_V1DF:
2625           return "movlpd\t{%1, %0|%0, %1}";
2626         case MODE_V2SF:
2627           return "movlps\t{%1, %0|%0, %1}";
2628         default:
2629           gcc_unreachable ();
2630         }
2631
2632     default:
2633       gcc_unreachable();
2634     }
2635 }
2636   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2637    (set (attr "mode")
2638         (cond [(eq_attr "alternative" "0,1,2")
2639                  (const_string "DF")
2640                (eq_attr "alternative" "3,4")
2641                  (const_string "SI")
2642
2643                /* For SSE1, we have many fewer alternatives.  */
2644                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2645                  (cond [(eq_attr "alternative" "5,6")
2646                           (const_string "V4SF")
2647                        ]
2648                    (const_string "V2SF"))
2649
2650                /* xorps is one byte shorter.  */
2651                (eq_attr "alternative" "5")
2652                  (cond [(ne (symbol_ref "optimize_size")
2653                             (const_int 0))
2654                           (const_string "V4SF")
2655                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2656                             (const_int 0))
2657                           (const_string "TI")
2658                        ]
2659                        (const_string "V2DF"))
2660
2661                /* For architectures resolving dependencies on
2662                   whole SSE registers use APD move to break dependency
2663                   chains, otherwise use short move to avoid extra work.
2664
2665                   movaps encodes one byte shorter.  */
2666                (eq_attr "alternative" "6")
2667                  (cond
2668                    [(ne (symbol_ref "optimize_size")
2669                         (const_int 0))
2670                       (const_string "V4SF")
2671                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672                         (const_int 0))
2673                       (const_string "V2DF")
2674                    ]
2675                    (const_string "DF"))
2676                /* For architectures resolving dependencies on register
2677                   parts we may avoid extra work to zero out upper part
2678                   of register.  */
2679                (eq_attr "alternative" "7")
2680                  (if_then_else
2681                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682                        (const_int 0))
2683                    (const_string "V1DF")
2684                    (const_string "DF"))
2685               ]
2686               (const_string "DF")))])
2687
2688 (define_split
2689   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690         (match_operand:DF 1 "general_operand" ""))]
2691   "reload_completed
2692    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2693    && ! (ANY_FP_REG_P (operands[0]) || 
2694          (GET_CODE (operands[0]) == SUBREG
2695           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2696    && ! (ANY_FP_REG_P (operands[1]) || 
2697          (GET_CODE (operands[1]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2699   [(const_int 0)]
2700   "ix86_split_long_move (operands); DONE;")
2701
2702 (define_insn "*swapdf"
2703   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2704         (match_operand:DF 1 "fp_register_operand" "+f"))
2705    (set (match_dup 1)
2706         (match_dup 0))]
2707   "reload_completed || TARGET_80387"
2708 {
2709   if (STACK_TOP_P (operands[0]))
2710     return "fxch\t%1";
2711   else
2712     return "fxch\t%0";
2713 }
2714   [(set_attr "type" "fxch")
2715    (set_attr "mode" "DF")])
2716
2717 (define_expand "movxf"
2718   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2719         (match_operand:XF 1 "general_operand" ""))]
2720   ""
2721   "ix86_expand_move (XFmode, operands); DONE;")
2722
2723 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2724 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2725 ;; Pushing using integer instructions is longer except for constants
2726 ;; and direct memory references.
2727 ;; (assuming that any given constant is pushed only once, but this ought to be
2728 ;;  handled elsewhere).
2729
2730 (define_insn "*pushxf_nointeger"
2731   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2732         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
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,SI")])
2741
2742 (define_insn "*pushxf_integer"
2743   [(set (match_operand:XF 0 "push_operand" "=<,<")
2744         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2745   "!optimize_size"
2746 {
2747   /* This insn should be already split before reg-stack.  */
2748   gcc_unreachable ();
2749 }
2750   [(set_attr "type" "multi")
2751    (set_attr "unit" "i387,*")
2752    (set_attr "mode" "XF,SI")])
2753
2754 (define_split
2755   [(set (match_operand 0 "push_operand" "")
2756         (match_operand 1 "general_operand" ""))]
2757   "reload_completed
2758    && (GET_MODE (operands[0]) == XFmode
2759        || GET_MODE (operands[0]) == DFmode)
2760    && !ANY_FP_REG_P (operands[1])"
2761   [(const_int 0)]
2762   "ix86_split_long_move (operands); DONE;")
2763
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "!TARGET_64BIT"
2768   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2769    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 (define_split
2773   [(set (match_operand:XF 0 "push_operand" "")
2774         (match_operand:XF 1 "any_fp_register_operand" ""))]
2775   "TARGET_64BIT"
2776   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2777    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2778   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779
2780 ;; Do not use integer registers when optimizing for size
2781 (define_insn "*movxf_nointeger"
2782   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2783         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2784   "optimize_size
2785    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2786    && (reload_in_progress || reload_completed
2787        || GET_CODE (operands[1]) != CONST_DOUBLE
2788        || memory_operand (operands[0], XFmode))" 
2789 {
2790   switch (which_alternative)
2791     {
2792     case 0:
2793       return output_387_reg_move (insn, operands);
2794
2795     case 1:
2796       /* There is no non-popping store to memory for XFmode.  So if
2797          we need one, follow the store with a load.  */
2798       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799         return "fstp%z0\t%y0\;fld%z0\t%y0";
2800       else
2801         return "fstp%z0\t%y0";
2802
2803     case 2:
2804       return standard_80387_constant_opcode (operands[1]);
2805
2806     case 3: case 4:
2807       return "#";
2808     default:
2809       gcc_unreachable ();
2810     }
2811 }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813    (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2817         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2818   "!optimize_size
2819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820    && (reload_in_progress || reload_completed
2821        || GET_CODE (operands[1]) != CONST_DOUBLE
2822        || memory_operand (operands[0], XFmode))" 
2823 {
2824   switch (which_alternative)
2825     {
2826     case 0:
2827       return output_387_reg_move (insn, operands);
2828
2829     case 1:
2830       /* There is no non-popping store to memory for XFmode.  So if
2831          we need one, follow the store with a load.  */
2832       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833         return "fstp%z0\t%y0\;fld%z0\t%y0";
2834       else
2835         return "fstp%z0\t%y0";
2836
2837     case 2:
2838       return standard_80387_constant_opcode (operands[1]);
2839
2840     case 3: case 4:
2841       return "#";
2842
2843     default:
2844       gcc_unreachable ();
2845     }
2846 }
2847   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2848    (set_attr "mode" "XF,XF,XF,SI,SI")])
2849
2850 (define_split
2851   [(set (match_operand 0 "nonimmediate_operand" "")
2852         (match_operand 1 "general_operand" ""))]
2853   "reload_completed
2854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2855    && GET_MODE (operands[0]) == XFmode
2856    && ! (ANY_FP_REG_P (operands[0]) || 
2857          (GET_CODE (operands[0]) == SUBREG
2858           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2859    && ! (ANY_FP_REG_P (operands[1]) || 
2860          (GET_CODE (operands[1]) == SUBREG
2861           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2862   [(const_int 0)]
2863   "ix86_split_long_move (operands); DONE;")
2864
2865 (define_split
2866   [(set (match_operand 0 "register_operand" "")
2867         (match_operand 1 "memory_operand" ""))]
2868   "reload_completed
2869    && GET_CODE (operands[1]) == MEM
2870    && (GET_MODE (operands[0]) == XFmode
2871        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2872    && constant_pool_reference_p (operands[1])"
2873   [(set (match_dup 0) (match_dup 1))]
2874 {
2875   rtx c = avoid_constant_pool_reference (operands[1]);
2876   rtx r = operands[0];
2877
2878   if (GET_CODE (r) == SUBREG)
2879     r = SUBREG_REG (r);
2880
2881   if (SSE_REG_P (r))
2882     {
2883       if (!standard_sse_constant_p (c))
2884         FAIL;
2885     }
2886   else if (FP_REG_P (r))
2887     {
2888       if (!standard_80387_constant_p (c))
2889         FAIL;
2890     }
2891   else if (MMX_REG_P (r))
2892     FAIL;
2893
2894   operands[1] = c;
2895 })
2896
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   "TARGET_80387"
2903 {
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2908 }
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2911
2912 (define_expand "movtf"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914         (match_operand:TF 1 "nonimmediate_operand" ""))]
2915   "TARGET_64BIT"
2916 {
2917   ix86_expand_move (TFmode, operands);
2918   DONE;
2919 })
2920
2921 (define_insn "*movtf_internal"
2922   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2923         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2924   "TARGET_64BIT
2925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926 {
2927   switch (which_alternative)
2928     {
2929     case 0:
2930     case 1:
2931       return "#";
2932     case 2:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "xorps\t%0, %0";
2935       else
2936         return "pxor\t%0, %0";
2937     case 3:
2938     case 4:
2939       if (get_attr_mode (insn) == MODE_V4SF)
2940         return "movaps\t{%1, %0|%0, %1}";
2941       else
2942         return "movdqa\t{%1, %0|%0, %1}";
2943     default:
2944       gcc_unreachable ();
2945     }
2946 }
2947   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2948    (set (attr "mode")
2949         (cond [(eq_attr "alternative" "2,3")
2950                  (if_then_else
2951                    (ne (symbol_ref "optimize_size")
2952                        (const_int 0))
2953                    (const_string "V4SF")
2954                    (const_string "TI"))
2955                (eq_attr "alternative" "4")
2956                  (if_then_else
2957                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2958                             (const_int 0))
2959                         (ne (symbol_ref "optimize_size")
2960                             (const_int 0)))
2961                    (const_string "V4SF")
2962                    (const_string "TI"))]
2963                (const_string "DI")))])
2964
2965 (define_split
2966   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2967         (match_operand:TF 1 "general_operand" ""))]
2968   "reload_completed && !SSE_REG_P (operands[0])
2969    && !SSE_REG_P (operands[1])"
2970   [(const_int 0)]
2971   "ix86_split_long_move (operands); DONE;")
2972 \f
2973 ;; Zero extension instructions
2974
2975 (define_expand "zero_extendhisi2"
2976   [(set (match_operand:SI 0 "register_operand" "")
2977      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2978   ""
2979 {
2980   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2981     {
2982       operands[1] = force_reg (HImode, operands[1]);
2983       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2984       DONE;
2985     }
2986 })
2987
2988 (define_insn "zero_extendhisi2_and"
2989   [(set (match_operand:SI 0 "register_operand" "=r")
2990      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   "#"
2994   [(set_attr "type" "alu1")
2995    (set_attr "mode" "SI")])
2996
2997 (define_split
2998   [(set (match_operand:SI 0 "register_operand" "")
2999         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3000    (clobber (reg:CC FLAGS_REG))]
3001   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3002   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3003               (clobber (reg:CC FLAGS_REG))])]
3004   "")
3005
3006 (define_insn "*zero_extendhisi2_movzwl"
3007   [(set (match_operand:SI 0 "register_operand" "=r")
3008      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3009   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010   "movz{wl|x}\t{%1, %0|%0, %1}"
3011   [(set_attr "type" "imovx")
3012    (set_attr "mode" "SI")])
3013
3014 (define_expand "zero_extendqihi2"
3015   [(parallel
3016     [(set (match_operand:HI 0 "register_operand" "")
3017        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018      (clobber (reg:CC FLAGS_REG))])]
3019   ""
3020   "")
3021
3022 (define_insn "*zero_extendqihi2_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027   "#"
3028   [(set_attr "type" "alu1")
3029    (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw_and"
3032   [(set (match_operand:HI 0 "register_operand" "=r,r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3036   "#"
3037   [(set_attr "type" "imovx,alu1")
3038    (set_attr "mode" "HI")])
3039
3040 ; zero extend to SImode here to avoid partial register stalls
3041 (define_insn "*zero_extendqihi2_movzbl"
3042   [(set (match_operand:HI 0 "register_operand" "=r")
3043      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbw case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:HI 0 "register_operand" "")
3064         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3069    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3070   [(set (match_dup 0) (const_int 0))
3071    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072   "operands[2] = gen_lowpart (QImode, operands[0]);")
3073
3074 ;; Rest is handled by single and.
3075 (define_split
3076   [(set (match_operand:HI 0 "register_operand" "")
3077         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3078    (clobber (reg:CC FLAGS_REG))]
3079   "reload_completed
3080    && true_regnum (operands[0]) == true_regnum (operands[1])"
3081   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3082               (clobber (reg:CC FLAGS_REG))])]
3083   "")
3084
3085 (define_expand "zero_extendqisi2"
3086   [(parallel
3087     [(set (match_operand:SI 0 "register_operand" "")
3088        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3089      (clobber (reg:CC FLAGS_REG))])]
3090   ""
3091   "")
3092
3093 (define_insn "*zero_extendqisi2_and"
3094   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3095      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3096    (clobber (reg:CC FLAGS_REG))]
3097   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3098   "#"
3099   [(set_attr "type" "alu1")
3100    (set_attr "mode" "SI")])
3101
3102 (define_insn "*zero_extendqisi2_movzbw_and"
3103   [(set (match_operand:SI 0 "register_operand" "=r,r")
3104      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3105    (clobber (reg:CC FLAGS_REG))]
3106   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3107   "#"
3108   [(set_attr "type" "imovx,alu1")
3109    (set_attr "mode" "SI")])
3110
3111 (define_insn "*zero_extendqisi2_movzbw"
3112   [(set (match_operand:SI 0 "register_operand" "=r")
3113      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3114   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3115   "movz{bl|x}\t{%1, %0|%0, %1}"
3116   [(set_attr "type" "imovx")
3117    (set_attr "mode" "SI")])
3118
3119 ;; For the movzbl case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3126    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3127   [(set (match_dup 0)
3128         (zero_extend:SI (match_dup 1)))])
3129
3130 ;; When source and destination does not overlap, clear destination
3131 ;; first and then do the movb
3132 (define_split
3133   [(set (match_operand:SI 0 "register_operand" "")
3134         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3135    (clobber (reg:CC FLAGS_REG))]
3136   "reload_completed
3137    && ANY_QI_REG_P (operands[0])
3138    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3139    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3140    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3141   [(set (match_dup 0) (const_int 0))
3142    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3143   "operands[2] = gen_lowpart (QImode, operands[0]);")
3144
3145 ;; Rest is handled by single and.
3146 (define_split
3147   [(set (match_operand:SI 0 "register_operand" "")
3148         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3149    (clobber (reg:CC FLAGS_REG))]
3150   "reload_completed
3151    && true_regnum (operands[0]) == true_regnum (operands[1])"
3152   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3153               (clobber (reg:CC FLAGS_REG))])]
3154   "")
3155
3156 ;; %%% Kill me once multi-word ops are sane.
3157 (define_expand "zero_extendsidi2"
3158   [(set (match_operand:DI 0 "register_operand" "=r")
3159      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3160   ""
3161   "if (!TARGET_64BIT)
3162      {
3163        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3164        DONE;
3165      }
3166   ")
3167
3168 (define_insn "zero_extendsidi2_32"
3169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3170         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "!TARGET_64BIT"
3173   "@
3174    #
3175    #
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "mode" "SI,SI,SI,DI,TI")
3180    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3181
3182 (define_insn "zero_extendsidi2_rex64"
3183   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3184      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3185   "TARGET_64BIT"
3186   "@
3187    mov\t{%k1, %k0|%k0, %k1}
3188    #
3189    movd\t{%1, %0|%0, %1}
3190    movd\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3192    (set_attr "mode" "SI,DI,SI,SI")])
3193
3194 (define_split
3195   [(set (match_operand:DI 0 "memory_operand" "")
3196      (zero_extend:DI (match_dup 0)))]
3197   "TARGET_64BIT"
3198   [(set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_split 
3202   [(set (match_operand:DI 0 "register_operand" "")
3203         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "!TARGET_64BIT && reload_completed
3206    && true_regnum (operands[0]) == true_regnum (operands[1])"
3207   [(set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_split 
3211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3212         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3213    (clobber (reg:CC FLAGS_REG))]
3214   "!TARGET_64BIT && reload_completed
3215    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3216   [(set (match_dup 3) (match_dup 1))
3217    (set (match_dup 4) (const_int 0))]
3218   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3219
3220 (define_insn "zero_extendhidi2"
3221   [(set (match_operand:DI 0 "register_operand" "=r")
3222      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223   "TARGET_64BIT"
3224   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "DI")])
3227
3228 (define_insn "zero_extendqidi2"
3229   [(set (match_operand:DI 0 "register_operand" "=r")
3230      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3231   "TARGET_64BIT"
3232   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3233   [(set_attr "type" "imovx")
3234    (set_attr "mode" "DI")])
3235 \f
3236 ;; Sign extension instructions
3237
3238 (define_expand "extendsidi2"
3239   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3240                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3241               (clobber (reg:CC FLAGS_REG))
3242               (clobber (match_scratch:SI 2 ""))])]
3243   ""
3244 {
3245   if (TARGET_64BIT)
3246     {
3247       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3248       DONE;
3249     }
3250 })
3251
3252 (define_insn "*extendsidi2_1"
3253   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3254         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3255    (clobber (reg:CC FLAGS_REG))
3256    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3257   "!TARGET_64BIT"
3258   "#")
3259
3260 (define_insn "extendsidi2_rex64"
3261   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3262         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3263   "TARGET_64BIT"
3264   "@
3265    {cltq|cdqe}
3266    movs{lq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")
3269    (set_attr "prefix_0f" "0")
3270    (set_attr "modrm" "0,1")])
3271
3272 (define_insn "extendhidi2"
3273   [(set (match_operand:DI 0 "register_operand" "=r")
3274         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3275   "TARGET_64BIT"
3276   "movs{wq|x}\t{%1,%0|%0, %1}"
3277   [(set_attr "type" "imovx")
3278    (set_attr "mode" "DI")])
3279
3280 (define_insn "extendqidi2"
3281   [(set (match_operand:DI 0 "register_operand" "=r")
3282         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3283   "TARGET_64BIT"
3284   "movs{bq|x}\t{%1,%0|%0, %1}"
3285    [(set_attr "type" "imovx")
3286     (set_attr "mode" "DI")])
3287
3288 ;; Extend to memory case when source register does die.
3289 (define_split 
3290   [(set (match_operand:DI 0 "memory_operand" "")
3291         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3292    (clobber (reg:CC FLAGS_REG))
3293    (clobber (match_operand:SI 2 "register_operand" ""))]
3294   "(reload_completed
3295     && dead_or_set_p (insn, operands[1])
3296     && !reg_mentioned_p (operands[1], operands[0]))"
3297   [(set (match_dup 3) (match_dup 1))
3298    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3299               (clobber (reg:CC FLAGS_REG))])
3300    (set (match_dup 4) (match_dup 1))]
3301   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302
3303 ;; Extend to memory case when source register does not die.
3304 (define_split 
3305   [(set (match_operand:DI 0 "memory_operand" "")
3306         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307    (clobber (reg:CC FLAGS_REG))
3308    (clobber (match_operand:SI 2 "register_operand" ""))]
3309   "reload_completed"
3310   [(const_int 0)]
3311 {
3312   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313
3314   emit_move_insn (operands[3], operands[1]);
3315
3316   /* Generate a cltd if possible and doing so it profitable.  */
3317   if (true_regnum (operands[1]) == 0
3318       && true_regnum (operands[2]) == 1
3319       && (optimize_size || TARGET_USE_CLTD))
3320     {
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3322     }
3323   else
3324     {
3325       emit_move_insn (operands[2], operands[1]);
3326       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3327     }
3328   emit_move_insn (operands[4], operands[2]);
3329   DONE;
3330 })
3331
3332 ;; Extend to register case.  Optimize case where source and destination
3333 ;; registers match and cases where we can use cltd.
3334 (define_split 
3335   [(set (match_operand:DI 0 "register_operand" "")
3336         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337    (clobber (reg:CC FLAGS_REG))
3338    (clobber (match_scratch:SI 2 ""))]
3339   "reload_completed"
3340   [(const_int 0)]
3341 {
3342   split_di (&operands[0], 1, &operands[3], &operands[4]);
3343
3344   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3345     emit_move_insn (operands[3], operands[1]);
3346
3347   /* Generate a cltd if possible and doing so it profitable.  */
3348   if (true_regnum (operands[3]) == 0
3349       && (optimize_size || TARGET_USE_CLTD))
3350     {
3351       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3352       DONE;
3353     }
3354
3355   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3356     emit_move_insn (operands[4], operands[1]);
3357
3358   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3359   DONE;
3360 })
3361
3362 (define_insn "extendhisi2"
3363   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3364         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3365   ""
3366 {
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cwtl|cwde}";
3371     default:
3372       return "movs{wl|x}\t{%1,%0|%0, %1}";
3373     }
3374 }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "SI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3387
3388 (define_insn "*extendhisi2_zext"
3389   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3390         (zero_extend:DI
3391           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3392   "TARGET_64BIT"
3393 {
3394   switch (get_attr_prefix_0f (insn))
3395     {
3396     case 0:
3397       return "{cwtl|cwde}";
3398     default:
3399       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3400     }
3401 }
3402   [(set_attr "type" "imovx")
3403    (set_attr "mode" "SI")
3404    (set (attr "prefix_0f")
3405      ;; movsx is short decodable while cwtl is vector decoded.
3406      (if_then_else (and (eq_attr "cpu" "!k6")
3407                         (eq_attr "alternative" "0"))
3408         (const_string "0")
3409         (const_string "1")))
3410    (set (attr "modrm")
3411      (if_then_else (eq_attr "prefix_0f" "0")
3412         (const_string "0")
3413         (const_string "1")))])
3414
3415 (define_insn "extendqihi2"
3416   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3417         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3418   ""
3419 {
3420   switch (get_attr_prefix_0f (insn))
3421     {
3422     case 0:
3423       return "{cbtw|cbw}";
3424     default:
3425       return "movs{bw|x}\t{%1,%0|%0, %1}";
3426     }
3427 }
3428   [(set_attr "type" "imovx")
3429    (set_attr "mode" "HI")
3430    (set (attr "prefix_0f")
3431      ;; movsx is short decodable while cwtl is vector decoded.
3432      (if_then_else (and (eq_attr "cpu" "!k6")
3433                         (eq_attr "alternative" "0"))
3434         (const_string "0")
3435         (const_string "1")))
3436    (set (attr "modrm")
3437      (if_then_else (eq_attr "prefix_0f" "0")
3438         (const_string "0")
3439         (const_string "1")))])
3440
3441 (define_insn "extendqisi2"
3442   [(set (match_operand:SI 0 "register_operand" "=r")
3443         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444   ""
3445   "movs{bl|x}\t{%1,%0|%0, %1}"
3446    [(set_attr "type" "imovx")
3447     (set_attr "mode" "SI")])
3448
3449 (define_insn "*extendqisi2_zext"
3450   [(set (match_operand:DI 0 "register_operand" "=r")
3451         (zero_extend:DI
3452           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3453   "TARGET_64BIT"
3454   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3455    [(set_attr "type" "imovx")
3456     (set_attr "mode" "SI")])
3457 \f
3458 ;; Conversions between float and double.
3459
3460 ;; These are all no-ops in the model used for the 80387.  So just
3461 ;; emit moves.
3462
3463 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3464 (define_insn "*dummy_extendsfdf2"
3465   [(set (match_operand:DF 0 "push_operand" "=<")
3466         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3467   "0"
3468   "#")
3469
3470 (define_split
3471   [(set (match_operand:DF 0 "push_operand" "")
3472         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3473   "!TARGET_64BIT"
3474   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3475    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3476
3477 (define_split
3478   [(set (match_operand:DF 0 "push_operand" "")
3479         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3480   "TARGET_64BIT"
3481   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3482    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3483
3484 (define_insn "*dummy_extendsfxf2"
3485   [(set (match_operand:XF 0 "push_operand" "=<")
3486         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3487   "0"
3488   "#")
3489
3490 (define_split
3491   [(set (match_operand:XF 0 "push_operand" "")
3492         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3493   ""
3494   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3495    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3496   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_split
3499   [(set (match_operand:XF 0 "push_operand" "")
3500         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3501   "TARGET_64BIT"
3502   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3503    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3504   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505
3506 (define_split
3507   [(set (match_operand:XF 0 "push_operand" "")
3508         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3509   ""
3510   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3511    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3512   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513
3514 (define_split
3515   [(set (match_operand:XF 0 "push_operand" "")
3516         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3517   "TARGET_64BIT"
3518   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3519    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3520   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521
3522 (define_expand "extendsfdf2"
3523   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3524         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3525   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526 {
3527   /* ??? Needed for compress_float_constant since all fp constants
3528      are LEGITIMATE_CONSTANT_P.  */
3529   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3531   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3532     operands[1] = force_reg (SFmode, operands[1]);
3533 })
3534
3535 (define_insn "*extendsfdf2_mixed"
3536   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3537         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3538   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3539    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540 {
3541   switch (which_alternative)
3542     {
3543     case 0:
3544       return output_387_reg_move (insn, operands);
3545
3546     case 1:
3547       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3548         return "fstp%z0\t%y0";
3549       else
3550         return "fst%z0\t%y0";
3551
3552     case 2:
3553       return "cvtss2sd\t{%1, %0|%0, %1}";
3554
3555     default:
3556       gcc_unreachable ();
3557     }
3558 }
3559   [(set_attr "type" "fmov,fmov,ssecvt")
3560    (set_attr "mode" "SF,XF,DF")])
3561
3562 (define_insn "*extendsfdf2_sse"
3563   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3564         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3565   "TARGET_SSE2 && TARGET_SSE_MATH
3566    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567   "cvtss2sd\t{%1, %0|%0, %1}"
3568   [(set_attr "type" "ssecvt")
3569    (set_attr "mode" "DF")])
3570
3571 (define_insn "*extendsfdf2_i387"
3572   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3573         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3574   "TARGET_80387
3575    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3576 {
3577   switch (which_alternative)
3578     {
3579     case 0:
3580       return output_387_reg_move (insn, operands);
3581
3582     case 1:
3583       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584         return "fstp%z0\t%y0";
3585       else
3586         return "fst%z0\t%y0";
3587
3588     default:
3589       gcc_unreachable ();
3590     }
3591 }
3592   [(set_attr "type" "fmov")
3593    (set_attr "mode" "SF,XF")])
3594
3595 (define_expand "extendsfxf2"
3596   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3597         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3598   "TARGET_80387"
3599 {
3600   /* ??? Needed for compress_float_constant since all fp constants
3601      are LEGITIMATE_CONSTANT_P.  */
3602   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3603     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3604   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3605     operands[1] = force_reg (SFmode, operands[1]);
3606 })
3607
3608 (define_insn "*extendsfxf2_i387"
3609   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3610         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3611   "TARGET_80387
3612    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3613 {
3614   switch (which_alternative)
3615     {
3616     case 0:
3617       return output_387_reg_move (insn, operands);
3618
3619     case 1:
3620       /* There is no non-popping store to memory for XFmode.  So if
3621          we need one, follow the store with a load.  */
3622       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3623         return "fstp%z0\t%y0";
3624       else
3625         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3626
3627     default:
3628       gcc_unreachable ();
3629     }
3630 }
3631   [(set_attr "type" "fmov")
3632    (set_attr "mode" "SF,XF")])
3633
3634 (define_expand "extenddfxf2"
3635   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3636         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3637   "TARGET_80387"
3638 {
3639   /* ??? Needed for compress_float_constant since all fp constants
3640      are LEGITIMATE_CONSTANT_P.  */
3641   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3642     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3643   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3644     operands[1] = force_reg (DFmode, operands[1]);
3645 })
3646
3647 (define_insn "*extenddfxf2_i387"
3648   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3649         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3650   "TARGET_80387
3651    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3652 {
3653   switch (which_alternative)
3654     {
3655     case 0:
3656       return output_387_reg_move (insn, operands);
3657
3658     case 1:
3659       /* There is no non-popping store to memory for XFmode.  So if
3660          we need one, follow the store with a load.  */
3661       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3662         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3663       else
3664         return "fstp%z0\t%y0";
3665
3666     default:
3667       gcc_unreachable ();
3668     }
3669 }
3670   [(set_attr "type" "fmov")
3671    (set_attr "mode" "DF,XF")])
3672
3673 ;; %%% This seems bad bad news.
3674 ;; This cannot output into an f-reg because there is no way to be sure
3675 ;; of truncating in that case.  Otherwise this is just like a simple move
3676 ;; insn.  So we pretend we can output to a reg in order to get better
3677 ;; register preferencing, but we really use a stack slot.
3678
3679 ;; Conversion from DFmode to SFmode.
3680
3681 (define_expand "truncdfsf2"
3682   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3683         (float_truncate:SF
3684           (match_operand:DF 1 "nonimmediate_operand" "")))]
3685   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3686 {
3687   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3688     operands[1] = force_reg (DFmode, operands[1]);
3689
3690   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3691     ;
3692   else if (flag_unsafe_math_optimizations)
3693     ;
3694   else
3695     {
3696       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3697       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3698       DONE;
3699     }
3700 })
3701
3702 (define_expand "truncdfsf2_with_temp"
3703   [(parallel [(set (match_operand:SF 0 "" "")
3704                    (float_truncate:SF (match_operand:DF 1 "" "")))
3705               (clobber (match_operand:SF 2 "" ""))])]
3706   "")
3707
3708 (define_insn "*truncdfsf_fast_mixed"
3709   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3710         (float_truncate:SF
3711           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3712   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3713 {
3714   switch (which_alternative)
3715     {
3716     case 0:
3717       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3718         return "fstp%z0\t%y0";
3719       else
3720         return "fst%z0\t%y0";
3721     case 1:
3722       return output_387_reg_move (insn, operands);
3723     case 2:
3724       return "cvtsd2ss\t{%1, %0|%0, %1}";
3725     default:
3726       gcc_unreachable ();
3727     }
3728 }
3729   [(set_attr "type" "fmov,fmov,ssecvt")
3730    (set_attr "mode" "SF")])
3731
3732 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3733 ;; because nothing we do here is unsafe.
3734 (define_insn "*truncdfsf_fast_sse"
3735   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3736         (float_truncate:SF
3737           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3738   "TARGET_SSE2 && TARGET_SSE_MATH"
3739   "cvtsd2ss\t{%1, %0|%0, %1}"
3740   [(set_attr "type" "ssecvt")
3741    (set_attr "mode" "SF")])
3742
3743 (define_insn "*truncdfsf_fast_i387"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3747   "TARGET_80387 && flag_unsafe_math_optimizations"
3748   "* return output_387_reg_move (insn, operands);"
3749   [(set_attr "type" "fmov")
3750    (set_attr "mode" "SF")])
3751
3752 (define_insn "*truncdfsf_mixed"
3753   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3754         (float_truncate:SF
3755           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3756    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3757   "TARGET_MIX_SSE_I387"
3758 {
3759   switch (which_alternative)
3760     {
3761     case 0:
3762       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3763         return "fstp%z0\t%y0";
3764       else
3765         return "fst%z0\t%y0";
3766     case 1:
3767       return "#";
3768     case 2:
3769       return "cvtsd2ss\t{%1, %0|%0, %1}";
3770     default:
3771       gcc_unreachable ();
3772     }
3773 }
3774   [(set_attr "type" "fmov,multi,ssecvt")
3775    (set_attr "unit" "*,i387,*")
3776    (set_attr "mode" "SF")])
3777
3778 (define_insn "*truncdfsf_i387"
3779   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3780         (float_truncate:SF
3781           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3782    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3783   "TARGET_80387"
3784 {
3785   switch (which_alternative)
3786     {
3787     case 0:
3788       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789         return "fstp%z0\t%y0";
3790       else
3791         return "fst%z0\t%y0";
3792     case 1:
3793       return "#";
3794     default:
3795       gcc_unreachable ();
3796     }
3797 }
3798   [(set_attr "type" "fmov,multi")
3799    (set_attr "unit" "*,i387")
3800    (set_attr "mode" "SF")])
3801
3802 (define_insn "*truncdfsf2_i387_1"
3803   [(set (match_operand:SF 0 "memory_operand" "=m")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "register_operand" "f")))]
3806   "TARGET_80387
3807    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3808    && !TARGET_MIX_SSE_I387"
3809 {
3810   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811     return "fstp%z0\t%y0";
3812   else
3813     return "fst%z0\t%y0";
3814 }
3815   [(set_attr "type" "fmov")
3816    (set_attr "mode" "SF")])
3817
3818 (define_split
3819   [(set (match_operand:SF 0 "register_operand" "")
3820         (float_truncate:SF
3821          (match_operand:DF 1 "fp_register_operand" "")))
3822    (clobber (match_operand 2 "" ""))]
3823   "reload_completed"
3824   [(set (match_dup 2) (match_dup 1))
3825    (set (match_dup 0) (match_dup 2))]
3826 {
3827   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3828 })
3829
3830 ;; Conversion from XFmode to SFmode.
3831
3832 (define_expand "truncxfsf2"
3833   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3834                    (float_truncate:SF
3835                     (match_operand:XF 1 "register_operand" "")))
3836               (clobber (match_dup 2))])]
3837   "TARGET_80387"
3838 {
3839   if (flag_unsafe_math_optimizations)
3840     {
3841       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3842       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3843       if (reg != operands[0])
3844         emit_move_insn (operands[0], reg);
3845       DONE;
3846     }
3847   else
3848     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3849 })
3850
3851 (define_insn "*truncxfsf2_mixed"
3852   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3853         (float_truncate:SF
3854          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3855    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3856   "TARGET_MIX_SSE_I387"
3857 {
3858   gcc_assert (!which_alternative);
3859   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3860     return "fstp%z0\t%y0";
3861   else
3862     return "fst%z0\t%y0";
3863 }
3864   [(set_attr "type" "fmov,multi,multi,multi")
3865    (set_attr "unit" "*,i387,i387,i387")
3866    (set_attr "mode" "SF")])
3867
3868 (define_insn "truncxfsf2_i387_noop"
3869   [(set (match_operand:SF 0 "register_operand" "=f")
3870         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3871   "TARGET_80387 && flag_unsafe_math_optimizations"
3872 {
3873   return output_387_reg_move (insn, operands);
3874 }
3875   [(set_attr "type" "fmov")
3876    (set_attr "mode" "SF")])
3877
3878 (define_insn "*truncxfsf2_i387"
3879   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3880         (float_truncate:SF
3881          (match_operand:XF 1 "register_operand" "f,f,f")))
3882    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3883   "TARGET_80387"
3884 {
3885   gcc_assert (!which_alternative);
3886   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3887     return "fstp%z0\t%y0";
3888    else
3889      return "fst%z0\t%y0";
3890 }
3891   [(set_attr "type" "fmov,multi,multi")
3892    (set_attr "unit" "*,i387,i387")
3893    (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncxfsf2_i387_1"
3896   [(set (match_operand:SF 0 "memory_operand" "=m")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "f")))]
3899   "TARGET_80387"
3900 {
3901   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3902     return "fstp%z0\t%y0";
3903   else
3904     return "fst%z0\t%y0";
3905 }
3906   [(set_attr "type" "fmov")
3907    (set_attr "mode" "SF")])
3908
3909 (define_split
3910   [(set (match_operand:SF 0 "register_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387 && reload_completed"
3915   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3916    (set (match_dup 0) (match_dup 2))]
3917   "")
3918
3919 (define_split
3920   [(set (match_operand:SF 0 "memory_operand" "")
3921         (float_truncate:SF
3922          (match_operand:XF 1 "register_operand" "")))
3923    (clobber (match_operand:SF 2 "memory_operand" ""))]
3924   "TARGET_80387"
3925   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3926   "")
3927
3928 ;; Conversion from XFmode to DFmode.
3929
3930 (define_expand "truncxfdf2"
3931   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932                    (float_truncate:DF
3933                     (match_operand:XF 1 "register_operand" "")))
3934               (clobber (match_dup 2))])]
3935   "TARGET_80387"
3936 {
3937   if (flag_unsafe_math_optimizations)
3938     {
3939       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3940       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3941       if (reg != operands[0])
3942         emit_move_insn (operands[0], reg);
3943       DONE;
3944     }
3945   else
3946     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3947 })
3948
3949 (define_insn "*truncxfdf2_mixed"
3950   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3951         (float_truncate:DF
3952          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3953    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3954   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3955 {
3956   gcc_assert (!which_alternative);
3957   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3958     return "fstp%z0\t%y0";
3959   else
3960     return "fst%z0\t%y0";
3961 }
3962   [(set_attr "type" "fmov,multi,multi,multi")
3963    (set_attr "unit" "*,i387,i387,i387")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "truncxfdf2_i387_noop"
3967   [(set (match_operand:DF 0 "register_operand" "=f")
3968         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3969   "TARGET_80387 && flag_unsafe_math_optimizations"
3970 {
3971   return output_387_reg_move (insn, operands);
3972 }
3973   [(set_attr "type" "fmov")
3974    (set_attr "mode" "DF")])
3975
3976 (define_insn "*truncxfdf2_i387"
3977   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "f,f,f")))
3980    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3981   "TARGET_80387"
3982 {
3983   gcc_assert (!which_alternative);
3984   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3985     return "fstp%z0\t%y0";
3986   else
3987     return "fst%z0\t%y0";
3988 }
3989   [(set_attr "type" "fmov,multi,multi")
3990    (set_attr "unit" "*,i387,i387")
3991    (set_attr "mode" "DF")])
3992
3993 (define_insn "*truncxfdf2_i387_1"
3994   [(set (match_operand:DF 0 "memory_operand" "=m")
3995         (float_truncate:DF
3996           (match_operand:XF 1 "register_operand" "f")))]
3997   "TARGET_80387"
3998 {
3999   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4000     return "fstp%z0\t%y0";
4001   else
4002     return "fst%z0\t%y0";
4003 }
4004   [(set_attr "type" "fmov")
4005    (set_attr "mode" "DF")])
4006
4007 (define_split
4008   [(set (match_operand:DF 0 "register_operand" "")
4009         (float_truncate:DF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:DF 2 "memory_operand" ""))]
4012   "TARGET_80387 && reload_completed"
4013   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4014    (set (match_dup 0) (match_dup 2))]
4015   "")
4016
4017 (define_split
4018   [(set (match_operand:DF 0 "memory_operand" "")
4019         (float_truncate:DF
4020          (match_operand:XF 1 "register_operand" "")))
4021    (clobber (match_operand:DF 2 "memory_operand" ""))]
4022   "TARGET_80387"
4023   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4024   "")
4025 \f
4026 ;; Signed conversion to DImode.
4027
4028 (define_expand "fix_truncxfdi2"
4029   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4030                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4031               (clobber (reg:CC FLAGS_REG))])]
4032   "TARGET_80387"
4033 {
4034   if (TARGET_FISTTP)
4035    {
4036      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4037      DONE;
4038    }
4039 })
4040
4041 (define_expand "fix_trunc<mode>di2"
4042   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4043                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4044               (clobber (reg:CC FLAGS_REG))])]
4045   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4046 {
4047   if (TARGET_FISTTP
4048       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4049    {
4050      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4051      DONE;
4052    }
4053   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4054    {
4055      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4056      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4057      if (out != operands[0])
4058         emit_move_insn (operands[0], out);
4059      DONE;
4060    }
4061 })
4062
4063 ;; Signed conversion to SImode.
4064
4065 (define_expand "fix_truncxfsi2"
4066   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4067                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4068               (clobber (reg:CC FLAGS_REG))])]
4069   "TARGET_80387"
4070 {
4071   if (TARGET_FISTTP)
4072    {
4073      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4074      DONE;
4075    }
4076 })
4077
4078 (define_expand "fix_trunc<mode>si2"
4079   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4080                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4083 {
4084   if (TARGET_FISTTP
4085       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4086    {
4087      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4088      DONE;
4089    }
4090   if (SSE_FLOAT_MODE_P (<MODE>mode))
4091    {
4092      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4093      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4094      if (out != operands[0])
4095         emit_move_insn (operands[0], out);
4096      DONE;
4097    }
4098 })
4099
4100 ;; Signed conversion to HImode.
4101
4102 (define_expand "fix_trunc<mode>hi2"
4103   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4104                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4105               (clobber (reg:CC FLAGS_REG))])]
4106   "TARGET_80387
4107    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4108 {
4109   if (TARGET_FISTTP)
4110    {
4111      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4112      DONE;
4113    }
4114 })
4115
4116 ;; When SSE is available, it is always faster to use it!
4117 (define_insn "fix_truncsfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4120   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4121   "cvttss2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "SF")
4124    (set_attr "athlon_decode" "double,vector")])
4125
4126 (define_insn "fix_truncdfdi_sse"
4127   [(set (match_operand:DI 0 "register_operand" "=r,r")
4128         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4129   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "DF")
4133    (set_attr "athlon_decode" "double,vector")])
4134
4135 (define_insn "fix_truncsfsi_sse"
4136   [(set (match_operand:SI 0 "register_operand" "=r,r")
4137         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4138   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttss2si\t{%1, %0|%0, %1}"
4140   [(set_attr "type" "sseicvt")
4141    (set_attr "mode" "DF")
4142    (set_attr "athlon_decode" "double,vector")])
4143
4144 (define_insn "fix_truncdfsi_sse"
4145   [(set (match_operand:SI 0 "register_operand" "=r,r")
4146         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4147   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4148   "cvttsd2si\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "sseicvt")
4150    (set_attr "mode" "DF")
4151    (set_attr "athlon_decode" "double,vector")])
4152
4153 ;; Avoid vector decoded forms of the instruction.
4154 (define_peephole2
4155   [(match_scratch:DF 2 "Y")
4156    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4157         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4158   "TARGET_K8 && !optimize_size"
4159   [(set (match_dup 2) (match_dup 1))
4160    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4161   "")
4162
4163 (define_peephole2
4164   [(match_scratch:SF 2 "x")
4165    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4166         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4167   "TARGET_K8 && !optimize_size"
4168   [(set (match_dup 2) (match_dup 1))
4169    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4170   "")
4171
4172 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4173   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4174         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4175   "TARGET_FISTTP
4176    && FLOAT_MODE_P (GET_MODE (operands[1]))
4177    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4178          && (TARGET_64BIT || <MODE>mode != DImode))
4179         && TARGET_SSE_MATH)
4180    && !(reload_completed || reload_in_progress)"
4181   "#"
4182   "&& 1"
4183   [(const_int 0)]
4184 {
4185   if (memory_operand (operands[0], VOIDmode))
4186     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4187   else
4188     {
4189       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4190       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4191                                                             operands[1],
4192                                                             operands[2]));
4193     }
4194   DONE;
4195 }
4196   [(set_attr "type" "fisttp")
4197    (set_attr "mode" "<MODE>")])
4198
4199 (define_insn "fix_trunc<mode>_i387_fisttp"
4200   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4201         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4202    (clobber (match_scratch:XF 2 "=&1f"))]
4203   "TARGET_FISTTP
4204    && FLOAT_MODE_P (GET_MODE (operands[1]))
4205    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4206          && (TARGET_64BIT || <MODE>mode != DImode))
4207         && TARGET_SSE_MATH)"
4208   "* return output_fix_trunc (insn, operands, 1);"
4209   [(set_attr "type" "fisttp")
4210    (set_attr "mode" "<MODE>")])
4211
4212 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4213   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4214         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4215    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4216    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4217   "TARGET_FISTTP
4218    && FLOAT_MODE_P (GET_MODE (operands[1]))
4219    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4220         && (TARGET_64BIT || <MODE>mode != DImode))
4221         && TARGET_SSE_MATH)"
4222   "#"
4223   [(set_attr "type" "fisttp")
4224    (set_attr "mode" "<MODE>")])
4225
4226 (define_split
4227   [(set (match_operand:X87MODEI 0 "register_operand" "")
4228         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4229    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4230    (clobber (match_scratch 3 ""))]
4231   "reload_completed"
4232   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4233               (clobber (match_dup 3))])
4234    (set (match_dup 0) (match_dup 2))]
4235   "")
4236
4237 (define_split
4238   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4239         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4240    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4241    (clobber (match_scratch 3 ""))]
4242   "reload_completed"
4243   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4244               (clobber (match_dup 3))])]
4245   "")
4246
4247 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4248 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4249 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4250 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4251 ;; function in i386.c.
4252 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4253   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4254         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4255    (clobber (reg:CC FLAGS_REG))]
4256   "TARGET_80387 && !TARGET_FISTTP
4257    && FLOAT_MODE_P (GET_MODE (operands[1]))
4258    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4259          && (TARGET_64BIT || <MODE>mode != DImode))
4260    && !(reload_completed || reload_in_progress)"
4261   "#"
4262   "&& 1"
4263   [(const_int 0)]
4264 {
4265   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4266
4267   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4268   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4269   if (memory_operand (operands[0], VOIDmode))
4270     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4271                                          operands[2], operands[3]));
4272   else
4273     {
4274       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4275       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4276                                                      operands[2], operands[3],
4277                                                      operands[4]));
4278     }
4279   DONE;
4280 }
4281   [(set_attr "type" "fistp")
4282    (set_attr "i387_cw" "trunc")
4283    (set_attr "mode" "<MODE>")])
4284
4285 (define_insn "fix_truncdi_i387"
4286   [(set (match_operand:DI 0 "memory_operand" "=m")
4287         (fix:DI (match_operand 1 "register_operand" "f")))
4288    (use (match_operand:HI 2 "memory_operand" "m"))
4289    (use (match_operand:HI 3 "memory_operand" "m"))
4290    (clobber (match_scratch:XF 4 "=&1f"))]
4291   "TARGET_80387 && !TARGET_FISTTP
4292    && FLOAT_MODE_P (GET_MODE (operands[1]))
4293    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4294   "* return output_fix_trunc (insn, operands, 0);"
4295   [(set_attr "type" "fistp")
4296    (set_attr "i387_cw" "trunc")
4297    (set_attr "mode" "DI")])
4298
4299 (define_insn "fix_truncdi_i387_with_temp"
4300   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4301         (fix:DI (match_operand 1 "register_operand" "f,f")))
4302    (use (match_operand:HI 2 "memory_operand" "m,m"))
4303    (use (match_operand:HI 3 "memory_operand" "m,m"))
4304    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4305    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4306   "TARGET_80387 && !TARGET_FISTTP
4307    && FLOAT_MODE_P (GET_MODE (operands[1]))
4308    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4309   "#"
4310   [(set_attr "type" "fistp")
4311    (set_attr "i387_cw" "trunc")
4312    (set_attr "mode" "DI")])
4313
4314 (define_split 
4315   [(set (match_operand:DI 0 "register_operand" "")
4316         (fix:DI (match_operand 1 "register_operand" "")))
4317    (use (match_operand:HI 2 "memory_operand" ""))
4318    (use (match_operand:HI 3 "memory_operand" ""))
4319    (clobber (match_operand:DI 4 "memory_operand" ""))
4320    (clobber (match_scratch 5 ""))]
4321   "reload_completed"
4322   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4323               (use (match_dup 2))
4324               (use (match_dup 3))
4325               (clobber (match_dup 5))])
4326    (set (match_dup 0) (match_dup 4))]
4327   "")
4328
4329 (define_split 
4330   [(set (match_operand:DI 0 "memory_operand" "")
4331         (fix:DI (match_operand 1 "register_operand" "")))
4332    (use (match_operand:HI 2 "memory_operand" ""))
4333    (use (match_operand:HI 3 "memory_operand" ""))
4334    (clobber (match_operand:DI 4 "memory_operand" ""))
4335    (clobber (match_scratch 5 ""))]
4336   "reload_completed"
4337   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4338               (use (match_dup 2))
4339               (use (match_dup 3))
4340               (clobber (match_dup 5))])]
4341   "")
4342
4343 (define_insn "fix_trunc<mode>_i387"
4344   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4345         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4346    (use (match_operand:HI 2 "memory_operand" "m"))
4347    (use (match_operand:HI 3 "memory_operand" "m"))]
4348   "TARGET_80387 && !TARGET_FISTTP
4349    && FLOAT_MODE_P (GET_MODE (operands[1]))
4350    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4351   "* return output_fix_trunc (insn, operands, 0);"
4352   [(set_attr "type" "fistp")
4353    (set_attr "i387_cw" "trunc")
4354    (set_attr "mode" "<MODE>")])
4355
4356 (define_insn "fix_trunc<mode>_i387_with_temp"
4357   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4358         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4359    (use (match_operand:HI 2 "memory_operand" "m,m"))
4360    (use (match_operand:HI 3 "memory_operand" "m,m"))
4361    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4362   "TARGET_80387 && !TARGET_FISTTP
4363    && FLOAT_MODE_P (GET_MODE (operands[1]))
4364    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4365   "#"
4366   [(set_attr "type" "fistp")
4367    (set_attr "i387_cw" "trunc")
4368    (set_attr "mode" "<MODE>")])
4369
4370 (define_split 
4371   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4372         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4373    (use (match_operand:HI 2 "memory_operand" ""))
4374    (use (match_operand:HI 3 "memory_operand" ""))
4375    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4376   "reload_completed"
4377   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4378               (use (match_dup 2))
4379               (use (match_dup 3))])
4380    (set (match_dup 0) (match_dup 4))]
4381   "")
4382
4383 (define_split 
4384   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4385         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4386    (use (match_operand:HI 2 "memory_operand" ""))
4387    (use (match_operand:HI 3 "memory_operand" ""))
4388    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4389   "reload_completed"
4390   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4391               (use (match_dup 2))
4392               (use (match_dup 3))])]
4393   "")
4394
4395 (define_insn "x86_fnstcw_1"
4396   [(set (match_operand:HI 0 "memory_operand" "=m")
4397         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4398   "TARGET_80387"
4399   "fnstcw\t%0"
4400   [(set_attr "length" "2")
4401    (set_attr "mode" "HI")
4402    (set_attr "unit" "i387")])
4403
4404 (define_insn "x86_fldcw_1"
4405   [(set (reg:HI FPSR_REG)
4406         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4407   "TARGET_80387"
4408   "fldcw\t%0"
4409   [(set_attr "length" "2")
4410    (set_attr "mode" "HI")
4411    (set_attr "unit" "i387")
4412    (set_attr "athlon_decode" "vector")])
4413 \f
4414 ;; Conversion between fixed point and floating point.
4415
4416 ;; Even though we only accept memory inputs, the backend _really_
4417 ;; wants to be able to do this between registers.
4418
4419 (define_expand "floathisf2"
4420   [(set (match_operand:SF 0 "register_operand" "")
4421         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4422   "TARGET_80387 || TARGET_SSE_MATH"
4423 {
4424   if (TARGET_SSE_MATH)
4425     {
4426       emit_insn (gen_floatsisf2 (operands[0],
4427                                  convert_to_mode (SImode, operands[1], 0)));
4428       DONE;
4429     }
4430 })
4431
4432 (define_insn "*floathisf2_i387"
4433   [(set (match_operand:SF 0 "register_operand" "=f,f")
4434         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4435   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4436   "@
4437    fild%z1\t%1
4438    #"
4439   [(set_attr "type" "fmov,multi")
4440    (set_attr "mode" "SF")
4441    (set_attr "unit" "*,i387")
4442    (set_attr "fp_int_src" "true")])
4443
4444 (define_expand "floatsisf2"
4445   [(set (match_operand:SF 0 "register_operand" "")
4446         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4447   "TARGET_80387 || TARGET_SSE_MATH"
4448   "")
4449
4450 (define_insn "*floatsisf2_mixed"
4451   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4452         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4453   "TARGET_MIX_SSE_I387"
4454   "@
4455    fild%z1\t%1
4456    #
4457    cvtsi2ss\t{%1, %0|%0, %1}
4458    cvtsi2ss\t{%1, %0|%0, %1}"
4459   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4460    (set_attr "mode" "SF")
4461    (set_attr "unit" "*,i387,*,*")
4462    (set_attr "athlon_decode" "*,*,vector,double")
4463    (set_attr "fp_int_src" "true")])
4464
4465 (define_insn "*floatsisf2_sse"
4466   [(set (match_operand:SF 0 "register_operand" "=x,x")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4468   "TARGET_SSE_MATH"
4469   "cvtsi2ss\t{%1, %0|%0, %1}"
4470   [(set_attr "type" "sseicvt")
4471    (set_attr "mode" "SF")
4472    (set_attr "athlon_decode" "vector,double")
4473    (set_attr "fp_int_src" "true")])
4474
4475 (define_insn "*floatsisf2_i387"
4476   [(set (match_operand:SF 0 "register_operand" "=f,f")
4477         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4478   "TARGET_80387"
4479   "@
4480    fild%z1\t%1
4481    #"
4482   [(set_attr "type" "fmov,multi")
4483    (set_attr "mode" "SF")
4484    (set_attr "unit" "*,i387")
4485    (set_attr "fp_int_src" "true")])
4486
4487 (define_expand "floatdisf2"
4488   [(set (match_operand:SF 0 "register_operand" "")
4489         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4490   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4491   "")
4492
4493 (define_insn "*floatdisf2_mixed"
4494   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4495         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4496   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4497   "@
4498    fild%z1\t%1
4499    #
4500    cvtsi2ss{q}\t{%1, %0|%0, %1}
4501    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4502   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4503    (set_attr "mode" "SF")
4504    (set_attr "unit" "*,i387,*,*")
4505    (set_attr "athlon_decode" "*,*,vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_sse"
4509   [(set (match_operand:SF 0 "register_operand" "=x,x")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4511   "TARGET_64BIT && TARGET_SSE_MATH"
4512   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4513   [(set_attr "type" "sseicvt")
4514    (set_attr "mode" "SF")
4515    (set_attr "athlon_decode" "vector,double")
4516    (set_attr "fp_int_src" "true")])
4517
4518 (define_insn "*floatdisf2_i387"
4519   [(set (match_operand:SF 0 "register_operand" "=f,f")
4520         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4521   "TARGET_80387"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "SF")
4527    (set_attr "unit" "*,i387")
4528    (set_attr "fp_int_src" "true")])
4529
4530 (define_expand "floathidf2"
4531   [(set (match_operand:DF 0 "register_operand" "")
4532         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4533   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4534 {
4535   if (TARGET_SSE2 && TARGET_SSE_MATH)
4536     {
4537       emit_insn (gen_floatsidf2 (operands[0],
4538                                  convert_to_mode (SImode, operands[1], 0)));
4539       DONE;
4540     }
4541 })
4542
4543 (define_insn "*floathidf2_i387"
4544   [(set (match_operand:DF 0 "register_operand" "=f,f")
4545         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4546   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4547   "@
4548    fild%z1\t%1
4549    #"
4550   [(set_attr "type" "fmov,multi")
4551    (set_attr "mode" "DF")
4552    (set_attr "unit" "*,i387")
4553    (set_attr "fp_int_src" "true")])
4554
4555 (define_expand "floatsidf2"
4556   [(set (match_operand:DF 0 "register_operand" "")
4557         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4558   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4559   "")
4560
4561 (define_insn "*floatsidf2_mixed"
4562   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4563         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4564   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4565   "@
4566    fild%z1\t%1
4567    #
4568    cvtsi2sd\t{%1, %0|%0, %1}
4569    cvtsi2sd\t{%1, %0|%0, %1}"
4570   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4571    (set_attr "mode" "DF")
4572    (set_attr "unit" "*,i387,*,*")
4573    (set_attr "athlon_decode" "*,*,double,direct")
4574    (set_attr "fp_int_src" "true")])
4575
4576 (define_insn "*floatsidf2_sse"
4577   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4579   "TARGET_SSE2 && TARGET_SSE_MATH"
4580   "cvtsi2sd\t{%1, %0|%0, %1}"
4581   [(set_attr "type" "sseicvt")
4582    (set_attr "mode" "DF")
4583    (set_attr "athlon_decode" "double,direct")
4584    (set_attr "fp_int_src" "true")])
4585
4586 (define_insn "*floatsidf2_i387"
4587   [(set (match_operand:DF 0 "register_operand" "=f,f")
4588         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4589   "TARGET_80387"
4590   "@
4591    fild%z1\t%1
4592    #"
4593   [(set_attr "type" "fmov,multi")
4594    (set_attr "mode" "DF")
4595    (set_attr "unit" "*,i387")
4596    (set_attr "fp_int_src" "true")])
4597
4598 (define_expand "floatdidf2"
4599   [(set (match_operand:DF 0 "register_operand" "")
4600         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4601   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4602   "")
4603
4604 (define_insn "*floatdidf2_mixed"
4605   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4606         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4607   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4608   "@
4609    fild%z1\t%1
4610    #
4611    cvtsi2sd{q}\t{%1, %0|%0, %1}
4612    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4613   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4614    (set_attr "mode" "DF")
4615    (set_attr "unit" "*,i387,*,*")
4616    (set_attr "athlon_decode" "*,*,double,direct")
4617    (set_attr "fp_int_src" "true")])
4618
4619 (define_insn "*floatdidf2_sse"
4620   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4622   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4623   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4624   [(set_attr "type" "sseicvt")
4625    (set_attr "mode" "DF")
4626    (set_attr "athlon_decode" "double,direct")
4627    (set_attr "fp_int_src" "true")])
4628
4629 (define_insn "*floatdidf2_i387"
4630   [(set (match_operand:DF 0 "register_operand" "=f,f")
4631         (float:DF (match_operand:DI 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" "DF")
4638    (set_attr "unit" "*,i387")
4639    (set_attr "fp_int_src" "true")])
4640
4641 (define_insn "floathixf2"
4642   [(set (match_operand:XF 0 "register_operand" "=f,f")
4643         (float:XF (match_operand:HI 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 "floatsixf2"
4654   [(set (match_operand:XF 0 "register_operand" "=f,f")
4655         (float:XF (match_operand:SI 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 (define_insn "floatdixf2"
4666   [(set (match_operand:XF 0 "register_operand" "=f,f")
4667         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4668   "TARGET_80387"
4669   "@
4670    fild%z1\t%1
4671    #"
4672   [(set_attr "type" "fmov,multi")
4673    (set_attr "mode" "XF")
4674    (set_attr "unit" "*,i387")
4675    (set_attr "fp_int_src" "true")])
4676
4677 ;; %%% Kill these when reload knows how to do it.
4678 (define_split
4679   [(set (match_operand 0 "fp_register_operand" "")
4680         (float (match_operand 1 "register_operand" "")))]
4681   "reload_completed
4682    && TARGET_80387
4683    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4684   [(const_int 0)]
4685 {
4686   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4687   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4688   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4689   ix86_free_from_memory (GET_MODE (operands[1]));
4690   DONE;
4691 })
4692
4693 (define_expand "floatunssisf2"
4694   [(use (match_operand:SF 0 "register_operand" ""))
4695    (use (match_operand:SI 1 "register_operand" ""))]
4696   "!TARGET_64BIT && TARGET_SSE_MATH"
4697   "x86_emit_floatuns (operands); DONE;")
4698
4699 (define_expand "floatunsdisf2"
4700   [(use (match_operand:SF 0 "register_operand" ""))
4701    (use (match_operand:DI 1 "register_operand" ""))]
4702   "TARGET_64BIT && TARGET_SSE_MATH"
4703   "x86_emit_floatuns (operands); DONE;")
4704
4705 (define_expand "floatunsdidf2"
4706   [(use (match_operand:DF 0 "register_operand" ""))
4707    (use (match_operand:DI 1 "register_operand" ""))]
4708   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4709   "x86_emit_floatuns (operands); DONE;")
4710 \f
4711 ;; SSE extract/set expanders
4712
4713 \f
4714 ;; Add instructions
4715
4716 ;; %%% splits for addditi3
4717
4718 (define_expand "addti3"
4719   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4720         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4721                  (match_operand:TI 2 "x86_64_general_operand" "")))
4722    (clobber (reg:CC FLAGS_REG))]
4723   "TARGET_64BIT"
4724   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4725
4726 (define_insn "*addti3_1"
4727   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4728         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4729                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4730    (clobber (reg:CC FLAGS_REG))]
4731   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4732   "#")
4733
4734 (define_split
4735   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4736         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4737                  (match_operand:TI 2 "general_operand" "")))
4738    (clobber (reg:CC FLAGS_REG))]
4739   "TARGET_64BIT && reload_completed"
4740   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4741                                           UNSPEC_ADD_CARRY))
4742               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4743    (parallel [(set (match_dup 3)
4744                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4745                                      (match_dup 4))
4746                             (match_dup 5)))
4747               (clobber (reg:CC FLAGS_REG))])]
4748   "split_ti (operands+0, 1, operands+0, operands+3);
4749    split_ti (operands+1, 1, operands+1, operands+4);
4750    split_ti (operands+2, 1, operands+2, operands+5);")
4751
4752 ;; %%% splits for addsidi3
4753 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4754 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4755 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4756
4757 (define_expand "adddi3"
4758   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4759         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4760                  (match_operand:DI 2 "x86_64_general_operand" "")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   ""
4763   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4764
4765 (define_insn "*adddi3_1"
4766   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4767         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4768                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4769    (clobber (reg:CC FLAGS_REG))]
4770   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4771   "#")
4772
4773 (define_split
4774   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4775         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4776                  (match_operand:DI 2 "general_operand" "")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "!TARGET_64BIT && reload_completed"
4779   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4780                                           UNSPEC_ADD_CARRY))
4781               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4782    (parallel [(set (match_dup 3)
4783                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4784                                      (match_dup 4))
4785                             (match_dup 5)))
4786               (clobber (reg:CC FLAGS_REG))])]
4787   "split_di (operands+0, 1, operands+0, operands+3);
4788    split_di (operands+1, 1, operands+1, operands+4);
4789    split_di (operands+2, 1, operands+2, operands+5);")
4790
4791 (define_insn "adddi3_carry_rex64"
4792   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4793           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4794                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4795                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4796    (clobber (reg:CC FLAGS_REG))]
4797   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4798   "adc{q}\t{%2, %0|%0, %2}"
4799   [(set_attr "type" "alu")
4800    (set_attr "pent_pair" "pu")
4801    (set_attr "mode" "DI")])
4802
4803 (define_insn "*adddi3_cc_rex64"
4804   [(set (reg:CC FLAGS_REG)
4805         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4806                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4807                    UNSPEC_ADD_CARRY))
4808    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4809         (plus:DI (match_dup 1) (match_dup 2)))]
4810   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4811   "add{q}\t{%2, %0|%0, %2}"
4812   [(set_attr "type" "alu")
4813    (set_attr "mode" "DI")])
4814
4815 (define_insn "addqi3_carry"
4816   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4817           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4818                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4819                    (match_operand:QI 2 "general_operand" "qi,qm")))
4820    (clobber (reg:CC FLAGS_REG))]
4821   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4822   "adc{b}\t{%2, %0|%0, %2}"
4823   [(set_attr "type" "alu")
4824    (set_attr "pent_pair" "pu")
4825    (set_attr "mode" "QI")])
4826
4827 (define_insn "addhi3_carry"
4828   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4829           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4830                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4831                    (match_operand:HI 2 "general_operand" "ri,rm")))
4832    (clobber (reg:CC FLAGS_REG))]
4833   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4834   "adc{w}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "pent_pair" "pu")
4837    (set_attr "mode" "HI")])
4838
4839 (define_insn "addsi3_carry"
4840   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4841           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4842                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4843                    (match_operand:SI 2 "general_operand" "ri,rm")))
4844    (clobber (reg:CC FLAGS_REG))]
4845   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4846   "adc{l}\t{%2, %0|%0, %2}"
4847   [(set_attr "type" "alu")
4848    (set_attr "pent_pair" "pu")
4849    (set_attr "mode" "SI")])
4850
4851 (define_insn "*addsi3_carry_zext"
4852   [(set (match_operand:DI 0 "register_operand" "=r")
4853           (zero_extend:DI 
4854             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4855                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4856                      (match_operand:SI 2 "general_operand" "rim"))))
4857    (clobber (reg:CC FLAGS_REG))]
4858   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4859   "adc{l}\t{%2, %k0|%k0, %2}"
4860   [(set_attr "type" "alu")
4861    (set_attr "pent_pair" "pu")
4862    (set_attr "mode" "SI")])
4863
4864 (define_insn "*addsi3_cc"
4865   [(set (reg:CC FLAGS_REG)
4866         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4867                     (match_operand:SI 2 "general_operand" "ri,rm")]
4868                    UNSPEC_ADD_CARRY))
4869    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4870         (plus:SI (match_dup 1) (match_dup 2)))]
4871   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4872   "add{l}\t{%2, %0|%0, %2}"
4873   [(set_attr "type" "alu")
4874    (set_attr "mode" "SI")])
4875
4876 (define_insn "addqi3_cc"
4877   [(set (reg:CC FLAGS_REG)
4878         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4879                     (match_operand:QI 2 "general_operand" "qi,qm")]
4880                    UNSPEC_ADD_CARRY))
4881    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4882         (plus:QI (match_dup 1) (match_dup 2)))]
4883   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4884   "add{b}\t{%2, %0|%0, %2}"
4885   [(set_attr "type" "alu")
4886    (set_attr "mode" "QI")])
4887
4888 (define_expand "addsi3"
4889   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4890                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4891                             (match_operand:SI 2 "general_operand" "")))
4892               (clobber (reg:CC FLAGS_REG))])]
4893   ""
4894   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4895
4896 (define_insn "*lea_1"
4897   [(set (match_operand:SI 0 "register_operand" "=r")
4898         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4899   "!TARGET_64BIT"
4900   "lea{l}\t{%a1, %0|%0, %a1}"
4901   [(set_attr "type" "lea")
4902    (set_attr "mode" "SI")])
4903
4904 (define_insn "*lea_1_rex64"
4905   [(set (match_operand:SI 0 "register_operand" "=r")
4906         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4907   "TARGET_64BIT"
4908   "lea{l}\t{%a1, %0|%0, %a1}"
4909   [(set_attr "type" "lea")
4910    (set_attr "mode" "SI")])
4911
4912 (define_insn "*lea_1_zext"
4913   [(set (match_operand:DI 0 "register_operand" "=r")
4914         (zero_extend:DI
4915          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4916   "TARGET_64BIT"
4917   "lea{l}\t{%a1, %k0|%k0, %a1}"
4918   [(set_attr "type" "lea")
4919    (set_attr "mode" "SI")])
4920
4921 (define_insn "*lea_2_rex64"
4922   [(set (match_operand:DI 0 "register_operand" "=r")
4923         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4924   "TARGET_64BIT"
4925   "lea{q}\t{%a1, %0|%0, %a1}"
4926   [(set_attr "type" "lea")
4927    (set_attr "mode" "DI")])
4928
4929 ;; The lea patterns for non-Pmodes needs to be matched by several
4930 ;; insns converted to real lea by splitters.
4931
4932 (define_insn_and_split "*lea_general_1"
4933   [(set (match_operand 0 "register_operand" "=r")
4934         (plus (plus (match_operand 1 "index_register_operand" "l")
4935                     (match_operand 2 "register_operand" "r"))
4936               (match_operand 3 "immediate_operand" "i")))]
4937   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4938     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4939    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4940    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4941    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4942    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4943        || GET_MODE (operands[3]) == VOIDmode)"
4944   "#"
4945   "&& reload_completed"
4946   [(const_int 0)]
4947 {
4948   rtx pat;
4949   operands[0] = gen_lowpart (SImode, operands[0]);
4950   operands[1] = gen_lowpart (Pmode, operands[1]);
4951   operands[2] = gen_lowpart (Pmode, operands[2]);
4952   operands[3] = gen_lowpart (Pmode, operands[3]);
4953   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4954                       operands[3]);
4955   if (Pmode != SImode)
4956     pat = gen_rtx_SUBREG (SImode, pat, 0);
4957   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4958   DONE;
4959 }
4960   [(set_attr "type" "lea")
4961    (set_attr "mode" "SI")])
4962
4963 (define_insn_and_split "*lea_general_1_zext"
4964   [(set (match_operand:DI 0 "register_operand" "=r")
4965         (zero_extend:DI
4966           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4967                             (match_operand:SI 2 "register_operand" "r"))
4968                    (match_operand:SI 3 "immediate_operand" "i"))))]
4969   "TARGET_64BIT"
4970   "#"
4971   "&& reload_completed"
4972   [(set (match_dup 0)
4973         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4974                                                      (match_dup 2))
4975                                             (match_dup 3)) 0)))]
4976 {
4977   operands[1] = gen_lowpart (Pmode, operands[1]);
4978   operands[2] = gen_lowpart (Pmode, operands[2]);
4979   operands[3] = gen_lowpart (Pmode, operands[3]);
4980 }
4981   [(set_attr "type" "lea")
4982    (set_attr "mode" "SI")])
4983
4984 (define_insn_and_split "*lea_general_2"
4985   [(set (match_operand 0 "register_operand" "=r")
4986         (plus (mult (match_operand 1 "index_register_operand" "l")
4987                     (match_operand 2 "const248_operand" "i"))
4988               (match_operand 3 "nonmemory_operand" "ri")))]
4989   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4990     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4991    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4992    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4993    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4994        || GET_MODE (operands[3]) == VOIDmode)"
4995   "#"
4996   "&& reload_completed"
4997   [(const_int 0)]
4998 {
4999   rtx pat;
5000   operands[0] = gen_lowpart (SImode, operands[0]);
5001   operands[1] = gen_lowpart (Pmode, operands[1]);
5002   operands[3] = gen_lowpart (Pmode, operands[3]);
5003   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5004                       operands[3]);
5005   if (Pmode != SImode)
5006     pat = gen_rtx_SUBREG (SImode, pat, 0);
5007   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5008   DONE;
5009 }
5010   [(set_attr "type" "lea")
5011    (set_attr "mode" "SI")])
5012
5013 (define_insn_and_split "*lea_general_2_zext"
5014   [(set (match_operand:DI 0 "register_operand" "=r")
5015         (zero_extend:DI
5016           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5017                             (match_operand:SI 2 "const248_operand" "n"))
5018                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5019   "TARGET_64BIT"
5020   "#"
5021   "&& reload_completed"
5022   [(set (match_dup 0)
5023         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5024                                                      (match_dup 2))
5025                                             (match_dup 3)) 0)))]
5026 {
5027   operands[1] = gen_lowpart (Pmode, operands[1]);
5028   operands[3] = gen_lowpart (Pmode, operands[3]);
5029 }
5030   [(set_attr "type" "lea")
5031    (set_attr "mode" "SI")])
5032
5033 (define_insn_and_split "*lea_general_3"
5034   [(set (match_operand 0 "register_operand" "=r")
5035         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5036                           (match_operand 2 "const248_operand" "i"))
5037                     (match_operand 3 "register_operand" "r"))
5038               (match_operand 4 "immediate_operand" "i")))]
5039   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5040     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5041    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5042    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5043    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5044   "#"
5045   "&& reload_completed"
5046   [(const_int 0)]
5047 {
5048   rtx pat;
5049   operands[0] = gen_lowpart (SImode, operands[0]);
5050   operands[1] = gen_lowpart (Pmode, operands[1]);
5051   operands[3] = gen_lowpart (Pmode, operands[3]);
5052   operands[4] = gen_lowpart (Pmode, operands[4]);
5053   pat = gen_rtx_PLUS (Pmode,
5054                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5055                                                          operands[2]),
5056                                     operands[3]),
5057                       operands[4]);
5058   if (Pmode != SImode)
5059     pat = gen_rtx_SUBREG (SImode, pat, 0);
5060   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5061   DONE;
5062 }
5063   [(set_attr "type" "lea")
5064    (set_attr "mode" "SI")])
5065
5066 (define_insn_and_split "*lea_general_3_zext"
5067   [(set (match_operand:DI 0 "register_operand" "=r")
5068         (zero_extend:DI
5069           (plus:SI (plus:SI (mult:SI
5070                               (match_operand:SI 1 "index_register_operand" "l")
5071                               (match_operand:SI 2 "const248_operand" "n"))
5072                             (match_operand:SI 3 "register_operand" "r"))
5073                    (match_operand:SI 4 "immediate_operand" "i"))))]
5074   "TARGET_64BIT"
5075   "#"
5076   "&& reload_completed"
5077   [(set (match_dup 0)
5078         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5079                                                               (match_dup 2))
5080                                                      (match_dup 3))
5081                                             (match_dup 4)) 0)))]
5082 {
5083   operands[1] = gen_lowpart (Pmode, operands[1]);
5084   operands[3] = gen_lowpart (Pmode, operands[3]);
5085   operands[4] = gen_lowpart (Pmode, operands[4]);
5086 }
5087   [(set_attr "type" "lea")
5088    (set_attr "mode" "SI")])
5089
5090 (define_insn "*adddi_1_rex64"
5091   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5092         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5093                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5094    (clobber (reg:CC FLAGS_REG))]
5095   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5096 {
5097   switch (get_attr_type (insn))
5098     {
5099     case TYPE_LEA:
5100       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5101       return "lea{q}\t{%a2, %0|%0, %a2}";
5102
5103     case TYPE_INCDEC:
5104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5105       if (operands[2] == const1_rtx)
5106         return "inc{q}\t%0";
5107       else
5108         {
5109           gcc_assert (operands[2] == constm1_rtx);
5110           return "dec{q}\t%0";
5111         }
5112
5113     default:
5114       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5115
5116       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5117          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5118       if (GET_CODE (operands[2]) == CONST_INT
5119           /* Avoid overflows.  */
5120           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5121           && (INTVAL (operands[2]) == 128
5122               || (INTVAL (operands[2]) < 0
5123                   && INTVAL (operands[2]) != -128)))
5124         {
5125           operands[2] = GEN_INT (-INTVAL (operands[2]));
5126           return "sub{q}\t{%2, %0|%0, %2}";
5127         }
5128       return "add{q}\t{%2, %0|%0, %2}";
5129     }
5130 }
5131   [(set (attr "type")
5132      (cond [(eq_attr "alternative" "2")
5133               (const_string "lea")
5134             ; Current assemblers are broken and do not allow @GOTOFF in
5135             ; ought but a memory context.
5136             (match_operand:DI 2 "pic_symbolic_operand" "")
5137               (const_string "lea")
5138             (match_operand:DI 2 "incdec_operand" "")
5139               (const_string "incdec")
5140            ]
5141            (const_string "alu")))
5142    (set_attr "mode" "DI")])
5143
5144 ;; Convert lea to the lea pattern to avoid flags dependency.
5145 (define_split
5146   [(set (match_operand:DI 0 "register_operand" "")
5147         (plus:DI (match_operand:DI 1 "register_operand" "")
5148                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5149    (clobber (reg:CC FLAGS_REG))]
5150   "TARGET_64BIT && reload_completed
5151    && true_regnum (operands[0]) != true_regnum (operands[1])"
5152   [(set (match_dup 0)
5153         (plus:DI (match_dup 1)
5154                  (match_dup 2)))]
5155   "")
5156
5157 (define_insn "*adddi_2_rex64"
5158   [(set (reg FLAGS_REG)
5159         (compare
5160           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5161                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5162           (const_int 0)))                       
5163    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5164         (plus:DI (match_dup 1) (match_dup 2)))]
5165   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5166    && ix86_binary_operator_ok (PLUS, DImode, operands)
5167    /* Current assemblers are broken and do not allow @GOTOFF in
5168       ought but a memory context.  */
5169    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5170 {
5171   switch (get_attr_type (insn))
5172     {
5173     case TYPE_INCDEC:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175       if (operands[2] == const1_rtx)
5176         return "inc{q}\t%0";
5177       else
5178         {
5179           gcc_assert (operands[2] == constm1_rtx);
5180           return "dec{q}\t%0";
5181         }
5182
5183     default:
5184       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5185       /* ???? We ought to handle there the 32bit case too
5186          - do we need new constraint?  */
5187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5189       if (GET_CODE (operands[2]) == CONST_INT
5190           /* Avoid overflows.  */
5191           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5192           && (INTVAL (operands[2]) == 128
5193               || (INTVAL (operands[2]) < 0
5194                   && INTVAL (operands[2]) != -128)))
5195         {
5196           operands[2] = GEN_INT (-INTVAL (operands[2]));
5197           return "sub{q}\t{%2, %0|%0, %2}";
5198         }
5199       return "add{q}\t{%2, %0|%0, %2}";
5200     }
5201 }
5202   [(set (attr "type")
5203      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5204         (const_string "incdec")
5205         (const_string "alu")))
5206    (set_attr "mode" "DI")])
5207
5208 (define_insn "*adddi_3_rex64"
5209   [(set (reg FLAGS_REG)
5210         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5211                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5212    (clobber (match_scratch:DI 0 "=r"))]
5213   "TARGET_64BIT
5214    && ix86_match_ccmode (insn, CCZmode)
5215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5216    /* Current assemblers are broken and do not allow @GOTOFF in
5217       ought but a memory context.  */
5218    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5219 {
5220   switch (get_attr_type (insn))
5221     {
5222     case TYPE_INCDEC:
5223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224       if (operands[2] == const1_rtx)
5225         return "inc{q}\t%0";
5226       else
5227         {
5228           gcc_assert (operands[2] == constm1_rtx);
5229           return "dec{q}\t%0";
5230         }
5231
5232     default:
5233       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5234       /* ???? We ought to handle there the 32bit case too
5235          - do we need new constraint?  */
5236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5238       if (GET_CODE (operands[2]) == CONST_INT
5239           /* Avoid overflows.  */
5240           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5241           && (INTVAL (operands[2]) == 128
5242               || (INTVAL (operands[2]) < 0
5243                   && INTVAL (operands[2]) != -128)))
5244         {
5245           operands[2] = GEN_INT (-INTVAL (operands[2]));
5246           return "sub{q}\t{%2, %0|%0, %2}";
5247         }
5248       return "add{q}\t{%2, %0|%0, %2}";
5249     }
5250 }
5251   [(set (attr "type")
5252      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5253         (const_string "incdec")
5254         (const_string "alu")))
5255    (set_attr "mode" "DI")])
5256
5257 ; For comparisons against 1, -1 and 128, we may generate better code
5258 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5259 ; is matched then.  We can't accept general immediate, because for
5260 ; case of overflows,  the result is messed up.
5261 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5262 ; when negated.
5263 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5264 ; only for comparisons not depending on it.
5265 (define_insn "*adddi_4_rex64"
5266   [(set (reg FLAGS_REG)
5267         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5268                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5269    (clobber (match_scratch:DI 0 "=rm"))]
5270   "TARGET_64BIT
5271    &&  ix86_match_ccmode (insn, CCGCmode)"
5272 {
5273   switch (get_attr_type (insn))
5274     {
5275     case TYPE_INCDEC:
5276       if (operands[2] == constm1_rtx)
5277         return "inc{q}\t%0";
5278       else
5279         {
5280           gcc_assert (operands[2] == const1_rtx);
5281           return "dec{q}\t%0";
5282         }
5283
5284     default:
5285       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5286       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5287          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5288       if ((INTVAL (operands[2]) == -128
5289            || (INTVAL (operands[2]) > 0
5290                && INTVAL (operands[2]) != 128))
5291           /* Avoid overflows.  */
5292           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5293         return "sub{q}\t{%2, %0|%0, %2}";
5294       operands[2] = GEN_INT (-INTVAL (operands[2]));
5295       return "add{q}\t{%2, %0|%0, %2}";
5296     }
5297 }
5298   [(set (attr "type")
5299      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5300         (const_string "incdec")
5301         (const_string "alu")))
5302    (set_attr "mode" "DI")])
5303
5304 (define_insn "*adddi_5_rex64"
5305   [(set (reg FLAGS_REG)
5306         (compare
5307           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5308                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5309           (const_int 0)))                       
5310    (clobber (match_scratch:DI 0 "=r"))]
5311   "TARGET_64BIT
5312    && ix86_match_ccmode (insn, CCGOCmode)
5313    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5314    /* Current assemblers are broken and do not allow @GOTOFF in
5315       ought but a memory context.  */
5316    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5317 {
5318   switch (get_attr_type (insn))
5319     {
5320     case TYPE_INCDEC:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322       if (operands[2] == const1_rtx)
5323         return "inc{q}\t%0";
5324       else
5325         {
5326           gcc_assert (operands[2] == constm1_rtx);
5327           return "dec{q}\t%0";
5328         }
5329
5330     default:
5331       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5333          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5334       if (GET_CODE (operands[2]) == CONST_INT
5335           /* Avoid overflows.  */
5336           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5337           && (INTVAL (operands[2]) == 128
5338               || (INTVAL (operands[2]) < 0
5339                   && INTVAL (operands[2]) != -128)))
5340         {
5341           operands[2] = GEN_INT (-INTVAL (operands[2]));
5342           return "sub{q}\t{%2, %0|%0, %2}";
5343         }
5344       return "add{q}\t{%2, %0|%0, %2}";
5345     }
5346 }
5347   [(set (attr "type")
5348      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5349         (const_string "incdec")
5350         (const_string "alu")))
5351    (set_attr "mode" "DI")])
5352
5353
5354 (define_insn "*addsi_1"
5355   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5356         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5357                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5358    (clobber (reg:CC FLAGS_REG))]
5359   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5360 {
5361   switch (get_attr_type (insn))
5362     {
5363     case TYPE_LEA:
5364       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5365       return "lea{l}\t{%a2, %0|%0, %a2}";
5366
5367     case TYPE_INCDEC:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369       if (operands[2] == const1_rtx)
5370         return "inc{l}\t%0";
5371       else
5372         {
5373           gcc_assert (operands[2] == constm1_rtx);
5374           return "dec{l}\t%0";
5375         }
5376
5377     default:
5378       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5379
5380       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5381          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5382       if (GET_CODE (operands[2]) == CONST_INT
5383           && (INTVAL (operands[2]) == 128
5384               || (INTVAL (operands[2]) < 0
5385                   && INTVAL (operands[2]) != -128)))
5386         {
5387           operands[2] = GEN_INT (-INTVAL (operands[2]));
5388           return "sub{l}\t{%2, %0|%0, %2}";
5389         }
5390       return "add{l}\t{%2, %0|%0, %2}";
5391     }
5392 }
5393   [(set (attr "type")
5394      (cond [(eq_attr "alternative" "2")
5395               (const_string "lea")
5396             ; Current assemblers are broken and do not allow @GOTOFF in
5397             ; ought but a memory context.
5398             (match_operand:SI 2 "pic_symbolic_operand" "")
5399               (const_string "lea")
5400             (match_operand:SI 2 "incdec_operand" "")
5401               (const_string "incdec")
5402            ]
5403            (const_string "alu")))
5404    (set_attr "mode" "SI")])
5405
5406 ;; Convert lea to the lea pattern to avoid flags dependency.
5407 (define_split
5408   [(set (match_operand 0 "register_operand" "")
5409         (plus (match_operand 1 "register_operand" "")
5410               (match_operand 2 "nonmemory_operand" "")))
5411    (clobber (reg:CC FLAGS_REG))]
5412   "reload_completed
5413    && true_regnum (operands[0]) != true_regnum (operands[1])"
5414   [(const_int 0)]
5415 {
5416   rtx pat;
5417   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5418      may confuse gen_lowpart.  */
5419   if (GET_MODE (operands[0]) != Pmode)
5420     {
5421       operands[1] = gen_lowpart (Pmode, operands[1]);
5422       operands[2] = gen_lowpart (Pmode, operands[2]);
5423     }
5424   operands[0] = gen_lowpart (SImode, operands[0]);
5425   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5426   if (Pmode != SImode)
5427     pat = gen_rtx_SUBREG (SImode, pat, 0);
5428   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5429   DONE;
5430 })
5431
5432 ;; It may seem that nonimmediate operand is proper one for operand 1.
5433 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5434 ;; we take care in ix86_binary_operator_ok to not allow two memory
5435 ;; operands so proper swapping will be done in reload.  This allow
5436 ;; patterns constructed from addsi_1 to match.
5437 (define_insn "addsi_1_zext"
5438   [(set (match_operand:DI 0 "register_operand" "=r,r")
5439         (zero_extend:DI
5440           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5441                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5442    (clobber (reg:CC FLAGS_REG))]
5443   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5444 {
5445   switch (get_attr_type (insn))
5446     {
5447     case TYPE_LEA:
5448       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5449       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5450
5451     case TYPE_INCDEC:
5452       if (operands[2] == const1_rtx)
5453         return "inc{l}\t%k0";
5454       else
5455         {
5456           gcc_assert (operands[2] == constm1_rtx);
5457           return "dec{l}\t%k0";
5458         }
5459
5460     default:
5461       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5463       if (GET_CODE (operands[2]) == CONST_INT
5464           && (INTVAL (operands[2]) == 128
5465               || (INTVAL (operands[2]) < 0
5466                   && INTVAL (operands[2]) != -128)))
5467         {
5468           operands[2] = GEN_INT (-INTVAL (operands[2]));
5469           return "sub{l}\t{%2, %k0|%k0, %2}";
5470         }
5471       return "add{l}\t{%2, %k0|%k0, %2}";
5472     }
5473 }
5474   [(set (attr "type")
5475      (cond [(eq_attr "alternative" "1")
5476               (const_string "lea")
5477             ; Current assemblers are broken and do not allow @GOTOFF in
5478             ; ought but a memory context.
5479             (match_operand:SI 2 "pic_symbolic_operand" "")
5480               (const_string "lea")
5481             (match_operand:SI 2 "incdec_operand" "")
5482               (const_string "incdec")
5483            ]
5484            (const_string "alu")))
5485    (set_attr "mode" "SI")])
5486
5487 ;; Convert lea to the lea pattern to avoid flags dependency.
5488 (define_split
5489   [(set (match_operand:DI 0 "register_operand" "")
5490         (zero_extend:DI
5491           (plus:SI (match_operand:SI 1 "register_operand" "")
5492                    (match_operand:SI 2 "nonmemory_operand" ""))))
5493    (clobber (reg:CC FLAGS_REG))]
5494   "TARGET_64BIT && reload_completed
5495    && true_regnum (operands[0]) != true_regnum (operands[1])"
5496   [(set (match_dup 0)
5497         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5498 {
5499   operands[1] = gen_lowpart (Pmode, operands[1]);
5500   operands[2] = gen_lowpart (Pmode, operands[2]);
5501 })
5502
5503 (define_insn "*addsi_2"
5504   [(set (reg FLAGS_REG)
5505         (compare
5506           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5507                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5508           (const_int 0)))                       
5509    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5510         (plus:SI (match_dup 1) (match_dup 2)))]
5511   "ix86_match_ccmode (insn, CCGOCmode)
5512    && ix86_binary_operator_ok (PLUS, SImode, operands)
5513    /* Current assemblers are broken and do not allow @GOTOFF in
5514       ought but a memory context.  */
5515    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5516 {
5517   switch (get_attr_type (insn))
5518     {
5519     case TYPE_INCDEC:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       if (operands[2] == const1_rtx)
5522         return "inc{l}\t%0";
5523       else
5524         {
5525           gcc_assert (operands[2] == constm1_rtx);
5526           return "dec{l}\t%0";
5527         }
5528
5529     default:
5530       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5532          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5533       if (GET_CODE (operands[2]) == CONST_INT
5534           && (INTVAL (operands[2]) == 128
5535               || (INTVAL (operands[2]) < 0
5536                   && INTVAL (operands[2]) != -128)))
5537         {
5538           operands[2] = GEN_INT (-INTVAL (operands[2]));
5539           return "sub{l}\t{%2, %0|%0, %2}";
5540         }
5541       return "add{l}\t{%2, %0|%0, %2}";
5542     }
5543 }
5544   [(set (attr "type")
5545      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5546         (const_string "incdec")
5547         (const_string "alu")))
5548    (set_attr "mode" "SI")])
5549
5550 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5551 (define_insn "*addsi_2_zext"
5552   [(set (reg FLAGS_REG)
5553         (compare
5554           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5555                    (match_operand:SI 2 "general_operand" "rmni"))
5556           (const_int 0)))                       
5557    (set (match_operand:DI 0 "register_operand" "=r")
5558         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5559   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5560    && ix86_binary_operator_ok (PLUS, SImode, operands)
5561    /* Current assemblers are broken and do not allow @GOTOFF in
5562       ought but a memory context.  */
5563    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5564 {
5565   switch (get_attr_type (insn))
5566     {
5567     case TYPE_INCDEC:
5568       if (operands[2] == const1_rtx)
5569         return "inc{l}\t%k0";
5570       else
5571         {
5572           gcc_assert (operands[2] == constm1_rtx);
5573           return "dec{l}\t%k0";
5574         }
5575
5576     default:
5577       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5578          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5579       if (GET_CODE (operands[2]) == CONST_INT
5580           && (INTVAL (operands[2]) == 128
5581               || (INTVAL (operands[2]) < 0
5582                   && INTVAL (operands[2]) != -128)))
5583         {
5584           operands[2] = GEN_INT (-INTVAL (operands[2]));
5585           return "sub{l}\t{%2, %k0|%k0, %2}";
5586         }
5587       return "add{l}\t{%2, %k0|%k0, %2}";
5588     }
5589 }
5590   [(set (attr "type")
5591      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5592         (const_string "incdec")
5593         (const_string "alu")))
5594    (set_attr "mode" "SI")])
5595
5596 (define_insn "*addsi_3"
5597   [(set (reg FLAGS_REG)
5598         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5599                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5600    (clobber (match_scratch:SI 0 "=r"))]
5601   "ix86_match_ccmode (insn, CCZmode)
5602    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5603    /* Current assemblers are broken and do not allow @GOTOFF in
5604       ought but a memory context.  */
5605    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5606 {
5607   switch (get_attr_type (insn))
5608     {
5609     case TYPE_INCDEC:
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       if (operands[2] == const1_rtx)
5612         return "inc{l}\t%0";
5613       else
5614         {
5615           gcc_assert (operands[2] == constm1_rtx);
5616           return "dec{l}\t%0";
5617         }
5618
5619     default:
5620       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5622          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5623       if (GET_CODE (operands[2]) == CONST_INT
5624           && (INTVAL (operands[2]) == 128
5625               || (INTVAL (operands[2]) < 0
5626                   && INTVAL (operands[2]) != -128)))
5627         {
5628           operands[2] = GEN_INT (-INTVAL (operands[2]));
5629           return "sub{l}\t{%2, %0|%0, %2}";
5630         }
5631       return "add{l}\t{%2, %0|%0, %2}";
5632     }
5633 }
5634   [(set (attr "type")
5635      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5636         (const_string "incdec")
5637         (const_string "alu")))
5638    (set_attr "mode" "SI")])
5639
5640 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5641 (define_insn "*addsi_3_zext"
5642   [(set (reg FLAGS_REG)
5643         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5644                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5645    (set (match_operand:DI 0 "register_operand" "=r")
5646         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5647   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5648    && ix86_binary_operator_ok (PLUS, SImode, operands)
5649    /* Current assemblers are broken and do not allow @GOTOFF in
5650       ought but a memory context.  */
5651    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5652 {
5653   switch (get_attr_type (insn))
5654     {
5655     case TYPE_INCDEC:
5656       if (operands[2] == const1_rtx)
5657         return "inc{l}\t%k0";
5658       else
5659         {
5660           gcc_assert (operands[2] == constm1_rtx);
5661           return "dec{l}\t%k0";
5662         }
5663
5664     default:
5665       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5666          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5667       if (GET_CODE (operands[2]) == CONST_INT
5668           && (INTVAL (operands[2]) == 128
5669               || (INTVAL (operands[2]) < 0
5670                   && INTVAL (operands[2]) != -128)))
5671         {
5672           operands[2] = GEN_INT (-INTVAL (operands[2]));
5673           return "sub{l}\t{%2, %k0|%k0, %2}";
5674         }
5675       return "add{l}\t{%2, %k0|%k0, %2}";
5676     }
5677 }
5678   [(set (attr "type")
5679      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5680         (const_string "incdec")
5681         (const_string "alu")))
5682    (set_attr "mode" "SI")])
5683
5684 ; For comparisons against 1, -1 and 128, we may generate better code
5685 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5686 ; is matched then.  We can't accept general immediate, because for
5687 ; case of overflows,  the result is messed up.
5688 ; This pattern also don't hold of 0x80000000, since the value overflows
5689 ; when negated.
5690 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5691 ; only for comparisons not depending on it.
5692 (define_insn "*addsi_4"
5693   [(set (reg FLAGS_REG)
5694         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5695                  (match_operand:SI 2 "const_int_operand" "n")))
5696    (clobber (match_scratch:SI 0 "=rm"))]
5697   "ix86_match_ccmode (insn, CCGCmode)
5698    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5699 {
5700   switch (get_attr_type (insn))
5701     {
5702     case TYPE_INCDEC:
5703       if (operands[2] == constm1_rtx)
5704         return "inc{l}\t%0";
5705       else
5706         {
5707           gcc_assert (operands[2] == const1_rtx);
5708           return "dec{l}\t%0";
5709         }
5710
5711     default:
5712       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5713       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5714          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5715       if ((INTVAL (operands[2]) == -128
5716            || (INTVAL (operands[2]) > 0
5717                && INTVAL (operands[2]) != 128)))
5718         return "sub{l}\t{%2, %0|%0, %2}";
5719       operands[2] = GEN_INT (-INTVAL (operands[2]));
5720       return "add{l}\t{%2, %0|%0, %2}";
5721     }
5722 }
5723   [(set (attr "type")
5724      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5725         (const_string "incdec")
5726         (const_string "alu")))
5727    (set_attr "mode" "SI")])
5728
5729 (define_insn "*addsi_5"
5730   [(set (reg FLAGS_REG)
5731         (compare
5732           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5733                    (match_operand:SI 2 "general_operand" "rmni"))
5734           (const_int 0)))                       
5735    (clobber (match_scratch:SI 0 "=r"))]
5736   "ix86_match_ccmode (insn, CCGOCmode)
5737    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5738    /* Current assemblers are broken and do not allow @GOTOFF in
5739       ought but a memory context.  */
5740    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741 {
5742   switch (get_attr_type (insn))
5743     {
5744     case TYPE_INCDEC:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       if (operands[2] == const1_rtx)
5747         return "inc{l}\t%0";
5748       else
5749         {
5750           gcc_assert (operands[2] == constm1_rtx);
5751           return "dec{l}\t%0";
5752         }
5753
5754     default:
5755       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5756       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5757          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5758       if (GET_CODE (operands[2]) == CONST_INT
5759           && (INTVAL (operands[2]) == 128
5760               || (INTVAL (operands[2]) < 0
5761                   && INTVAL (operands[2]) != -128)))
5762         {
5763           operands[2] = GEN_INT (-INTVAL (operands[2]));
5764           return "sub{l}\t{%2, %0|%0, %2}";
5765         }
5766       return "add{l}\t{%2, %0|%0, %2}";
5767     }
5768 }
5769   [(set (attr "type")
5770      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5771         (const_string "incdec")
5772         (const_string "alu")))
5773    (set_attr "mode" "SI")])
5774
5775 (define_expand "addhi3"
5776   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5777                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5778                             (match_operand:HI 2 "general_operand" "")))
5779               (clobber (reg:CC FLAGS_REG))])]
5780   "TARGET_HIMODE_MATH"
5781   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5782
5783 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5784 ;; type optimizations enabled by define-splits.  This is not important
5785 ;; for PII, and in fact harmful because of partial register stalls.
5786
5787 (define_insn "*addhi_1_lea"
5788   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5789         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5790                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5791    (clobber (reg:CC FLAGS_REG))]
5792   "!TARGET_PARTIAL_REG_STALL
5793    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5794 {
5795   switch (get_attr_type (insn))
5796     {
5797     case TYPE_LEA:
5798       return "#";
5799     case TYPE_INCDEC:
5800       if (operands[2] == const1_rtx)
5801         return "inc{w}\t%0";
5802       else
5803         {
5804           gcc_assert (operands[2] == constm1_rtx);
5805           return "dec{w}\t%0";
5806         }
5807
5808     default:
5809       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5810          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5811       if (GET_CODE (operands[2]) == CONST_INT
5812           && (INTVAL (operands[2]) == 128
5813               || (INTVAL (operands[2]) < 0
5814                   && INTVAL (operands[2]) != -128)))
5815         {
5816           operands[2] = GEN_INT (-INTVAL (operands[2]));
5817           return "sub{w}\t{%2, %0|%0, %2}";
5818         }
5819       return "add{w}\t{%2, %0|%0, %2}";
5820     }
5821 }
5822   [(set (attr "type")
5823      (if_then_else (eq_attr "alternative" "2")
5824         (const_string "lea")
5825         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5826            (const_string "incdec")
5827            (const_string "alu"))))
5828    (set_attr "mode" "HI,HI,SI")])
5829
5830 (define_insn "*addhi_1"
5831   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5832         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5833                  (match_operand:HI 2 "general_operand" "ri,rm")))
5834    (clobber (reg:CC FLAGS_REG))]
5835   "TARGET_PARTIAL_REG_STALL
5836    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5837 {
5838   switch (get_attr_type (insn))
5839     {
5840     case TYPE_INCDEC:
5841       if (operands[2] == const1_rtx)
5842         return "inc{w}\t%0";
5843       else
5844         {
5845           gcc_assert (operands[2] == constm1_rtx);
5846           return "dec{w}\t%0";
5847         }
5848
5849     default:
5850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852       if (GET_CODE (operands[2]) == CONST_INT
5853           && (INTVAL (operands[2]) == 128
5854               || (INTVAL (operands[2]) < 0
5855                   && INTVAL (operands[2]) != -128)))
5856         {
5857           operands[2] = GEN_INT (-INTVAL (operands[2]));
5858           return "sub{w}\t{%2, %0|%0, %2}";
5859         }
5860       return "add{w}\t{%2, %0|%0, %2}";
5861     }
5862 }
5863   [(set (attr "type")
5864      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5865         (const_string "incdec")
5866         (const_string "alu")))
5867    (set_attr "mode" "HI")])
5868
5869 (define_insn "*addhi_2"
5870   [(set (reg FLAGS_REG)
5871         (compare
5872           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5873                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5874           (const_int 0)))                       
5875    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5876         (plus:HI (match_dup 1) (match_dup 2)))]
5877   "ix86_match_ccmode (insn, CCGOCmode)
5878    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5879 {
5880   switch (get_attr_type (insn))
5881     {
5882     case TYPE_INCDEC:
5883       if (operands[2] == const1_rtx)
5884         return "inc{w}\t%0";
5885       else
5886         {
5887           gcc_assert (operands[2] == constm1_rtx);
5888           return "dec{w}\t%0";
5889         }
5890
5891     default:
5892       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5893          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5894       if (GET_CODE (operands[2]) == CONST_INT
5895           && (INTVAL (operands[2]) == 128
5896               || (INTVAL (operands[2]) < 0
5897                   && INTVAL (operands[2]) != -128)))
5898         {
5899           operands[2] = GEN_INT (-INTVAL (operands[2]));
5900           return "sub{w}\t{%2, %0|%0, %2}";
5901         }
5902       return "add{w}\t{%2, %0|%0, %2}";
5903     }
5904 }
5905   [(set (attr "type")
5906      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5907         (const_string "incdec")
5908         (const_string "alu")))
5909    (set_attr "mode" "HI")])
5910
5911 (define_insn "*addhi_3"
5912   [(set (reg FLAGS_REG)
5913         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5914                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5915    (clobber (match_scratch:HI 0 "=r"))]
5916   "ix86_match_ccmode (insn, CCZmode)
5917    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5918 {
5919   switch (get_attr_type (insn))
5920     {
5921     case TYPE_INCDEC:
5922       if (operands[2] == const1_rtx)
5923         return "inc{w}\t%0";
5924       else
5925         {
5926           gcc_assert (operands[2] == constm1_rtx);
5927           return "dec{w}\t%0";
5928         }
5929
5930     default:
5931       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5932          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5933       if (GET_CODE (operands[2]) == CONST_INT
5934           && (INTVAL (operands[2]) == 128
5935               || (INTVAL (operands[2]) < 0
5936                   && INTVAL (operands[2]) != -128)))
5937         {
5938           operands[2] = GEN_INT (-INTVAL (operands[2]));
5939           return "sub{w}\t{%2, %0|%0, %2}";
5940         }
5941       return "add{w}\t{%2, %0|%0, %2}";
5942     }
5943 }
5944   [(set (attr "type")
5945      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5946         (const_string "incdec")
5947         (const_string "alu")))
5948    (set_attr "mode" "HI")])
5949
5950 ; See comments above addsi_4 for details.
5951 (define_insn "*addhi_4"
5952   [(set (reg FLAGS_REG)
5953         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5954                  (match_operand:HI 2 "const_int_operand" "n")))
5955    (clobber (match_scratch:HI 0 "=rm"))]
5956   "ix86_match_ccmode (insn, CCGCmode)
5957    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5958 {
5959   switch (get_attr_type (insn))
5960     {
5961     case TYPE_INCDEC:
5962       if (operands[2] == constm1_rtx)
5963         return "inc{w}\t%0";
5964       else
5965         {
5966           gcc_assert (operands[2] == const1_rtx);
5967           return "dec{w}\t%0";
5968         }
5969
5970     default:
5971       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5972       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5973          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5974       if ((INTVAL (operands[2]) == -128
5975            || (INTVAL (operands[2]) > 0
5976                && INTVAL (operands[2]) != 128)))
5977         return "sub{w}\t{%2, %0|%0, %2}";
5978       operands[2] = GEN_INT (-INTVAL (operands[2]));
5979       return "add{w}\t{%2, %0|%0, %2}";
5980     }
5981 }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu")))
5986    (set_attr "mode" "SI")])
5987
5988
5989 (define_insn "*addhi_5"
5990   [(set (reg FLAGS_REG)
5991         (compare
5992           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5993                    (match_operand:HI 2 "general_operand" "rmni"))
5994           (const_int 0)))                       
5995    (clobber (match_scratch:HI 0 "=r"))]
5996   "ix86_match_ccmode (insn, CCGOCmode)
5997    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5998 {
5999   switch (get_attr_type (insn))
6000     {
6001     case TYPE_INCDEC:
6002       if (operands[2] == const1_rtx)
6003         return "inc{w}\t%0";
6004       else
6005         {
6006           gcc_assert (operands[2] == constm1_rtx);
6007           return "dec{w}\t%0";
6008         }
6009
6010     default:
6011       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6013       if (GET_CODE (operands[2]) == CONST_INT
6014           && (INTVAL (operands[2]) == 128
6015               || (INTVAL (operands[2]) < 0
6016                   && INTVAL (operands[2]) != -128)))
6017         {
6018           operands[2] = GEN_INT (-INTVAL (operands[2]));
6019           return "sub{w}\t{%2, %0|%0, %2}";
6020         }
6021       return "add{w}\t{%2, %0|%0, %2}";
6022     }
6023 }
6024   [(set (attr "type")
6025      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6026         (const_string "incdec")
6027         (const_string "alu")))
6028    (set_attr "mode" "HI")])
6029
6030 (define_expand "addqi3"
6031   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6032                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6033                             (match_operand:QI 2 "general_operand" "")))
6034               (clobber (reg:CC FLAGS_REG))])]
6035   "TARGET_QIMODE_MATH"
6036   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6037
6038 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6039 (define_insn "*addqi_1_lea"
6040   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6041         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6042                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6043    (clobber (reg:CC FLAGS_REG))]
6044   "!TARGET_PARTIAL_REG_STALL
6045    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6046 {
6047   int widen = (which_alternative == 2);
6048   switch (get_attr_type (insn))
6049     {
6050     case TYPE_LEA:
6051       return "#";
6052     case TYPE_INCDEC:
6053       if (operands[2] == const1_rtx)
6054         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6055       else
6056         {
6057           gcc_assert (operands[2] == constm1_rtx);
6058           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6059         }
6060
6061     default:
6062       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6063          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6064       if (GET_CODE (operands[2]) == CONST_INT
6065           && (INTVAL (operands[2]) == 128
6066               || (INTVAL (operands[2]) < 0
6067                   && INTVAL (operands[2]) != -128)))
6068         {
6069           operands[2] = GEN_INT (-INTVAL (operands[2]));
6070           if (widen)
6071             return "sub{l}\t{%2, %k0|%k0, %2}";
6072           else
6073             return "sub{b}\t{%2, %0|%0, %2}";
6074         }
6075       if (widen)
6076         return "add{l}\t{%k2, %k0|%k0, %k2}";
6077       else
6078         return "add{b}\t{%2, %0|%0, %2}";
6079     }
6080 }
6081   [(set (attr "type")
6082      (if_then_else (eq_attr "alternative" "3")
6083         (const_string "lea")
6084         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6085            (const_string "incdec")
6086            (const_string "alu"))))
6087    (set_attr "mode" "QI,QI,SI,SI")])
6088
6089 (define_insn "*addqi_1"
6090   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6091         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6092                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6093    (clobber (reg:CC FLAGS_REG))]
6094   "TARGET_PARTIAL_REG_STALL
6095    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6096 {
6097   int widen = (which_alternative == 2);
6098   switch (get_attr_type (insn))
6099     {
6100     case TYPE_INCDEC:
6101       if (operands[2] == const1_rtx)
6102         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6103       else
6104         {
6105           gcc_assert (operands[2] == constm1_rtx);
6106           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6107         }
6108
6109     default:
6110       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6111          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6112       if (GET_CODE (operands[2]) == CONST_INT
6113           && (INTVAL (operands[2]) == 128
6114               || (INTVAL (operands[2]) < 0
6115                   && INTVAL (operands[2]) != -128)))
6116         {
6117           operands[2] = GEN_INT (-INTVAL (operands[2]));
6118           if (widen)
6119             return "sub{l}\t{%2, %k0|%k0, %2}";
6120           else
6121             return "sub{b}\t{%2, %0|%0, %2}";
6122         }
6123       if (widen)
6124         return "add{l}\t{%k2, %k0|%k0, %k2}";
6125       else
6126         return "add{b}\t{%2, %0|%0, %2}";
6127     }
6128 }
6129   [(set (attr "type")
6130      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6131         (const_string "incdec")
6132         (const_string "alu")))
6133    (set_attr "mode" "QI,QI,SI")])
6134
6135 (define_insn "*addqi_1_slp"
6136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6137         (plus:QI (match_dup 0)
6138                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6139    (clobber (reg:CC FLAGS_REG))]
6140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6142 {
6143   switch (get_attr_type (insn))
6144     {
6145     case TYPE_INCDEC:
6146       if (operands[1] == const1_rtx)
6147         return "inc{b}\t%0";
6148       else
6149         {
6150           gcc_assert (operands[1] == constm1_rtx);
6151           return "dec{b}\t%0";
6152         }
6153
6154     default:
6155       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6156       if (GET_CODE (operands[1]) == CONST_INT
6157           && INTVAL (operands[1]) < 0)
6158         {
6159           operands[1] = GEN_INT (-INTVAL (operands[1]));
6160           return "sub{b}\t{%1, %0|%0, %1}";
6161         }
6162       return "add{b}\t{%1, %0|%0, %1}";
6163     }
6164 }
6165   [(set (attr "type")
6166      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6167         (const_string "incdec")
6168         (const_string "alu1")))
6169    (set (attr "memory")
6170      (if_then_else (match_operand 1 "memory_operand" "")
6171         (const_string "load")
6172         (const_string "none")))
6173    (set_attr "mode" "QI")])
6174
6175 (define_insn "*addqi_2"
6176   [(set (reg FLAGS_REG)
6177         (compare
6178           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6179                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6180           (const_int 0)))
6181    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6182         (plus:QI (match_dup 1) (match_dup 2)))]
6183   "ix86_match_ccmode (insn, CCGOCmode)
6184    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6185 {
6186   switch (get_attr_type (insn))
6187     {
6188     case TYPE_INCDEC:
6189       if (operands[2] == const1_rtx)
6190         return "inc{b}\t%0";
6191       else
6192         {
6193           gcc_assert (operands[2] == constm1_rtx
6194                       || (GET_CODE (operands[2]) == CONST_INT
6195                           && INTVAL (operands[2]) == 255));
6196           return "dec{b}\t%0";
6197         }
6198
6199     default:
6200       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6201       if (GET_CODE (operands[2]) == CONST_INT
6202           && INTVAL (operands[2]) < 0)
6203         {
6204           operands[2] = GEN_INT (-INTVAL (operands[2]));
6205           return "sub{b}\t{%2, %0|%0, %2}";
6206         }
6207       return "add{b}\t{%2, %0|%0, %2}";
6208     }
6209 }
6210   [(set (attr "type")
6211      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212         (const_string "incdec")
6213         (const_string "alu")))
6214    (set_attr "mode" "QI")])
6215
6216 (define_insn "*addqi_3"
6217   [(set (reg FLAGS_REG)
6218         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6219                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6220    (clobber (match_scratch:QI 0 "=q"))]
6221   "ix86_match_ccmode (insn, CCZmode)
6222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6223 {
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_INCDEC:
6227       if (operands[2] == const1_rtx)
6228         return "inc{b}\t%0";
6229       else
6230         {
6231           gcc_assert (operands[2] == constm1_rtx
6232                       || (GET_CODE (operands[2]) == CONST_INT
6233                           && INTVAL (operands[2]) == 255));
6234           return "dec{b}\t%0";
6235         }
6236
6237     default:
6238       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6239       if (GET_CODE (operands[2]) == CONST_INT
6240           && INTVAL (operands[2]) < 0)
6241         {
6242           operands[2] = GEN_INT (-INTVAL (operands[2]));
6243           return "sub{b}\t{%2, %0|%0, %2}";
6244         }
6245       return "add{b}\t{%2, %0|%0, %2}";
6246     }
6247 }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set_attr "mode" "QI")])
6253
6254 ; See comments above addsi_4 for details.
6255 (define_insn "*addqi_4"
6256   [(set (reg FLAGS_REG)
6257         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6258                  (match_operand:QI 2 "const_int_operand" "n")))
6259    (clobber (match_scratch:QI 0 "=qm"))]
6260   "ix86_match_ccmode (insn, CCGCmode)
6261    && (INTVAL (operands[2]) & 0xff) != 0x80"
6262 {
6263   switch (get_attr_type (insn))
6264     {
6265     case TYPE_INCDEC:
6266       if (operands[2] == constm1_rtx
6267           || (GET_CODE (operands[2]) == CONST_INT
6268               && INTVAL (operands[2]) == 255))
6269         return "inc{b}\t%0";
6270       else
6271         {
6272           gcc_assert (operands[2] == const1_rtx);
6273           return "dec{b}\t%0";
6274         }
6275
6276     default:
6277       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6278       if (INTVAL (operands[2]) < 0)
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           return "add{b}\t{%2, %0|%0, %2}";
6282         }
6283       return "sub{b}\t{%2, %0|%0, %2}";
6284     }
6285 }
6286   [(set (attr "type")
6287      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6288         (const_string "incdec")
6289         (const_string "alu")))
6290    (set_attr "mode" "QI")])
6291
6292
6293 (define_insn "*addqi_5"
6294   [(set (reg FLAGS_REG)
6295         (compare
6296           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6297                    (match_operand:QI 2 "general_operand" "qmni"))
6298           (const_int 0)))
6299    (clobber (match_scratch:QI 0 "=q"))]
6300   "ix86_match_ccmode (insn, CCGOCmode)
6301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6302 {
6303   switch (get_attr_type (insn))
6304     {
6305     case TYPE_INCDEC:
6306       if (operands[2] == const1_rtx)
6307         return "inc{b}\t%0";
6308       else
6309         {
6310           gcc_assert (operands[2] == constm1_rtx
6311                       || (GET_CODE (operands[2]) == CONST_INT
6312                           && INTVAL (operands[2]) == 255));
6313           return "dec{b}\t%0";
6314         }
6315
6316     default:
6317       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6318       if (GET_CODE (operands[2]) == CONST_INT
6319           && INTVAL (operands[2]) < 0)
6320         {
6321           operands[2] = GEN_INT (-INTVAL (operands[2]));
6322           return "sub{b}\t{%2, %0|%0, %2}";
6323         }
6324       return "add{b}\t{%2, %0|%0, %2}";
6325     }
6326 }
6327   [(set (attr "type")
6328      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6329         (const_string "incdec")
6330         (const_string "alu")))
6331    (set_attr "mode" "QI")])
6332
6333
6334 (define_insn "addqi_ext_1"
6335   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6336                          (const_int 8)
6337                          (const_int 8))
6338         (plus:SI
6339           (zero_extract:SI
6340             (match_operand 1 "ext_register_operand" "0")
6341             (const_int 8)
6342             (const_int 8))
6343           (match_operand:QI 2 "general_operand" "Qmn")))
6344    (clobber (reg:CC FLAGS_REG))]
6345   "!TARGET_64BIT"
6346 {
6347   switch (get_attr_type (insn))
6348     {
6349     case TYPE_INCDEC:
6350       if (operands[2] == const1_rtx)
6351         return "inc{b}\t%h0";
6352       else
6353         {
6354           gcc_assert (operands[2] == constm1_rtx
6355                       || (GET_CODE (operands[2]) == CONST_INT
6356                           && INTVAL (operands[2]) == 255));
6357           return "dec{b}\t%h0";
6358         }
6359
6360     default:
6361       return "add{b}\t{%2, %h0|%h0, %2}";
6362     }
6363 }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6369
6370 (define_insn "*addqi_ext_1_rex64"
6371   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6372                          (const_int 8)
6373                          (const_int 8))
6374         (plus:SI
6375           (zero_extract:SI
6376             (match_operand 1 "ext_register_operand" "0")
6377             (const_int 8)
6378             (const_int 8))
6379           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6380    (clobber (reg:CC FLAGS_REG))]
6381   "TARGET_64BIT"
6382 {
6383   switch (get_attr_type (insn))
6384     {
6385     case TYPE_INCDEC:
6386       if (operands[2] == const1_rtx)
6387         return "inc{b}\t%h0";
6388       else
6389         {
6390           gcc_assert (operands[2] == constm1_rtx
6391                       || (GET_CODE (operands[2]) == CONST_INT
6392                           && INTVAL (operands[2]) == 255));
6393           return "dec{b}\t%h0";
6394         }
6395
6396     default:
6397       return "add{b}\t{%2, %h0|%h0, %2}";
6398     }
6399 }
6400   [(set (attr "type")
6401      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6402         (const_string "incdec")
6403         (const_string "alu")))
6404    (set_attr "mode" "QI")])
6405
6406 (define_insn "*addqi_ext_2"
6407   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6408                          (const_int 8)
6409                          (const_int 8))
6410         (plus:SI
6411           (zero_extract:SI
6412             (match_operand 1 "ext_register_operand" "%0")
6413             (const_int 8)
6414             (const_int 8))
6415           (zero_extract:SI
6416             (match_operand 2 "ext_register_operand" "Q")
6417             (const_int 8)
6418             (const_int 8))))
6419    (clobber (reg:CC FLAGS_REG))]
6420   ""
6421   "add{b}\t{%h2, %h0|%h0, %h2}"
6422   [(set_attr "type" "alu")
6423    (set_attr "mode" "QI")])
6424
6425 ;; The patterns that match these are at the end of this file.
6426
6427 (define_expand "addxf3"
6428   [(set (match_operand:XF 0 "register_operand" "")
6429         (plus:XF (match_operand:XF 1 "register_operand" "")
6430                  (match_operand:XF 2 "register_operand" "")))]
6431   "TARGET_80387"
6432   "")
6433
6434 (define_expand "adddf3"
6435   [(set (match_operand:DF 0 "register_operand" "")
6436         (plus:DF (match_operand:DF 1 "register_operand" "")
6437                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6438   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6439   "")
6440
6441 (define_expand "addsf3"
6442   [(set (match_operand:SF 0 "register_operand" "")
6443         (plus:SF (match_operand:SF 1 "register_operand" "")
6444                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6445   "TARGET_80387 || TARGET_SSE_MATH"
6446   "")
6447 \f
6448 ;; Subtract instructions
6449
6450 ;; %%% splits for subditi3
6451
6452 (define_expand "subti3"
6453   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6454                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6455                              (match_operand:TI 2 "x86_64_general_operand" "")))
6456               (clobber (reg:CC FLAGS_REG))])]
6457   "TARGET_64BIT"
6458   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6459
6460 (define_insn "*subti3_1"
6461   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6462         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6463                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6466   "#")
6467
6468 (define_split
6469   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6470         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6471                   (match_operand:TI 2 "general_operand" "")))
6472    (clobber (reg:CC FLAGS_REG))]
6473   "TARGET_64BIT && reload_completed"
6474   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6475               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6476    (parallel [(set (match_dup 3)
6477                    (minus:DI (match_dup 4)
6478                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6479                                       (match_dup 5))))
6480               (clobber (reg:CC FLAGS_REG))])]
6481   "split_ti (operands+0, 1, operands+0, operands+3);
6482    split_ti (operands+1, 1, operands+1, operands+4);
6483    split_ti (operands+2, 1, operands+2, operands+5);")
6484
6485 ;; %%% splits for subsidi3
6486
6487 (define_expand "subdi3"
6488   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6489                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6490                              (match_operand:DI 2 "x86_64_general_operand" "")))
6491               (clobber (reg:CC FLAGS_REG))])]
6492   ""
6493   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6494
6495 (define_insn "*subdi3_1"
6496   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6497         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6498                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6499    (clobber (reg:CC FLAGS_REG))]
6500   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6501   "#")
6502
6503 (define_split
6504   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6505         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6506                   (match_operand:DI 2 "general_operand" "")))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "!TARGET_64BIT && reload_completed"
6509   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6510               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6511    (parallel [(set (match_dup 3)
6512                    (minus:SI (match_dup 4)
6513                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6514                                       (match_dup 5))))
6515               (clobber (reg:CC FLAGS_REG))])]
6516   "split_di (operands+0, 1, operands+0, operands+3);
6517    split_di (operands+1, 1, operands+1, operands+4);
6518    split_di (operands+2, 1, operands+2, operands+5);")
6519
6520 (define_insn "subdi3_carry_rex64"
6521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6522           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6523             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6524                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6527   "sbb{q}\t{%2, %0|%0, %2}"
6528   [(set_attr "type" "alu")
6529    (set_attr "pent_pair" "pu")
6530    (set_attr "mode" "DI")])
6531
6532 (define_insn "*subdi_1_rex64"
6533   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6534         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6535                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6538   "sub{q}\t{%2, %0|%0, %2}"
6539   [(set_attr "type" "alu")
6540    (set_attr "mode" "DI")])
6541
6542 (define_insn "*subdi_2_rex64"
6543   [(set (reg FLAGS_REG)
6544         (compare
6545           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6547           (const_int 0)))
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, CCGOCmode)
6551    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6552   "sub{q}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "DI")])
6555
6556 (define_insn "*subdi_3_rex63"
6557   [(set (reg FLAGS_REG)
6558         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6559                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6560    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6561         (minus:DI (match_dup 1) (match_dup 2)))]
6562   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6563    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6564   "sub{q}\t{%2, %0|%0, %2}"
6565   [(set_attr "type" "alu")
6566    (set_attr "mode" "DI")])
6567
6568 (define_insn "subqi3_carry"
6569   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6570           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6571             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6572                (match_operand:QI 2 "general_operand" "qi,qm"))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6575   "sbb{b}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "pent_pair" "pu")
6578    (set_attr "mode" "QI")])
6579
6580 (define_insn "subhi3_carry"
6581   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6582           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6583             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6584                (match_operand:HI 2 "general_operand" "ri,rm"))))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6587   "sbb{w}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "pent_pair" "pu")
6590    (set_attr "mode" "HI")])
6591
6592 (define_insn "subsi3_carry"
6593   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6594           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6595             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6596                (match_operand:SI 2 "general_operand" "ri,rm"))))
6597    (clobber (reg:CC FLAGS_REG))]
6598   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6599   "sbb{l}\t{%2, %0|%0, %2}"
6600   [(set_attr "type" "alu")
6601    (set_attr "pent_pair" "pu")
6602    (set_attr "mode" "SI")])
6603
6604 (define_insn "subsi3_carry_zext"
6605   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6606           (zero_extend:DI
6607             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6608               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6609                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6612   "sbb{l}\t{%2, %k0|%k0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "pent_pair" "pu")
6615    (set_attr "mode" "SI")])
6616
6617 (define_expand "subsi3"
6618   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6619                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6620                              (match_operand:SI 2 "general_operand" "")))
6621               (clobber (reg:CC FLAGS_REG))])]
6622   ""
6623   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6624
6625 (define_insn "*subsi_1"
6626   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6627         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6628                   (match_operand:SI 2 "general_operand" "ri,rm")))
6629    (clobber (reg:CC FLAGS_REG))]
6630   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6631   "sub{l}\t{%2, %0|%0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "SI")])
6634
6635 (define_insn "*subsi_1_zext"
6636   [(set (match_operand:DI 0 "register_operand" "=r")
6637         (zero_extend:DI
6638           (minus:SI (match_operand:SI 1 "register_operand" "0")
6639                     (match_operand:SI 2 "general_operand" "rim"))))
6640    (clobber (reg:CC FLAGS_REG))]
6641   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sub{l}\t{%2, %k0|%k0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "SI")])
6645
6646 (define_insn "*subsi_2"
6647   [(set (reg FLAGS_REG)
6648         (compare
6649           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6650                     (match_operand:SI 2 "general_operand" "ri,rm"))
6651           (const_int 0)))
6652    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6653         (minus:SI (match_dup 1) (match_dup 2)))]
6654   "ix86_match_ccmode (insn, CCGOCmode)
6655    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6656   "sub{l}\t{%2, %0|%0, %2}"
6657   [(set_attr "type" "alu")
6658    (set_attr "mode" "SI")])
6659
6660 (define_insn "*subsi_2_zext"
6661   [(set (reg FLAGS_REG)
6662         (compare
6663           (minus:SI (match_operand:SI 1 "register_operand" "0")
6664                     (match_operand:SI 2 "general_operand" "rim"))
6665           (const_int 0)))
6666    (set (match_operand:DI 0 "register_operand" "=r")
6667         (zero_extend:DI
6668           (minus:SI (match_dup 1)
6669                     (match_dup 2))))]
6670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6671    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672   "sub{l}\t{%2, %k0|%k0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "mode" "SI")])
6675
6676 (define_insn "*subsi_3"
6677   [(set (reg FLAGS_REG)
6678         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6679                  (match_operand:SI 2 "general_operand" "ri,rm")))
6680    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6681         (minus:SI (match_dup 1) (match_dup 2)))]
6682   "ix86_match_ccmode (insn, CCmode)
6683    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6684   "sub{l}\t{%2, %0|%0, %2}"
6685   [(set_attr "type" "alu")
6686    (set_attr "mode" "SI")])
6687
6688 (define_insn "*subsi_3_zext"
6689   [(set (reg FLAGS_REG)
6690         (compare (match_operand:SI 1 "register_operand" "0")
6691                  (match_operand:SI 2 "general_operand" "rim")))
6692    (set (match_operand:DI 0 "register_operand" "=r")
6693         (zero_extend:DI
6694           (minus:SI (match_dup 1)
6695                     (match_dup 2))))]
6696   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6697    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698   "sub{q}\t{%2, %0|%0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "mode" "DI")])
6701
6702 (define_expand "subhi3"
6703   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6704                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6705                              (match_operand:HI 2 "general_operand" "")))
6706               (clobber (reg:CC FLAGS_REG))])]
6707   "TARGET_HIMODE_MATH"
6708   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6709
6710 (define_insn "*subhi_1"
6711   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6712         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6713                   (match_operand:HI 2 "general_operand" "ri,rm")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6716   "sub{w}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "HI")])
6719
6720 (define_insn "*subhi_2"
6721   [(set (reg FLAGS_REG)
6722         (compare
6723           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6724                     (match_operand:HI 2 "general_operand" "ri,rm"))
6725           (const_int 0)))
6726    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6727         (minus:HI (match_dup 1) (match_dup 2)))]
6728   "ix86_match_ccmode (insn, CCGOCmode)
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_insn "*subhi_3"
6735   [(set (reg FLAGS_REG)
6736         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6737                  (match_operand:HI 2 "general_operand" "ri,rm")))
6738    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:HI (match_dup 1) (match_dup 2)))]
6740   "ix86_match_ccmode (insn, CCmode)
6741    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6742   "sub{w}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "alu")
6744    (set_attr "mode" "HI")])
6745
6746 (define_expand "subqi3"
6747   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6748                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6749                              (match_operand:QI 2 "general_operand" "")))
6750               (clobber (reg:CC FLAGS_REG))])]
6751   "TARGET_QIMODE_MATH"
6752   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6753
6754 (define_insn "*subqi_1"
6755   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6756         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6757                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6760   "sub{b}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "QI")])
6763
6764 (define_insn "*subqi_1_slp"
6765   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6766         (minus:QI (match_dup 0)
6767                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6768    (clobber (reg:CC FLAGS_REG))]
6769   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6770    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6771   "sub{b}\t{%1, %0|%0, %1}"
6772   [(set_attr "type" "alu1")
6773    (set_attr "mode" "QI")])
6774
6775 (define_insn "*subqi_2"
6776   [(set (reg FLAGS_REG)
6777         (compare
6778           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6779                     (match_operand:QI 2 "general_operand" "qi,qm"))
6780           (const_int 0)))
6781    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6782         (minus:HI (match_dup 1) (match_dup 2)))]
6783   "ix86_match_ccmode (insn, CCGOCmode)
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 (define_insn "*subqi_3"
6790   [(set (reg FLAGS_REG)
6791         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6792                  (match_operand:QI 2 "general_operand" "qi,qm")))
6793    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6794         (minus:HI (match_dup 1) (match_dup 2)))]
6795   "ix86_match_ccmode (insn, CCmode)
6796    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6797   "sub{b}\t{%2, %0|%0, %2}"
6798   [(set_attr "type" "alu")
6799    (set_attr "mode" "QI")])
6800
6801 ;; The patterns that match these are at the end of this file.
6802
6803 (define_expand "subxf3"
6804   [(set (match_operand:XF 0 "register_operand" "")
6805         (minus:XF (match_operand:XF 1 "register_operand" "")
6806                   (match_operand:XF 2 "register_operand" "")))]
6807   "TARGET_80387"
6808   "")
6809
6810 (define_expand "subdf3"
6811   [(set (match_operand:DF 0 "register_operand" "")
6812         (minus:DF (match_operand:DF 1 "register_operand" "")
6813                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6814   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6815   "")
6816
6817 (define_expand "subsf3"
6818   [(set (match_operand:SF 0 "register_operand" "")
6819         (minus:SF (match_operand:SF 1 "register_operand" "")
6820                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6821   "TARGET_80387 || TARGET_SSE_MATH"
6822   "")
6823 \f
6824 ;; Multiply instructions
6825
6826 (define_expand "muldi3"
6827   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6828                    (mult:DI (match_operand:DI 1 "register_operand" "")
6829                             (match_operand:DI 2 "x86_64_general_operand" "")))
6830               (clobber (reg:CC FLAGS_REG))])]
6831   "TARGET_64BIT"
6832   "")
6833
6834 (define_insn "*muldi3_1_rex64"
6835   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6836         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6837                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6838    (clobber (reg:CC FLAGS_REG))]
6839   "TARGET_64BIT
6840    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6841   "@
6842    imul{q}\t{%2, %1, %0|%0, %1, %2}
6843    imul{q}\t{%2, %1, %0|%0, %1, %2}
6844    imul{q}\t{%2, %0|%0, %2}"
6845   [(set_attr "type" "imul")
6846    (set_attr "prefix_0f" "0,0,1")
6847    (set (attr "athlon_decode")
6848         (cond [(eq_attr "cpu" "athlon")
6849                   (const_string "vector")
6850                (eq_attr "alternative" "1")
6851                   (const_string "vector")
6852                (and (eq_attr "alternative" "2")
6853                     (match_operand 1 "memory_operand" ""))
6854                   (const_string "vector")]
6855               (const_string "direct")))
6856    (set_attr "mode" "DI")])
6857
6858 (define_expand "mulsi3"
6859   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6860                    (mult:SI (match_operand:SI 1 "register_operand" "")
6861                             (match_operand:SI 2 "general_operand" "")))
6862               (clobber (reg:CC FLAGS_REG))])]
6863   ""
6864   "")
6865
6866 (define_insn "*mulsi3_1"
6867   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6868         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6869                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6870    (clobber (reg:CC FLAGS_REG))]
6871   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6872   "@
6873    imul{l}\t{%2, %1, %0|%0, %1, %2}
6874    imul{l}\t{%2, %1, %0|%0, %1, %2}
6875    imul{l}\t{%2, %0|%0, %2}"
6876   [(set_attr "type" "imul")
6877    (set_attr "prefix_0f" "0,0,1")
6878    (set (attr "athlon_decode")
6879         (cond [(eq_attr "cpu" "athlon")
6880                   (const_string "vector")
6881                (eq_attr "alternative" "1")
6882                   (const_string "vector")
6883                (and (eq_attr "alternative" "2")
6884                     (match_operand 1 "memory_operand" ""))
6885                   (const_string "vector")]
6886               (const_string "direct")))
6887    (set_attr "mode" "SI")])
6888
6889 (define_insn "*mulsi3_1_zext"
6890   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6891         (zero_extend:DI
6892           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6893                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6894    (clobber (reg:CC FLAGS_REG))]
6895   "TARGET_64BIT
6896    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6897   "@
6898    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6899    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6900    imul{l}\t{%2, %k0|%k0, %2}"
6901   [(set_attr "type" "imul")
6902    (set_attr "prefix_0f" "0,0,1")
6903    (set (attr "athlon_decode")
6904         (cond [(eq_attr "cpu" "athlon")
6905                   (const_string "vector")
6906                (eq_attr "alternative" "1")
6907                   (const_string "vector")
6908                (and (eq_attr "alternative" "2")
6909                     (match_operand 1 "memory_operand" ""))
6910                   (const_string "vector")]
6911               (const_string "direct")))
6912    (set_attr "mode" "SI")])
6913
6914 (define_expand "mulhi3"
6915   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6916                    (mult:HI (match_operand:HI 1 "register_operand" "")
6917                             (match_operand:HI 2 "general_operand" "")))
6918               (clobber (reg:CC FLAGS_REG))])]
6919   "TARGET_HIMODE_MATH"
6920   "")
6921
6922 (define_insn "*mulhi3_1"
6923   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6924         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6925                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6926    (clobber (reg:CC FLAGS_REG))]
6927   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6928   "@
6929    imul{w}\t{%2, %1, %0|%0, %1, %2}
6930    imul{w}\t{%2, %1, %0|%0, %1, %2}
6931    imul{w}\t{%2, %0|%0, %2}"
6932   [(set_attr "type" "imul")
6933    (set_attr "prefix_0f" "0,0,1")
6934    (set (attr "athlon_decode")
6935         (cond [(eq_attr "cpu" "athlon")
6936                   (const_string "vector")
6937                (eq_attr "alternative" "1,2")
6938                   (const_string "vector")]
6939               (const_string "direct")))
6940    (set_attr "mode" "HI")])
6941
6942 (define_expand "mulqi3"
6943   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6944                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6945                             (match_operand:QI 2 "register_operand" "")))
6946               (clobber (reg:CC FLAGS_REG))])]
6947   "TARGET_QIMODE_MATH"
6948   "")
6949
6950 (define_insn "*mulqi3_1"
6951   [(set (match_operand:QI 0 "register_operand" "=a")
6952         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6953                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "TARGET_QIMODE_MATH
6956    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6957   "mul{b}\t%2"
6958   [(set_attr "type" "imul")
6959    (set_attr "length_immediate" "0")
6960    (set (attr "athlon_decode")
6961      (if_then_else (eq_attr "cpu" "athlon")
6962         (const_string "vector")
6963         (const_string "direct")))
6964    (set_attr "mode" "QI")])
6965
6966 (define_expand "umulqihi3"
6967   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6968                    (mult:HI (zero_extend:HI
6969                               (match_operand:QI 1 "nonimmediate_operand" ""))
6970                             (zero_extend:HI
6971                               (match_operand:QI 2 "register_operand" ""))))
6972               (clobber (reg:CC FLAGS_REG))])]
6973   "TARGET_QIMODE_MATH"
6974   "")
6975
6976 (define_insn "*umulqihi3_1"
6977   [(set (match_operand:HI 0 "register_operand" "=a")
6978         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6979                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "TARGET_QIMODE_MATH
6982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6983   "mul{b}\t%2"
6984   [(set_attr "type" "imul")
6985    (set_attr "length_immediate" "0")
6986    (set (attr "athlon_decode")
6987      (if_then_else (eq_attr "cpu" "athlon")
6988         (const_string "vector")
6989         (const_string "direct")))
6990    (set_attr "mode" "QI")])
6991
6992 (define_expand "mulqihi3"
6993   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6995                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6996               (clobber (reg:CC FLAGS_REG))])]
6997   "TARGET_QIMODE_MATH"
6998   "")
6999
7000 (define_insn "*mulqihi3_insn"
7001   [(set (match_operand:HI 0 "register_operand" "=a")
7002         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7003                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "TARGET_QIMODE_MATH
7006    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7007   "imul{b}\t%2"
7008   [(set_attr "type" "imul")
7009    (set_attr "length_immediate" "0")
7010    (set (attr "athlon_decode")
7011      (if_then_else (eq_attr "cpu" "athlon")
7012         (const_string "vector")
7013         (const_string "direct")))
7014    (set_attr "mode" "QI")])
7015
7016 (define_expand "umulditi3"
7017   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7018                    (mult:TI (zero_extend:TI
7019                               (match_operand:DI 1 "nonimmediate_operand" ""))
7020                             (zero_extend:TI
7021                               (match_operand:DI 2 "register_operand" ""))))
7022               (clobber (reg:CC FLAGS_REG))])]
7023   "TARGET_64BIT"
7024   "")
7025
7026 (define_insn "*umulditi3_insn"
7027   [(set (match_operand:TI 0 "register_operand" "=A")
7028         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7029                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7030    (clobber (reg:CC FLAGS_REG))]
7031   "TARGET_64BIT
7032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7033   "mul{q}\t%2"
7034   [(set_attr "type" "imul")
7035    (set_attr "length_immediate" "0")
7036    (set (attr "athlon_decode")
7037      (if_then_else (eq_attr "cpu" "athlon")
7038         (const_string "vector")
7039         (const_string "double")))
7040    (set_attr "mode" "DI")])
7041
7042 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7043 (define_expand "umulsidi3"
7044   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7045                    (mult:DI (zero_extend:DI
7046                               (match_operand:SI 1 "nonimmediate_operand" ""))
7047                             (zero_extend:DI
7048                               (match_operand:SI 2 "register_operand" ""))))
7049               (clobber (reg:CC FLAGS_REG))])]
7050   "!TARGET_64BIT"
7051   "")
7052
7053 (define_insn "*umulsidi3_insn"
7054   [(set (match_operand:DI 0 "register_operand" "=A")
7055         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7056                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7057    (clobber (reg:CC FLAGS_REG))]
7058   "!TARGET_64BIT
7059    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7060   "mul{l}\t%2"
7061   [(set_attr "type" "imul")
7062    (set_attr "length_immediate" "0")
7063    (set (attr "athlon_decode")
7064      (if_then_else (eq_attr "cpu" "athlon")
7065         (const_string "vector")
7066         (const_string "double")))
7067    (set_attr "mode" "SI")])
7068
7069 (define_expand "mulditi3"
7070   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7071                    (mult:TI (sign_extend:TI
7072                               (match_operand:DI 1 "nonimmediate_operand" ""))
7073                             (sign_extend:TI
7074                               (match_operand:DI 2 "register_operand" ""))))
7075               (clobber (reg:CC FLAGS_REG))])]
7076   "TARGET_64BIT"
7077   "")
7078
7079 (define_insn "*mulditi3_insn"
7080   [(set (match_operand:TI 0 "register_operand" "=A")
7081         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7082                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7083    (clobber (reg:CC FLAGS_REG))]
7084   "TARGET_64BIT
7085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7086   "imul{q}\t%2"
7087   [(set_attr "type" "imul")
7088    (set_attr "length_immediate" "0")
7089    (set (attr "athlon_decode")
7090      (if_then_else (eq_attr "cpu" "athlon")
7091         (const_string "vector")
7092         (const_string "double")))
7093    (set_attr "mode" "DI")])
7094
7095 (define_expand "mulsidi3"
7096   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7097                    (mult:DI (sign_extend:DI
7098                               (match_operand:SI 1 "nonimmediate_operand" ""))
7099                             (sign_extend:DI
7100                               (match_operand:SI 2 "register_operand" ""))))
7101               (clobber (reg:CC FLAGS_REG))])]
7102   "!TARGET_64BIT"
7103   "")
7104
7105 (define_insn "*mulsidi3_insn"
7106   [(set (match_operand:DI 0 "register_operand" "=A")
7107         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7108                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7109    (clobber (reg:CC FLAGS_REG))]
7110   "!TARGET_64BIT
7111    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7112   "imul{l}\t%2"
7113   [(set_attr "type" "imul")
7114    (set_attr "length_immediate" "0")
7115    (set (attr "athlon_decode")
7116      (if_then_else (eq_attr "cpu" "athlon")
7117         (const_string "vector")
7118         (const_string "double")))
7119    (set_attr "mode" "SI")])
7120
7121 (define_expand "umuldi3_highpart"
7122   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123                    (truncate:DI
7124                      (lshiftrt:TI
7125                        (mult:TI (zero_extend:TI
7126                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7127                                 (zero_extend:TI
7128                                   (match_operand:DI 2 "register_operand" "")))
7129                        (const_int 64))))
7130               (clobber (match_scratch:DI 3 ""))
7131               (clobber (reg:CC FLAGS_REG))])]
7132   "TARGET_64BIT"
7133   "")
7134
7135 (define_insn "*umuldi3_highpart_rex64"
7136   [(set (match_operand:DI 0 "register_operand" "=d")
7137         (truncate:DI
7138           (lshiftrt:TI
7139             (mult:TI (zero_extend:TI
7140                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7141                      (zero_extend:TI
7142                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7143             (const_int 64))))
7144    (clobber (match_scratch:DI 3 "=1"))
7145    (clobber (reg:CC FLAGS_REG))]
7146   "TARGET_64BIT
7147    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7148   "mul{q}\t%2"
7149   [(set_attr "type" "imul")
7150    (set_attr "length_immediate" "0")
7151    (set (attr "athlon_decode")
7152      (if_then_else (eq_attr "cpu" "athlon")
7153         (const_string "vector")
7154         (const_string "double")))
7155    (set_attr "mode" "DI")])
7156
7157 (define_expand "umulsi3_highpart"
7158   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7159                    (truncate:SI
7160                      (lshiftrt:DI
7161                        (mult:DI (zero_extend:DI
7162                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7163                                 (zero_extend:DI
7164                                   (match_operand:SI 2 "register_operand" "")))
7165                        (const_int 32))))
7166               (clobber (match_scratch:SI 3 ""))
7167               (clobber (reg:CC FLAGS_REG))])]
7168   ""
7169   "")
7170
7171 (define_insn "*umulsi3_highpart_insn"
7172   [(set (match_operand:SI 0 "register_operand" "=d")
7173         (truncate:SI
7174           (lshiftrt:DI
7175             (mult:DI (zero_extend:DI
7176                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7177                      (zero_extend:DI
7178                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7179             (const_int 32))))
7180    (clobber (match_scratch:SI 3 "=1"))
7181    (clobber (reg:CC FLAGS_REG))]
7182   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7183   "mul{l}\t%2"
7184   [(set_attr "type" "imul")
7185    (set_attr "length_immediate" "0")
7186    (set (attr "athlon_decode")
7187      (if_then_else (eq_attr "cpu" "athlon")
7188         (const_string "vector")
7189         (const_string "double")))
7190    (set_attr "mode" "SI")])
7191
7192 (define_insn "*umulsi3_highpart_zext"
7193   [(set (match_operand:DI 0 "register_operand" "=d")
7194         (zero_extend:DI (truncate:SI
7195           (lshiftrt:DI
7196             (mult:DI (zero_extend:DI
7197                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7198                      (zero_extend:DI
7199                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7200             (const_int 32)))))
7201    (clobber (match_scratch:SI 3 "=1"))
7202    (clobber (reg:CC FLAGS_REG))]
7203   "TARGET_64BIT
7204    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7205   "mul{l}\t%2"
7206   [(set_attr "type" "imul")
7207    (set_attr "length_immediate" "0")
7208    (set (attr "athlon_decode")
7209      (if_then_else (eq_attr "cpu" "athlon")
7210         (const_string "vector")
7211         (const_string "double")))
7212    (set_attr "mode" "SI")])
7213
7214 (define_expand "smuldi3_highpart"
7215   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7216                    (truncate:DI
7217                      (lshiftrt:TI
7218                        (mult:TI (sign_extend:TI
7219                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7220                                 (sign_extend:TI
7221                                   (match_operand:DI 2 "register_operand" "")))
7222                        (const_int 64))))
7223               (clobber (match_scratch:DI 3 ""))
7224               (clobber (reg:CC FLAGS_REG))])]
7225   "TARGET_64BIT"
7226   "")
7227
7228 (define_insn "*smuldi3_highpart_rex64"
7229   [(set (match_operand:DI 0 "register_operand" "=d")
7230         (truncate:DI
7231           (lshiftrt:TI
7232             (mult:TI (sign_extend:TI
7233                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7234                      (sign_extend:TI
7235                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7236             (const_int 64))))
7237    (clobber (match_scratch:DI 3 "=1"))
7238    (clobber (reg:CC FLAGS_REG))]
7239   "TARGET_64BIT
7240    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7241   "imul{q}\t%2"
7242   [(set_attr "type" "imul")
7243    (set (attr "athlon_decode")
7244      (if_then_else (eq_attr "cpu" "athlon")
7245         (const_string "vector")
7246         (const_string "double")))
7247    (set_attr "mode" "DI")])
7248
7249 (define_expand "smulsi3_highpart"
7250   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7251                    (truncate:SI
7252                      (lshiftrt:DI
7253                        (mult:DI (sign_extend:DI
7254                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7255                                 (sign_extend:DI
7256                                   (match_operand:SI 2 "register_operand" "")))
7257                        (const_int 32))))
7258               (clobber (match_scratch:SI 3 ""))
7259               (clobber (reg:CC FLAGS_REG))])]
7260   ""
7261   "")
7262
7263 (define_insn "*smulsi3_highpart_insn"
7264   [(set (match_operand:SI 0 "register_operand" "=d")
7265         (truncate:SI
7266           (lshiftrt:DI
7267             (mult:DI (sign_extend:DI
7268                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7269                      (sign_extend:DI
7270                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7271             (const_int 32))))
7272    (clobber (match_scratch:SI 3 "=1"))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7275   "imul{l}\t%2"
7276   [(set_attr "type" "imul")
7277    (set (attr "athlon_decode")
7278      (if_then_else (eq_attr "cpu" "athlon")
7279         (const_string "vector")
7280         (const_string "double")))
7281    (set_attr "mode" "SI")])
7282
7283 (define_insn "*smulsi3_highpart_zext"
7284   [(set (match_operand:DI 0 "register_operand" "=d")
7285         (zero_extend:DI (truncate:SI
7286           (lshiftrt:DI
7287             (mult:DI (sign_extend:DI
7288                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7289                      (sign_extend:DI
7290                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7291             (const_int 32)))))
7292    (clobber (match_scratch:SI 3 "=1"))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "TARGET_64BIT
7295    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7296   "imul{l}\t%2"
7297   [(set_attr "type" "imul")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "double")))
7302    (set_attr "mode" "SI")])
7303
7304 ;; The patterns that match these are at the end of this file.
7305
7306 (define_expand "mulxf3"
7307   [(set (match_operand:XF 0 "register_operand" "")
7308         (mult:XF (match_operand:XF 1 "register_operand" "")
7309                  (match_operand:XF 2 "register_operand" "")))]
7310   "TARGET_80387"
7311   "")
7312
7313 (define_expand "muldf3"
7314   [(set (match_operand:DF 0 "register_operand" "")
7315         (mult:DF (match_operand:DF 1 "register_operand" "")
7316                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7317   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7318   "")
7319
7320 (define_expand "mulsf3"
7321   [(set (match_operand:SF 0 "register_operand" "")
7322         (mult:SF (match_operand:SF 1 "register_operand" "")
7323                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7324   "TARGET_80387 || TARGET_SSE_MATH"
7325   "")
7326 \f
7327 ;; Divide instructions
7328
7329 (define_insn "divqi3"
7330   [(set (match_operand:QI 0 "register_operand" "=a")
7331         (div:QI (match_operand:HI 1 "register_operand" "0")
7332                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_QIMODE_MATH"
7335   "idiv{b}\t%2"
7336   [(set_attr "type" "idiv")
7337    (set_attr "mode" "QI")])
7338
7339 (define_insn "udivqi3"
7340   [(set (match_operand:QI 0 "register_operand" "=a")
7341         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7342                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7343    (clobber (reg:CC FLAGS_REG))]
7344   "TARGET_QIMODE_MATH"
7345   "div{b}\t%2"
7346   [(set_attr "type" "idiv")
7347    (set_attr "mode" "QI")])
7348
7349 ;; The patterns that match these are at the end of this file.
7350
7351 (define_expand "divxf3"
7352   [(set (match_operand:XF 0 "register_operand" "")
7353         (div:XF (match_operand:XF 1 "register_operand" "")
7354                 (match_operand:XF 2 "register_operand" "")))]
7355   "TARGET_80387"
7356   "")
7357
7358 (define_expand "divdf3"
7359   [(set (match_operand:DF 0 "register_operand" "")
7360         (div:DF (match_operand:DF 1 "register_operand" "")
7361                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7362    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7363    "")
7364  
7365 (define_expand "divsf3"
7366   [(set (match_operand:SF 0 "register_operand" "")
7367         (div:SF (match_operand:SF 1 "register_operand" "")
7368                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7369   "TARGET_80387 || TARGET_SSE_MATH"
7370   "")
7371 \f
7372 ;; Remainder instructions.
7373
7374 (define_expand "divmoddi4"
7375   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7376                    (div:DI (match_operand:DI 1 "register_operand" "")
7377                            (match_operand:DI 2 "nonimmediate_operand" "")))
7378               (set (match_operand:DI 3 "register_operand" "")
7379                    (mod:DI (match_dup 1) (match_dup 2)))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_64BIT"
7382   "")
7383
7384 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7385 ;; Penalize eax case slightly because it results in worse scheduling
7386 ;; of code.
7387 (define_insn "*divmoddi4_nocltd_rex64"
7388   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7389         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7390                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7391    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7392         (mod:DI (match_dup 2) (match_dup 3)))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7395   "#"
7396   [(set_attr "type" "multi")])
7397
7398 (define_insn "*divmoddi4_cltd_rex64"
7399   [(set (match_operand:DI 0 "register_operand" "=a")
7400         (div:DI (match_operand:DI 2 "register_operand" "a")
7401                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7402    (set (match_operand:DI 1 "register_operand" "=&d")
7403         (mod:DI (match_dup 2) (match_dup 3)))
7404    (clobber (reg:CC FLAGS_REG))]
7405   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7406   "#"
7407   [(set_attr "type" "multi")])
7408
7409 (define_insn "*divmoddi_noext_rex64"
7410   [(set (match_operand:DI 0 "register_operand" "=a")
7411         (div:DI (match_operand:DI 1 "register_operand" "0")
7412                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7413    (set (match_operand:DI 3 "register_operand" "=d")
7414         (mod:DI (match_dup 1) (match_dup 2)))
7415    (use (match_operand:DI 4 "register_operand" "3"))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT"
7418   "idiv{q}\t%2"
7419   [(set_attr "type" "idiv")
7420    (set_attr "mode" "DI")])
7421
7422 (define_split
7423   [(set (match_operand:DI 0 "register_operand" "")
7424         (div:DI (match_operand:DI 1 "register_operand" "")
7425                 (match_operand:DI 2 "nonimmediate_operand" "")))
7426    (set (match_operand:DI 3 "register_operand" "")
7427         (mod:DI (match_dup 1) (match_dup 2)))
7428    (clobber (reg:CC FLAGS_REG))]
7429   "TARGET_64BIT && reload_completed"
7430   [(parallel [(set (match_dup 3)
7431                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7432               (clobber (reg:CC FLAGS_REG))])
7433    (parallel [(set (match_dup 0)
7434                    (div:DI (reg:DI 0) (match_dup 2)))
7435               (set (match_dup 3)
7436                    (mod:DI (reg:DI 0) (match_dup 2)))
7437               (use (match_dup 3))
7438               (clobber (reg:CC FLAGS_REG))])]
7439 {
7440   /* Avoid use of cltd in favor of a mov+shift.  */
7441   if (!TARGET_USE_CLTD && !optimize_size)
7442     {
7443       if (true_regnum (operands[1]))
7444         emit_move_insn (operands[0], operands[1]);
7445       else
7446         emit_move_insn (operands[3], operands[1]);
7447       operands[4] = operands[3];
7448     }
7449   else
7450     {
7451       gcc_assert (!true_regnum (operands[1]));
7452       operands[4] = operands[1];
7453     }
7454 })
7455
7456
7457 (define_expand "divmodsi4"
7458   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7459                    (div:SI (match_operand:SI 1 "register_operand" "")
7460                            (match_operand:SI 2 "nonimmediate_operand" "")))
7461               (set (match_operand:SI 3 "register_operand" "")
7462                    (mod:SI (match_dup 1) (match_dup 2)))
7463               (clobber (reg:CC FLAGS_REG))])]
7464   ""
7465   "")
7466
7467 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7468 ;; Penalize eax case slightly because it results in worse scheduling
7469 ;; of code.
7470 (define_insn "*divmodsi4_nocltd"
7471   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7472         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7473                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7474    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7475         (mod:SI (match_dup 2) (match_dup 3)))
7476    (clobber (reg:CC FLAGS_REG))]
7477   "!optimize_size && !TARGET_USE_CLTD"
7478   "#"
7479   [(set_attr "type" "multi")])
7480
7481 (define_insn "*divmodsi4_cltd"
7482   [(set (match_operand:SI 0 "register_operand" "=a")
7483         (div:SI (match_operand:SI 2 "register_operand" "a")
7484                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7485    (set (match_operand:SI 1 "register_operand" "=&d")
7486         (mod:SI (match_dup 2) (match_dup 3)))
7487    (clobber (reg:CC FLAGS_REG))]
7488   "optimize_size || TARGET_USE_CLTD"
7489   "#"
7490   [(set_attr "type" "multi")])
7491
7492 (define_insn "*divmodsi_noext"
7493   [(set (match_operand:SI 0 "register_operand" "=a")
7494         (div:SI (match_operand:SI 1 "register_operand" "0")
7495                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7496    (set (match_operand:SI 3 "register_operand" "=d")
7497         (mod:SI (match_dup 1) (match_dup 2)))
7498    (use (match_operand:SI 4 "register_operand" "3"))
7499    (clobber (reg:CC FLAGS_REG))]
7500   ""
7501   "idiv{l}\t%2"
7502   [(set_attr "type" "idiv")
7503    (set_attr "mode" "SI")])
7504
7505 (define_split
7506   [(set (match_operand:SI 0 "register_operand" "")
7507         (div:SI (match_operand:SI 1 "register_operand" "")
7508                 (match_operand:SI 2 "nonimmediate_operand" "")))
7509    (set (match_operand:SI 3 "register_operand" "")
7510         (mod:SI (match_dup 1) (match_dup 2)))
7511    (clobber (reg:CC FLAGS_REG))]
7512   "reload_completed"
7513   [(parallel [(set (match_dup 3)
7514                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7515               (clobber (reg:CC FLAGS_REG))])
7516    (parallel [(set (match_dup 0)
7517                    (div:SI (reg:SI 0) (match_dup 2)))
7518               (set (match_dup 3)
7519                    (mod:SI (reg:SI 0) (match_dup 2)))
7520               (use (match_dup 3))
7521               (clobber (reg:CC FLAGS_REG))])]
7522 {
7523   /* Avoid use of cltd in favor of a mov+shift.  */
7524   if (!TARGET_USE_CLTD && !optimize_size)
7525     {
7526       if (true_regnum (operands[1]))
7527         emit_move_insn (operands[0], operands[1]);
7528       else
7529         emit_move_insn (operands[3], operands[1]);
7530       operands[4] = operands[3];
7531     }
7532   else
7533     {
7534       gcc_assert (!true_regnum (operands[1]));
7535       operands[4] = operands[1];
7536     }
7537 })
7538 ;; %%% Split me.
7539 (define_insn "divmodhi4"
7540   [(set (match_operand:HI 0 "register_operand" "=a")
7541         (div:HI (match_operand:HI 1 "register_operand" "0")
7542                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7543    (set (match_operand:HI 3 "register_operand" "=&d")
7544         (mod:HI (match_dup 1) (match_dup 2)))
7545    (clobber (reg:CC FLAGS_REG))]
7546   "TARGET_HIMODE_MATH"
7547   "cwtd\;idiv{w}\t%2"
7548   [(set_attr "type" "multi")
7549    (set_attr "length_immediate" "0")
7550    (set_attr "mode" "SI")])
7551
7552 (define_insn "udivmoddi4"
7553   [(set (match_operand:DI 0 "register_operand" "=a")
7554         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7555                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7556    (set (match_operand:DI 3 "register_operand" "=&d")
7557         (umod:DI (match_dup 1) (match_dup 2)))
7558    (clobber (reg:CC FLAGS_REG))]
7559   "TARGET_64BIT"
7560   "xor{q}\t%3, %3\;div{q}\t%2"
7561   [(set_attr "type" "multi")
7562    (set_attr "length_immediate" "0")
7563    (set_attr "mode" "DI")])
7564
7565 (define_insn "*udivmoddi4_noext"
7566   [(set (match_operand:DI 0 "register_operand" "=a")
7567         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7568                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7569    (set (match_operand:DI 3 "register_operand" "=d")
7570         (umod:DI (match_dup 1) (match_dup 2)))
7571    (use (match_dup 3))
7572    (clobber (reg:CC FLAGS_REG))]
7573   "TARGET_64BIT"
7574   "div{q}\t%2"
7575   [(set_attr "type" "idiv")
7576    (set_attr "mode" "DI")])
7577
7578 (define_split
7579   [(set (match_operand:DI 0 "register_operand" "")
7580         (udiv:DI (match_operand:DI 1 "register_operand" "")
7581                  (match_operand:DI 2 "nonimmediate_operand" "")))
7582    (set (match_operand:DI 3 "register_operand" "")
7583         (umod:DI (match_dup 1) (match_dup 2)))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "TARGET_64BIT && reload_completed"
7586   [(set (match_dup 3) (const_int 0))
7587    (parallel [(set (match_dup 0)
7588                    (udiv:DI (match_dup 1) (match_dup 2)))
7589               (set (match_dup 3)
7590                    (umod:DI (match_dup 1) (match_dup 2)))
7591               (use (match_dup 3))
7592               (clobber (reg:CC FLAGS_REG))])]
7593   "")
7594
7595 (define_insn "udivmodsi4"
7596   [(set (match_operand:SI 0 "register_operand" "=a")
7597         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7598                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7599    (set (match_operand:SI 3 "register_operand" "=&d")
7600         (umod:SI (match_dup 1) (match_dup 2)))
7601    (clobber (reg:CC FLAGS_REG))]
7602   ""
7603   "xor{l}\t%3, %3\;div{l}\t%2"
7604   [(set_attr "type" "multi")
7605    (set_attr "length_immediate" "0")
7606    (set_attr "mode" "SI")])
7607
7608 (define_insn "*udivmodsi4_noext"
7609   [(set (match_operand:SI 0 "register_operand" "=a")
7610         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7611                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7612    (set (match_operand:SI 3 "register_operand" "=d")
7613         (umod:SI (match_dup 1) (match_dup 2)))
7614    (use (match_dup 3))
7615    (clobber (reg:CC FLAGS_REG))]
7616   ""
7617   "div{l}\t%2"
7618   [(set_attr "type" "idiv")
7619    (set_attr "mode" "SI")])
7620
7621 (define_split
7622   [(set (match_operand:SI 0 "register_operand" "")
7623         (udiv:SI (match_operand:SI 1 "register_operand" "")
7624                  (match_operand:SI 2 "nonimmediate_operand" "")))
7625    (set (match_operand:SI 3 "register_operand" "")
7626         (umod:SI (match_dup 1) (match_dup 2)))
7627    (clobber (reg:CC FLAGS_REG))]
7628   "reload_completed"
7629   [(set (match_dup 3) (const_int 0))
7630    (parallel [(set (match_dup 0)
7631                    (udiv:SI (match_dup 1) (match_dup 2)))
7632               (set (match_dup 3)
7633                    (umod:SI (match_dup 1) (match_dup 2)))
7634               (use (match_dup 3))
7635               (clobber (reg:CC FLAGS_REG))])]
7636   "")
7637
7638 (define_expand "udivmodhi4"
7639   [(set (match_dup 4) (const_int 0))
7640    (parallel [(set (match_operand:HI 0 "register_operand" "")
7641                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7642                             (match_operand:HI 2 "nonimmediate_operand" "")))
7643               (set (match_operand:HI 3 "register_operand" "")
7644                    (umod:HI (match_dup 1) (match_dup 2)))
7645               (use (match_dup 4))
7646               (clobber (reg:CC FLAGS_REG))])]
7647   "TARGET_HIMODE_MATH"
7648   "operands[4] = gen_reg_rtx (HImode);")
7649
7650 (define_insn "*udivmodhi_noext"
7651   [(set (match_operand:HI 0 "register_operand" "=a")
7652         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7653                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7654    (set (match_operand:HI 3 "register_operand" "=d")
7655         (umod:HI (match_dup 1) (match_dup 2)))
7656    (use (match_operand:HI 4 "register_operand" "3"))
7657    (clobber (reg:CC FLAGS_REG))]
7658   ""
7659   "div{w}\t%2"
7660   [(set_attr "type" "idiv")
7661    (set_attr "mode" "HI")])
7662
7663 ;; We cannot use div/idiv for double division, because it causes
7664 ;; "division by zero" on the overflow and that's not what we expect
7665 ;; from truncate.  Because true (non truncating) double division is
7666 ;; never generated, we can't create this insn anyway.
7667 ;
7668 ;(define_insn ""
7669 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7670 ;       (truncate:SI
7671 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7672 ;                  (zero_extend:DI
7673 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7674 ;   (set (match_operand:SI 3 "register_operand" "=d")
7675 ;       (truncate:SI
7676 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7677 ;   (clobber (reg:CC FLAGS_REG))]
7678 ;  ""
7679 ;  "div{l}\t{%2, %0|%0, %2}"
7680 ;  [(set_attr "type" "idiv")])
7681 \f
7682 ;;- Logical AND instructions
7683
7684 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7685 ;; Note that this excludes ah.
7686
7687 (define_insn "*testdi_1_rex64"
7688   [(set (reg FLAGS_REG)
7689         (compare
7690           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7691                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7692           (const_int 0)))]
7693   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7694    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7695   "@
7696    test{l}\t{%k1, %k0|%k0, %k1}
7697    test{l}\t{%k1, %k0|%k0, %k1}
7698    test{q}\t{%1, %0|%0, %1}
7699    test{q}\t{%1, %0|%0, %1}
7700    test{q}\t{%1, %0|%0, %1}"
7701   [(set_attr "type" "test")
7702    (set_attr "modrm" "0,1,0,1,1")
7703    (set_attr "mode" "SI,SI,DI,DI,DI")
7704    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7705
7706 (define_insn "testsi_1"
7707   [(set (reg FLAGS_REG)
7708         (compare
7709           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7710                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7711           (const_int 0)))]
7712   "ix86_match_ccmode (insn, CCNOmode)
7713    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7714   "test{l}\t{%1, %0|%0, %1}"
7715   [(set_attr "type" "test")
7716    (set_attr "modrm" "0,1,1")
7717    (set_attr "mode" "SI")
7718    (set_attr "pent_pair" "uv,np,uv")])
7719
7720 (define_expand "testsi_ccno_1"
7721   [(set (reg:CCNO FLAGS_REG)
7722         (compare:CCNO
7723           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7724                   (match_operand:SI 1 "nonmemory_operand" ""))
7725           (const_int 0)))]
7726   ""
7727   "")
7728
7729 (define_insn "*testhi_1"
7730   [(set (reg FLAGS_REG)
7731         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7732                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7733                  (const_int 0)))]
7734   "ix86_match_ccmode (insn, CCNOmode)
7735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7736   "test{w}\t{%1, %0|%0, %1}"
7737   [(set_attr "type" "test")
7738    (set_attr "modrm" "0,1,1")
7739    (set_attr "mode" "HI")
7740    (set_attr "pent_pair" "uv,np,uv")])
7741
7742 (define_expand "testqi_ccz_1"
7743   [(set (reg:CCZ FLAGS_REG)
7744         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7745                              (match_operand:QI 1 "nonmemory_operand" ""))
7746                  (const_int 0)))]
7747   ""
7748   "")
7749
7750 (define_insn "*testqi_1_maybe_si"
7751   [(set (reg FLAGS_REG)
7752         (compare
7753           (and:QI
7754             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7755             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7756           (const_int 0)))]
7757    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7758     && ix86_match_ccmode (insn,
7759                          GET_CODE (operands[1]) == CONST_INT
7760                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7761 {
7762   if (which_alternative == 3)
7763     {
7764       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7765         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7766       return "test{l}\t{%1, %k0|%k0, %1}";
7767     }
7768   return "test{b}\t{%1, %0|%0, %1}";
7769 }
7770   [(set_attr "type" "test")
7771    (set_attr "modrm" "0,1,1,1")
7772    (set_attr "mode" "QI,QI,QI,SI")
7773    (set_attr "pent_pair" "uv,np,uv,np")])
7774
7775 (define_insn "*testqi_1"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:QI
7779             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7780             (match_operand:QI 1 "general_operand" "n,n,qn"))
7781           (const_int 0)))]
7782   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7783    && ix86_match_ccmode (insn, CCNOmode)"
7784   "test{b}\t{%1, %0|%0, %1}"
7785   [(set_attr "type" "test")
7786    (set_attr "modrm" "0,1,1")
7787    (set_attr "mode" "QI")
7788    (set_attr "pent_pair" "uv,np,uv")])
7789
7790 (define_expand "testqi_ext_ccno_0"
7791   [(set (reg:CCNO FLAGS_REG)
7792         (compare:CCNO
7793           (and:SI
7794             (zero_extract:SI
7795               (match_operand 0 "ext_register_operand" "")
7796               (const_int 8)
7797               (const_int 8))
7798             (match_operand 1 "const_int_operand" ""))
7799           (const_int 0)))]
7800   ""
7801   "")
7802
7803 (define_insn "*testqi_ext_0"
7804   [(set (reg FLAGS_REG)
7805         (compare
7806           (and:SI
7807             (zero_extract:SI
7808               (match_operand 0 "ext_register_operand" "Q")
7809               (const_int 8)
7810               (const_int 8))
7811             (match_operand 1 "const_int_operand" "n"))
7812           (const_int 0)))]
7813   "ix86_match_ccmode (insn, CCNOmode)"
7814   "test{b}\t{%1, %h0|%h0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "mode" "QI")
7817    (set_attr "length_immediate" "1")
7818    (set_attr "pent_pair" "np")])
7819
7820 (define_insn "*testqi_ext_1"
7821   [(set (reg FLAGS_REG)
7822         (compare
7823           (and:SI
7824             (zero_extract:SI
7825               (match_operand 0 "ext_register_operand" "Q")
7826               (const_int 8)
7827               (const_int 8))
7828             (zero_extend:SI
7829               (match_operand:QI 1 "general_operand" "Qm")))
7830           (const_int 0)))]
7831   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7832    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7833   "test{b}\t{%1, %h0|%h0, %1}"
7834   [(set_attr "type" "test")
7835    (set_attr "mode" "QI")])
7836
7837 (define_insn "*testqi_ext_1_rex64"
7838   [(set (reg FLAGS_REG)
7839         (compare
7840           (and:SI
7841             (zero_extract:SI
7842               (match_operand 0 "ext_register_operand" "Q")
7843               (const_int 8)
7844               (const_int 8))
7845             (zero_extend:SI
7846               (match_operand:QI 1 "register_operand" "Q")))
7847           (const_int 0)))]
7848   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7849   "test{b}\t{%1, %h0|%h0, %1}"
7850   [(set_attr "type" "test")
7851    (set_attr "mode" "QI")])
7852
7853 (define_insn "*testqi_ext_2"
7854   [(set (reg FLAGS_REG)
7855         (compare
7856           (and:SI
7857             (zero_extract:SI
7858               (match_operand 0 "ext_register_operand" "Q")
7859               (const_int 8)
7860               (const_int 8))
7861             (zero_extract:SI
7862               (match_operand 1 "ext_register_operand" "Q")
7863               (const_int 8)
7864               (const_int 8)))
7865           (const_int 0)))]
7866   "ix86_match_ccmode (insn, CCNOmode)"
7867   "test{b}\t{%h1, %h0|%h0, %h1}"
7868   [(set_attr "type" "test")
7869    (set_attr "mode" "QI")])
7870
7871 ;; Combine likes to form bit extractions for some tests.  Humor it.
7872 (define_insn "*testqi_ext_3"
7873   [(set (reg FLAGS_REG)
7874         (compare (zero_extract:SI
7875                    (match_operand 0 "nonimmediate_operand" "rm")
7876                    (match_operand:SI 1 "const_int_operand" "")
7877                    (match_operand:SI 2 "const_int_operand" ""))
7878                  (const_int 0)))]
7879   "ix86_match_ccmode (insn, CCNOmode)
7880    && (GET_MODE (operands[0]) == SImode
7881        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7882        || GET_MODE (operands[0]) == HImode
7883        || GET_MODE (operands[0]) == QImode)"
7884   "#")
7885
7886 (define_insn "*testqi_ext_3_rex64"
7887   [(set (reg FLAGS_REG)
7888         (compare (zero_extract:DI
7889                    (match_operand 0 "nonimmediate_operand" "rm")
7890                    (match_operand:DI 1 "const_int_operand" "")
7891                    (match_operand:DI 2 "const_int_operand" ""))
7892                  (const_int 0)))]
7893   "TARGET_64BIT
7894    && ix86_match_ccmode (insn, CCNOmode)
7895    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7896    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7897    /* Ensure that resulting mask is zero or sign extended operand.  */
7898    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7899        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7900            && INTVAL (operands[1]) > 32))
7901    && (GET_MODE (operands[0]) == SImode
7902        || GET_MODE (operands[0]) == DImode
7903        || GET_MODE (operands[0]) == HImode
7904        || GET_MODE (operands[0]) == QImode)"
7905   "#")
7906
7907 (define_split
7908   [(set (match_operand 0 "flags_reg_operand" "")
7909         (match_operator 1 "compare_operator"
7910           [(zero_extract
7911              (match_operand 2 "nonimmediate_operand" "")
7912              (match_operand 3 "const_int_operand" "")
7913              (match_operand 4 "const_int_operand" ""))
7914            (const_int 0)]))]
7915   "ix86_match_ccmode (insn, CCNOmode)"
7916   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7917 {
7918   rtx val = operands[2];
7919   HOST_WIDE_INT len = INTVAL (operands[3]);
7920   HOST_WIDE_INT pos = INTVAL (operands[4]);
7921   HOST_WIDE_INT mask;
7922   enum machine_mode mode, submode;
7923
7924   mode = GET_MODE (val);
7925   if (GET_CODE (val) == MEM)
7926     {
7927       /* ??? Combine likes to put non-volatile mem extractions in QImode
7928          no matter the size of the test.  So find a mode that works.  */
7929       if (! MEM_VOLATILE_P (val))
7930         {
7931           mode = smallest_mode_for_size (pos + len, MODE_INT);
7932           val = adjust_address (val, mode, 0);
7933         }
7934     }
7935   else if (GET_CODE (val) == SUBREG
7936            && (submode = GET_MODE (SUBREG_REG (val)),
7937                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7938            && pos + len <= GET_MODE_BITSIZE (submode))
7939     {
7940       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7941       mode = submode;
7942       val = SUBREG_REG (val);
7943     }
7944   else if (mode == HImode && pos + len <= 8)
7945     {
7946       /* Small HImode tests can be converted to QImode.  */
7947       mode = QImode;
7948       val = gen_lowpart (QImode, val);
7949     }
7950
7951   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7952   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7953
7954   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7955 })
7956
7957 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7958 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7959 ;; this is relatively important trick.
7960 ;; Do the conversion only post-reload to avoid limiting of the register class
7961 ;; to QI regs.
7962 (define_split
7963   [(set (match_operand 0 "flags_reg_operand" "")
7964         (match_operator 1 "compare_operator"
7965           [(and (match_operand 2 "register_operand" "")
7966                 (match_operand 3 "const_int_operand" ""))
7967            (const_int 0)]))]
7968    "reload_completed
7969     && QI_REG_P (operands[2])
7970     && GET_MODE (operands[2]) != QImode
7971     && ((ix86_match_ccmode (insn, CCZmode)
7972          && !(INTVAL (operands[3]) & ~(255 << 8)))
7973         || (ix86_match_ccmode (insn, CCNOmode)
7974             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7975   [(set (match_dup 0)
7976         (match_op_dup 1
7977           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7978                    (match_dup 3))
7979            (const_int 0)]))]
7980   "operands[2] = gen_lowpart (SImode, operands[2]);
7981    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7982
7983 (define_split
7984   [(set (match_operand 0 "flags_reg_operand" "")
7985         (match_operator 1 "compare_operator"
7986           [(and (match_operand 2 "nonimmediate_operand" "")
7987                 (match_operand 3 "const_int_operand" ""))
7988            (const_int 0)]))]
7989    "reload_completed
7990     && GET_MODE (operands[2]) != QImode
7991     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7992     && ((ix86_match_ccmode (insn, CCZmode)
7993          && !(INTVAL (operands[3]) & ~255))
7994         || (ix86_match_ccmode (insn, CCNOmode)
7995             && !(INTVAL (operands[3]) & ~127)))"
7996   [(set (match_dup 0)
7997         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7998                          (const_int 0)]))]
7999   "operands[2] = gen_lowpart (QImode, operands[2]);
8000    operands[3] = gen_lowpart (QImode, operands[3]);")
8001
8002
8003 ;; %%% This used to optimize known byte-wide and operations to memory,
8004 ;; and sometimes to QImode registers.  If this is considered useful,
8005 ;; it should be done with splitters.
8006
8007 (define_expand "anddi3"
8008   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8009         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8010                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8011    (clobber (reg:CC FLAGS_REG))]
8012   "TARGET_64BIT"
8013   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8014
8015 (define_insn "*anddi_1_rex64"
8016   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8017         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8018                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8019    (clobber (reg:CC FLAGS_REG))]
8020   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8021 {
8022   switch (get_attr_type (insn))
8023     {
8024     case TYPE_IMOVX:
8025       {
8026         enum machine_mode mode;
8027
8028         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8029         if (INTVAL (operands[2]) == 0xff)
8030           mode = QImode;
8031         else
8032           {
8033             gcc_assert (INTVAL (operands[2]) == 0xffff);
8034             mode = HImode;
8035           }
8036         
8037         operands[1] = gen_lowpart (mode, operands[1]);
8038         if (mode == QImode)
8039           return "movz{bq|x}\t{%1,%0|%0, %1}";
8040         else
8041           return "movz{wq|x}\t{%1,%0|%0, %1}";
8042       }
8043
8044     default:
8045       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8046       if (get_attr_mode (insn) == MODE_SI)
8047         return "and{l}\t{%k2, %k0|%k0, %k2}";
8048       else
8049         return "and{q}\t{%2, %0|%0, %2}";
8050     }
8051 }
8052   [(set_attr "type" "alu,alu,alu,imovx")
8053    (set_attr "length_immediate" "*,*,*,0")
8054    (set_attr "mode" "SI,DI,DI,DI")])
8055
8056 (define_insn "*anddi_2"
8057   [(set (reg FLAGS_REG)
8058         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8059                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8060                  (const_int 0)))
8061    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8062         (and:DI (match_dup 1) (match_dup 2)))]
8063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8064    && ix86_binary_operator_ok (AND, DImode, operands)"
8065   "@
8066    and{l}\t{%k2, %k0|%k0, %k2}
8067    and{q}\t{%2, %0|%0, %2}
8068    and{q}\t{%2, %0|%0, %2}"
8069   [(set_attr "type" "alu")
8070    (set_attr "mode" "SI,DI,DI")])
8071
8072 (define_expand "andsi3"
8073   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8074         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8075                 (match_operand:SI 2 "general_operand" "")))
8076    (clobber (reg:CC FLAGS_REG))]
8077   ""
8078   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8079
8080 (define_insn "*andsi_1"
8081   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8082         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8083                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8084    (clobber (reg:CC FLAGS_REG))]
8085   "ix86_binary_operator_ok (AND, SImode, operands)"
8086 {
8087   switch (get_attr_type (insn))
8088     {
8089     case TYPE_IMOVX:
8090       {
8091         enum machine_mode mode;
8092
8093         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8094         if (INTVAL (operands[2]) == 0xff)
8095           mode = QImode;
8096         else
8097           {
8098             gcc_assert (INTVAL (operands[2]) == 0xffff);
8099             mode = HImode;
8100           }
8101         
8102         operands[1] = gen_lowpart (mode, operands[1]);
8103         if (mode == QImode)
8104           return "movz{bl|x}\t{%1,%0|%0, %1}";
8105         else
8106           return "movz{wl|x}\t{%1,%0|%0, %1}";
8107       }
8108
8109     default:
8110       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8111       return "and{l}\t{%2, %0|%0, %2}";
8112     }
8113 }
8114   [(set_attr "type" "alu,alu,imovx")
8115    (set_attr "length_immediate" "*,*,0")
8116    (set_attr "mode" "SI")])
8117
8118 (define_split
8119   [(set (match_operand 0 "register_operand" "")
8120         (and (match_dup 0)
8121              (const_int -65536)))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8124   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8125   "operands[1] = gen_lowpart (HImode, operands[0]);")
8126
8127 (define_split
8128   [(set (match_operand 0 "ext_register_operand" "")
8129         (and (match_dup 0)
8130              (const_int -256)))
8131    (clobber (reg:CC FLAGS_REG))]
8132   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8133   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8134   "operands[1] = gen_lowpart (QImode, operands[0]);")
8135
8136 (define_split
8137   [(set (match_operand 0 "ext_register_operand" "")
8138         (and (match_dup 0)
8139              (const_int -65281)))
8140    (clobber (reg:CC FLAGS_REG))]
8141   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8142   [(parallel [(set (zero_extract:SI (match_dup 0)
8143                                     (const_int 8)
8144                                     (const_int 8))
8145                    (xor:SI 
8146                      (zero_extract:SI (match_dup 0)
8147                                       (const_int 8)
8148                                       (const_int 8))
8149                      (zero_extract:SI (match_dup 0)
8150                                       (const_int 8)
8151                                       (const_int 8))))
8152               (clobber (reg:CC FLAGS_REG))])]
8153   "operands[0] = gen_lowpart (SImode, operands[0]);")
8154
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*andsi_1_zext"
8157   [(set (match_operand:DI 0 "register_operand" "=r")
8158         (zero_extend:DI
8159           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160                   (match_operand:SI 2 "general_operand" "rim"))))
8161    (clobber (reg:CC FLAGS_REG))]
8162   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8163   "and{l}\t{%2, %k0|%k0, %2}"
8164   [(set_attr "type" "alu")
8165    (set_attr "mode" "SI")])
8166
8167 (define_insn "*andsi_2"
8168   [(set (reg FLAGS_REG)
8169         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8170                          (match_operand:SI 2 "general_operand" "rim,ri"))
8171                  (const_int 0)))
8172    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8173         (and:SI (match_dup 1) (match_dup 2)))]
8174   "ix86_match_ccmode (insn, CCNOmode)
8175    && ix86_binary_operator_ok (AND, SImode, operands)"
8176   "and{l}\t{%2, %0|%0, %2}"
8177   [(set_attr "type" "alu")
8178    (set_attr "mode" "SI")])
8179
8180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8181 (define_insn "*andsi_2_zext"
8182   [(set (reg FLAGS_REG)
8183         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8184                          (match_operand:SI 2 "general_operand" "rim"))
8185                  (const_int 0)))
8186    (set (match_operand:DI 0 "register_operand" "=r")
8187         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8188   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8189    && ix86_binary_operator_ok (AND, SImode, operands)"
8190   "and{l}\t{%2, %k0|%k0, %2}"
8191   [(set_attr "type" "alu")
8192    (set_attr "mode" "SI")])
8193
8194 (define_expand "andhi3"
8195   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8196         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8197                 (match_operand:HI 2 "general_operand" "")))
8198    (clobber (reg:CC FLAGS_REG))]
8199   "TARGET_HIMODE_MATH"
8200   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8201
8202 (define_insn "*andhi_1"
8203   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8204         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8205                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "ix86_binary_operator_ok (AND, HImode, operands)"
8208 {
8209   switch (get_attr_type (insn))
8210     {
8211     case TYPE_IMOVX:
8212       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8213       gcc_assert (INTVAL (operands[2]) == 0xff);
8214       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8215
8216     default:
8217       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218
8219       return "and{w}\t{%2, %0|%0, %2}";
8220     }
8221 }
8222   [(set_attr "type" "alu,alu,imovx")
8223    (set_attr "length_immediate" "*,*,0")
8224    (set_attr "mode" "HI,HI,SI")])
8225
8226 (define_insn "*andhi_2"
8227   [(set (reg FLAGS_REG)
8228         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8229                          (match_operand:HI 2 "general_operand" "rim,ri"))
8230                  (const_int 0)))
8231    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8232         (and:HI (match_dup 1) (match_dup 2)))]
8233   "ix86_match_ccmode (insn, CCNOmode)
8234    && ix86_binary_operator_ok (AND, HImode, operands)"
8235   "and{w}\t{%2, %0|%0, %2}"
8236   [(set_attr "type" "alu")
8237    (set_attr "mode" "HI")])
8238
8239 (define_expand "andqi3"
8240   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8241         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8242                 (match_operand:QI 2 "general_operand" "")))
8243    (clobber (reg:CC FLAGS_REG))]
8244   "TARGET_QIMODE_MATH"
8245   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8246
8247 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8248 (define_insn "*andqi_1"
8249   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8250         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8251                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8252    (clobber (reg:CC FLAGS_REG))]
8253   "ix86_binary_operator_ok (AND, QImode, operands)"
8254   "@
8255    and{b}\t{%2, %0|%0, %2}
8256    and{b}\t{%2, %0|%0, %2}
8257    and{l}\t{%k2, %k0|%k0, %k2}"
8258   [(set_attr "type" "alu")
8259    (set_attr "mode" "QI,QI,SI")])
8260
8261 (define_insn "*andqi_1_slp"
8262   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8263         (and:QI (match_dup 0)
8264                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8265    (clobber (reg:CC FLAGS_REG))]
8266   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8267    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8268   "and{b}\t{%1, %0|%0, %1}"
8269   [(set_attr "type" "alu1")
8270    (set_attr "mode" "QI")])
8271
8272 (define_insn "*andqi_2_maybe_si"
8273   [(set (reg FLAGS_REG)
8274         (compare (and:QI
8275                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8276                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8277                  (const_int 0)))
8278    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8279         (and:QI (match_dup 1) (match_dup 2)))]
8280   "ix86_binary_operator_ok (AND, QImode, operands)
8281    && ix86_match_ccmode (insn,
8282                          GET_CODE (operands[2]) == CONST_INT
8283                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8284 {
8285   if (which_alternative == 2)
8286     {
8287       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8288         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8289       return "and{l}\t{%2, %k0|%k0, %2}";
8290     }
8291   return "and{b}\t{%2, %0|%0, %2}";
8292 }
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "QI,QI,SI")])
8295
8296 (define_insn "*andqi_2"
8297   [(set (reg FLAGS_REG)
8298         (compare (and:QI
8299                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8300                    (match_operand:QI 2 "general_operand" "qim,qi"))
8301                  (const_int 0)))
8302    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8303         (and:QI (match_dup 1) (match_dup 2)))]
8304   "ix86_match_ccmode (insn, CCNOmode)
8305    && ix86_binary_operator_ok (AND, QImode, operands)"
8306   "and{b}\t{%2, %0|%0, %2}"
8307   [(set_attr "type" "alu")
8308    (set_attr "mode" "QI")])
8309
8310 (define_insn "*andqi_2_slp"
8311   [(set (reg FLAGS_REG)
8312         (compare (and:QI
8313                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8314                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8315                  (const_int 0)))
8316    (set (strict_low_part (match_dup 0))
8317         (and:QI (match_dup 0) (match_dup 1)))]
8318   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8319    && ix86_match_ccmode (insn, CCNOmode)
8320    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8321   "and{b}\t{%1, %0|%0, %1}"
8322   [(set_attr "type" "alu1")
8323    (set_attr "mode" "QI")])
8324
8325 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8326 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8327 ;; for a QImode operand, which of course failed.
8328
8329 (define_insn "andqi_ext_0"
8330   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8331                          (const_int 8)
8332                          (const_int 8))
8333         (and:SI 
8334           (zero_extract:SI
8335             (match_operand 1 "ext_register_operand" "0")
8336             (const_int 8)
8337             (const_int 8))
8338           (match_operand 2 "const_int_operand" "n")))
8339    (clobber (reg:CC FLAGS_REG))]
8340   ""
8341   "and{b}\t{%2, %h0|%h0, %2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "length_immediate" "1")
8344    (set_attr "mode" "QI")])
8345
8346 ;; Generated by peephole translating test to and.  This shows up
8347 ;; often in fp comparisons.
8348
8349 (define_insn "*andqi_ext_0_cc"
8350   [(set (reg FLAGS_REG)
8351         (compare
8352           (and:SI
8353             (zero_extract:SI
8354               (match_operand 1 "ext_register_operand" "0")
8355               (const_int 8)
8356               (const_int 8))
8357             (match_operand 2 "const_int_operand" "n"))
8358           (const_int 0)))
8359    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360                          (const_int 8)
8361                          (const_int 8))
8362         (and:SI 
8363           (zero_extract:SI
8364             (match_dup 1)
8365             (const_int 8)
8366             (const_int 8))
8367           (match_dup 2)))]
8368   "ix86_match_ccmode (insn, CCNOmode)"
8369   "and{b}\t{%2, %h0|%h0, %2}"
8370   [(set_attr "type" "alu")
8371    (set_attr "length_immediate" "1")
8372    (set_attr "mode" "QI")])
8373
8374 (define_insn "*andqi_ext_1"
8375   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8376                          (const_int 8)
8377                          (const_int 8))
8378         (and:SI 
8379           (zero_extract:SI
8380             (match_operand 1 "ext_register_operand" "0")
8381             (const_int 8)
8382             (const_int 8))
8383           (zero_extend:SI
8384             (match_operand:QI 2 "general_operand" "Qm"))))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "!TARGET_64BIT"
8387   "and{b}\t{%2, %h0|%h0, %2}"
8388   [(set_attr "type" "alu")
8389    (set_attr "length_immediate" "0")
8390    (set_attr "mode" "QI")])
8391
8392 (define_insn "*andqi_ext_1_rex64"
8393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8394                          (const_int 8)
8395                          (const_int 8))
8396         (and:SI 
8397           (zero_extract:SI
8398             (match_operand 1 "ext_register_operand" "0")
8399             (const_int 8)
8400             (const_int 8))
8401           (zero_extend:SI
8402             (match_operand 2 "ext_register_operand" "Q"))))
8403    (clobber (reg:CC FLAGS_REG))]
8404   "TARGET_64BIT"
8405   "and{b}\t{%2, %h0|%h0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "length_immediate" "0")
8408    (set_attr "mode" "QI")])
8409
8410 (define_insn "*andqi_ext_2"
8411   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8412                          (const_int 8)
8413                          (const_int 8))
8414         (and:SI
8415           (zero_extract:SI
8416             (match_operand 1 "ext_register_operand" "%0")
8417             (const_int 8)
8418             (const_int 8))
8419           (zero_extract:SI
8420             (match_operand 2 "ext_register_operand" "Q")
8421             (const_int 8)
8422             (const_int 8))))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "and{b}\t{%h2, %h0|%h0, %h2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "length_immediate" "0")
8428    (set_attr "mode" "QI")])
8429
8430 ;; Convert wide AND instructions with immediate operand to shorter QImode
8431 ;; equivalents when possible.
8432 ;; Don't do the splitting with memory operands, since it introduces risk
8433 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8434 ;; for size, but that can (should?) be handled by generic code instead.
8435 (define_split
8436   [(set (match_operand 0 "register_operand" "")
8437         (and (match_operand 1 "register_operand" "")
8438              (match_operand 2 "const_int_operand" "")))
8439    (clobber (reg:CC FLAGS_REG))]
8440    "reload_completed
8441     && QI_REG_P (operands[0])
8442     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8443     && !(~INTVAL (operands[2]) & ~(255 << 8))
8444     && GET_MODE (operands[0]) != QImode"
8445   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8446                    (and:SI (zero_extract:SI (match_dup 1)
8447                                             (const_int 8) (const_int 8))
8448                            (match_dup 2)))
8449               (clobber (reg:CC FLAGS_REG))])]
8450   "operands[0] = gen_lowpart (SImode, operands[0]);
8451    operands[1] = gen_lowpart (SImode, operands[1]);
8452    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8453
8454 ;; Since AND can be encoded with sign extended immediate, this is only
8455 ;; profitable when 7th bit is not set.
8456 (define_split
8457   [(set (match_operand 0 "register_operand" "")
8458         (and (match_operand 1 "general_operand" "")
8459              (match_operand 2 "const_int_operand" "")))
8460    (clobber (reg:CC FLAGS_REG))]
8461    "reload_completed
8462     && ANY_QI_REG_P (operands[0])
8463     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8464     && !(~INTVAL (operands[2]) & ~255)
8465     && !(INTVAL (operands[2]) & 128)
8466     && GET_MODE (operands[0]) != QImode"
8467   [(parallel [(set (strict_low_part (match_dup 0))
8468                    (and:QI (match_dup 1)
8469                            (match_dup 2)))
8470               (clobber (reg:CC FLAGS_REG))])]
8471   "operands[0] = gen_lowpart (QImode, operands[0]);
8472    operands[1] = gen_lowpart (QImode, operands[1]);
8473    operands[2] = gen_lowpart (QImode, operands[2]);")
8474 \f
8475 ;; Logical inclusive OR instructions
8476
8477 ;; %%% This used to optimize known byte-wide and operations to memory.
8478 ;; If this is considered useful, it should be done with splitters.
8479
8480 (define_expand "iordi3"
8481   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8482         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8483                 (match_operand:DI 2 "x86_64_general_operand" "")))
8484    (clobber (reg:CC FLAGS_REG))]
8485   "TARGET_64BIT"
8486   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8487
8488 (define_insn "*iordi_1_rex64"
8489   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8490         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8491                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "TARGET_64BIT
8494    && ix86_binary_operator_ok (IOR, DImode, operands)"
8495   "or{q}\t{%2, %0|%0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "mode" "DI")])
8498
8499 (define_insn "*iordi_2_rex64"
8500   [(set (reg FLAGS_REG)
8501         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8502                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8503                  (const_int 0)))
8504    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8505         (ior:DI (match_dup 1) (match_dup 2)))]
8506   "TARGET_64BIT
8507    && ix86_match_ccmode (insn, CCNOmode)
8508    && ix86_binary_operator_ok (IOR, DImode, operands)"
8509   "or{q}\t{%2, %0|%0, %2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "mode" "DI")])
8512
8513 (define_insn "*iordi_3_rex64"
8514   [(set (reg FLAGS_REG)
8515         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8516                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8517                  (const_int 0)))
8518    (clobber (match_scratch:DI 0 "=r"))]
8519   "TARGET_64BIT
8520    && ix86_match_ccmode (insn, CCNOmode)
8521    && ix86_binary_operator_ok (IOR, DImode, operands)"
8522   "or{q}\t{%2, %0|%0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "DI")])
8525
8526
8527 (define_expand "iorsi3"
8528   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8529         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8530                 (match_operand:SI 2 "general_operand" "")))
8531    (clobber (reg:CC FLAGS_REG))]
8532   ""
8533   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8534
8535 (define_insn "*iorsi_1"
8536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8537         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8538                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8539    (clobber (reg:CC FLAGS_REG))]
8540   "ix86_binary_operator_ok (IOR, SImode, operands)"
8541   "or{l}\t{%2, %0|%0, %2}"
8542   [(set_attr "type" "alu")
8543    (set_attr "mode" "SI")])
8544
8545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8546 (define_insn "*iorsi_1_zext"
8547   [(set (match_operand:DI 0 "register_operand" "=rm")
8548         (zero_extend:DI
8549           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8550                   (match_operand:SI 2 "general_operand" "rim"))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8553   "or{l}\t{%2, %k0|%k0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "SI")])
8556
8557 (define_insn "*iorsi_1_zext_imm"
8558   [(set (match_operand:DI 0 "register_operand" "=rm")
8559         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8560                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8561    (clobber (reg:CC FLAGS_REG))]
8562   "TARGET_64BIT"
8563   "or{l}\t{%2, %k0|%k0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "SI")])
8566
8567 (define_insn "*iorsi_2"
8568   [(set (reg FLAGS_REG)
8569         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8570                          (match_operand:SI 2 "general_operand" "rim,ri"))
8571                  (const_int 0)))
8572    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8573         (ior:SI (match_dup 1) (match_dup 2)))]
8574   "ix86_match_ccmode (insn, CCNOmode)
8575    && ix86_binary_operator_ok (IOR, SImode, operands)"
8576   "or{l}\t{%2, %0|%0, %2}"
8577   [(set_attr "type" "alu")
8578    (set_attr "mode" "SI")])
8579
8580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581 ;; ??? Special case for immediate operand is missing - it is tricky.
8582 (define_insn "*iorsi_2_zext"
8583   [(set (reg FLAGS_REG)
8584         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585                          (match_operand:SI 2 "general_operand" "rim"))
8586                  (const_int 0)))
8587    (set (match_operand:DI 0 "register_operand" "=r")
8588         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, SImode, operands)"
8591   "or{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 (define_insn "*iorsi_2_zext_imm"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8598                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8599                  (const_int 0)))
8600    (set (match_operand:DI 0 "register_operand" "=r")
8601         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8602   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, SImode, operands)"
8604   "or{l}\t{%2, %k0|%k0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "SI")])
8607
8608 (define_insn "*iorsi_3"
8609   [(set (reg FLAGS_REG)
8610         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8611                          (match_operand:SI 2 "general_operand" "rim"))
8612                  (const_int 0)))
8613    (clobber (match_scratch:SI 0 "=r"))]
8614   "ix86_match_ccmode (insn, CCNOmode)
8615    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8616   "or{l}\t{%2, %0|%0, %2}"
8617   [(set_attr "type" "alu")
8618    (set_attr "mode" "SI")])
8619
8620 (define_expand "iorhi3"
8621   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8622         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8623                 (match_operand:HI 2 "general_operand" "")))
8624    (clobber (reg:CC FLAGS_REG))]
8625   "TARGET_HIMODE_MATH"
8626   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8627
8628 (define_insn "*iorhi_1"
8629   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8630         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "ix86_binary_operator_ok (IOR, HImode, operands)"
8634   "or{w}\t{%2, %0|%0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "mode" "HI")])
8637
8638 (define_insn "*iorhi_2"
8639   [(set (reg FLAGS_REG)
8640         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8641                          (match_operand:HI 2 "general_operand" "rim,ri"))
8642                  (const_int 0)))
8643    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8644         (ior:HI (match_dup 1) (match_dup 2)))]
8645   "ix86_match_ccmode (insn, CCNOmode)
8646    && ix86_binary_operator_ok (IOR, HImode, operands)"
8647   "or{w}\t{%2, %0|%0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "HI")])
8650
8651 (define_insn "*iorhi_3"
8652   [(set (reg FLAGS_REG)
8653         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8654                          (match_operand:HI 2 "general_operand" "rim"))
8655                  (const_int 0)))
8656    (clobber (match_scratch:HI 0 "=r"))]
8657   "ix86_match_ccmode (insn, CCNOmode)
8658    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8659   "or{w}\t{%2, %0|%0, %2}"
8660   [(set_attr "type" "alu")
8661    (set_attr "mode" "HI")])
8662
8663 (define_expand "iorqi3"
8664   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8665         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8666                 (match_operand:QI 2 "general_operand" "")))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "TARGET_QIMODE_MATH"
8669   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8670
8671 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8672 (define_insn "*iorqi_1"
8673   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8674         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8675                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "ix86_binary_operator_ok (IOR, QImode, operands)"
8678   "@
8679    or{b}\t{%2, %0|%0, %2}
8680    or{b}\t{%2, %0|%0, %2}
8681    or{l}\t{%k2, %k0|%k0, %k2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "QI,QI,SI")])
8684
8685 (define_insn "*iorqi_1_slp"
8686   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8687         (ior:QI (match_dup 0)
8688                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8691    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8692   "or{b}\t{%1, %0|%0, %1}"
8693   [(set_attr "type" "alu1")
8694    (set_attr "mode" "QI")])
8695
8696 (define_insn "*iorqi_2"
8697   [(set (reg FLAGS_REG)
8698         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8699                          (match_operand:QI 2 "general_operand" "qim,qi"))
8700                  (const_int 0)))
8701    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8702         (ior:QI (match_dup 1) (match_dup 2)))]
8703   "ix86_match_ccmode (insn, CCNOmode)
8704    && ix86_binary_operator_ok (IOR, QImode, operands)"
8705   "or{b}\t{%2, %0|%0, %2}"
8706   [(set_attr "type" "alu")
8707    (set_attr "mode" "QI")])
8708
8709 (define_insn "*iorqi_2_slp"
8710   [(set (reg FLAGS_REG)
8711         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8712                          (match_operand:QI 1 "general_operand" "qim,qi"))
8713                  (const_int 0)))
8714    (set (strict_low_part (match_dup 0))
8715         (ior:QI (match_dup 0) (match_dup 1)))]
8716   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8717    && ix86_match_ccmode (insn, CCNOmode)
8718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8719   "or{b}\t{%1, %0|%0, %1}"
8720   [(set_attr "type" "alu1")
8721    (set_attr "mode" "QI")])
8722
8723 (define_insn "*iorqi_3"
8724   [(set (reg FLAGS_REG)
8725         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8726                          (match_operand:QI 2 "general_operand" "qim"))
8727                  (const_int 0)))
8728    (clobber (match_scratch:QI 0 "=q"))]
8729   "ix86_match_ccmode (insn, CCNOmode)
8730    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8731   "or{b}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "QI")])
8734
8735 (define_insn "iorqi_ext_0"
8736   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8737                          (const_int 8)
8738                          (const_int 8))
8739         (ior:SI 
8740           (zero_extract:SI
8741             (match_operand 1 "ext_register_operand" "0")
8742             (const_int 8)
8743             (const_int 8))
8744           (match_operand 2 "const_int_operand" "n")))
8745    (clobber (reg:CC FLAGS_REG))]
8746   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8747   "or{b}\t{%2, %h0|%h0, %2}"
8748   [(set_attr "type" "alu")
8749    (set_attr "length_immediate" "1")
8750    (set_attr "mode" "QI")])
8751
8752 (define_insn "*iorqi_ext_1"
8753   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754                          (const_int 8)
8755                          (const_int 8))
8756         (ior:SI 
8757           (zero_extract:SI
8758             (match_operand 1 "ext_register_operand" "0")
8759             (const_int 8)
8760             (const_int 8))
8761           (zero_extend:SI
8762             (match_operand:QI 2 "general_operand" "Qm"))))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "!TARGET_64BIT
8765    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8766   "or{b}\t{%2, %h0|%h0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "length_immediate" "0")
8769    (set_attr "mode" "QI")])
8770
8771 (define_insn "*iorqi_ext_1_rex64"
8772   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773                          (const_int 8)
8774                          (const_int 8))
8775         (ior:SI 
8776           (zero_extract:SI
8777             (match_operand 1 "ext_register_operand" "0")
8778             (const_int 8)
8779             (const_int 8))
8780           (zero_extend:SI
8781             (match_operand 2 "ext_register_operand" "Q"))))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "TARGET_64BIT
8784    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8785   "or{b}\t{%2, %h0|%h0, %2}"
8786   [(set_attr "type" "alu")
8787    (set_attr "length_immediate" "0")
8788    (set_attr "mode" "QI")])
8789
8790 (define_insn "*iorqi_ext_2"
8791   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8792                          (const_int 8)
8793                          (const_int 8))
8794         (ior:SI 
8795           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8796                            (const_int 8)
8797                            (const_int 8))
8798           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8799                            (const_int 8)
8800                            (const_int 8))))
8801    (clobber (reg:CC FLAGS_REG))]
8802   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8803   "ior{b}\t{%h2, %h0|%h0, %h2}"
8804   [(set_attr "type" "alu")
8805    (set_attr "length_immediate" "0")
8806    (set_attr "mode" "QI")])
8807
8808 (define_split
8809   [(set (match_operand 0 "register_operand" "")
8810         (ior (match_operand 1 "register_operand" "")
8811              (match_operand 2 "const_int_operand" "")))
8812    (clobber (reg:CC FLAGS_REG))]
8813    "reload_completed
8814     && QI_REG_P (operands[0])
8815     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8816     && !(INTVAL (operands[2]) & ~(255 << 8))
8817     && GET_MODE (operands[0]) != QImode"
8818   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8819                    (ior:SI (zero_extract:SI (match_dup 1)
8820                                             (const_int 8) (const_int 8))
8821                            (match_dup 2)))
8822               (clobber (reg:CC FLAGS_REG))])]
8823   "operands[0] = gen_lowpart (SImode, operands[0]);
8824    operands[1] = gen_lowpart (SImode, operands[1]);
8825    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8826
8827 ;; Since OR can be encoded with sign extended immediate, this is only
8828 ;; profitable when 7th bit is set.
8829 (define_split
8830   [(set (match_operand 0 "register_operand" "")
8831         (ior (match_operand 1 "general_operand" "")
8832              (match_operand 2 "const_int_operand" "")))
8833    (clobber (reg:CC FLAGS_REG))]
8834    "reload_completed
8835     && ANY_QI_REG_P (operands[0])
8836     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8837     && !(INTVAL (operands[2]) & ~255)
8838     && (INTVAL (operands[2]) & 128)
8839     && GET_MODE (operands[0]) != QImode"
8840   [(parallel [(set (strict_low_part (match_dup 0))
8841                    (ior:QI (match_dup 1)
8842                            (match_dup 2)))
8843               (clobber (reg:CC FLAGS_REG))])]
8844   "operands[0] = gen_lowpart (QImode, operands[0]);
8845    operands[1] = gen_lowpart (QImode, operands[1]);
8846    operands[2] = gen_lowpart (QImode, operands[2]);")
8847 \f
8848 ;; Logical XOR instructions
8849
8850 ;; %%% This used to optimize known byte-wide and operations to memory.
8851 ;; If this is considered useful, it should be done with splitters.
8852
8853 (define_expand "xordi3"
8854   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8855         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8856                 (match_operand:DI 2 "x86_64_general_operand" "")))
8857    (clobber (reg:CC FLAGS_REG))]
8858   "TARGET_64BIT"
8859   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8860
8861 (define_insn "*xordi_1_rex64"
8862   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8863         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8864                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8865    (clobber (reg:CC FLAGS_REG))]
8866   "TARGET_64BIT
8867    && ix86_binary_operator_ok (XOR, DImode, operands)"
8868   "@
8869    xor{q}\t{%2, %0|%0, %2}
8870    xor{q}\t{%2, %0|%0, %2}"
8871   [(set_attr "type" "alu")
8872    (set_attr "mode" "DI,DI")])
8873
8874 (define_insn "*xordi_2_rex64"
8875   [(set (reg FLAGS_REG)
8876         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8877                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8878                  (const_int 0)))
8879    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8880         (xor:DI (match_dup 1) (match_dup 2)))]
8881   "TARGET_64BIT
8882    && ix86_match_ccmode (insn, CCNOmode)
8883    && ix86_binary_operator_ok (XOR, DImode, operands)"
8884   "@
8885    xor{q}\t{%2, %0|%0, %2}
8886    xor{q}\t{%2, %0|%0, %2}"
8887   [(set_attr "type" "alu")
8888    (set_attr "mode" "DI,DI")])
8889
8890 (define_insn "*xordi_3_rex64"
8891   [(set (reg FLAGS_REG)
8892         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8893                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8894                  (const_int 0)))
8895    (clobber (match_scratch:DI 0 "=r"))]
8896   "TARGET_64BIT
8897    && ix86_match_ccmode (insn, CCNOmode)
8898    && ix86_binary_operator_ok (XOR, DImode, operands)"
8899   "xor{q}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "DI")])
8902
8903 (define_expand "xorsi3"
8904   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8905         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8906                 (match_operand:SI 2 "general_operand" "")))
8907    (clobber (reg:CC FLAGS_REG))]
8908   ""
8909   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8910
8911 (define_insn "*xorsi_1"
8912   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8913         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8914                 (match_operand:SI 2 "general_operand" "ri,rm")))
8915    (clobber (reg:CC FLAGS_REG))]
8916   "ix86_binary_operator_ok (XOR, SImode, operands)"
8917   "xor{l}\t{%2, %0|%0, %2}"
8918   [(set_attr "type" "alu")
8919    (set_attr "mode" "SI")])
8920
8921 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8922 ;; Add speccase for immediates
8923 (define_insn "*xorsi_1_zext"
8924   [(set (match_operand:DI 0 "register_operand" "=r")
8925         (zero_extend:DI
8926           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8927                   (match_operand:SI 2 "general_operand" "rim"))))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930   "xor{l}\t{%2, %k0|%k0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "SI")])
8933
8934 (define_insn "*xorsi_1_zext_imm"
8935   [(set (match_operand:DI 0 "register_operand" "=r")
8936         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8937                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8938    (clobber (reg:CC FLAGS_REG))]
8939   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8940   "xor{l}\t{%2, %k0|%k0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "SI")])
8943
8944 (define_insn "*xorsi_2"
8945   [(set (reg FLAGS_REG)
8946         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8947                          (match_operand:SI 2 "general_operand" "rim,ri"))
8948                  (const_int 0)))
8949    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8950         (xor:SI (match_dup 1) (match_dup 2)))]
8951   "ix86_match_ccmode (insn, CCNOmode)
8952    && ix86_binary_operator_ok (XOR, SImode, operands)"
8953   "xor{l}\t{%2, %0|%0, %2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "SI")])
8956
8957 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8958 ;; ??? Special case for immediate operand is missing - it is tricky.
8959 (define_insn "*xorsi_2_zext"
8960   [(set (reg FLAGS_REG)
8961         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962                          (match_operand:SI 2 "general_operand" "rim"))
8963                  (const_int 0)))
8964    (set (match_operand:DI 0 "register_operand" "=r")
8965         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8966   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, SImode, operands)"
8968   "xor{l}\t{%2, %k0|%k0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "SI")])
8971
8972 (define_insn "*xorsi_2_zext_imm"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8975                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8976                  (const_int 0)))
8977    (set (match_operand:DI 0 "register_operand" "=r")
8978         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8979   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, SImode, operands)"
8981   "xor{l}\t{%2, %k0|%k0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "SI")])
8984
8985 (define_insn "*xorsi_3"
8986   [(set (reg FLAGS_REG)
8987         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8988                          (match_operand:SI 2 "general_operand" "rim"))
8989                  (const_int 0)))
8990    (clobber (match_scratch:SI 0 "=r"))]
8991   "ix86_match_ccmode (insn, CCNOmode)
8992    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8993   "xor{l}\t{%2, %0|%0, %2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "mode" "SI")])
8996
8997 (define_expand "xorhi3"
8998   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8999         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9000                 (match_operand:HI 2 "general_operand" "")))
9001    (clobber (reg:CC FLAGS_REG))]
9002   "TARGET_HIMODE_MATH"
9003   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9004
9005 (define_insn "*xorhi_1"
9006   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9007         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9009    (clobber (reg:CC FLAGS_REG))]
9010   "ix86_binary_operator_ok (XOR, HImode, operands)"
9011   "xor{w}\t{%2, %0|%0, %2}"
9012   [(set_attr "type" "alu")
9013    (set_attr "mode" "HI")])
9014
9015 (define_insn "*xorhi_2"
9016   [(set (reg FLAGS_REG)
9017         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9018                          (match_operand:HI 2 "general_operand" "rim,ri"))
9019                  (const_int 0)))
9020    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9021         (xor:HI (match_dup 1) (match_dup 2)))]
9022   "ix86_match_ccmode (insn, CCNOmode)
9023    && ix86_binary_operator_ok (XOR, HImode, operands)"
9024   "xor{w}\t{%2, %0|%0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "HI")])
9027
9028 (define_insn "*xorhi_3"
9029   [(set (reg FLAGS_REG)
9030         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9031                          (match_operand:HI 2 "general_operand" "rim"))
9032                  (const_int 0)))
9033    (clobber (match_scratch:HI 0 "=r"))]
9034   "ix86_match_ccmode (insn, CCNOmode)
9035    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9036   "xor{w}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "HI")])
9039
9040 (define_expand "xorqi3"
9041   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9042         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9043                 (match_operand:QI 2 "general_operand" "")))
9044    (clobber (reg:CC FLAGS_REG))]
9045   "TARGET_QIMODE_MATH"
9046   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9047
9048 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9049 (define_insn "*xorqi_1"
9050   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9051         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9052                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "ix86_binary_operator_ok (XOR, QImode, operands)"
9055   "@
9056    xor{b}\t{%2, %0|%0, %2}
9057    xor{b}\t{%2, %0|%0, %2}
9058    xor{l}\t{%k2, %k0|%k0, %k2}"
9059   [(set_attr "type" "alu")
9060    (set_attr "mode" "QI,QI,SI")])
9061
9062 (define_insn "*xorqi_1_slp"
9063   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9064         (xor:QI (match_dup 0)
9065                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9066    (clobber (reg:CC FLAGS_REG))]
9067   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9068    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9069   "xor{b}\t{%1, %0|%0, %1}"
9070   [(set_attr "type" "alu1")
9071    (set_attr "mode" "QI")])
9072
9073 (define_insn "xorqi_ext_0"
9074   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9075                          (const_int 8)
9076                          (const_int 8))
9077         (xor:SI 
9078           (zero_extract:SI
9079             (match_operand 1 "ext_register_operand" "0")
9080             (const_int 8)
9081             (const_int 8))
9082           (match_operand 2 "const_int_operand" "n")))
9083    (clobber (reg:CC FLAGS_REG))]
9084   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9085   "xor{b}\t{%2, %h0|%h0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "length_immediate" "1")
9088    (set_attr "mode" "QI")])
9089
9090 (define_insn "*xorqi_ext_1"
9091   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9092                          (const_int 8)
9093                          (const_int 8))
9094         (xor:SI 
9095           (zero_extract:SI
9096             (match_operand 1 "ext_register_operand" "0")
9097             (const_int 8)
9098             (const_int 8))
9099           (zero_extend:SI
9100             (match_operand:QI 2 "general_operand" "Qm"))))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "!TARGET_64BIT
9103    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9104   "xor{b}\t{%2, %h0|%h0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "length_immediate" "0")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "*xorqi_ext_1_rex64"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (xor:SI 
9114           (zero_extract:SI
9115             (match_operand 1 "ext_register_operand" "0")
9116             (const_int 8)
9117             (const_int 8))
9118           (zero_extend:SI
9119             (match_operand 2 "ext_register_operand" "Q"))))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "TARGET_64BIT
9122    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9123   "xor{b}\t{%2, %h0|%h0, %2}"
9124   [(set_attr "type" "alu")
9125    (set_attr "length_immediate" "0")
9126    (set_attr "mode" "QI")])
9127
9128 (define_insn "*xorqi_ext_2"
9129   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9130                          (const_int 8)
9131                          (const_int 8))
9132         (xor:SI 
9133           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9134                            (const_int 8)
9135                            (const_int 8))
9136           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9137                            (const_int 8)
9138                            (const_int 8))))
9139    (clobber (reg:CC FLAGS_REG))]
9140   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9141   "xor{b}\t{%h2, %h0|%h0, %h2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "length_immediate" "0")
9144    (set_attr "mode" "QI")])
9145
9146 (define_insn "*xorqi_cc_1"
9147   [(set (reg FLAGS_REG)
9148         (compare
9149           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9150                   (match_operand:QI 2 "general_operand" "qim,qi"))
9151           (const_int 0)))
9152    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9153         (xor:QI (match_dup 1) (match_dup 2)))]
9154   "ix86_match_ccmode (insn, CCNOmode)
9155    && ix86_binary_operator_ok (XOR, QImode, operands)"
9156   "xor{b}\t{%2, %0|%0, %2}"
9157   [(set_attr "type" "alu")
9158    (set_attr "mode" "QI")])
9159
9160 (define_insn "*xorqi_2_slp"
9161   [(set (reg FLAGS_REG)
9162         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9163                          (match_operand:QI 1 "general_operand" "qim,qi"))
9164                  (const_int 0)))
9165    (set (strict_low_part (match_dup 0))
9166         (xor:QI (match_dup 0) (match_dup 1)))]
9167   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9168    && ix86_match_ccmode (insn, CCNOmode)
9169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9170   "xor{b}\t{%1, %0|%0, %1}"
9171   [(set_attr "type" "alu1")
9172    (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_cc_2"
9175   [(set (reg FLAGS_REG)
9176         (compare
9177           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9178                   (match_operand:QI 2 "general_operand" "qim"))
9179           (const_int 0)))
9180    (clobber (match_scratch:QI 0 "=q"))]
9181   "ix86_match_ccmode (insn, CCNOmode)
9182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9183   "xor{b}\t{%2, %0|%0, %2}"
9184   [(set_attr "type" "alu")
9185    (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_cc_ext_1"
9188   [(set (reg FLAGS_REG)
9189         (compare
9190           (xor:SI
9191             (zero_extract:SI
9192               (match_operand 1 "ext_register_operand" "0")
9193               (const_int 8)
9194               (const_int 8))
9195             (match_operand:QI 2 "general_operand" "qmn"))
9196           (const_int 0)))
9197    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9198                          (const_int 8)
9199                          (const_int 8))
9200         (xor:SI 
9201           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9202           (match_dup 2)))]
9203   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9204   "xor{b}\t{%2, %h0|%h0, %2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "mode" "QI")])
9207
9208 (define_insn "*xorqi_cc_ext_1_rex64"
9209   [(set (reg FLAGS_REG)
9210         (compare
9211           (xor:SI
9212             (zero_extract:SI
9213               (match_operand 1 "ext_register_operand" "0")
9214               (const_int 8)
9215               (const_int 8))
9216             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9217           (const_int 0)))
9218    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219                          (const_int 8)
9220                          (const_int 8))
9221         (xor:SI 
9222           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9223           (match_dup 2)))]
9224   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9225   "xor{b}\t{%2, %h0|%h0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "mode" "QI")])
9228
9229 (define_expand "xorqi_cc_ext_1"
9230   [(parallel [
9231      (set (reg:CCNO FLAGS_REG)
9232           (compare:CCNO
9233             (xor:SI
9234               (zero_extract:SI
9235                 (match_operand 1 "ext_register_operand" "")
9236                 (const_int 8)
9237                 (const_int 8))
9238               (match_operand:QI 2 "general_operand" ""))
9239             (const_int 0)))
9240      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9241                            (const_int 8)
9242                            (const_int 8))
9243           (xor:SI 
9244             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9245             (match_dup 2)))])]
9246   ""
9247   "")
9248
9249 (define_split
9250   [(set (match_operand 0 "register_operand" "")
9251         (xor (match_operand 1 "register_operand" "")
9252              (match_operand 2 "const_int_operand" "")))
9253    (clobber (reg:CC FLAGS_REG))]
9254    "reload_completed
9255     && QI_REG_P (operands[0])
9256     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9257     && !(INTVAL (operands[2]) & ~(255 << 8))
9258     && GET_MODE (operands[0]) != QImode"
9259   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9260                    (xor:SI (zero_extract:SI (match_dup 1)
9261                                             (const_int 8) (const_int 8))
9262                            (match_dup 2)))
9263               (clobber (reg:CC FLAGS_REG))])]
9264   "operands[0] = gen_lowpart (SImode, operands[0]);
9265    operands[1] = gen_lowpart (SImode, operands[1]);
9266    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9267
9268 ;; Since XOR can be encoded with sign extended immediate, this is only
9269 ;; profitable when 7th bit is set.
9270 (define_split
9271   [(set (match_operand 0 "register_operand" "")
9272         (xor (match_operand 1 "general_operand" "")
9273              (match_operand 2 "const_int_operand" "")))
9274    (clobber (reg:CC FLAGS_REG))]
9275    "reload_completed
9276     && ANY_QI_REG_P (operands[0])
9277     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9278     && !(INTVAL (operands[2]) & ~255)
9279     && (INTVAL (operands[2]) & 128)
9280     && GET_MODE (operands[0]) != QImode"
9281   [(parallel [(set (strict_low_part (match_dup 0))
9282                    (xor:QI (match_dup 1)
9283                            (match_dup 2)))
9284               (clobber (reg:CC FLAGS_REG))])]
9285   "operands[0] = gen_lowpart (QImode, operands[0]);
9286    operands[1] = gen_lowpart (QImode, operands[1]);
9287    operands[2] = gen_lowpart (QImode, operands[2]);")
9288 \f
9289 ;; Negation instructions
9290
9291 (define_expand "negti2"
9292   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9293                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9294               (clobber (reg:CC FLAGS_REG))])]
9295   "TARGET_64BIT"
9296   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9297
9298 (define_insn "*negti2_1"
9299   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9300         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "TARGET_64BIT
9303    && ix86_unary_operator_ok (NEG, TImode, operands)"
9304   "#")
9305
9306 (define_split
9307   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9308         (neg:TI (match_operand:TI 1 "general_operand" "")))
9309    (clobber (reg:CC FLAGS_REG))]
9310   "TARGET_64BIT && reload_completed"
9311   [(parallel
9312     [(set (reg:CCZ FLAGS_REG)
9313           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9314      (set (match_dup 0) (neg:DI (match_dup 2)))])
9315    (parallel
9316     [(set (match_dup 1)
9317           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9318                             (match_dup 3))
9319                    (const_int 0)))
9320      (clobber (reg:CC FLAGS_REG))])
9321    (parallel
9322     [(set (match_dup 1)
9323           (neg:DI (match_dup 1)))
9324      (clobber (reg:CC FLAGS_REG))])]
9325   "split_ti (operands+1, 1, operands+2, operands+3);
9326    split_ti (operands+0, 1, operands+0, operands+1);")
9327
9328 (define_expand "negdi2"
9329   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9330                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9331               (clobber (reg:CC FLAGS_REG))])]
9332   ""
9333   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9334
9335 (define_insn "*negdi2_1"
9336   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9337         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "!TARGET_64BIT
9340    && ix86_unary_operator_ok (NEG, DImode, operands)"
9341   "#")
9342
9343 (define_split
9344   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9345         (neg:DI (match_operand:DI 1 "general_operand" "")))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "!TARGET_64BIT && reload_completed"
9348   [(parallel
9349     [(set (reg:CCZ FLAGS_REG)
9350           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9351      (set (match_dup 0) (neg:SI (match_dup 2)))])
9352    (parallel
9353     [(set (match_dup 1)
9354           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9355                             (match_dup 3))
9356                    (const_int 0)))
9357      (clobber (reg:CC FLAGS_REG))])
9358    (parallel
9359     [(set (match_dup 1)
9360           (neg:SI (match_dup 1)))
9361      (clobber (reg:CC FLAGS_REG))])]
9362   "split_di (operands+1, 1, operands+2, operands+3);
9363    split_di (operands+0, 1, operands+0, operands+1);")
9364
9365 (define_insn "*negdi2_1_rex64"
9366   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9367         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9370   "neg{q}\t%0"
9371   [(set_attr "type" "negnot")
9372    (set_attr "mode" "DI")])
9373
9374 ;; The problem with neg is that it does not perform (compare x 0),
9375 ;; it really performs (compare 0 x), which leaves us with the zero
9376 ;; flag being the only useful item.
9377
9378 (define_insn "*negdi2_cmpz_rex64"
9379   [(set (reg:CCZ FLAGS_REG)
9380         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9381                      (const_int 0)))
9382    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9383         (neg:DI (match_dup 1)))]
9384   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9385   "neg{q}\t%0"
9386   [(set_attr "type" "negnot")
9387    (set_attr "mode" "DI")])
9388
9389
9390 (define_expand "negsi2"
9391   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9392                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9393               (clobber (reg:CC FLAGS_REG))])]
9394   ""
9395   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9396
9397 (define_insn "*negsi2_1"
9398   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9399         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "ix86_unary_operator_ok (NEG, SImode, operands)"
9402   "neg{l}\t%0"
9403   [(set_attr "type" "negnot")
9404    (set_attr "mode" "SI")])
9405
9406 ;; Combine is quite creative about this pattern.
9407 (define_insn "*negsi2_1_zext"
9408   [(set (match_operand:DI 0 "register_operand" "=r")
9409         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9410                                         (const_int 32)))
9411                      (const_int 32)))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9414   "neg{l}\t%k0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "SI")])
9417
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9421
9422 (define_insn "*negsi2_cmpz"
9423   [(set (reg:CCZ FLAGS_REG)
9424         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9425                      (const_int 0)))
9426    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427         (neg:SI (match_dup 1)))]
9428   "ix86_unary_operator_ok (NEG, SImode, operands)"
9429   "neg{l}\t%0"
9430   [(set_attr "type" "negnot")
9431    (set_attr "mode" "SI")])
9432
9433 (define_insn "*negsi2_cmpz_zext"
9434   [(set (reg:CCZ FLAGS_REG)
9435         (compare:CCZ (lshiftrt:DI
9436                        (neg:DI (ashift:DI
9437                                  (match_operand:DI 1 "register_operand" "0")
9438                                  (const_int 32)))
9439                        (const_int 32))
9440                      (const_int 0)))
9441    (set (match_operand:DI 0 "register_operand" "=r")
9442         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9443                                         (const_int 32)))
9444                      (const_int 32)))]
9445   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9446   "neg{l}\t%k0"
9447   [(set_attr "type" "negnot")
9448    (set_attr "mode" "SI")])
9449
9450 (define_expand "neghi2"
9451   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9452                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9453               (clobber (reg:CC FLAGS_REG))])]
9454   "TARGET_HIMODE_MATH"
9455   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9456
9457 (define_insn "*neghi2_1"
9458   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9459         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9460    (clobber (reg:CC FLAGS_REG))]
9461   "ix86_unary_operator_ok (NEG, HImode, operands)"
9462   "neg{w}\t%0"
9463   [(set_attr "type" "negnot")
9464    (set_attr "mode" "HI")])
9465
9466 (define_insn "*neghi2_cmpz"
9467   [(set (reg:CCZ FLAGS_REG)
9468         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9469                      (const_int 0)))
9470    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9471         (neg:HI (match_dup 1)))]
9472   "ix86_unary_operator_ok (NEG, HImode, operands)"
9473   "neg{w}\t%0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "HI")])
9476
9477 (define_expand "negqi2"
9478   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9479                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9480               (clobber (reg:CC FLAGS_REG))])]
9481   "TARGET_QIMODE_MATH"
9482   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9483
9484 (define_insn "*negqi2_1"
9485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9486         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "ix86_unary_operator_ok (NEG, QImode, operands)"
9489   "neg{b}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "QI")])
9492
9493 (define_insn "*negqi2_cmpz"
9494   [(set (reg:CCZ FLAGS_REG)
9495         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9496                      (const_int 0)))
9497    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9498         (neg:QI (match_dup 1)))]
9499   "ix86_unary_operator_ok (NEG, QImode, operands)"
9500   "neg{b}\t%0"
9501   [(set_attr "type" "negnot")
9502    (set_attr "mode" "QI")])
9503
9504 ;; Changing of sign for FP values is doable using integer unit too.
9505
9506 (define_expand "negsf2"
9507   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509   "TARGET_80387 || TARGET_SSE_MATH"
9510   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9511
9512 (define_expand "abssf2"
9513   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9514         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9515   "TARGET_80387 || TARGET_SSE_MATH"
9516   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9517
9518 (define_insn "*absnegsf2_mixed"
9519   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9520         (match_operator:SF 3 "absneg_operator"
9521           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9522    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9525    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526   "#")
9527
9528 (define_insn "*absnegsf2_sse"
9529   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9530         (match_operator:SF 3 "absneg_operator"
9531           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9532    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9533    (clobber (reg:CC FLAGS_REG))]
9534   "TARGET_SSE_MATH
9535    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536   "#")
9537
9538 (define_insn "*absnegsf2_i387"
9539   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9540         (match_operator:SF 3 "absneg_operator"
9541           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9542    (use (match_operand 2 "" ""))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "TARGET_80387 && !TARGET_SSE_MATH
9545    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9546   "#")
9547
9548 (define_expand "copysignsf3"
9549   [(match_operand:SF 0 "register_operand" "")
9550    (match_operand:SF 1 "nonmemory_operand" "")
9551    (match_operand:SF 2 "register_operand" "")]
9552   "TARGET_SSE_MATH"
9553 {
9554   ix86_expand_copysign (operands);
9555   DONE;
9556 })
9557
9558 (define_insn_and_split "copysignsf3_const"
9559   [(set (match_operand:SF 0 "register_operand"          "=x")
9560         (unspec:SF
9561           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9562            (match_operand:SF 2 "register_operand"       "0")
9563            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9564           UNSPEC_COPYSIGN))]
9565   "TARGET_SSE_MATH"
9566   "#"
9567   "&& reload_completed"
9568   [(const_int 0)]
9569 {
9570   ix86_split_copysign_const (operands);
9571   DONE;
9572 })
9573
9574 (define_insn "copysignsf3_var"
9575   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9576         (unspec:SF
9577           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9578            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9579            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9580            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9581           UNSPEC_COPYSIGN))
9582    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9583   "TARGET_SSE_MATH"
9584   "#")
9585
9586 (define_split
9587   [(set (match_operand:SF 0 "register_operand" "")
9588         (unspec:SF
9589           [(match_operand:SF 2 "register_operand" "")
9590            (match_operand:SF 3 "register_operand" "")
9591            (match_operand:V4SF 4 "" "")
9592            (match_operand:V4SF 5 "" "")]
9593           UNSPEC_COPYSIGN))
9594    (clobber (match_scratch:V4SF 1 ""))]
9595   "TARGET_SSE_MATH && reload_completed"
9596   [(const_int 0)]
9597 {
9598   ix86_split_copysign_var (operands);
9599   DONE;
9600 })
9601
9602 (define_expand "negdf2"
9603   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9607
9608 (define_expand "absdf2"
9609   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9610         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9611   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9612   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9613
9614 (define_insn "*absnegdf2_mixed"
9615   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9616         (match_operator:DF 3 "absneg_operator"
9617           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9618    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9621    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622   "#")
9623
9624 (define_insn "*absnegdf2_sse"
9625   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9626         (match_operator:DF 3 "absneg_operator"
9627           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9628    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "TARGET_SSE2 && TARGET_SSE_MATH
9631    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632   "#")
9633
9634 (define_insn "*absnegdf2_i387"
9635   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9636         (match_operator:DF 3 "absneg_operator"
9637           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9638    (use (match_operand 2 "" ""))
9639    (clobber (reg:CC FLAGS_REG))]
9640   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9641    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9642   "#")
9643
9644 (define_expand "copysigndf3"
9645   [(match_operand:DF 0 "register_operand" "")
9646    (match_operand:DF 1 "nonmemory_operand" "")
9647    (match_operand:DF 2 "register_operand" "")]
9648   "TARGET_SSE2 && TARGET_SSE_MATH"
9649 {
9650   ix86_expand_copysign (operands);
9651   DONE;
9652 })
9653
9654 (define_insn_and_split "copysigndf3_const"
9655   [(set (match_operand:DF 0 "register_operand"          "=x")
9656         (unspec:DF
9657           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9658            (match_operand:DF 2 "register_operand"       "0")
9659            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9660           UNSPEC_COPYSIGN))]
9661   "TARGET_SSE2 && TARGET_SSE_MATH"
9662   "#"
9663   "&& reload_completed"
9664   [(const_int 0)]
9665 {
9666   ix86_split_copysign_const (operands);
9667   DONE;
9668 })
9669
9670 (define_insn "copysigndf3_var"
9671   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9672         (unspec:DF
9673           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9674            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9675            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9676            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9677           UNSPEC_COPYSIGN))
9678    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9679   "TARGET_SSE2 && TARGET_SSE_MATH"
9680   "#")
9681
9682 (define_split
9683   [(set (match_operand:DF 0 "register_operand" "")
9684         (unspec:DF
9685           [(match_operand:DF 2 "register_operand" "")
9686            (match_operand:DF 3 "register_operand" "")
9687            (match_operand:V2DF 4 "" "")
9688            (match_operand:V2DF 5 "" "")]
9689           UNSPEC_COPYSIGN))
9690    (clobber (match_scratch:V2DF 1 ""))]
9691   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9692   [(const_int 0)]
9693 {
9694   ix86_split_copysign_var (operands);
9695   DONE;
9696 })
9697
9698 (define_expand "negxf2"
9699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701   "TARGET_80387"
9702   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9703
9704 (define_expand "absxf2"
9705   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9706         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9707   "TARGET_80387"
9708   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9709
9710 (define_insn "*absnegxf2_i387"
9711   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9712         (match_operator:XF 3 "absneg_operator"
9713           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9714    (use (match_operand 2 "" ""))
9715    (clobber (reg:CC FLAGS_REG))]
9716   "TARGET_80387
9717    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9718   "#")
9719
9720 ;; Splitters for fp abs and neg.
9721
9722 (define_split
9723   [(set (match_operand 0 "fp_register_operand" "")
9724         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9725    (use (match_operand 2 "" ""))
9726    (clobber (reg:CC FLAGS_REG))]
9727   "reload_completed"
9728   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9729
9730 (define_split
9731   [(set (match_operand 0 "register_operand" "")
9732         (match_operator 3 "absneg_operator"
9733           [(match_operand 1 "register_operand" "")]))
9734    (use (match_operand 2 "nonimmediate_operand" ""))
9735    (clobber (reg:CC FLAGS_REG))]
9736   "reload_completed && SSE_REG_P (operands[0])"
9737   [(set (match_dup 0) (match_dup 3))]
9738 {
9739   enum machine_mode mode = GET_MODE (operands[0]);
9740   enum machine_mode vmode = GET_MODE (operands[2]);
9741   rtx tmp;
9742   
9743   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9744   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9745   if (operands_match_p (operands[0], operands[2]))
9746     {
9747       tmp = operands[1];
9748       operands[1] = operands[2];
9749       operands[2] = tmp;
9750     }
9751   if (GET_CODE (operands[3]) == ABS)
9752     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9753   else
9754     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9755   operands[3] = tmp;
9756 })
9757
9758 (define_split
9759   [(set (match_operand:SF 0 "register_operand" "")
9760         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9761    (use (match_operand:V4SF 2 "" ""))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "reload_completed"
9764   [(parallel [(set (match_dup 0) (match_dup 1))
9765               (clobber (reg:CC FLAGS_REG))])]
9766
9767   rtx tmp;
9768   operands[0] = gen_lowpart (SImode, operands[0]);
9769   if (GET_CODE (operands[1]) == ABS)
9770     {
9771       tmp = gen_int_mode (0x7fffffff, SImode);
9772       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9773     }
9774   else
9775     {
9776       tmp = gen_int_mode (0x80000000, SImode);
9777       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9778     }
9779   operands[1] = tmp;
9780 })
9781
9782 (define_split
9783   [(set (match_operand:DF 0 "register_operand" "")
9784         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9785    (use (match_operand 2 "" ""))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "reload_completed"
9788   [(parallel [(set (match_dup 0) (match_dup 1))
9789               (clobber (reg:CC FLAGS_REG))])]
9790 {
9791   rtx tmp;
9792   if (TARGET_64BIT)
9793     {
9794       tmp = gen_lowpart (DImode, operands[0]);
9795       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9796       operands[0] = tmp;
9797
9798       if (GET_CODE (operands[1]) == ABS)
9799         tmp = const0_rtx;
9800       else
9801         tmp = gen_rtx_NOT (DImode, tmp);
9802     }
9803   else
9804     {
9805       operands[0] = gen_highpart (SImode, operands[0]);
9806       if (GET_CODE (operands[1]) == ABS)
9807         {
9808           tmp = gen_int_mode (0x7fffffff, SImode);
9809           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9810         }
9811       else
9812         {
9813           tmp = gen_int_mode (0x80000000, SImode);
9814           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9815         }
9816     }
9817   operands[1] = tmp;
9818 })
9819
9820 (define_split
9821   [(set (match_operand:XF 0 "register_operand" "")
9822         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9823    (use (match_operand 2 "" ""))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "reload_completed"
9826   [(parallel [(set (match_dup 0) (match_dup 1))
9827               (clobber (reg:CC FLAGS_REG))])]
9828 {
9829   rtx tmp;
9830   operands[0] = gen_rtx_REG (SImode,
9831                              true_regnum (operands[0])
9832                              + (TARGET_64BIT ? 1 : 2));
9833   if (GET_CODE (operands[1]) == ABS)
9834     {
9835       tmp = GEN_INT (0x7fff);
9836       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9837     }
9838   else
9839     {
9840       tmp = GEN_INT (0x8000);
9841       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9842     }
9843   operands[1] = tmp;
9844 })
9845
9846 (define_split
9847   [(set (match_operand 0 "memory_operand" "")
9848         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9849    (use (match_operand 2 "" ""))
9850    (clobber (reg:CC FLAGS_REG))]
9851   "reload_completed"
9852   [(parallel [(set (match_dup 0) (match_dup 1))
9853               (clobber (reg:CC FLAGS_REG))])]
9854 {
9855   enum machine_mode mode = GET_MODE (operands[0]);
9856   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9857   rtx tmp;
9858
9859   operands[0] = adjust_address (operands[0], QImode, size - 1);
9860   if (GET_CODE (operands[1]) == ABS)
9861     {
9862       tmp = gen_int_mode (0x7f, QImode);
9863       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9864     }
9865   else
9866     {
9867       tmp = gen_int_mode (0x80, QImode);
9868       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9869     }
9870   operands[1] = tmp;
9871 })
9872
9873 ;; Conditionalize these after reload. If they match before reload, we 
9874 ;; lose the clobber and ability to use integer instructions.
9875
9876 (define_insn "*negsf2_1"
9877   [(set (match_operand:SF 0 "register_operand" "=f")
9878         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9879   "TARGET_80387 && reload_completed"
9880   "fchs"
9881   [(set_attr "type" "fsgn")
9882    (set_attr "mode" "SF")])
9883
9884 (define_insn "*negdf2_1"
9885   [(set (match_operand:DF 0 "register_operand" "=f")
9886         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9887   "TARGET_80387 && reload_completed"
9888   "fchs"
9889   [(set_attr "type" "fsgn")
9890    (set_attr "mode" "DF")])
9891
9892 (define_insn "*negxf2_1"
9893   [(set (match_operand:XF 0 "register_operand" "=f")
9894         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9895   "TARGET_80387 && reload_completed"
9896   "fchs"
9897   [(set_attr "type" "fsgn")
9898    (set_attr "mode" "XF")])
9899
9900 (define_insn "*abssf2_1"
9901   [(set (match_operand:SF 0 "register_operand" "=f")
9902         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9903   "TARGET_80387 && reload_completed"
9904   "fabs"
9905   [(set_attr "type" "fsgn")
9906    (set_attr "mode" "SF")])
9907
9908 (define_insn "*absdf2_1"
9909   [(set (match_operand:DF 0 "register_operand" "=f")
9910         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9911   "TARGET_80387 && reload_completed"
9912   "fabs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "DF")])
9915
9916 (define_insn "*absxf2_1"
9917   [(set (match_operand:XF 0 "register_operand" "=f")
9918         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9919   "TARGET_80387 && reload_completed"
9920   "fabs"
9921   [(set_attr "type" "fsgn")
9922    (set_attr "mode" "DF")])
9923
9924 (define_insn "*negextendsfdf2"
9925   [(set (match_operand:DF 0 "register_operand" "=f")
9926         (neg:DF (float_extend:DF
9927                   (match_operand:SF 1 "register_operand" "0"))))]
9928   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9929   "fchs"
9930   [(set_attr "type" "fsgn")
9931    (set_attr "mode" "DF")])
9932
9933 (define_insn "*negextenddfxf2"
9934   [(set (match_operand:XF 0 "register_operand" "=f")
9935         (neg:XF (float_extend:XF
9936                   (match_operand:DF 1 "register_operand" "0"))))]
9937   "TARGET_80387"
9938   "fchs"
9939   [(set_attr "type" "fsgn")
9940    (set_attr "mode" "XF")])
9941
9942 (define_insn "*negextendsfxf2"
9943   [(set (match_operand:XF 0 "register_operand" "=f")
9944         (neg:XF (float_extend:XF
9945                   (match_operand:SF 1 "register_operand" "0"))))]
9946   "TARGET_80387"
9947   "fchs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "XF")])
9950
9951 (define_insn "*absextendsfdf2"
9952   [(set (match_operand:DF 0 "register_operand" "=f")
9953         (abs:DF (float_extend:DF
9954                   (match_operand:SF 1 "register_operand" "0"))))]
9955   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9956   "fabs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9959
9960 (define_insn "*absextenddfxf2"
9961   [(set (match_operand:XF 0 "register_operand" "=f")
9962         (abs:XF (float_extend:XF
9963           (match_operand:DF 1 "register_operand" "0"))))]
9964   "TARGET_80387"
9965   "fabs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "XF")])
9968
9969 (define_insn "*absextendsfxf2"
9970   [(set (match_operand:XF 0 "register_operand" "=f")
9971         (abs:XF (float_extend:XF
9972           (match_operand:SF 1 "register_operand" "0"))))]
9973   "TARGET_80387"
9974   "fabs"
9975   [(set_attr "type" "fsgn")
9976    (set_attr "mode" "XF")])
9977 \f
9978 ;; One complement instructions
9979
9980 (define_expand "one_cmpldi2"
9981   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9982         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9983   "TARGET_64BIT"
9984   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9985
9986 (define_insn "*one_cmpldi2_1_rex64"
9987   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9988         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9989   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9990   "not{q}\t%0"
9991   [(set_attr "type" "negnot")
9992    (set_attr "mode" "DI")])
9993
9994 (define_insn "*one_cmpldi2_2_rex64"
9995   [(set (reg FLAGS_REG)
9996         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9997                  (const_int 0)))
9998    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9999         (not:DI (match_dup 1)))]
10000   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10001    && ix86_unary_operator_ok (NOT, DImode, operands)"
10002   "#"
10003   [(set_attr "type" "alu1")
10004    (set_attr "mode" "DI")])
10005
10006 (define_split
10007   [(set (match_operand 0 "flags_reg_operand" "")
10008         (match_operator 2 "compare_operator"
10009           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10010            (const_int 0)]))
10011    (set (match_operand:DI 1 "nonimmediate_operand" "")
10012         (not:DI (match_dup 3)))]
10013   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10014   [(parallel [(set (match_dup 0)
10015                    (match_op_dup 2
10016                      [(xor:DI (match_dup 3) (const_int -1))
10017                       (const_int 0)]))
10018               (set (match_dup 1)
10019                    (xor:DI (match_dup 3) (const_int -1)))])]
10020   "")
10021
10022 (define_expand "one_cmplsi2"
10023   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10024         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10025   ""
10026   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10027
10028 (define_insn "*one_cmplsi2_1"
10029   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10030         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10031   "ix86_unary_operator_ok (NOT, SImode, operands)"
10032   "not{l}\t%0"
10033   [(set_attr "type" "negnot")
10034    (set_attr "mode" "SI")])
10035
10036 ;; ??? Currently never generated - xor is used instead.
10037 (define_insn "*one_cmplsi2_1_zext"
10038   [(set (match_operand:DI 0 "register_operand" "=r")
10039         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10040   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10041   "not{l}\t%k0"
10042   [(set_attr "type" "negnot")
10043    (set_attr "mode" "SI")])
10044
10045 (define_insn "*one_cmplsi2_2"
10046   [(set (reg FLAGS_REG)
10047         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10048                  (const_int 0)))
10049    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10050         (not:SI (match_dup 1)))]
10051   "ix86_match_ccmode (insn, CCNOmode)
10052    && ix86_unary_operator_ok (NOT, SImode, operands)"
10053   "#"
10054   [(set_attr "type" "alu1")
10055    (set_attr "mode" "SI")])
10056
10057 (define_split
10058   [(set (match_operand 0 "flags_reg_operand" "")
10059         (match_operator 2 "compare_operator"
10060           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10061            (const_int 0)]))
10062    (set (match_operand:SI 1 "nonimmediate_operand" "")
10063         (not:SI (match_dup 3)))]
10064   "ix86_match_ccmode (insn, CCNOmode)"
10065   [(parallel [(set (match_dup 0)
10066                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10067                                     (const_int 0)]))
10068               (set (match_dup 1)
10069                    (xor:SI (match_dup 3) (const_int -1)))])]
10070   "")
10071
10072 ;; ??? Currently never generated - xor is used instead.
10073 (define_insn "*one_cmplsi2_2_zext"
10074   [(set (reg FLAGS_REG)
10075         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10076                  (const_int 0)))
10077    (set (match_operand:DI 0 "register_operand" "=r")
10078         (zero_extend:DI (not:SI (match_dup 1))))]
10079   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10080    && ix86_unary_operator_ok (NOT, SImode, operands)"
10081   "#"
10082   [(set_attr "type" "alu1")
10083    (set_attr "mode" "SI")])
10084
10085 (define_split
10086   [(set (match_operand 0 "flags_reg_operand" "")
10087         (match_operator 2 "compare_operator"
10088           [(not:SI (match_operand:SI 3 "register_operand" ""))
10089            (const_int 0)]))
10090    (set (match_operand:DI 1 "register_operand" "")
10091         (zero_extend:DI (not:SI (match_dup 3))))]
10092   "ix86_match_ccmode (insn, CCNOmode)"
10093   [(parallel [(set (match_dup 0)
10094                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095                                     (const_int 0)]))
10096               (set (match_dup 1)
10097                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10098   "")
10099
10100 (define_expand "one_cmplhi2"
10101   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10102         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10103   "TARGET_HIMODE_MATH"
10104   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10105
10106 (define_insn "*one_cmplhi2_1"
10107   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10108         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10109   "ix86_unary_operator_ok (NOT, HImode, operands)"
10110   "not{w}\t%0"
10111   [(set_attr "type" "negnot")
10112    (set_attr "mode" "HI")])
10113
10114 (define_insn "*one_cmplhi2_2"
10115   [(set (reg FLAGS_REG)
10116         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10117                  (const_int 0)))
10118    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10119         (not:HI (match_dup 1)))]
10120   "ix86_match_ccmode (insn, CCNOmode)
10121    && ix86_unary_operator_ok (NEG, HImode, operands)"
10122   "#"
10123   [(set_attr "type" "alu1")
10124    (set_attr "mode" "HI")])
10125
10126 (define_split
10127   [(set (match_operand 0 "flags_reg_operand" "")
10128         (match_operator 2 "compare_operator"
10129           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10130            (const_int 0)]))
10131    (set (match_operand:HI 1 "nonimmediate_operand" "")
10132         (not:HI (match_dup 3)))]
10133   "ix86_match_ccmode (insn, CCNOmode)"
10134   [(parallel [(set (match_dup 0)
10135                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10136                                     (const_int 0)]))
10137               (set (match_dup 1)
10138                    (xor:HI (match_dup 3) (const_int -1)))])]
10139   "")
10140
10141 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10142 (define_expand "one_cmplqi2"
10143   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10144         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10145   "TARGET_QIMODE_MATH"
10146   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10147
10148 (define_insn "*one_cmplqi2_1"
10149   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10150         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10151   "ix86_unary_operator_ok (NOT, QImode, operands)"
10152   "@
10153    not{b}\t%0
10154    not{l}\t%k0"
10155   [(set_attr "type" "negnot")
10156    (set_attr "mode" "QI,SI")])
10157
10158 (define_insn "*one_cmplqi2_2"
10159   [(set (reg FLAGS_REG)
10160         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10161                  (const_int 0)))
10162    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10163         (not:QI (match_dup 1)))]
10164   "ix86_match_ccmode (insn, CCNOmode)
10165    && ix86_unary_operator_ok (NOT, QImode, operands)"
10166   "#"
10167   [(set_attr "type" "alu1")
10168    (set_attr "mode" "QI")])
10169
10170 (define_split
10171   [(set (match_operand 0 "flags_reg_operand" "")
10172         (match_operator 2 "compare_operator"
10173           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10174            (const_int 0)]))
10175    (set (match_operand:QI 1 "nonimmediate_operand" "")
10176         (not:QI (match_dup 3)))]
10177   "ix86_match_ccmode (insn, CCNOmode)"
10178   [(parallel [(set (match_dup 0)
10179                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10180                                     (const_int 0)]))
10181               (set (match_dup 1)
10182                    (xor:QI (match_dup 3) (const_int -1)))])]
10183   "")
10184 \f
10185 ;; Arithmetic shift instructions
10186
10187 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10188 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10189 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10190 ;; from the assembler input.
10191 ;;
10192 ;; This instruction shifts the target reg/mem as usual, but instead of
10193 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10194 ;; is a left shift double, bits are taken from the high order bits of
10195 ;; reg, else if the insn is a shift right double, bits are taken from the
10196 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10197 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10198 ;;
10199 ;; Since sh[lr]d does not change the `reg' operand, that is done
10200 ;; separately, making all shifts emit pairs of shift double and normal
10201 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10202 ;; support a 63 bit shift, each shift where the count is in a reg expands
10203 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10204 ;;
10205 ;; If the shift count is a constant, we need never emit more than one
10206 ;; shift pair, instead using moves and sign extension for counts greater
10207 ;; than 31.
10208
10209 (define_expand "ashlti3"
10210   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10211                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10212                               (match_operand:QI 2 "nonmemory_operand" "")))
10213               (clobber (reg:CC FLAGS_REG))])]
10214   "TARGET_64BIT"
10215 {
10216   if (! immediate_operand (operands[2], QImode))
10217     {
10218       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10219       DONE;
10220     }
10221   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10222   DONE;
10223 })
10224
10225 (define_insn "ashlti3_1"
10226   [(set (match_operand:TI 0 "register_operand" "=r")
10227         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228                    (match_operand:QI 2 "register_operand" "c")))
10229    (clobber (match_scratch:DI 3 "=&r"))
10230    (clobber (reg:CC FLAGS_REG))]
10231   "TARGET_64BIT"
10232   "#"
10233   [(set_attr "type" "multi")])
10234
10235 (define_insn "*ashlti3_2"
10236   [(set (match_operand:TI 0 "register_operand" "=r")
10237         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10238                    (match_operand:QI 2 "immediate_operand" "O")))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "TARGET_64BIT"
10241   "#"
10242   [(set_attr "type" "multi")])
10243
10244 (define_split
10245   [(set (match_operand:TI 0 "register_operand" "")
10246         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10247                    (match_operand:QI 2 "register_operand" "")))
10248    (clobber (match_scratch:DI 3 ""))
10249    (clobber (reg:CC FLAGS_REG))]
10250   "TARGET_64BIT && reload_completed"
10251   [(const_int 0)]
10252   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10253
10254 (define_split
10255   [(set (match_operand:TI 0 "register_operand" "")
10256         (ashift:TI (match_operand:TI 1 "register_operand" "")
10257                    (match_operand:QI 2 "immediate_operand" "")))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "TARGET_64BIT && reload_completed"
10260   [(const_int 0)]
10261   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10262
10263 (define_insn "x86_64_shld"
10264   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10265         (ior:DI (ashift:DI (match_dup 0)
10266                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10267                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10268                   (minus:QI (const_int 64) (match_dup 2)))))
10269    (clobber (reg:CC FLAGS_REG))]
10270   "TARGET_64BIT"
10271   "@
10272    shld{q}\t{%2, %1, %0|%0, %1, %2}
10273    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10274   [(set_attr "type" "ishift")
10275    (set_attr "prefix_0f" "1")
10276    (set_attr "mode" "DI")
10277    (set_attr "athlon_decode" "vector")])
10278
10279 (define_expand "x86_64_shift_adj"
10280   [(set (reg:CCZ FLAGS_REG)
10281         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10282                              (const_int 64))
10283                      (const_int 0)))
10284    (set (match_operand:DI 0 "register_operand" "")
10285         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286                          (match_operand:DI 1 "register_operand" "")
10287                          (match_dup 0)))
10288    (set (match_dup 1)
10289         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10290                          (match_operand:DI 3 "register_operand" "r")
10291                          (match_dup 1)))]
10292   "TARGET_64BIT"
10293   "")
10294
10295 (define_expand "ashldi3"
10296   [(set (match_operand:DI 0 "shiftdi_operand" "")
10297         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10298                    (match_operand:QI 2 "nonmemory_operand" "")))]
10299   ""
10300   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10301
10302 (define_insn "*ashldi3_1_rex64"
10303   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10304         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10305                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10308 {
10309   switch (get_attr_type (insn))
10310     {
10311     case TYPE_ALU:
10312       gcc_assert (operands[2] == const1_rtx);
10313       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10314       return "add{q}\t{%0, %0|%0, %0}";
10315
10316     case TYPE_LEA:
10317       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10318       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10319       operands[1] = gen_rtx_MULT (DImode, operands[1],
10320                                   GEN_INT (1 << INTVAL (operands[2])));
10321       return "lea{q}\t{%a1, %0|%0, %a1}";
10322
10323     default:
10324       if (REG_P (operands[2]))
10325         return "sal{q}\t{%b2, %0|%0, %b2}";
10326       else if (operands[2] == const1_rtx
10327                && (TARGET_SHIFT1 || optimize_size))
10328         return "sal{q}\t%0";
10329       else
10330         return "sal{q}\t{%2, %0|%0, %2}";
10331     }
10332 }
10333   [(set (attr "type")
10334      (cond [(eq_attr "alternative" "1")
10335               (const_string "lea")
10336             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10337                           (const_int 0))
10338                       (match_operand 0 "register_operand" ""))
10339                  (match_operand 2 "const1_operand" ""))
10340               (const_string "alu")
10341            ]
10342            (const_string "ishift")))
10343    (set_attr "mode" "DI")])
10344
10345 ;; Convert lea to the lea pattern to avoid flags dependency.
10346 (define_split
10347   [(set (match_operand:DI 0 "register_operand" "")
10348         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10349                    (match_operand:QI 2 "immediate_operand" "")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT && reload_completed
10352    && true_regnum (operands[0]) != true_regnum (operands[1])"
10353   [(set (match_dup 0)
10354         (mult:DI (match_dup 1)
10355                  (match_dup 2)))]
10356   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10357
10358 ;; This pattern can't accept a variable shift count, since shifts by
10359 ;; zero don't affect the flags.  We assume that shifts by constant
10360 ;; zero are optimized away.
10361 (define_insn "*ashldi3_cmp_rex64"
10362   [(set (reg FLAGS_REG)
10363         (compare
10364           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10365                      (match_operand:QI 2 "immediate_operand" "e"))
10366           (const_int 0)))
10367    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10368         (ashift:DI (match_dup 1) (match_dup 2)))]
10369   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10370    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10371 {
10372   switch (get_attr_type (insn))
10373     {
10374     case TYPE_ALU:
10375       gcc_assert (operands[2] == const1_rtx);
10376       return "add{q}\t{%0, %0|%0, %0}";
10377
10378     default:
10379       if (REG_P (operands[2]))
10380         return "sal{q}\t{%b2, %0|%0, %b2}";
10381       else if (operands[2] == const1_rtx
10382                && (TARGET_SHIFT1 || optimize_size))
10383         return "sal{q}\t%0";
10384       else
10385         return "sal{q}\t{%2, %0|%0, %2}";
10386     }
10387 }
10388   [(set (attr "type")
10389      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10390                           (const_int 0))
10391                       (match_operand 0 "register_operand" ""))
10392                  (match_operand 2 "const1_operand" ""))
10393               (const_string "alu")
10394            ]
10395            (const_string "ishift")))
10396    (set_attr "mode" "DI")])
10397
10398 (define_insn "*ashldi3_1"
10399   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10400         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10401                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10402    (clobber (reg:CC FLAGS_REG))]
10403   "!TARGET_64BIT"
10404   "#"
10405   [(set_attr "type" "multi")])
10406
10407 ;; By default we don't ask for a scratch register, because when DImode
10408 ;; values are manipulated, registers are already at a premium.  But if
10409 ;; we have one handy, we won't turn it away.
10410 (define_peephole2
10411   [(match_scratch:SI 3 "r")
10412    (parallel [(set (match_operand:DI 0 "register_operand" "")
10413                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414                               (match_operand:QI 2 "nonmemory_operand" "")))
10415               (clobber (reg:CC FLAGS_REG))])
10416    (match_dup 3)]
10417   "!TARGET_64BIT && TARGET_CMOVE"
10418   [(const_int 0)]
10419   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10420
10421 (define_split
10422   [(set (match_operand:DI 0 "register_operand" "")
10423         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10424                    (match_operand:QI 2 "nonmemory_operand" "")))
10425    (clobber (reg:CC FLAGS_REG))]
10426   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10427                      ? flow2_completed : reload_completed)"
10428   [(const_int 0)]
10429   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10430
10431 (define_insn "x86_shld_1"
10432   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10433         (ior:SI (ashift:SI (match_dup 0)
10434                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10435                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10436                   (minus:QI (const_int 32) (match_dup 2)))))
10437    (clobber (reg:CC FLAGS_REG))]
10438   ""
10439   "@
10440    shld{l}\t{%2, %1, %0|%0, %1, %2}
10441    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10442   [(set_attr "type" "ishift")
10443    (set_attr "prefix_0f" "1")
10444    (set_attr "mode" "SI")
10445    (set_attr "pent_pair" "np")
10446    (set_attr "athlon_decode" "vector")])
10447
10448 (define_expand "x86_shift_adj_1"
10449   [(set (reg:CCZ FLAGS_REG)
10450         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10451                              (const_int 32))
10452                      (const_int 0)))
10453    (set (match_operand:SI 0 "register_operand" "")
10454         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10455                          (match_operand:SI 1 "register_operand" "")
10456                          (match_dup 0)))
10457    (set (match_dup 1)
10458         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10459                          (match_operand:SI 3 "register_operand" "r")
10460                          (match_dup 1)))]
10461   "TARGET_CMOVE"
10462   "")
10463
10464 (define_expand "x86_shift_adj_2"
10465   [(use (match_operand:SI 0 "register_operand" ""))
10466    (use (match_operand:SI 1 "register_operand" ""))
10467    (use (match_operand:QI 2 "register_operand" ""))]
10468   ""
10469 {
10470   rtx label = gen_label_rtx ();
10471   rtx tmp;
10472
10473   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10474
10475   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10476   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10477   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10478                               gen_rtx_LABEL_REF (VOIDmode, label),
10479                               pc_rtx);
10480   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10481   JUMP_LABEL (tmp) = label;
10482
10483   emit_move_insn (operands[0], operands[1]);
10484   ix86_expand_clear (operands[1]);
10485
10486   emit_label (label);
10487   LABEL_NUSES (label) = 1;
10488
10489   DONE;
10490 })
10491
10492 (define_expand "ashlsi3"
10493   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10494         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10495                    (match_operand:QI 2 "nonmemory_operand" "")))
10496    (clobber (reg:CC FLAGS_REG))]
10497   ""
10498   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10499
10500 (define_insn "*ashlsi3_1"
10501   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10502         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10503                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10504    (clobber (reg:CC FLAGS_REG))]
10505   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10506 {
10507   switch (get_attr_type (insn))
10508     {
10509     case TYPE_ALU:
10510       gcc_assert (operands[2] == const1_rtx);
10511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10512       return "add{l}\t{%0, %0|%0, %0}";
10513
10514     case TYPE_LEA:
10515       return "#";
10516
10517     default:
10518       if (REG_P (operands[2]))
10519         return "sal{l}\t{%b2, %0|%0, %b2}";
10520       else if (operands[2] == const1_rtx
10521                && (TARGET_SHIFT1 || optimize_size))
10522         return "sal{l}\t%0";
10523       else
10524         return "sal{l}\t{%2, %0|%0, %2}";
10525     }
10526 }
10527   [(set (attr "type")
10528      (cond [(eq_attr "alternative" "1")
10529               (const_string "lea")
10530             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531                           (const_int 0))
10532                       (match_operand 0 "register_operand" ""))
10533                  (match_operand 2 "const1_operand" ""))
10534               (const_string "alu")
10535            ]
10536            (const_string "ishift")))
10537    (set_attr "mode" "SI")])
10538
10539 ;; Convert lea to the lea pattern to avoid flags dependency.
10540 (define_split
10541   [(set (match_operand 0 "register_operand" "")
10542         (ashift (match_operand 1 "index_register_operand" "")
10543                 (match_operand:QI 2 "const_int_operand" "")))
10544    (clobber (reg:CC FLAGS_REG))]
10545   "reload_completed
10546    && true_regnum (operands[0]) != true_regnum (operands[1])
10547    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10548   [(const_int 0)]
10549 {
10550   rtx pat;
10551   enum machine_mode mode = GET_MODE (operands[0]);
10552
10553   if (GET_MODE_SIZE (mode) < 4)
10554     operands[0] = gen_lowpart (SImode, operands[0]);
10555   if (mode != Pmode)
10556     operands[1] = gen_lowpart (Pmode, operands[1]);
10557   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10558
10559   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10560   if (Pmode != SImode)
10561     pat = gen_rtx_SUBREG (SImode, pat, 0);
10562   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10563   DONE;
10564 })
10565
10566 ;; Rare case of shifting RSP is handled by generating move and shift
10567 (define_split
10568   [(set (match_operand 0 "register_operand" "")
10569         (ashift (match_operand 1 "register_operand" "")
10570                 (match_operand:QI 2 "const_int_operand" "")))
10571    (clobber (reg:CC FLAGS_REG))]
10572   "reload_completed
10573    && true_regnum (operands[0]) != true_regnum (operands[1])"
10574   [(const_int 0)]
10575 {
10576   rtx pat, clob;
10577   emit_move_insn (operands[1], operands[0]);
10578   pat = gen_rtx_SET (VOIDmode, operands[0],
10579                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10580                                      operands[0], operands[2]));
10581   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10582   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10583   DONE;
10584 })
10585
10586 (define_insn "*ashlsi3_1_zext"
10587   [(set (match_operand:DI 0 "register_operand" "=r,r")
10588         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10589                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10590    (clobber (reg:CC FLAGS_REG))]
10591   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10592 {
10593   switch (get_attr_type (insn))
10594     {
10595     case TYPE_ALU:
10596       gcc_assert (operands[2] == const1_rtx);
10597       return "add{l}\t{%k0, %k0|%k0, %k0}";
10598
10599     case TYPE_LEA:
10600       return "#";
10601
10602     default:
10603       if (REG_P (operands[2]))
10604         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10605       else if (operands[2] == const1_rtx
10606                && (TARGET_SHIFT1 || optimize_size))
10607         return "sal{l}\t%k0";
10608       else
10609         return "sal{l}\t{%2, %k0|%k0, %2}";
10610     }
10611 }
10612   [(set (attr "type")
10613      (cond [(eq_attr "alternative" "1")
10614               (const_string "lea")
10615             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10616                      (const_int 0))
10617                  (match_operand 2 "const1_operand" ""))
10618               (const_string "alu")
10619            ]
10620            (const_string "ishift")))
10621    (set_attr "mode" "SI")])
10622
10623 ;; Convert lea to the lea pattern to avoid flags dependency.
10624 (define_split
10625   [(set (match_operand:DI 0 "register_operand" "")
10626         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10627                                 (match_operand:QI 2 "const_int_operand" ""))))
10628    (clobber (reg:CC FLAGS_REG))]
10629   "TARGET_64BIT && reload_completed
10630    && true_regnum (operands[0]) != true_regnum (operands[1])"
10631   [(set (match_dup 0) (zero_extend:DI
10632                         (subreg:SI (mult:SI (match_dup 1)
10633                                             (match_dup 2)) 0)))]
10634 {
10635   operands[1] = gen_lowpart (Pmode, operands[1]);
10636   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10637 })
10638
10639 ;; This pattern can't accept a variable shift count, since shifts by
10640 ;; zero don't affect the flags.  We assume that shifts by constant
10641 ;; zero are optimized away.
10642 (define_insn "*ashlsi3_cmp"
10643   [(set (reg FLAGS_REG)
10644         (compare
10645           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10646                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10647           (const_int 0)))
10648    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10649         (ashift:SI (match_dup 1) (match_dup 2)))]
10650   "ix86_match_ccmode (insn, CCGOCmode)
10651    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10652 {
10653   switch (get_attr_type (insn))
10654     {
10655     case TYPE_ALU:
10656       gcc_assert (operands[2] == const1_rtx);
10657       return "add{l}\t{%0, %0|%0, %0}";
10658
10659     default:
10660       if (REG_P (operands[2]))
10661         return "sal{l}\t{%b2, %0|%0, %b2}";
10662       else if (operands[2] == const1_rtx
10663                && (TARGET_SHIFT1 || optimize_size))
10664         return "sal{l}\t%0";
10665       else
10666         return "sal{l}\t{%2, %0|%0, %2}";
10667     }
10668 }
10669   [(set (attr "type")
10670      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10671                           (const_int 0))
10672                       (match_operand 0 "register_operand" ""))
10673                  (match_operand 2 "const1_operand" ""))
10674               (const_string "alu")
10675            ]
10676            (const_string "ishift")))
10677    (set_attr "mode" "SI")])
10678
10679 (define_insn "*ashlsi3_cmp_zext"
10680   [(set (reg FLAGS_REG)
10681         (compare
10682           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10683                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10684           (const_int 0)))
10685    (set (match_operand:DI 0 "register_operand" "=r")
10686         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10687   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10689 {
10690   switch (get_attr_type (insn))
10691     {
10692     case TYPE_ALU:
10693       gcc_assert (operands[2] == const1_rtx);
10694       return "add{l}\t{%k0, %k0|%k0, %k0}";
10695
10696     default:
10697       if (REG_P (operands[2]))
10698         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10699       else if (operands[2] == const1_rtx
10700                && (TARGET_SHIFT1 || optimize_size))
10701         return "sal{l}\t%k0";
10702       else
10703         return "sal{l}\t{%2, %k0|%k0, %2}";
10704     }
10705 }
10706   [(set (attr "type")
10707      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10708                      (const_int 0))
10709                  (match_operand 2 "const1_operand" ""))
10710               (const_string "alu")
10711            ]
10712            (const_string "ishift")))
10713    (set_attr "mode" "SI")])
10714
10715 (define_expand "ashlhi3"
10716   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10717         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10718                    (match_operand:QI 2 "nonmemory_operand" "")))
10719    (clobber (reg:CC FLAGS_REG))]
10720   "TARGET_HIMODE_MATH"
10721   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10722
10723 (define_insn "*ashlhi3_1_lea"
10724   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10725         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10726                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10727    (clobber (reg:CC FLAGS_REG))]
10728   "!TARGET_PARTIAL_REG_STALL
10729    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10730 {
10731   switch (get_attr_type (insn))
10732     {
10733     case TYPE_LEA:
10734       return "#";
10735     case TYPE_ALU:
10736       gcc_assert (operands[2] == const1_rtx);
10737       return "add{w}\t{%0, %0|%0, %0}";
10738
10739     default:
10740       if (REG_P (operands[2]))
10741         return "sal{w}\t{%b2, %0|%0, %b2}";
10742       else if (operands[2] == const1_rtx
10743                && (TARGET_SHIFT1 || optimize_size))
10744         return "sal{w}\t%0";
10745       else
10746         return "sal{w}\t{%2, %0|%0, %2}";
10747     }
10748 }
10749   [(set (attr "type")
10750      (cond [(eq_attr "alternative" "1")
10751               (const_string "lea")
10752             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10753                           (const_int 0))
10754                       (match_operand 0 "register_operand" ""))
10755                  (match_operand 2 "const1_operand" ""))
10756               (const_string "alu")
10757            ]
10758            (const_string "ishift")))
10759    (set_attr "mode" "HI,SI")])
10760
10761 (define_insn "*ashlhi3_1"
10762   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10763         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10764                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10765    (clobber (reg:CC FLAGS_REG))]
10766   "TARGET_PARTIAL_REG_STALL
10767    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10768 {
10769   switch (get_attr_type (insn))
10770     {
10771     case TYPE_ALU:
10772       gcc_assert (operands[2] == const1_rtx);
10773       return "add{w}\t{%0, %0|%0, %0}";
10774
10775     default:
10776       if (REG_P (operands[2]))
10777         return "sal{w}\t{%b2, %0|%0, %b2}";
10778       else if (operands[2] == const1_rtx
10779                && (TARGET_SHIFT1 || optimize_size))
10780         return "sal{w}\t%0";
10781       else
10782         return "sal{w}\t{%2, %0|%0, %2}";
10783     }
10784 }
10785   [(set (attr "type")
10786      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10787                           (const_int 0))
10788                       (match_operand 0 "register_operand" ""))
10789                  (match_operand 2 "const1_operand" ""))
10790               (const_string "alu")
10791            ]
10792            (const_string "ishift")))
10793    (set_attr "mode" "HI")])
10794
10795 ;; This pattern can't accept a variable shift count, since shifts by
10796 ;; zero don't affect the flags.  We assume that shifts by constant
10797 ;; zero are optimized away.
10798 (define_insn "*ashlhi3_cmp"
10799   [(set (reg FLAGS_REG)
10800         (compare
10801           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10802                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10803           (const_int 0)))
10804    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10805         (ashift:HI (match_dup 1) (match_dup 2)))]
10806   "ix86_match_ccmode (insn, CCGOCmode)
10807    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10808 {
10809   switch (get_attr_type (insn))
10810     {
10811     case TYPE_ALU:
10812       gcc_assert (operands[2] == const1_rtx);
10813       return "add{w}\t{%0, %0|%0, %0}";
10814
10815     default:
10816       if (REG_P (operands[2]))
10817         return "sal{w}\t{%b2, %0|%0, %b2}";
10818       else if (operands[2] == const1_rtx
10819                && (TARGET_SHIFT1 || optimize_size))
10820         return "sal{w}\t%0";
10821       else
10822         return "sal{w}\t{%2, %0|%0, %2}";
10823     }
10824 }
10825   [(set (attr "type")
10826      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10827                           (const_int 0))
10828                       (match_operand 0 "register_operand" ""))
10829                  (match_operand 2 "const1_operand" ""))
10830               (const_string "alu")
10831            ]
10832            (const_string "ishift")))
10833    (set_attr "mode" "HI")])
10834
10835 (define_expand "ashlqi3"
10836   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10837         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10838                    (match_operand:QI 2 "nonmemory_operand" "")))
10839    (clobber (reg:CC FLAGS_REG))]
10840   "TARGET_QIMODE_MATH"
10841   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10842
10843 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10844
10845 (define_insn "*ashlqi3_1_lea"
10846   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10847         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10848                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10849    (clobber (reg:CC FLAGS_REG))]
10850   "!TARGET_PARTIAL_REG_STALL
10851    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10852 {
10853   switch (get_attr_type (insn))
10854     {
10855     case TYPE_LEA:
10856       return "#";
10857     case TYPE_ALU:
10858       gcc_assert (operands[2] == const1_rtx);
10859       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10860         return "add{l}\t{%k0, %k0|%k0, %k0}";
10861       else
10862         return "add{b}\t{%0, %0|%0, %0}";
10863
10864     default:
10865       if (REG_P (operands[2]))
10866         {
10867           if (get_attr_mode (insn) == MODE_SI)
10868             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10869           else
10870             return "sal{b}\t{%b2, %0|%0, %b2}";
10871         }
10872       else if (operands[2] == const1_rtx
10873                && (TARGET_SHIFT1 || optimize_size))
10874         {
10875           if (get_attr_mode (insn) == MODE_SI)
10876             return "sal{l}\t%0";
10877           else
10878             return "sal{b}\t%0";
10879         }
10880       else
10881         {
10882           if (get_attr_mode (insn) == MODE_SI)
10883             return "sal{l}\t{%2, %k0|%k0, %2}";
10884           else
10885             return "sal{b}\t{%2, %0|%0, %2}";
10886         }
10887     }
10888 }
10889   [(set (attr "type")
10890      (cond [(eq_attr "alternative" "2")
10891               (const_string "lea")
10892             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893                           (const_int 0))
10894                       (match_operand 0 "register_operand" ""))
10895                  (match_operand 2 "const1_operand" ""))
10896               (const_string "alu")
10897            ]
10898            (const_string "ishift")))
10899    (set_attr "mode" "QI,SI,SI")])
10900
10901 (define_insn "*ashlqi3_1"
10902   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10903         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10904                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "TARGET_PARTIAL_REG_STALL
10907    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10908 {
10909   switch (get_attr_type (insn))
10910     {
10911     case TYPE_ALU:
10912       gcc_assert (operands[2] == const1_rtx);
10913       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10914         return "add{l}\t{%k0, %k0|%k0, %k0}";
10915       else
10916         return "add{b}\t{%0, %0|%0, %0}";
10917
10918     default:
10919       if (REG_P (operands[2]))
10920         {
10921           if (get_attr_mode (insn) == MODE_SI)
10922             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10923           else
10924             return "sal{b}\t{%b2, %0|%0, %b2}";
10925         }
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         {
10929           if (get_attr_mode (insn) == MODE_SI)
10930             return "sal{l}\t%0";
10931           else
10932             return "sal{b}\t%0";
10933         }
10934       else
10935         {
10936           if (get_attr_mode (insn) == MODE_SI)
10937             return "sal{l}\t{%2, %k0|%k0, %2}";
10938           else
10939             return "sal{b}\t{%2, %0|%0, %2}";
10940         }
10941     }
10942 }
10943   [(set (attr "type")
10944      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10945                           (const_int 0))
10946                       (match_operand 0 "register_operand" ""))
10947                  (match_operand 2 "const1_operand" ""))
10948               (const_string "alu")
10949            ]
10950            (const_string "ishift")))
10951    (set_attr "mode" "QI,SI")])
10952
10953 ;; This pattern can't accept a variable shift count, since shifts by
10954 ;; zero don't affect the flags.  We assume that shifts by constant
10955 ;; zero are optimized away.
10956 (define_insn "*ashlqi3_cmp"
10957   [(set (reg FLAGS_REG)
10958         (compare
10959           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10960                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10961           (const_int 0)))
10962    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10963         (ashift:QI (match_dup 1) (match_dup 2)))]
10964   "ix86_match_ccmode (insn, CCGOCmode)
10965    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10966 {
10967   switch (get_attr_type (insn))
10968     {
10969     case TYPE_ALU:
10970       gcc_assert (operands[2] == const1_rtx);
10971       return "add{b}\t{%0, %0|%0, %0}";
10972
10973     default:
10974       if (REG_P (operands[2]))
10975         return "sal{b}\t{%b2, %0|%0, %b2}";
10976       else if (operands[2] == const1_rtx
10977                && (TARGET_SHIFT1 || optimize_size))
10978         return "sal{b}\t%0";
10979       else
10980         return "sal{b}\t{%2, %0|%0, %2}";
10981     }
10982 }
10983   [(set (attr "type")
10984      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985                           (const_int 0))
10986                       (match_operand 0 "register_operand" ""))
10987                  (match_operand 2 "const1_operand" ""))
10988               (const_string "alu")
10989            ]
10990            (const_string "ishift")))
10991    (set_attr "mode" "QI")])
10992
10993 ;; See comment above `ashldi3' about how this works.
10994
10995 (define_expand "ashrti3"
10996   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10997                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10998                                 (match_operand:QI 2 "nonmemory_operand" "")))
10999               (clobber (reg:CC FLAGS_REG))])]
11000   "TARGET_64BIT"
11001 {
11002   if (! immediate_operand (operands[2], QImode))
11003     {
11004       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11005       DONE;
11006     }
11007   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11008   DONE;
11009 })
11010
11011 (define_insn "ashrti3_1"
11012   [(set (match_operand:TI 0 "register_operand" "=r")
11013         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11014                      (match_operand:QI 2 "register_operand" "c")))
11015    (clobber (match_scratch:DI 3 "=&r"))
11016    (clobber (reg:CC FLAGS_REG))]
11017   "TARGET_64BIT"
11018   "#"
11019   [(set_attr "type" "multi")])
11020
11021 (define_insn "*ashrti3_2"
11022   [(set (match_operand:TI 0 "register_operand" "=r")
11023         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11024                      (match_operand:QI 2 "immediate_operand" "O")))
11025    (clobber (reg:CC FLAGS_REG))]
11026   "TARGET_64BIT"
11027   "#"
11028   [(set_attr "type" "multi")])
11029
11030 (define_split
11031   [(set (match_operand:TI 0 "register_operand" "")
11032         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11033                      (match_operand:QI 2 "register_operand" "")))
11034    (clobber (match_scratch:DI 3 ""))
11035    (clobber (reg:CC FLAGS_REG))]
11036   "TARGET_64BIT && reload_completed"
11037   [(const_int 0)]
11038   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11039
11040 (define_split
11041   [(set (match_operand:TI 0 "register_operand" "")
11042         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11043                      (match_operand:QI 2 "immediate_operand" "")))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT && reload_completed"
11046   [(const_int 0)]
11047   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11048
11049 (define_insn "x86_64_shrd"
11050   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11051         (ior:DI (ashiftrt:DI (match_dup 0)
11052                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11053                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11054                   (minus:QI (const_int 64) (match_dup 2)))))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "TARGET_64BIT"
11057   "@
11058    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11059    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11060   [(set_attr "type" "ishift")
11061    (set_attr "prefix_0f" "1")
11062    (set_attr "mode" "DI")
11063    (set_attr "athlon_decode" "vector")])
11064
11065 (define_expand "ashrdi3"
11066   [(set (match_operand:DI 0 "shiftdi_operand" "")
11067         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11068                      (match_operand:QI 2 "nonmemory_operand" "")))]
11069   ""
11070   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11071
11072 (define_insn "*ashrdi3_63_rex64"
11073   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11074         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11075                      (match_operand:DI 2 "const_int_operand" "i,i")))
11076    (clobber (reg:CC FLAGS_REG))]
11077   "TARGET_64BIT && INTVAL (operands[2]) == 63
11078    && (TARGET_USE_CLTD || optimize_size)
11079    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11080   "@
11081    {cqto|cqo}
11082    sar{q}\t{%2, %0|%0, %2}"
11083   [(set_attr "type" "imovx,ishift")
11084    (set_attr "prefix_0f" "0,*")
11085    (set_attr "length_immediate" "0,*")
11086    (set_attr "modrm" "0,1")
11087    (set_attr "mode" "DI")])
11088
11089 (define_insn "*ashrdi3_1_one_bit_rex64"
11090   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11091         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11092                      (match_operand:QI 2 "const1_operand" "")))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11095    && (TARGET_SHIFT1 || optimize_size)"
11096   "sar{q}\t%0"
11097   [(set_attr "type" "ishift")
11098    (set (attr "length") 
11099      (if_then_else (match_operand:DI 0 "register_operand" "") 
11100         (const_string "2")
11101         (const_string "*")))])
11102
11103 (define_insn "*ashrdi3_1_rex64"
11104   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11105         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11106                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11107    (clobber (reg:CC FLAGS_REG))]
11108   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109   "@
11110    sar{q}\t{%2, %0|%0, %2}
11111    sar{q}\t{%b2, %0|%0, %b2}"
11112   [(set_attr "type" "ishift")
11113    (set_attr "mode" "DI")])
11114
11115 ;; This pattern can't accept a variable shift count, since shifts by
11116 ;; zero don't affect the flags.  We assume that shifts by constant
11117 ;; zero are optimized away.
11118 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11119   [(set (reg FLAGS_REG)
11120         (compare
11121           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11122                        (match_operand:QI 2 "const1_operand" ""))
11123           (const_int 0)))
11124    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11125         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11126   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11127    && (TARGET_SHIFT1 || optimize_size)
11128    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11129   "sar{q}\t%0"
11130   [(set_attr "type" "ishift")
11131    (set (attr "length") 
11132      (if_then_else (match_operand:DI 0 "register_operand" "") 
11133         (const_string "2")
11134         (const_string "*")))])
11135
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags.  We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*ashrdi3_cmp_rex64"
11140   [(set (reg FLAGS_REG)
11141         (compare
11142           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11143                        (match_operand:QI 2 "const_int_operand" "n"))
11144           (const_int 0)))
11145    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11146         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11147   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11148    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11149   "sar{q}\t{%2, %0|%0, %2}"
11150   [(set_attr "type" "ishift")
11151    (set_attr "mode" "DI")])
11152
11153 (define_insn "*ashrdi3_1"
11154   [(set (match_operand:DI 0 "register_operand" "=r")
11155         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11156                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11157    (clobber (reg:CC FLAGS_REG))]
11158   "!TARGET_64BIT"
11159   "#"
11160   [(set_attr "type" "multi")])
11161
11162 ;; By default we don't ask for a scratch register, because when DImode
11163 ;; values are manipulated, registers are already at a premium.  But if
11164 ;; we have one handy, we won't turn it away.
11165 (define_peephole2
11166   [(match_scratch:SI 3 "r")
11167    (parallel [(set (match_operand:DI 0 "register_operand" "")
11168                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11169                                 (match_operand:QI 2 "nonmemory_operand" "")))
11170               (clobber (reg:CC FLAGS_REG))])
11171    (match_dup 3)]
11172   "!TARGET_64BIT && TARGET_CMOVE"
11173   [(const_int 0)]
11174   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11175
11176 (define_split
11177   [(set (match_operand:DI 0 "register_operand" "")
11178         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11179                      (match_operand:QI 2 "nonmemory_operand" "")))
11180    (clobber (reg:CC FLAGS_REG))]
11181   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11182                      ? flow2_completed : reload_completed)"
11183   [(const_int 0)]
11184   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11185
11186 (define_insn "x86_shrd_1"
11187   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11188         (ior:SI (ashiftrt:SI (match_dup 0)
11189                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11190                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11191                   (minus:QI (const_int 32) (match_dup 2)))))
11192    (clobber (reg:CC FLAGS_REG))]
11193   ""
11194   "@
11195    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11196    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11197   [(set_attr "type" "ishift")
11198    (set_attr "prefix_0f" "1")
11199    (set_attr "pent_pair" "np")
11200    (set_attr "mode" "SI")])
11201
11202 (define_expand "x86_shift_adj_3"
11203   [(use (match_operand:SI 0 "register_operand" ""))
11204    (use (match_operand:SI 1 "register_operand" ""))
11205    (use (match_operand:QI 2 "register_operand" ""))]
11206   ""
11207 {
11208   rtx label = gen_label_rtx ();
11209   rtx tmp;
11210
11211   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11212
11213   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11214   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11215   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11216                               gen_rtx_LABEL_REF (VOIDmode, label),
11217                               pc_rtx);
11218   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11219   JUMP_LABEL (tmp) = label;
11220
11221   emit_move_insn (operands[0], operands[1]);
11222   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11223
11224   emit_label (label);
11225   LABEL_NUSES (label) = 1;
11226
11227   DONE;
11228 })
11229
11230 (define_insn "ashrsi3_31"
11231   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11232         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11233                      (match_operand:SI 2 "const_int_operand" "i,i")))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11236    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11237   "@
11238    {cltd|cdq}
11239    sar{l}\t{%2, %0|%0, %2}"
11240   [(set_attr "type" "imovx,ishift")
11241    (set_attr "prefix_0f" "0,*")
11242    (set_attr "length_immediate" "0,*")
11243    (set_attr "modrm" "0,1")
11244    (set_attr "mode" "SI")])
11245
11246 (define_insn "*ashrsi3_31_zext"
11247   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11248         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11249                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11252    && INTVAL (operands[2]) == 31
11253    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11254   "@
11255    {cltd|cdq}
11256    sar{l}\t{%2, %k0|%k0, %2}"
11257   [(set_attr "type" "imovx,ishift")
11258    (set_attr "prefix_0f" "0,*")
11259    (set_attr "length_immediate" "0,*")
11260    (set_attr "modrm" "0,1")
11261    (set_attr "mode" "SI")])
11262
11263 (define_expand "ashrsi3"
11264   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11265         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11266                      (match_operand:QI 2 "nonmemory_operand" "")))
11267    (clobber (reg:CC FLAGS_REG))]
11268   ""
11269   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11270
11271 (define_insn "*ashrsi3_1_one_bit"
11272   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11273         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11274                      (match_operand:QI 2 "const1_operand" "")))
11275    (clobber (reg:CC FLAGS_REG))]
11276   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11277    && (TARGET_SHIFT1 || optimize_size)"
11278   "sar{l}\t%0"
11279   [(set_attr "type" "ishift")
11280    (set (attr "length") 
11281      (if_then_else (match_operand:SI 0 "register_operand" "") 
11282         (const_string "2")
11283         (const_string "*")))])
11284
11285 (define_insn "*ashrsi3_1_one_bit_zext"
11286   [(set (match_operand:DI 0 "register_operand" "=r")
11287         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11288                                      (match_operand:QI 2 "const1_operand" ""))))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11291    && (TARGET_SHIFT1 || optimize_size)"
11292   "sar{l}\t%k0"
11293   [(set_attr "type" "ishift")
11294    (set_attr "length" "2")])
11295
11296 (define_insn "*ashrsi3_1"
11297   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11298         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11299                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302   "@
11303    sar{l}\t{%2, %0|%0, %2}
11304    sar{l}\t{%b2, %0|%0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "SI")])
11307
11308 (define_insn "*ashrsi3_1_zext"
11309   [(set (match_operand:DI 0 "register_operand" "=r,r")
11310         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11311                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11312    (clobber (reg:CC FLAGS_REG))]
11313   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11314   "@
11315    sar{l}\t{%2, %k0|%k0, %2}
11316    sar{l}\t{%b2, %k0|%k0, %b2}"
11317   [(set_attr "type" "ishift")
11318    (set_attr "mode" "SI")])
11319
11320 ;; This pattern can't accept a variable shift count, since shifts by
11321 ;; zero don't affect the flags.  We assume that shifts by constant
11322 ;; zero are optimized away.
11323 (define_insn "*ashrsi3_one_bit_cmp"
11324   [(set (reg FLAGS_REG)
11325         (compare
11326           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11327                        (match_operand:QI 2 "const1_operand" ""))
11328           (const_int 0)))
11329    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11330         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11331   "ix86_match_ccmode (insn, CCGOCmode)
11332    && (TARGET_SHIFT1 || optimize_size)
11333    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11334   "sar{l}\t%0"
11335   [(set_attr "type" "ishift")
11336    (set (attr "length") 
11337      (if_then_else (match_operand:SI 0 "register_operand" "") 
11338         (const_string "2")
11339         (const_string "*")))])
11340
11341 (define_insn "*ashrsi3_one_bit_cmp_zext"
11342   [(set (reg FLAGS_REG)
11343         (compare
11344           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11345                        (match_operand:QI 2 "const1_operand" ""))
11346           (const_int 0)))
11347    (set (match_operand:DI 0 "register_operand" "=r")
11348         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11349   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11350    && (TARGET_SHIFT1 || optimize_size)
11351    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11352   "sar{l}\t%k0"
11353   [(set_attr "type" "ishift")
11354    (set_attr "length" "2")])
11355
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags.  We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashrsi3_cmp"
11360   [(set (reg FLAGS_REG)
11361         (compare
11362           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11364           (const_int 0)))
11365    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11367   "ix86_match_ccmode (insn, CCGOCmode)
11368    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11369   "sar{l}\t{%2, %0|%0, %2}"
11370   [(set_attr "type" "ishift")
11371    (set_attr "mode" "SI")])
11372
11373 (define_insn "*ashrsi3_cmp_zext"
11374   [(set (reg FLAGS_REG)
11375         (compare
11376           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11377                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11378           (const_int 0)))
11379    (set (match_operand:DI 0 "register_operand" "=r")
11380         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11383   "sar{l}\t{%2, %k0|%k0, %2}"
11384   [(set_attr "type" "ishift")
11385    (set_attr "mode" "SI")])
11386
11387 (define_expand "ashrhi3"
11388   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11389         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11390                      (match_operand:QI 2 "nonmemory_operand" "")))
11391    (clobber (reg:CC FLAGS_REG))]
11392   "TARGET_HIMODE_MATH"
11393   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11394
11395 (define_insn "*ashrhi3_1_one_bit"
11396   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11397         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11398                      (match_operand:QI 2 "const1_operand" "")))
11399    (clobber (reg:CC FLAGS_REG))]
11400   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11401    && (TARGET_SHIFT1 || optimize_size)"
11402   "sar{w}\t%0"
11403   [(set_attr "type" "ishift")
11404    (set (attr "length") 
11405      (if_then_else (match_operand 0 "register_operand" "") 
11406         (const_string "2")
11407         (const_string "*")))])
11408
11409 (define_insn "*ashrhi3_1"
11410   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11411         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11412                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11415   "@
11416    sar{w}\t{%2, %0|%0, %2}
11417    sar{w}\t{%b2, %0|%0, %b2}"
11418   [(set_attr "type" "ishift")
11419    (set_attr "mode" "HI")])
11420
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags.  We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*ashrhi3_one_bit_cmp"
11425   [(set (reg FLAGS_REG)
11426         (compare
11427           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11428                        (match_operand:QI 2 "const1_operand" ""))
11429           (const_int 0)))
11430    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11431         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11432   "ix86_match_ccmode (insn, CCGOCmode)
11433    && (TARGET_SHIFT1 || optimize_size)
11434    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11435   "sar{w}\t%0"
11436   [(set_attr "type" "ishift")
11437    (set (attr "length") 
11438      (if_then_else (match_operand 0 "register_operand" "") 
11439         (const_string "2")
11440         (const_string "*")))])
11441
11442 ;; This pattern can't accept a variable shift count, since shifts by
11443 ;; zero don't affect the flags.  We assume that shifts by constant
11444 ;; zero are optimized away.
11445 (define_insn "*ashrhi3_cmp"
11446   [(set (reg FLAGS_REG)
11447         (compare
11448           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11449                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11450           (const_int 0)))
11451    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11452         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11453   "ix86_match_ccmode (insn, CCGOCmode)
11454    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11455   "sar{w}\t{%2, %0|%0, %2}"
11456   [(set_attr "type" "ishift")
11457    (set_attr "mode" "HI")])
11458
11459 (define_expand "ashrqi3"
11460   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11461         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11462                      (match_operand:QI 2 "nonmemory_operand" "")))
11463    (clobber (reg:CC FLAGS_REG))]
11464   "TARGET_QIMODE_MATH"
11465   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11466
11467 (define_insn "*ashrqi3_1_one_bit"
11468   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11469         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11470                      (match_operand:QI 2 "const1_operand" "")))
11471    (clobber (reg:CC FLAGS_REG))]
11472   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11473    && (TARGET_SHIFT1 || optimize_size)"
11474   "sar{b}\t%0"
11475   [(set_attr "type" "ishift")
11476    (set (attr "length") 
11477      (if_then_else (match_operand 0 "register_operand" "") 
11478         (const_string "2")
11479         (const_string "*")))])
11480
11481 (define_insn "*ashrqi3_1_one_bit_slp"
11482   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11483         (ashiftrt:QI (match_dup 0)
11484                      (match_operand:QI 1 "const1_operand" "")))
11485    (clobber (reg:CC FLAGS_REG))]
11486   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11487    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11488    && (TARGET_SHIFT1 || optimize_size)"
11489   "sar{b}\t%0"
11490   [(set_attr "type" "ishift1")
11491    (set (attr "length") 
11492      (if_then_else (match_operand 0 "register_operand" "") 
11493         (const_string "2")
11494         (const_string "*")))])
11495
11496 (define_insn "*ashrqi3_1"
11497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11498         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11499                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11502   "@
11503    sar{b}\t{%2, %0|%0, %2}
11504    sar{b}\t{%b2, %0|%0, %b2}"
11505   [(set_attr "type" "ishift")
11506    (set_attr "mode" "QI")])
11507
11508 (define_insn "*ashrqi3_1_slp"
11509   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11510         (ashiftrt:QI (match_dup 0)
11511                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11514    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11515   "@
11516    sar{b}\t{%1, %0|%0, %1}
11517    sar{b}\t{%b1, %0|%0, %b1}"
11518   [(set_attr "type" "ishift1")
11519    (set_attr "mode" "QI")])
11520
11521 ;; This pattern can't accept a variable shift count, since shifts by
11522 ;; zero don't affect the flags.  We assume that shifts by constant
11523 ;; zero are optimized away.
11524 (define_insn "*ashrqi3_one_bit_cmp"
11525   [(set (reg FLAGS_REG)
11526         (compare
11527           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11528                        (match_operand:QI 2 "const1_operand" "I"))
11529           (const_int 0)))
11530    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11531         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11532   "ix86_match_ccmode (insn, CCGOCmode)
11533    && (TARGET_SHIFT1 || optimize_size)
11534    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11535   "sar{b}\t%0"
11536   [(set_attr "type" "ishift")
11537    (set (attr "length") 
11538      (if_then_else (match_operand 0 "register_operand" "") 
11539         (const_string "2")
11540         (const_string "*")))])
11541
11542 ;; This pattern can't accept a variable shift count, since shifts by
11543 ;; zero don't affect the flags.  We assume that shifts by constant
11544 ;; zero are optimized away.
11545 (define_insn "*ashrqi3_cmp"
11546   [(set (reg FLAGS_REG)
11547         (compare
11548           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11549                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11550           (const_int 0)))
11551    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11552         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11553   "ix86_match_ccmode (insn, CCGOCmode)
11554    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11555   "sar{b}\t{%2, %0|%0, %2}"
11556   [(set_attr "type" "ishift")
11557    (set_attr "mode" "QI")])
11558 \f
11559 ;; Logical shift instructions
11560
11561 ;; See comment above `ashldi3' about how this works.
11562
11563 (define_expand "lshrti3"
11564   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11565                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11566                                 (match_operand:QI 2 "nonmemory_operand" "")))
11567               (clobber (reg:CC FLAGS_REG))])]
11568   "TARGET_64BIT"
11569 {
11570   if (! immediate_operand (operands[2], QImode))
11571     {
11572       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11573       DONE;
11574     }
11575   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11576   DONE;
11577 })
11578
11579 (define_insn "lshrti3_1"
11580   [(set (match_operand:TI 0 "register_operand" "=r")
11581         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11582                      (match_operand:QI 2 "register_operand" "c")))
11583    (clobber (match_scratch:DI 3 "=&r"))
11584    (clobber (reg:CC FLAGS_REG))]
11585   "TARGET_64BIT"
11586   "#"
11587   [(set_attr "type" "multi")])
11588
11589 (define_insn "*lshrti3_2"
11590   [(set (match_operand:TI 0 "register_operand" "=r")
11591         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11592                      (match_operand:QI 2 "immediate_operand" "O")))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "TARGET_64BIT"
11595   "#"
11596   [(set_attr "type" "multi")])
11597
11598 (define_split 
11599   [(set (match_operand:TI 0 "register_operand" "")
11600         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11601                      (match_operand:QI 2 "register_operand" "")))
11602    (clobber (match_scratch:DI 3 ""))
11603    (clobber (reg:CC FLAGS_REG))]
11604   "TARGET_64BIT && reload_completed"
11605   [(const_int 0)]
11606   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11607
11608 (define_split 
11609   [(set (match_operand:TI 0 "register_operand" "")
11610         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11611                      (match_operand:QI 2 "immediate_operand" "")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "TARGET_64BIT && reload_completed"
11614   [(const_int 0)]
11615   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11616
11617 (define_expand "lshrdi3"
11618   [(set (match_operand:DI 0 "shiftdi_operand" "")
11619         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11620                      (match_operand:QI 2 "nonmemory_operand" "")))]
11621   ""
11622   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11623
11624 (define_insn "*lshrdi3_1_one_bit_rex64"
11625   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11626         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11627                      (match_operand:QI 2 "const1_operand" "")))
11628    (clobber (reg:CC FLAGS_REG))]
11629   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11630    && (TARGET_SHIFT1 || optimize_size)"
11631   "shr{q}\t%0"
11632   [(set_attr "type" "ishift")
11633    (set (attr "length") 
11634      (if_then_else (match_operand:DI 0 "register_operand" "") 
11635         (const_string "2")
11636         (const_string "*")))])
11637
11638 (define_insn "*lshrdi3_1_rex64"
11639   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11640         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11641                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644   "@
11645    shr{q}\t{%2, %0|%0, %2}
11646    shr{q}\t{%b2, %0|%0, %b2}"
11647   [(set_attr "type" "ishift")
11648    (set_attr "mode" "DI")])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags.  We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const1_operand" ""))
11658           (const_int 0)))
11659    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11660         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11661   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662    && (TARGET_SHIFT1 || optimize_size)
11663    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664   "shr{q}\t%0"
11665   [(set_attr "type" "ishift")
11666    (set (attr "length") 
11667      (if_then_else (match_operand:DI 0 "register_operand" "") 
11668         (const_string "2")
11669         (const_string "*")))])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags.  We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*lshrdi3_cmp_rex64"
11675   [(set (reg FLAGS_REG)
11676         (compare
11677           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11678                        (match_operand:QI 2 "const_int_operand" "e"))
11679           (const_int 0)))
11680    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11681         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11682   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11683    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684   "shr{q}\t{%2, %0|%0, %2}"
11685   [(set_attr "type" "ishift")
11686    (set_attr "mode" "DI")])
11687
11688 (define_insn "*lshrdi3_1"
11689   [(set (match_operand:DI 0 "register_operand" "=r")
11690         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11691                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11692    (clobber (reg:CC FLAGS_REG))]
11693   "!TARGET_64BIT"
11694   "#"
11695   [(set_attr "type" "multi")])
11696
11697 ;; By default we don't ask for a scratch register, because when DImode
11698 ;; values are manipulated, registers are already at a premium.  But if
11699 ;; we have one handy, we won't turn it away.
11700 (define_peephole2
11701   [(match_scratch:SI 3 "r")
11702    (parallel [(set (match_operand:DI 0 "register_operand" "")
11703                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11704                                 (match_operand:QI 2 "nonmemory_operand" "")))
11705               (clobber (reg:CC FLAGS_REG))])
11706    (match_dup 3)]
11707   "!TARGET_64BIT && TARGET_CMOVE"
11708   [(const_int 0)]
11709   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11710
11711 (define_split 
11712   [(set (match_operand:DI 0 "register_operand" "")
11713         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11714                      (match_operand:QI 2 "nonmemory_operand" "")))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11717                      ? flow2_completed : reload_completed)"
11718   [(const_int 0)]
11719   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11720
11721 (define_expand "lshrsi3"
11722   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11723         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11724                      (match_operand:QI 2 "nonmemory_operand" "")))
11725    (clobber (reg:CC FLAGS_REG))]
11726   ""
11727   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11728
11729 (define_insn "*lshrsi3_1_one_bit"
11730   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11732                      (match_operand:QI 2 "const1_operand" "")))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11735    && (TARGET_SHIFT1 || optimize_size)"
11736   "shr{l}\t%0"
11737   [(set_attr "type" "ishift")
11738    (set (attr "length") 
11739      (if_then_else (match_operand:SI 0 "register_operand" "") 
11740         (const_string "2")
11741         (const_string "*")))])
11742
11743 (define_insn "*lshrsi3_1_one_bit_zext"
11744   [(set (match_operand:DI 0 "register_operand" "=r")
11745         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11746                      (match_operand:QI 2 "const1_operand" "")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11749    && (TARGET_SHIFT1 || optimize_size)"
11750   "shr{l}\t%k0"
11751   [(set_attr "type" "ishift")
11752    (set_attr "length" "2")])
11753
11754 (define_insn "*lshrsi3_1"
11755   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11756         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11760   "@
11761    shr{l}\t{%2, %0|%0, %2}
11762    shr{l}\t{%b2, %0|%0, %b2}"
11763   [(set_attr "type" "ishift")
11764    (set_attr "mode" "SI")])
11765
11766 (define_insn "*lshrsi3_1_zext"
11767   [(set (match_operand:DI 0 "register_operand" "=r,r")
11768         (zero_extend:DI
11769           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11770                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11773   "@
11774    shr{l}\t{%2, %k0|%k0, %2}
11775    shr{l}\t{%b2, %k0|%k0, %b2}"
11776   [(set_attr "type" "ishift")
11777    (set_attr "mode" "SI")])
11778
11779 ;; This pattern can't accept a variable shift count, since shifts by
11780 ;; zero don't affect the flags.  We assume that shifts by constant
11781 ;; zero are optimized away.
11782 (define_insn "*lshrsi3_one_bit_cmp"
11783   [(set (reg FLAGS_REG)
11784         (compare
11785           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11786                        (match_operand:QI 2 "const1_operand" ""))
11787           (const_int 0)))
11788    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11789         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11790   "ix86_match_ccmode (insn, CCGOCmode)
11791    && (TARGET_SHIFT1 || optimize_size)
11792    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11793   "shr{l}\t%0"
11794   [(set_attr "type" "ishift")
11795    (set (attr "length") 
11796      (if_then_else (match_operand:SI 0 "register_operand" "") 
11797         (const_string "2")
11798         (const_string "*")))])
11799
11800 (define_insn "*lshrsi3_cmp_one_bit_zext"
11801   [(set (reg FLAGS_REG)
11802         (compare
11803           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11804                        (match_operand:QI 2 "const1_operand" ""))
11805           (const_int 0)))
11806    (set (match_operand:DI 0 "register_operand" "=r")
11807         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11808   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11809    && (TARGET_SHIFT1 || optimize_size)
11810    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11811   "shr{l}\t%k0"
11812   [(set_attr "type" "ishift")
11813    (set_attr "length" "2")])
11814
11815 ;; This pattern can't accept a variable shift count, since shifts by
11816 ;; zero don't affect the flags.  We assume that shifts by constant
11817 ;; zero are optimized away.
11818 (define_insn "*lshrsi3_cmp"
11819   [(set (reg FLAGS_REG)
11820         (compare
11821           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11822                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11823           (const_int 0)))
11824    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11825         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11826   "ix86_match_ccmode (insn, CCGOCmode)
11827    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11828   "shr{l}\t{%2, %0|%0, %2}"
11829   [(set_attr "type" "ishift")
11830    (set_attr "mode" "SI")])
11831
11832 (define_insn "*lshrsi3_cmp_zext"
11833   [(set (reg FLAGS_REG)
11834         (compare
11835           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11836                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11837           (const_int 0)))
11838    (set (match_operand:DI 0 "register_operand" "=r")
11839         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11840   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11841    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11842   "shr{l}\t{%2, %k0|%k0, %2}"
11843   [(set_attr "type" "ishift")
11844    (set_attr "mode" "SI")])
11845
11846 (define_expand "lshrhi3"
11847   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11848         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11849                      (match_operand:QI 2 "nonmemory_operand" "")))
11850    (clobber (reg:CC FLAGS_REG))]
11851   "TARGET_HIMODE_MATH"
11852   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11853
11854 (define_insn "*lshrhi3_1_one_bit"
11855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11856         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11857                      (match_operand:QI 2 "const1_operand" "")))
11858    (clobber (reg:CC FLAGS_REG))]
11859   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11860    && (TARGET_SHIFT1 || optimize_size)"
11861   "shr{w}\t%0"
11862   [(set_attr "type" "ishift")
11863    (set (attr "length") 
11864      (if_then_else (match_operand 0 "register_operand" "") 
11865         (const_string "2")
11866         (const_string "*")))])
11867
11868 (define_insn "*lshrhi3_1"
11869   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11870         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11871                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11874   "@
11875    shr{w}\t{%2, %0|%0, %2}
11876    shr{w}\t{%b2, %0|%0, %b2}"
11877   [(set_attr "type" "ishift")
11878    (set_attr "mode" "HI")])
11879
11880 ;; This pattern can't accept a variable shift count, since shifts by
11881 ;; zero don't affect the flags.  We assume that shifts by constant
11882 ;; zero are optimized away.
11883 (define_insn "*lshrhi3_one_bit_cmp"
11884   [(set (reg FLAGS_REG)
11885         (compare
11886           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11887                        (match_operand:QI 2 "const1_operand" ""))
11888           (const_int 0)))
11889    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11890         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11891   "ix86_match_ccmode (insn, CCGOCmode)
11892    && (TARGET_SHIFT1 || optimize_size)
11893    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894   "shr{w}\t%0"
11895   [(set_attr "type" "ishift")
11896    (set (attr "length") 
11897      (if_then_else (match_operand:SI 0 "register_operand" "") 
11898         (const_string "2")
11899         (const_string "*")))])
11900
11901 ;; This pattern can't accept a variable shift count, since shifts by
11902 ;; zero don't affect the flags.  We assume that shifts by constant
11903 ;; zero are optimized away.
11904 (define_insn "*lshrhi3_cmp"
11905   [(set (reg FLAGS_REG)
11906         (compare
11907           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11908                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11909           (const_int 0)))
11910    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11911         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11912   "ix86_match_ccmode (insn, CCGOCmode)
11913    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914   "shr{w}\t{%2, %0|%0, %2}"
11915   [(set_attr "type" "ishift")
11916    (set_attr "mode" "HI")])
11917
11918 (define_expand "lshrqi3"
11919   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11920         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11921                      (match_operand:QI 2 "nonmemory_operand" "")))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "TARGET_QIMODE_MATH"
11924   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11925
11926 (define_insn "*lshrqi3_1_one_bit"
11927   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11928         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929                      (match_operand:QI 2 "const1_operand" "")))
11930    (clobber (reg:CC FLAGS_REG))]
11931   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11932    && (TARGET_SHIFT1 || optimize_size)"
11933   "shr{b}\t%0"
11934   [(set_attr "type" "ishift")
11935    (set (attr "length") 
11936      (if_then_else (match_operand 0 "register_operand" "") 
11937         (const_string "2")
11938         (const_string "*")))])
11939
11940 (define_insn "*lshrqi3_1_one_bit_slp"
11941   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11942         (lshiftrt:QI (match_dup 0)
11943                      (match_operand:QI 1 "const1_operand" "")))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11946    && (TARGET_SHIFT1 || optimize_size)"
11947   "shr{b}\t%0"
11948   [(set_attr "type" "ishift1")
11949    (set (attr "length") 
11950      (if_then_else (match_operand 0 "register_operand" "") 
11951         (const_string "2")
11952         (const_string "*")))])
11953
11954 (define_insn "*lshrqi3_1"
11955   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11960   "@
11961    shr{b}\t{%2, %0|%0, %2}
11962    shr{b}\t{%b2, %0|%0, %b2}"
11963   [(set_attr "type" "ishift")
11964    (set_attr "mode" "QI")])
11965
11966 (define_insn "*lshrqi3_1_slp"
11967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968         (lshiftrt:QI (match_dup 0)
11969                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970    (clobber (reg:CC FLAGS_REG))]
11971   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11972    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11973   "@
11974    shr{b}\t{%1, %0|%0, %1}
11975    shr{b}\t{%b1, %0|%0, %b1}"
11976   [(set_attr "type" "ishift1")
11977    (set_attr "mode" "QI")])
11978
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags.  We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983   [(set (reg FLAGS_REG)
11984         (compare
11985           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986                        (match_operand:QI 2 "const1_operand" ""))
11987           (const_int 0)))
11988    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990   "ix86_match_ccmode (insn, CCGOCmode)
11991    && (TARGET_SHIFT1 || optimize_size)
11992    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11993   "shr{b}\t%0"
11994   [(set_attr "type" "ishift")
11995    (set (attr "length") 
11996      (if_then_else (match_operand:SI 0 "register_operand" "") 
11997         (const_string "2")
11998         (const_string "*")))])
11999
12000 ;; This pattern can't accept a variable shift count, since shifts by
12001 ;; zero don't affect the flags.  We assume that shifts by constant
12002 ;; zero are optimized away.
12003 (define_insn "*lshrqi2_cmp"
12004   [(set (reg FLAGS_REG)
12005         (compare
12006           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12007                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12008           (const_int 0)))
12009    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12010         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12011   "ix86_match_ccmode (insn, CCGOCmode)
12012    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12013   "shr{b}\t{%2, %0|%0, %2}"
12014   [(set_attr "type" "ishift")
12015    (set_attr "mode" "QI")])
12016 \f
12017 ;; Rotate instructions
12018
12019 (define_expand "rotldi3"
12020   [(set (match_operand:DI 0 "shiftdi_operand" "")
12021         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12022                    (match_operand:QI 2 "nonmemory_operand" "")))
12023    (clobber (reg:CC FLAGS_REG))]
12024  ""
12025 {
12026   if (TARGET_64BIT)
12027     {
12028       ix86_expand_binary_operator (ROTATE, DImode, operands);
12029       DONE;
12030     }
12031   if (!const_1_to_31_operand (operands[2], VOIDmode))
12032     FAIL;
12033   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12034   DONE;
12035 })
12036
12037 ;; Implement rotation using two double-precision shift instructions
12038 ;; and a scratch register.   
12039 (define_insn_and_split "ix86_rotldi3"
12040  [(set (match_operand:DI 0 "register_operand" "=r")
12041        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12042                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12043   (clobber (reg:CC FLAGS_REG))
12044   (clobber (match_scratch:SI 3 "=&r"))]
12045  "!TARGET_64BIT"
12046  "" 
12047  "&& reload_completed"
12048  [(set (match_dup 3) (match_dup 4))
12049   (parallel
12050    [(set (match_dup 4)
12051          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12052                  (lshiftrt:SI (match_dup 5)
12053                               (minus:QI (const_int 32) (match_dup 2)))))
12054     (clobber (reg:CC FLAGS_REG))])
12055   (parallel
12056    [(set (match_dup 5)
12057          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12058                  (lshiftrt:SI (match_dup 3)
12059                               (minus:QI (const_int 32) (match_dup 2)))))
12060     (clobber (reg:CC FLAGS_REG))])]
12061  "split_di (operands, 1, operands + 4, operands + 5);")
12062  
12063 (define_insn "*rotlsi3_1_one_bit_rex64"
12064   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12065         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12066                    (match_operand:QI 2 "const1_operand" "")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12069    && (TARGET_SHIFT1 || optimize_size)"
12070   "rol{q}\t%0"
12071   [(set_attr "type" "rotate")
12072    (set (attr "length") 
12073      (if_then_else (match_operand:DI 0 "register_operand" "") 
12074         (const_string "2")
12075         (const_string "*")))])
12076
12077 (define_insn "*rotldi3_1_rex64"
12078   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12079         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12080                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12081    (clobber (reg:CC FLAGS_REG))]
12082   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12083   "@
12084    rol{q}\t{%2, %0|%0, %2}
12085    rol{q}\t{%b2, %0|%0, %b2}"
12086   [(set_attr "type" "rotate")
12087    (set_attr "mode" "DI")])
12088
12089 (define_expand "rotlsi3"
12090   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12091         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12092                    (match_operand:QI 2 "nonmemory_operand" "")))
12093    (clobber (reg:CC FLAGS_REG))]
12094   ""
12095   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12096
12097 (define_insn "*rotlsi3_1_one_bit"
12098   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12099         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12100                    (match_operand:QI 2 "const1_operand" "")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12103    && (TARGET_SHIFT1 || optimize_size)"
12104   "rol{l}\t%0"
12105   [(set_attr "type" "rotate")
12106    (set (attr "length") 
12107      (if_then_else (match_operand:SI 0 "register_operand" "") 
12108         (const_string "2")
12109         (const_string "*")))])
12110
12111 (define_insn "*rotlsi3_1_one_bit_zext"
12112   [(set (match_operand:DI 0 "register_operand" "=r")
12113         (zero_extend:DI
12114           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12115                      (match_operand:QI 2 "const1_operand" ""))))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12118    && (TARGET_SHIFT1 || optimize_size)"
12119   "rol{l}\t%k0"
12120   [(set_attr "type" "rotate")
12121    (set_attr "length" "2")])
12122
12123 (define_insn "*rotlsi3_1"
12124   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12125         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12126                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129   "@
12130    rol{l}\t{%2, %0|%0, %2}
12131    rol{l}\t{%b2, %0|%0, %b2}"
12132   [(set_attr "type" "rotate")
12133    (set_attr "mode" "SI")])
12134
12135 (define_insn "*rotlsi3_1_zext"
12136   [(set (match_operand:DI 0 "register_operand" "=r,r")
12137         (zero_extend:DI
12138           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12139                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12142   "@
12143    rol{l}\t{%2, %k0|%k0, %2}
12144    rol{l}\t{%b2, %k0|%k0, %b2}"
12145   [(set_attr "type" "rotate")
12146    (set_attr "mode" "SI")])
12147
12148 (define_expand "rotlhi3"
12149   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12150         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12151                    (match_operand:QI 2 "nonmemory_operand" "")))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "TARGET_HIMODE_MATH"
12154   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12155
12156 (define_insn "*rotlhi3_1_one_bit"
12157   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12158         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12159                    (match_operand:QI 2 "const1_operand" "")))
12160    (clobber (reg:CC FLAGS_REG))]
12161   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12162    && (TARGET_SHIFT1 || optimize_size)"
12163   "rol{w}\t%0"
12164   [(set_attr "type" "rotate")
12165    (set (attr "length") 
12166      (if_then_else (match_operand 0 "register_operand" "") 
12167         (const_string "2")
12168         (const_string "*")))])
12169
12170 (define_insn "*rotlhi3_1"
12171   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12172         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12173                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12176   "@
12177    rol{w}\t{%2, %0|%0, %2}
12178    rol{w}\t{%b2, %0|%0, %b2}"
12179   [(set_attr "type" "rotate")
12180    (set_attr "mode" "HI")])
12181
12182 (define_expand "rotlqi3"
12183   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12184         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12185                    (match_operand:QI 2 "nonmemory_operand" "")))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "TARGET_QIMODE_MATH"
12188   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12189
12190 (define_insn "*rotlqi3_1_one_bit_slp"
12191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12192         (rotate:QI (match_dup 0)
12193                    (match_operand:QI 1 "const1_operand" "")))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12196    && (TARGET_SHIFT1 || optimize_size)"
12197   "rol{b}\t%0"
12198   [(set_attr "type" "rotate1")
12199    (set (attr "length") 
12200      (if_then_else (match_operand 0 "register_operand" "") 
12201         (const_string "2")
12202         (const_string "*")))])
12203
12204 (define_insn "*rotlqi3_1_one_bit"
12205   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12206         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207                    (match_operand:QI 2 "const1_operand" "")))
12208    (clobber (reg:CC FLAGS_REG))]
12209   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12210    && (TARGET_SHIFT1 || optimize_size)"
12211   "rol{b}\t%0"
12212   [(set_attr "type" "rotate")
12213    (set (attr "length") 
12214      (if_then_else (match_operand 0 "register_operand" "") 
12215         (const_string "2")
12216         (const_string "*")))])
12217
12218 (define_insn "*rotlqi3_1_slp"
12219   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12220         (rotate:QI (match_dup 0)
12221                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12224    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12225   "@
12226    rol{b}\t{%1, %0|%0, %1}
12227    rol{b}\t{%b1, %0|%0, %b1}"
12228   [(set_attr "type" "rotate1")
12229    (set_attr "mode" "QI")])
12230
12231 (define_insn "*rotlqi3_1"
12232   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12233         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12234                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12237   "@
12238    rol{b}\t{%2, %0|%0, %2}
12239    rol{b}\t{%b2, %0|%0, %b2}"
12240   [(set_attr "type" "rotate")
12241    (set_attr "mode" "QI")])
12242
12243 (define_expand "rotrdi3"
12244   [(set (match_operand:DI 0 "shiftdi_operand" "")
12245         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12246                    (match_operand:QI 2 "nonmemory_operand" "")))
12247    (clobber (reg:CC FLAGS_REG))]
12248  ""
12249 {
12250   if (TARGET_64BIT)
12251     {
12252       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12253       DONE;
12254     }
12255   if (!const_1_to_31_operand (operands[2], VOIDmode))
12256     FAIL;
12257   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12258   DONE;
12259 })
12260   
12261 ;; Implement rotation using two double-precision shift instructions
12262 ;; and a scratch register.   
12263 (define_insn_and_split "ix86_rotrdi3"
12264  [(set (match_operand:DI 0 "register_operand" "=r")
12265        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12266                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12267   (clobber (reg:CC FLAGS_REG))
12268   (clobber (match_scratch:SI 3 "=&r"))]
12269  "!TARGET_64BIT"
12270  ""
12271  "&& reload_completed"
12272  [(set (match_dup 3) (match_dup 4))
12273   (parallel
12274    [(set (match_dup 4)
12275          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12276                  (ashift:SI (match_dup 5)
12277                             (minus:QI (const_int 32) (match_dup 2)))))
12278     (clobber (reg:CC FLAGS_REG))])
12279   (parallel
12280    [(set (match_dup 5)
12281          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12282                  (ashift:SI (match_dup 3)
12283                             (minus:QI (const_int 32) (match_dup 2)))))
12284     (clobber (reg:CC FLAGS_REG))])]
12285  "split_di (operands, 1, operands + 4, operands + 5);")
12286
12287 (define_insn "*rotrdi3_1_one_bit_rex64"
12288   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12289         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12290                      (match_operand:QI 2 "const1_operand" "")))
12291    (clobber (reg:CC FLAGS_REG))]
12292   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12293    && (TARGET_SHIFT1 || optimize_size)"
12294   "ror{q}\t%0"
12295   [(set_attr "type" "rotate")
12296    (set (attr "length") 
12297      (if_then_else (match_operand:DI 0 "register_operand" "") 
12298         (const_string "2")
12299         (const_string "*")))])
12300
12301 (define_insn "*rotrdi3_1_rex64"
12302   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12303         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12304                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12307   "@
12308    ror{q}\t{%2, %0|%0, %2}
12309    ror{q}\t{%b2, %0|%0, %b2}"
12310   [(set_attr "type" "rotate")
12311    (set_attr "mode" "DI")])
12312
12313 (define_expand "rotrsi3"
12314   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12315         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12316                      (match_operand:QI 2 "nonmemory_operand" "")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   ""
12319   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12320
12321 (define_insn "*rotrsi3_1_one_bit"
12322   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12323         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12324                      (match_operand:QI 2 "const1_operand" "")))
12325    (clobber (reg:CC FLAGS_REG))]
12326   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12327    && (TARGET_SHIFT1 || optimize_size)"
12328   "ror{l}\t%0"
12329   [(set_attr "type" "rotate")
12330    (set (attr "length") 
12331      (if_then_else (match_operand:SI 0 "register_operand" "") 
12332         (const_string "2")
12333         (const_string "*")))])
12334
12335 (define_insn "*rotrsi3_1_one_bit_zext"
12336   [(set (match_operand:DI 0 "register_operand" "=r")
12337         (zero_extend:DI
12338           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12339                        (match_operand:QI 2 "const1_operand" ""))))
12340    (clobber (reg:CC FLAGS_REG))]
12341   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12342    && (TARGET_SHIFT1 || optimize_size)"
12343   "ror{l}\t%k0"
12344   [(set_attr "type" "rotate")
12345    (set (attr "length") 
12346      (if_then_else (match_operand:SI 0 "register_operand" "") 
12347         (const_string "2")
12348         (const_string "*")))])
12349
12350 (define_insn "*rotrsi3_1"
12351   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12352         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12353                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12356   "@
12357    ror{l}\t{%2, %0|%0, %2}
12358    ror{l}\t{%b2, %0|%0, %b2}"
12359   [(set_attr "type" "rotate")
12360    (set_attr "mode" "SI")])
12361
12362 (define_insn "*rotrsi3_1_zext"
12363   [(set (match_operand:DI 0 "register_operand" "=r,r")
12364         (zero_extend:DI
12365           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12366                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12369   "@
12370    ror{l}\t{%2, %k0|%k0, %2}
12371    ror{l}\t{%b2, %k0|%k0, %b2}"
12372   [(set_attr "type" "rotate")
12373    (set_attr "mode" "SI")])
12374
12375 (define_expand "rotrhi3"
12376   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12377         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12378                      (match_operand:QI 2 "nonmemory_operand" "")))
12379    (clobber (reg:CC FLAGS_REG))]
12380   "TARGET_HIMODE_MATH"
12381   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12382
12383 (define_insn "*rotrhi3_one_bit"
12384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12385         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386                      (match_operand:QI 2 "const1_operand" "")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12389    && (TARGET_SHIFT1 || optimize_size)"
12390   "ror{w}\t%0"
12391   [(set_attr "type" "rotate")
12392    (set (attr "length") 
12393      (if_then_else (match_operand 0 "register_operand" "") 
12394         (const_string "2")
12395         (const_string "*")))])
12396
12397 (define_insn "*rotrhi3"
12398   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12399         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12400                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12401    (clobber (reg:CC FLAGS_REG))]
12402   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12403   "@
12404    ror{w}\t{%2, %0|%0, %2}
12405    ror{w}\t{%b2, %0|%0, %b2}"
12406   [(set_attr "type" "rotate")
12407    (set_attr "mode" "HI")])
12408
12409 (define_expand "rotrqi3"
12410   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12411         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12412                      (match_operand:QI 2 "nonmemory_operand" "")))
12413    (clobber (reg:CC FLAGS_REG))]
12414   "TARGET_QIMODE_MATH"
12415   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12416
12417 (define_insn "*rotrqi3_1_one_bit"
12418   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12419         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420                      (match_operand:QI 2 "const1_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12423    && (TARGET_SHIFT1 || optimize_size)"
12424   "ror{b}\t%0"
12425   [(set_attr "type" "rotate")
12426    (set (attr "length") 
12427      (if_then_else (match_operand 0 "register_operand" "") 
12428         (const_string "2")
12429         (const_string "*")))])
12430
12431 (define_insn "*rotrqi3_1_one_bit_slp"
12432   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12433         (rotatert:QI (match_dup 0)
12434                      (match_operand:QI 1 "const1_operand" "")))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12437    && (TARGET_SHIFT1 || optimize_size)"
12438   "ror{b}\t%0"
12439   [(set_attr "type" "rotate1")
12440    (set (attr "length") 
12441      (if_then_else (match_operand 0 "register_operand" "") 
12442         (const_string "2")
12443         (const_string "*")))])
12444
12445 (define_insn "*rotrqi3_1"
12446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12451   "@
12452    ror{b}\t{%2, %0|%0, %2}
12453    ror{b}\t{%b2, %0|%0, %b2}"
12454   [(set_attr "type" "rotate")
12455    (set_attr "mode" "QI")])
12456
12457 (define_insn "*rotrqi3_1_slp"
12458   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459         (rotatert:QI (match_dup 0)
12460                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461    (clobber (reg:CC FLAGS_REG))]
12462   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12464   "@
12465    ror{b}\t{%1, %0|%0, %1}
12466    ror{b}\t{%b1, %0|%0, %b1}"
12467   [(set_attr "type" "rotate1")
12468    (set_attr "mode" "QI")])
12469 \f
12470 ;; Bit set / bit test instructions
12471
12472 (define_expand "extv"
12473   [(set (match_operand:SI 0 "register_operand" "")
12474         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12475                          (match_operand:SI 2 "immediate_operand" "")
12476                          (match_operand:SI 3 "immediate_operand" "")))]
12477   ""
12478 {
12479   /* Handle extractions from %ah et al.  */
12480   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12481     FAIL;
12482
12483   /* From mips.md: extract_bit_field doesn't verify that our source
12484      matches the predicate, so check it again here.  */
12485   if (! ext_register_operand (operands[1], VOIDmode))
12486     FAIL;
12487 })
12488
12489 (define_expand "extzv"
12490   [(set (match_operand:SI 0 "register_operand" "")
12491         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12492                          (match_operand:SI 2 "immediate_operand" "")
12493                          (match_operand:SI 3 "immediate_operand" "")))]
12494   ""
12495 {
12496   /* Handle extractions from %ah et al.  */
12497   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12498     FAIL;
12499
12500   /* From mips.md: extract_bit_field doesn't verify that our source
12501      matches the predicate, so check it again here.  */
12502   if (! ext_register_operand (operands[1], VOIDmode))
12503     FAIL;
12504 })
12505
12506 (define_expand "insv"
12507   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12508                       (match_operand 1 "immediate_operand" "")
12509                       (match_operand 2 "immediate_operand" ""))
12510         (match_operand 3 "register_operand" ""))]
12511   ""
12512 {
12513   /* Handle extractions from %ah et al.  */
12514   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12515     FAIL;
12516
12517   /* From mips.md: insert_bit_field doesn't verify that our source
12518      matches the predicate, so check it again here.  */
12519   if (! ext_register_operand (operands[0], VOIDmode))
12520     FAIL;
12521
12522   if (TARGET_64BIT)
12523     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12524   else
12525     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12526
12527   DONE;
12528 })
12529
12530 ;; %%% bts, btr, btc, bt.
12531 ;; In general these instructions are *slow* when applied to memory,
12532 ;; since they enforce atomic operation.  When applied to registers,
12533 ;; it depends on the cpu implementation.  They're never faster than
12534 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12535 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12536 ;; within the instruction itself, so operating on bits in the high
12537 ;; 32-bits of a register becomes easier.
12538 ;;
12539 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12540 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12541 ;; negdf respectively, so they can never be disabled entirely.
12542
12543 (define_insn "*btsq"
12544   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12545                          (const_int 1)
12546                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12547         (const_int 1))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12550   "bts{q} %1,%0"
12551   [(set_attr "type" "alu1")])
12552
12553 (define_insn "*btrq"
12554   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12555                          (const_int 1)
12556                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12557         (const_int 0))
12558    (clobber (reg:CC FLAGS_REG))]
12559   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12560   "btr{q} %1,%0"
12561   [(set_attr "type" "alu1")])
12562
12563 (define_insn "*btcq"
12564   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12565                          (const_int 1)
12566                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12567         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12568    (clobber (reg:CC FLAGS_REG))]
12569   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12570   "btc{q} %1,%0"
12571   [(set_attr "type" "alu1")])
12572
12573 ;; Allow Nocona to avoid these instructions if a register is available.
12574
12575 (define_peephole2
12576   [(match_scratch:DI 2 "r")
12577    (parallel [(set (zero_extract:DI
12578                      (match_operand:DI 0 "register_operand" "")
12579                      (const_int 1)
12580                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12581                    (const_int 1))
12582               (clobber (reg:CC FLAGS_REG))])]
12583   "TARGET_64BIT && !TARGET_USE_BT"
12584   [(const_int 0)]
12585 {
12586   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12587   rtx op1;
12588
12589   if (HOST_BITS_PER_WIDE_INT >= 64)
12590     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12591   else if (i < HOST_BITS_PER_WIDE_INT)
12592     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12593   else
12594     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12595
12596   op1 = immed_double_const (lo, hi, DImode);
12597   if (i >= 31)
12598     {
12599       emit_move_insn (operands[2], op1);
12600       op1 = operands[2];
12601     }
12602
12603   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12604   DONE;
12605 })
12606
12607 (define_peephole2
12608   [(match_scratch:DI 2 "r")
12609    (parallel [(set (zero_extract:DI
12610                      (match_operand:DI 0 "register_operand" "")
12611                      (const_int 1)
12612                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12613                    (const_int 0))
12614               (clobber (reg:CC FLAGS_REG))])]
12615   "TARGET_64BIT && !TARGET_USE_BT"
12616   [(const_int 0)]
12617 {
12618   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12619   rtx op1;
12620
12621   if (HOST_BITS_PER_WIDE_INT >= 64)
12622     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623   else if (i < HOST_BITS_PER_WIDE_INT)
12624     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12625   else
12626     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12627
12628   op1 = immed_double_const (~lo, ~hi, DImode);
12629   if (i >= 32)
12630     {
12631       emit_move_insn (operands[2], op1);
12632       op1 = operands[2];
12633     }
12634
12635   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12636   DONE;
12637 })
12638
12639 (define_peephole2
12640   [(match_scratch:DI 2 "r")
12641    (parallel [(set (zero_extract:DI
12642                      (match_operand:DI 0 "register_operand" "")
12643                      (const_int 1)
12644                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12645               (not:DI (zero_extract:DI
12646                         (match_dup 0) (const_int 1) (match_dup 1))))
12647               (clobber (reg:CC FLAGS_REG))])]
12648   "TARGET_64BIT && !TARGET_USE_BT"
12649   [(const_int 0)]
12650 {
12651   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12652   rtx op1;
12653
12654   if (HOST_BITS_PER_WIDE_INT >= 64)
12655     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12656   else if (i < HOST_BITS_PER_WIDE_INT)
12657     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12658   else
12659     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12660
12661   op1 = immed_double_const (lo, hi, DImode);
12662   if (i >= 31)
12663     {
12664       emit_move_insn (operands[2], op1);
12665       op1 = operands[2];
12666     }
12667
12668   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12669   DONE;
12670 })
12671 \f
12672 ;; Store-flag instructions.
12673
12674 ;; For all sCOND expanders, also expand the compare or test insn that
12675 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12676
12677 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12678 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12679 ;; way, which can later delete the movzx if only QImode is needed.
12680
12681 (define_expand "seq"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sne"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sgt"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sgtu"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "slt"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sltu"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sge"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   ""
12721   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sgeu"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   ""
12727   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sle"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   ""
12733   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sleu"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   ""
12739   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sunordered"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387 || TARGET_SSE"
12745   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "sordered"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387"
12751   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "suneq"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sunge"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sungt"
12766   [(set (match_operand:QI 0 "register_operand" "")
12767         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768   "TARGET_80387 || TARGET_SSE"
12769   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sunle"
12772   [(set (match_operand:QI 0 "register_operand" "")
12773         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774   "TARGET_80387 || TARGET_SSE"
12775   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12776
12777 (define_expand "sunlt"
12778   [(set (match_operand:QI 0 "register_operand" "")
12779         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780   "TARGET_80387 || TARGET_SSE"
12781   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12782
12783 (define_expand "sltgt"
12784   [(set (match_operand:QI 0 "register_operand" "")
12785         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12786   "TARGET_80387 || TARGET_SSE"
12787   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12788
12789 (define_insn "*setcc_1"
12790   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12791         (match_operator:QI 1 "ix86_comparison_operator"
12792           [(reg FLAGS_REG) (const_int 0)]))]
12793   ""
12794   "set%C1\t%0"
12795   [(set_attr "type" "setcc")
12796    (set_attr "mode" "QI")])
12797
12798 (define_insn "*setcc_2"
12799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12800         (match_operator:QI 1 "ix86_comparison_operator"
12801           [(reg FLAGS_REG) (const_int 0)]))]
12802   ""
12803   "set%C1\t%0"
12804   [(set_attr "type" "setcc")
12805    (set_attr "mode" "QI")])
12806
12807 ;; In general it is not safe to assume too much about CCmode registers,
12808 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12809 ;; conditions this is safe on x86, so help combine not create
12810 ;;
12811 ;;      seta    %al
12812 ;;      testb   %al, %al
12813 ;;      sete    %al
12814
12815 (define_split 
12816   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12817         (ne:QI (match_operator 1 "ix86_comparison_operator"
12818                  [(reg FLAGS_REG) (const_int 0)])
12819             (const_int 0)))]
12820   ""
12821   [(set (match_dup 0) (match_dup 1))]
12822 {
12823   PUT_MODE (operands[1], QImode);
12824 })
12825
12826 (define_split 
12827   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12828         (ne:QI (match_operator 1 "ix86_comparison_operator"
12829                  [(reg FLAGS_REG) (const_int 0)])
12830             (const_int 0)))]
12831   ""
12832   [(set (match_dup 0) (match_dup 1))]
12833 {
12834   PUT_MODE (operands[1], QImode);
12835 })
12836
12837 (define_split 
12838   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12839         (eq:QI (match_operator 1 "ix86_comparison_operator"
12840                  [(reg FLAGS_REG) (const_int 0)])
12841             (const_int 0)))]
12842   ""
12843   [(set (match_dup 0) (match_dup 1))]
12844 {
12845   rtx new_op1 = copy_rtx (operands[1]);
12846   operands[1] = new_op1;
12847   PUT_MODE (new_op1, QImode);
12848   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12849                                              GET_MODE (XEXP (new_op1, 0))));
12850
12851   /* Make sure that (a) the CCmode we have for the flags is strong
12852      enough for the reversed compare or (b) we have a valid FP compare.  */
12853   if (! ix86_comparison_operator (new_op1, VOIDmode))
12854     FAIL;
12855 })
12856
12857 (define_split 
12858   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12859         (eq:QI (match_operator 1 "ix86_comparison_operator"
12860                  [(reg FLAGS_REG) (const_int 0)])
12861             (const_int 0)))]
12862   ""
12863   [(set (match_dup 0) (match_dup 1))]
12864 {
12865   rtx new_op1 = copy_rtx (operands[1]);
12866   operands[1] = new_op1;
12867   PUT_MODE (new_op1, QImode);
12868   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12869                                              GET_MODE (XEXP (new_op1, 0))));
12870
12871   /* Make sure that (a) the CCmode we have for the flags is strong
12872      enough for the reversed compare or (b) we have a valid FP compare.  */
12873   if (! ix86_comparison_operator (new_op1, VOIDmode))
12874     FAIL;
12875 })
12876
12877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12878 ;; subsequent logical operations are used to imitate conditional moves.
12879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12880 ;; it directly.
12881
12882 (define_insn "*sse_setccsf"
12883   [(set (match_operand:SF 0 "register_operand" "=x")
12884         (match_operator:SF 1 "sse_comparison_operator"
12885           [(match_operand:SF 2 "register_operand" "0")
12886            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12887   "TARGET_SSE"
12888   "cmp%D1ss\t{%3, %0|%0, %3}"
12889   [(set_attr "type" "ssecmp")
12890    (set_attr "mode" "SF")])
12891
12892 (define_insn "*sse_setccdf"
12893   [(set (match_operand:DF 0 "register_operand" "=Y")
12894         (match_operator:DF 1 "sse_comparison_operator"
12895           [(match_operand:DF 2 "register_operand" "0")
12896            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12897   "TARGET_SSE2"
12898   "cmp%D1sd\t{%3, %0|%0, %3}"
12899   [(set_attr "type" "ssecmp")
12900    (set_attr "mode" "DF")])
12901 \f
12902 ;; Basic conditional jump instructions.
12903 ;; We ignore the overflow flag for signed branch instructions.
12904
12905 ;; For all bCOND expanders, also expand the compare or test insn that
12906 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12907
12908 (define_expand "beq"
12909   [(set (pc)
12910         (if_then_else (match_dup 1)
12911                       (label_ref (match_operand 0 "" ""))
12912                       (pc)))]
12913   ""
12914   "ix86_expand_branch (EQ, operands[0]); DONE;")
12915
12916 (define_expand "bne"
12917   [(set (pc)
12918         (if_then_else (match_dup 1)
12919                       (label_ref (match_operand 0 "" ""))
12920                       (pc)))]
12921   ""
12922   "ix86_expand_branch (NE, operands[0]); DONE;")
12923
12924 (define_expand "bgt"
12925   [(set (pc)
12926         (if_then_else (match_dup 1)
12927                       (label_ref (match_operand 0 "" ""))
12928                       (pc)))]
12929   ""
12930   "ix86_expand_branch (GT, operands[0]); DONE;")
12931
12932 (define_expand "bgtu"
12933   [(set (pc)
12934         (if_then_else (match_dup 1)
12935                       (label_ref (match_operand 0 "" ""))
12936                       (pc)))]
12937   ""
12938   "ix86_expand_branch (GTU, operands[0]); DONE;")
12939
12940 (define_expand "blt"
12941   [(set (pc)
12942         (if_then_else (match_dup 1)
12943                       (label_ref (match_operand 0 "" ""))
12944                       (pc)))]
12945   ""
12946   "ix86_expand_branch (LT, operands[0]); DONE;")
12947
12948 (define_expand "bltu"
12949   [(set (pc)
12950         (if_then_else (match_dup 1)
12951                       (label_ref (match_operand 0 "" ""))
12952                       (pc)))]
12953   ""
12954   "ix86_expand_branch (LTU, operands[0]); DONE;")
12955
12956 (define_expand "bge"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (GE, operands[0]); DONE;")
12963
12964 (define_expand "bgeu"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (GEU, operands[0]); DONE;")
12971
12972 (define_expand "ble"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "ix86_expand_branch (LE, operands[0]); DONE;")
12979
12980 (define_expand "bleu"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   ""
12986   "ix86_expand_branch (LEU, operands[0]); DONE;")
12987
12988 (define_expand "bunordered"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   "TARGET_80387 || TARGET_SSE_MATH"
12994   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12995
12996 (define_expand "bordered"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   "TARGET_80387 || TARGET_SSE_MATH"
13002   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13003
13004 (define_expand "buneq"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   "TARGET_80387 || TARGET_SSE_MATH"
13010   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13011
13012 (define_expand "bunge"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   "TARGET_80387 || TARGET_SSE_MATH"
13018   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13019
13020 (define_expand "bungt"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   "TARGET_80387 || TARGET_SSE_MATH"
13026   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13027
13028 (define_expand "bunle"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   "TARGET_80387 || TARGET_SSE_MATH"
13034   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13035
13036 (define_expand "bunlt"
13037   [(set (pc)
13038         (if_then_else (match_dup 1)
13039                       (label_ref (match_operand 0 "" ""))
13040                       (pc)))]
13041   "TARGET_80387 || TARGET_SSE_MATH"
13042   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13043
13044 (define_expand "bltgt"
13045   [(set (pc)
13046         (if_then_else (match_dup 1)
13047                       (label_ref (match_operand 0 "" ""))
13048                       (pc)))]
13049   "TARGET_80387 || TARGET_SSE_MATH"
13050   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13051
13052 (define_insn "*jcc_1"
13053   [(set (pc)
13054         (if_then_else (match_operator 1 "ix86_comparison_operator"
13055                                       [(reg FLAGS_REG) (const_int 0)])
13056                       (label_ref (match_operand 0 "" ""))
13057                       (pc)))]
13058   ""
13059   "%+j%C1\t%l0"
13060   [(set_attr "type" "ibr")
13061    (set_attr "modrm" "0")
13062    (set (attr "length")
13063            (if_then_else (and (ge (minus (match_dup 0) (pc))
13064                                   (const_int -126))
13065                               (lt (minus (match_dup 0) (pc))
13066                                   (const_int 128)))
13067              (const_int 2)
13068              (const_int 6)))])
13069
13070 (define_insn "*jcc_2"
13071   [(set (pc)
13072         (if_then_else (match_operator 1 "ix86_comparison_operator"
13073                                       [(reg FLAGS_REG) (const_int 0)])
13074                       (pc)
13075                       (label_ref (match_operand 0 "" ""))))]
13076   ""
13077   "%+j%c1\t%l0"
13078   [(set_attr "type" "ibr")
13079    (set_attr "modrm" "0")
13080    (set (attr "length")
13081            (if_then_else (and (ge (minus (match_dup 0) (pc))
13082                                   (const_int -126))
13083                               (lt (minus (match_dup 0) (pc))
13084                                   (const_int 128)))
13085              (const_int 2)
13086              (const_int 6)))])
13087
13088 ;; In general it is not safe to assume too much about CCmode registers,
13089 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13090 ;; conditions this is safe on x86, so help combine not create
13091 ;;
13092 ;;      seta    %al
13093 ;;      testb   %al, %al
13094 ;;      je      Lfoo
13095
13096 (define_split 
13097   [(set (pc)
13098         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13099                                       [(reg FLAGS_REG) (const_int 0)])
13100                           (const_int 0))
13101                       (label_ref (match_operand 1 "" ""))
13102                       (pc)))]
13103   ""
13104   [(set (pc)
13105         (if_then_else (match_dup 0)
13106                       (label_ref (match_dup 1))
13107                       (pc)))]
13108 {
13109   PUT_MODE (operands[0], VOIDmode);
13110 })
13111   
13112 (define_split 
13113   [(set (pc)
13114         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13115                                       [(reg FLAGS_REG) (const_int 0)])
13116                           (const_int 0))
13117                       (label_ref (match_operand 1 "" ""))
13118                       (pc)))]
13119   ""
13120   [(set (pc)
13121         (if_then_else (match_dup 0)
13122                       (label_ref (match_dup 1))
13123                       (pc)))]
13124 {
13125   rtx new_op0 = copy_rtx (operands[0]);
13126   operands[0] = new_op0;
13127   PUT_MODE (new_op0, VOIDmode);
13128   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13129                                              GET_MODE (XEXP (new_op0, 0))));
13130
13131   /* Make sure that (a) the CCmode we have for the flags is strong
13132      enough for the reversed compare or (b) we have a valid FP compare.  */
13133   if (! ix86_comparison_operator (new_op0, VOIDmode))
13134     FAIL;
13135 })
13136
13137 ;; Define combination compare-and-branch fp compare instructions to use
13138 ;; during early optimization.  Splitting the operation apart early makes
13139 ;; for bad code when we want to reverse the operation.
13140
13141 (define_insn "*fp_jcc_1_mixed"
13142   [(set (pc)
13143         (if_then_else (match_operator 0 "comparison_operator"
13144                         [(match_operand 1 "register_operand" "f#x,x#f")
13145                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13146           (label_ref (match_operand 3 "" ""))
13147           (pc)))
13148    (clobber (reg:CCFP FPSR_REG))
13149    (clobber (reg:CCFP FLAGS_REG))]
13150   "TARGET_MIX_SSE_I387
13151    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13152    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13153    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13154   "#")
13155
13156 (define_insn "*fp_jcc_1_sse"
13157   [(set (pc)
13158         (if_then_else (match_operator 0 "comparison_operator"
13159                         [(match_operand 1 "register_operand" "x")
13160                          (match_operand 2 "nonimmediate_operand" "xm")])
13161           (label_ref (match_operand 3 "" ""))
13162           (pc)))
13163    (clobber (reg:CCFP FPSR_REG))
13164    (clobber (reg:CCFP FLAGS_REG))]
13165   "TARGET_SSE_MATH
13166    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13167    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13168    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13169   "#")
13170
13171 (define_insn "*fp_jcc_1_387"
13172   [(set (pc)
13173         (if_then_else (match_operator 0 "comparison_operator"
13174                         [(match_operand 1 "register_operand" "f")
13175                          (match_operand 2 "register_operand" "f")])
13176           (label_ref (match_operand 3 "" ""))
13177           (pc)))
13178    (clobber (reg:CCFP FPSR_REG))
13179    (clobber (reg:CCFP FLAGS_REG))]
13180   "TARGET_CMOVE && TARGET_80387
13181    && FLOAT_MODE_P (GET_MODE (operands[1]))
13182    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184   "#")
13185
13186 (define_insn "*fp_jcc_2_mixed"
13187   [(set (pc)
13188         (if_then_else (match_operator 0 "comparison_operator"
13189                         [(match_operand 1 "register_operand" "f#x,x#f")
13190                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13191           (pc)
13192           (label_ref (match_operand 3 "" ""))))
13193    (clobber (reg:CCFP FPSR_REG))
13194    (clobber (reg:CCFP FLAGS_REG))]
13195   "TARGET_MIX_SSE_I387
13196    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13197    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13199   "#")
13200
13201 (define_insn "*fp_jcc_2_sse"
13202   [(set (pc)
13203         (if_then_else (match_operator 0 "comparison_operator"
13204                         [(match_operand 1 "register_operand" "x")
13205                          (match_operand 2 "nonimmediate_operand" "xm")])
13206           (pc)
13207           (label_ref (match_operand 3 "" ""))))
13208    (clobber (reg:CCFP FPSR_REG))
13209    (clobber (reg:CCFP FLAGS_REG))]
13210   "TARGET_SSE_MATH
13211    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13212    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214   "#")
13215
13216 (define_insn "*fp_jcc_2_387"
13217   [(set (pc)
13218         (if_then_else (match_operator 0 "comparison_operator"
13219                         [(match_operand 1 "register_operand" "f")
13220                          (match_operand 2 "register_operand" "f")])
13221           (pc)
13222           (label_ref (match_operand 3 "" ""))))
13223    (clobber (reg:CCFP FPSR_REG))
13224    (clobber (reg:CCFP FLAGS_REG))]
13225   "TARGET_CMOVE && TARGET_80387
13226    && FLOAT_MODE_P (GET_MODE (operands[1]))
13227    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13228    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13229   "#")
13230
13231 (define_insn "*fp_jcc_3_387"
13232   [(set (pc)
13233         (if_then_else (match_operator 0 "comparison_operator"
13234                         [(match_operand 1 "register_operand" "f")
13235                          (match_operand 2 "nonimmediate_operand" "fm")])
13236           (label_ref (match_operand 3 "" ""))
13237           (pc)))
13238    (clobber (reg:CCFP FPSR_REG))
13239    (clobber (reg:CCFP FLAGS_REG))
13240    (clobber (match_scratch:HI 4 "=a"))]
13241   "TARGET_80387
13242    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13243    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13244    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13245    && SELECT_CC_MODE (GET_CODE (operands[0]),
13246                       operands[1], operands[2]) == CCFPmode
13247    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248   "#")
13249
13250 (define_insn "*fp_jcc_4_387"
13251   [(set (pc)
13252         (if_then_else (match_operator 0 "comparison_operator"
13253                         [(match_operand 1 "register_operand" "f")
13254                          (match_operand 2 "nonimmediate_operand" "fm")])
13255           (pc)
13256           (label_ref (match_operand 3 "" ""))))
13257    (clobber (reg:CCFP FPSR_REG))
13258    (clobber (reg:CCFP FLAGS_REG))
13259    (clobber (match_scratch:HI 4 "=a"))]
13260   "TARGET_80387
13261    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13262    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13264    && SELECT_CC_MODE (GET_CODE (operands[0]),
13265                       operands[1], operands[2]) == CCFPmode
13266    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267   "#")
13268
13269 (define_insn "*fp_jcc_5_387"
13270   [(set (pc)
13271         (if_then_else (match_operator 0 "comparison_operator"
13272                         [(match_operand 1 "register_operand" "f")
13273                          (match_operand 2 "register_operand" "f")])
13274           (label_ref (match_operand 3 "" ""))
13275           (pc)))
13276    (clobber (reg:CCFP FPSR_REG))
13277    (clobber (reg:CCFP FLAGS_REG))
13278    (clobber (match_scratch:HI 4 "=a"))]
13279   "TARGET_80387
13280    && FLOAT_MODE_P (GET_MODE (operands[1]))
13281    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283   "#")
13284
13285 (define_insn "*fp_jcc_6_387"
13286   [(set (pc)
13287         (if_then_else (match_operator 0 "comparison_operator"
13288                         [(match_operand 1 "register_operand" "f")
13289                          (match_operand 2 "register_operand" "f")])
13290           (pc)
13291           (label_ref (match_operand 3 "" ""))))
13292    (clobber (reg:CCFP FPSR_REG))
13293    (clobber (reg:CCFP FLAGS_REG))
13294    (clobber (match_scratch:HI 4 "=a"))]
13295   "TARGET_80387
13296    && FLOAT_MODE_P (GET_MODE (operands[1]))
13297    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299   "#")
13300
13301 (define_insn "*fp_jcc_7_387"
13302   [(set (pc)
13303         (if_then_else (match_operator 0 "comparison_operator"
13304                         [(match_operand 1 "register_operand" "f")
13305                          (match_operand 2 "const0_operand" "X")])
13306           (label_ref (match_operand 3 "" ""))
13307           (pc)))
13308    (clobber (reg:CCFP FPSR_REG))
13309    (clobber (reg:CCFP FLAGS_REG))
13310    (clobber (match_scratch:HI 4 "=a"))]
13311   "TARGET_80387
13312    && FLOAT_MODE_P (GET_MODE (operands[1]))
13313    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315    && SELECT_CC_MODE (GET_CODE (operands[0]),
13316                       operands[1], operands[2]) == CCFPmode
13317    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318   "#")
13319
13320 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13321 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13322 ;; with a precedence over other operators and is always put in the first
13323 ;; place. Swap condition and operands to match ficom instruction.
13324
13325 (define_insn "*fp_jcc_8<mode>_387"
13326   [(set (pc)
13327         (if_then_else (match_operator 0 "comparison_operator"
13328                         [(match_operator 1 "float_operator"
13329                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13330                            (match_operand 3 "register_operand" "f,f")])
13331           (label_ref (match_operand 4 "" ""))
13332           (pc)))
13333    (clobber (reg:CCFP FPSR_REG))
13334    (clobber (reg:CCFP FLAGS_REG))
13335    (clobber (match_scratch:HI 5 "=a,a"))]
13336   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13337    && FLOAT_MODE_P (GET_MODE (operands[3]))
13338    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13339    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13340    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13341    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13342   "#")
13343
13344 (define_split
13345   [(set (pc)
13346         (if_then_else (match_operator 0 "comparison_operator"
13347                         [(match_operand 1 "register_operand" "")
13348                          (match_operand 2 "nonimmediate_operand" "")])
13349           (match_operand 3 "" "")
13350           (match_operand 4 "" "")))
13351    (clobber (reg:CCFP FPSR_REG))
13352    (clobber (reg:CCFP FLAGS_REG))]
13353   "reload_completed"
13354   [(const_int 0)]
13355 {
13356   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13357                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13358   DONE;
13359 })
13360
13361 (define_split
13362   [(set (pc)
13363         (if_then_else (match_operator 0 "comparison_operator"
13364                         [(match_operand 1 "register_operand" "")
13365                          (match_operand 2 "general_operand" "")])
13366           (match_operand 3 "" "")
13367           (match_operand 4 "" "")))
13368    (clobber (reg:CCFP FPSR_REG))
13369    (clobber (reg:CCFP FLAGS_REG))
13370    (clobber (match_scratch:HI 5 "=a"))]
13371   "reload_completed"
13372   [(const_int 0)]
13373 {
13374   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13375                         operands[3], operands[4], operands[5], NULL_RTX);
13376   DONE;
13377 })
13378
13379 (define_split
13380   [(set (pc)
13381         (if_then_else (match_operator 0 "comparison_operator"
13382                         [(match_operator 1 "float_operator"
13383                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13384                            (match_operand 3 "register_operand" "")])
13385           (match_operand 4 "" "")
13386           (match_operand 5 "" "")))
13387    (clobber (reg:CCFP FPSR_REG))
13388    (clobber (reg:CCFP FLAGS_REG))
13389    (clobber (match_scratch:HI 6 "=a"))]
13390   "reload_completed"
13391   [(const_int 0)]
13392 {
13393   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13394   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13395                         operands[3], operands[7],
13396                         operands[4], operands[5], operands[6], NULL_RTX);
13397   DONE;
13398 })
13399
13400 ;; %%% Kill this when reload knows how to do it.
13401 (define_split
13402   [(set (pc)
13403         (if_then_else (match_operator 0 "comparison_operator"
13404                         [(match_operator 1 "float_operator"
13405                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13406                            (match_operand 3 "register_operand" "")])
13407           (match_operand 4 "" "")
13408           (match_operand 5 "" "")))
13409    (clobber (reg:CCFP FPSR_REG))
13410    (clobber (reg:CCFP FLAGS_REG))
13411    (clobber (match_scratch:HI 6 "=a"))]
13412   "reload_completed"
13413   [(const_int 0)]
13414 {
13415   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13416   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13417   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13418                         operands[3], operands[7],
13419                         operands[4], operands[5], operands[6], operands[2]);
13420   DONE;
13421 })
13422 \f
13423 ;; Unconditional and other jump instructions
13424
13425 (define_insn "jump"
13426   [(set (pc)
13427         (label_ref (match_operand 0 "" "")))]
13428   ""
13429   "jmp\t%l0"
13430   [(set_attr "type" "ibr")
13431    (set (attr "length")
13432            (if_then_else (and (ge (minus (match_dup 0) (pc))
13433                                   (const_int -126))
13434                               (lt (minus (match_dup 0) (pc))
13435                                   (const_int 128)))
13436              (const_int 2)
13437              (const_int 5)))
13438    (set_attr "modrm" "0")])
13439
13440 (define_expand "indirect_jump"
13441   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13442   ""
13443   "")
13444
13445 (define_insn "*indirect_jump"
13446   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13447   "!TARGET_64BIT"
13448   "jmp\t%A0"
13449   [(set_attr "type" "ibr")
13450    (set_attr "length_immediate" "0")])
13451
13452 (define_insn "*indirect_jump_rtx64"
13453   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13454   "TARGET_64BIT"
13455   "jmp\t%A0"
13456   [(set_attr "type" "ibr")
13457    (set_attr "length_immediate" "0")])
13458
13459 (define_expand "tablejump"
13460   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13461               (use (label_ref (match_operand 1 "" "")))])]
13462   ""
13463 {
13464   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13465      relative.  Convert the relative address to an absolute address.  */
13466   if (flag_pic)
13467     {
13468       rtx op0, op1;
13469       enum rtx_code code;
13470
13471       if (TARGET_64BIT)
13472         {
13473           code = PLUS;
13474           op0 = operands[0];
13475           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13476         }
13477       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13478         {
13479           code = PLUS;
13480           op0 = operands[0];
13481           op1 = pic_offset_table_rtx;
13482         }
13483       else
13484         {
13485           code = MINUS;
13486           op0 = pic_offset_table_rtx;
13487           op1 = operands[0];
13488         }
13489
13490       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13491                                          OPTAB_DIRECT);
13492     }
13493 })
13494
13495 (define_insn "*tablejump_1"
13496   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13497    (use (label_ref (match_operand 1 "" "")))]
13498   "!TARGET_64BIT"
13499   "jmp\t%A0"
13500   [(set_attr "type" "ibr")
13501    (set_attr "length_immediate" "0")])
13502
13503 (define_insn "*tablejump_1_rtx64"
13504   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13505    (use (label_ref (match_operand 1 "" "")))]
13506   "TARGET_64BIT"
13507   "jmp\t%A0"
13508   [(set_attr "type" "ibr")
13509    (set_attr "length_immediate" "0")])
13510 \f
13511 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13512
13513 (define_peephole2
13514   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13515    (set (match_operand:QI 1 "register_operand" "")
13516         (match_operator:QI 2 "ix86_comparison_operator"
13517           [(reg FLAGS_REG) (const_int 0)]))
13518    (set (match_operand 3 "q_regs_operand" "")
13519         (zero_extend (match_dup 1)))]
13520   "(peep2_reg_dead_p (3, operands[1])
13521     || operands_match_p (operands[1], operands[3]))
13522    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13523   [(set (match_dup 4) (match_dup 0))
13524    (set (strict_low_part (match_dup 5))
13525         (match_dup 2))]
13526 {
13527   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13528   operands[5] = gen_lowpart (QImode, operands[3]);
13529   ix86_expand_clear (operands[3]);
13530 })
13531
13532 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13533
13534 (define_peephole2
13535   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13536    (set (match_operand:QI 1 "register_operand" "")
13537         (match_operator:QI 2 "ix86_comparison_operator"
13538           [(reg FLAGS_REG) (const_int 0)]))
13539    (parallel [(set (match_operand 3 "q_regs_operand" "")
13540                    (zero_extend (match_dup 1)))
13541               (clobber (reg:CC FLAGS_REG))])]
13542   "(peep2_reg_dead_p (3, operands[1])
13543     || operands_match_p (operands[1], operands[3]))
13544    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13545   [(set (match_dup 4) (match_dup 0))
13546    (set (strict_low_part (match_dup 5))
13547         (match_dup 2))]
13548 {
13549   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13550   operands[5] = gen_lowpart (QImode, operands[3]);
13551   ix86_expand_clear (operands[3]);
13552 })
13553 \f
13554 ;; Call instructions.
13555
13556 ;; The predicates normally associated with named expanders are not properly
13557 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13558 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13559
13560 ;; Call subroutine returning no value.
13561
13562 (define_expand "call_pop"
13563   [(parallel [(call (match_operand:QI 0 "" "")
13564                     (match_operand:SI 1 "" ""))
13565               (set (reg:SI SP_REG)
13566                    (plus:SI (reg:SI SP_REG)
13567                             (match_operand:SI 3 "" "")))])]
13568   "!TARGET_64BIT"
13569 {
13570   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13571   DONE;
13572 })
13573
13574 (define_insn "*call_pop_0"
13575   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13576          (match_operand:SI 1 "" ""))
13577    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13578                             (match_operand:SI 2 "immediate_operand" "")))]
13579   "!TARGET_64BIT"
13580 {
13581   if (SIBLING_CALL_P (insn))
13582     return "jmp\t%P0";
13583   else
13584     return "call\t%P0";
13585 }
13586   [(set_attr "type" "call")])
13587   
13588 (define_insn "*call_pop_1"
13589   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13590          (match_operand:SI 1 "" ""))
13591    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13592                             (match_operand:SI 2 "immediate_operand" "i")))]
13593   "!TARGET_64BIT"
13594 {
13595   if (constant_call_address_operand (operands[0], Pmode))
13596     {
13597       if (SIBLING_CALL_P (insn))
13598         return "jmp\t%P0";
13599       else
13600         return "call\t%P0";
13601     }
13602   if (SIBLING_CALL_P (insn))
13603     return "jmp\t%A0";
13604   else
13605     return "call\t%A0";
13606 }
13607   [(set_attr "type" "call")])
13608
13609 (define_expand "call"
13610   [(call (match_operand:QI 0 "" "")
13611          (match_operand 1 "" ""))
13612    (use (match_operand 2 "" ""))]
13613   ""
13614 {
13615   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13616   DONE;
13617 })
13618
13619 (define_expand "sibcall"
13620   [(call (match_operand:QI 0 "" "")
13621          (match_operand 1 "" ""))
13622    (use (match_operand 2 "" ""))]
13623   ""
13624 {
13625   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13626   DONE;
13627 })
13628
13629 (define_insn "*call_0"
13630   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13631          (match_operand 1 "" ""))]
13632   ""
13633 {
13634   if (SIBLING_CALL_P (insn))
13635     return "jmp\t%P0";
13636   else
13637     return "call\t%P0";
13638 }
13639   [(set_attr "type" "call")])
13640
13641 (define_insn "*call_1"
13642   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13643          (match_operand 1 "" ""))]
13644   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13645 {
13646   if (constant_call_address_operand (operands[0], Pmode))
13647     return "call\t%P0";
13648   return "call\t%A0";
13649 }
13650   [(set_attr "type" "call")])
13651
13652 (define_insn "*sibcall_1"
13653   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13654          (match_operand 1 "" ""))]
13655   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13656 {
13657   if (constant_call_address_operand (operands[0], Pmode))
13658     return "jmp\t%P0";
13659   return "jmp\t%A0";
13660 }
13661   [(set_attr "type" "call")])
13662
13663 (define_insn "*call_1_rex64"
13664   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13665          (match_operand 1 "" ""))]
13666   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13667 {
13668   if (constant_call_address_operand (operands[0], Pmode))
13669     return "call\t%P0";
13670   return "call\t%A0";
13671 }
13672   [(set_attr "type" "call")])
13673
13674 (define_insn "*sibcall_1_rex64"
13675   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13676          (match_operand 1 "" ""))]
13677   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13678   "jmp\t%P0"
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1_rex64_v"
13682   [(call (mem:QI (reg:DI 40))
13683          (match_operand 0 "" ""))]
13684   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13685   "jmp\t*%%r11"
13686   [(set_attr "type" "call")])
13687
13688
13689 ;; Call subroutine, returning value in operand 0
13690
13691 (define_expand "call_value_pop"
13692   [(parallel [(set (match_operand 0 "" "")
13693                    (call (match_operand:QI 1 "" "")
13694                          (match_operand:SI 2 "" "")))
13695               (set (reg:SI SP_REG)
13696                    (plus:SI (reg:SI SP_REG)
13697                             (match_operand:SI 4 "" "")))])]
13698   "!TARGET_64BIT"
13699 {
13700   ix86_expand_call (operands[0], operands[1], operands[2],
13701                     operands[3], operands[4], 0);
13702   DONE;
13703 })
13704
13705 (define_expand "call_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, 0);
13714   DONE;
13715 })
13716
13717 (define_expand "sibcall_value"
13718   [(set (match_operand 0 "" "")
13719         (call (match_operand:QI 1 "" "")
13720               (match_operand:SI 2 "" "")))
13721    (use (match_operand:SI 3 "" ""))]
13722   ;; Operand 2 not used on the i386.
13723   ""
13724 {
13725   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13726   DONE;
13727 })
13728
13729 ;; Call subroutine returning any type.
13730
13731 (define_expand "untyped_call"
13732   [(parallel [(call (match_operand 0 "" "")
13733                     (const_int 0))
13734               (match_operand 1 "" "")
13735               (match_operand 2 "" "")])]
13736   ""
13737 {
13738   int i;
13739
13740   /* In order to give reg-stack an easier job in validating two
13741      coprocessor registers as containing a possible return value,
13742      simply pretend the untyped call returns a complex long double
13743      value.  */
13744
13745   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13746                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13747                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13748                     NULL, 0);
13749
13750   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13751     {
13752       rtx set = XVECEXP (operands[2], 0, i);
13753       emit_move_insn (SET_DEST (set), SET_SRC (set));
13754     }
13755
13756   /* The optimizer does not know that the call sets the function value
13757      registers we stored in the result block.  We avoid problems by
13758      claiming that all hard registers are used and clobbered at this
13759      point.  */
13760   emit_insn (gen_blockage (const0_rtx));
13761
13762   DONE;
13763 })
13764 \f
13765 ;; Prologue and epilogue instructions
13766
13767 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13768 ;; all of memory.  This blocks insns from being moved across this point.
13769
13770 (define_insn "blockage"
13771   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13772   ""
13773   ""
13774   [(set_attr "length" "0")])
13775
13776 ;; Insn emitted into the body of a function to return from a function.
13777 ;; This is only done if the function's epilogue is known to be simple.
13778 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13779
13780 (define_expand "return"
13781   [(return)]
13782   "ix86_can_use_return_insn_p ()"
13783 {
13784   if (current_function_pops_args)
13785     {
13786       rtx popc = GEN_INT (current_function_pops_args);
13787       emit_jump_insn (gen_return_pop_internal (popc));
13788       DONE;
13789     }
13790 })
13791
13792 (define_insn "return_internal"
13793   [(return)]
13794   "reload_completed"
13795   "ret"
13796   [(set_attr "length" "1")
13797    (set_attr "length_immediate" "0")
13798    (set_attr "modrm" "0")])
13799
13800 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13801 ;; instruction Athlon and K8 have.
13802
13803 (define_insn "return_internal_long"
13804   [(return)
13805    (unspec [(const_int 0)] UNSPEC_REP)]
13806   "reload_completed"
13807   "rep {;} ret"
13808   [(set_attr "length" "1")
13809    (set_attr "length_immediate" "0")
13810    (set_attr "prefix_rep" "1")
13811    (set_attr "modrm" "0")])
13812
13813 (define_insn "return_pop_internal"
13814   [(return)
13815    (use (match_operand:SI 0 "const_int_operand" ""))]
13816   "reload_completed"
13817   "ret\t%0"
13818   [(set_attr "length" "3")
13819    (set_attr "length_immediate" "2")
13820    (set_attr "modrm" "0")])
13821
13822 (define_insn "return_indirect_internal"
13823   [(return)
13824    (use (match_operand:SI 0 "register_operand" "r"))]
13825   "reload_completed"
13826   "jmp\t%A0"
13827   [(set_attr "type" "ibr")
13828    (set_attr "length_immediate" "0")])
13829
13830 (define_insn "nop"
13831   [(const_int 0)]
13832   ""
13833   "nop"
13834   [(set_attr "length" "1")
13835    (set_attr "length_immediate" "0")
13836    (set_attr "modrm" "0")])
13837
13838 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13839 ;; branch prediction penalty for the third jump in a 16-byte
13840 ;; block on K8.
13841
13842 (define_insn "align"
13843   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13844   ""
13845 {
13846 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13847   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13848 #else
13849   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13850      The align insn is used to avoid 3 jump instructions in the row to improve
13851      branch prediction and the benefits hardly outweight the cost of extra 8
13852      nops on the average inserted by full alignment pseudo operation.  */
13853 #endif
13854   return "";
13855 }
13856   [(set_attr "length" "16")])
13857
13858 (define_expand "prologue"
13859   [(const_int 1)]
13860   ""
13861   "ix86_expand_prologue (); DONE;")
13862
13863 (define_insn "set_got"
13864   [(set (match_operand:SI 0 "register_operand" "=r")
13865         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13866    (clobber (reg:CC FLAGS_REG))]
13867   "!TARGET_64BIT"
13868   { return output_set_got (operands[0]); }
13869   [(set_attr "type" "multi")
13870    (set_attr "length" "12")])
13871
13872 (define_insn "set_got_rex64"
13873   [(set (match_operand:DI 0 "register_operand" "=r")
13874         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13875   "TARGET_64BIT"
13876   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13877   [(set_attr "type" "lea")
13878    (set_attr "length" "6")])
13879
13880 (define_expand "epilogue"
13881   [(const_int 1)]
13882   ""
13883   "ix86_expand_epilogue (1); DONE;")
13884
13885 (define_expand "sibcall_epilogue"
13886   [(const_int 1)]
13887   ""
13888   "ix86_expand_epilogue (0); DONE;")
13889
13890 (define_expand "eh_return"
13891   [(use (match_operand 0 "register_operand" ""))]
13892   ""
13893 {
13894   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13895
13896   /* Tricky bit: we write the address of the handler to which we will
13897      be returning into someone else's stack frame, one word below the
13898      stack address we wish to restore.  */
13899   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13900   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13901   tmp = gen_rtx_MEM (Pmode, tmp);
13902   emit_move_insn (tmp, ra);
13903
13904   if (Pmode == SImode)
13905     emit_jump_insn (gen_eh_return_si (sa));
13906   else
13907     emit_jump_insn (gen_eh_return_di (sa));
13908   emit_barrier ();
13909   DONE;
13910 })
13911
13912 (define_insn_and_split "eh_return_si"
13913   [(set (pc) 
13914         (unspec [(match_operand:SI 0 "register_operand" "c")]
13915                  UNSPEC_EH_RETURN))]
13916   "!TARGET_64BIT"
13917   "#"
13918   "reload_completed"
13919   [(const_int 1)]
13920   "ix86_expand_epilogue (2); DONE;")
13921
13922 (define_insn_and_split "eh_return_di"
13923   [(set (pc) 
13924         (unspec [(match_operand:DI 0 "register_operand" "c")]
13925                  UNSPEC_EH_RETURN))]
13926   "TARGET_64BIT"
13927   "#"
13928   "reload_completed"
13929   [(const_int 1)]
13930   "ix86_expand_epilogue (2); DONE;")
13931
13932 (define_insn "leave"
13933   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13934    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13935    (clobber (mem:BLK (scratch)))]
13936   "!TARGET_64BIT"
13937   "leave"
13938   [(set_attr "type" "leave")])
13939
13940 (define_insn "leave_rex64"
13941   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13942    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13943    (clobber (mem:BLK (scratch)))]
13944   "TARGET_64BIT"
13945   "leave"
13946   [(set_attr "type" "leave")])
13947 \f
13948 (define_expand "ffssi2"
13949   [(parallel
13950      [(set (match_operand:SI 0 "register_operand" "") 
13951            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13952       (clobber (match_scratch:SI 2 ""))
13953       (clobber (reg:CC FLAGS_REG))])]
13954   ""
13955   "")
13956
13957 (define_insn_and_split "*ffs_cmove"
13958   [(set (match_operand:SI 0 "register_operand" "=r") 
13959         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13960    (clobber (match_scratch:SI 2 "=&r"))
13961    (clobber (reg:CC FLAGS_REG))]
13962   "TARGET_CMOVE"
13963   "#"
13964   "&& reload_completed"
13965   [(set (match_dup 2) (const_int -1))
13966    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13967               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13968    (set (match_dup 0) (if_then_else:SI
13969                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13970                         (match_dup 2)
13971                         (match_dup 0)))
13972    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13973               (clobber (reg:CC FLAGS_REG))])]
13974   "")
13975
13976 (define_insn_and_split "*ffs_no_cmove"
13977   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13978         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13979    (clobber (match_scratch:SI 2 "=&q"))
13980    (clobber (reg:CC FLAGS_REG))]
13981   ""
13982   "#"
13983   "reload_completed"
13984   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13985               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13986    (set (strict_low_part (match_dup 3))
13987         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13988    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13989               (clobber (reg:CC FLAGS_REG))])
13990    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13991               (clobber (reg:CC FLAGS_REG))])
13992    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13993               (clobber (reg:CC FLAGS_REG))])]
13994 {
13995   operands[3] = gen_lowpart (QImode, operands[2]);
13996   ix86_expand_clear (operands[2]);
13997 })
13998
13999 (define_insn "*ffssi_1"
14000   [(set (reg:CCZ FLAGS_REG)
14001         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14002                      (const_int 0)))
14003    (set (match_operand:SI 0 "register_operand" "=r")
14004         (ctz:SI (match_dup 1)))]
14005   ""
14006   "bsf{l}\t{%1, %0|%0, %1}"
14007   [(set_attr "prefix_0f" "1")])
14008
14009 (define_expand "ffsdi2"
14010   [(parallel
14011      [(set (match_operand:DI 0 "register_operand" "") 
14012            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14013       (clobber (match_scratch:DI 2 ""))
14014       (clobber (reg:CC FLAGS_REG))])]
14015   "TARGET_64BIT && TARGET_CMOVE"
14016   "")
14017
14018 (define_insn_and_split "*ffs_rex64"
14019   [(set (match_operand:DI 0 "register_operand" "=r") 
14020         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14021    (clobber (match_scratch:DI 2 "=&r"))
14022    (clobber (reg:CC FLAGS_REG))]
14023   "TARGET_64BIT && TARGET_CMOVE"
14024   "#"
14025   "&& reload_completed"
14026   [(set (match_dup 2) (const_int -1))
14027    (parallel [(set (reg:CCZ FLAGS_REG)
14028                    (compare:CCZ (match_dup 1) (const_int 0)))
14029               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14030    (set (match_dup 0) (if_then_else:DI
14031                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14032                         (match_dup 2)
14033                         (match_dup 0)))
14034    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14035               (clobber (reg:CC FLAGS_REG))])]
14036   "")
14037
14038 (define_insn "*ffsdi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:DI 0 "register_operand" "=r")
14043         (ctz:DI (match_dup 1)))]
14044   "TARGET_64BIT"
14045   "bsf{q}\t{%1, %0|%0, %1}"
14046   [(set_attr "prefix_0f" "1")])
14047
14048 (define_insn "ctzsi2"
14049   [(set (match_operand:SI 0 "register_operand" "=r")
14050         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14051    (clobber (reg:CC FLAGS_REG))]
14052   ""
14053   "bsf{l}\t{%1, %0|%0, %1}"
14054   [(set_attr "prefix_0f" "1")])
14055
14056 (define_insn "ctzdi2"
14057   [(set (match_operand:DI 0 "register_operand" "=r")
14058         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14059    (clobber (reg:CC FLAGS_REG))]
14060   "TARGET_64BIT"
14061   "bsf{q}\t{%1, %0|%0, %1}"
14062   [(set_attr "prefix_0f" "1")])
14063
14064 (define_expand "clzsi2"
14065   [(parallel
14066      [(set (match_operand:SI 0 "register_operand" "")
14067            (minus:SI (const_int 31)
14068                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14069       (clobber (reg:CC FLAGS_REG))])
14070    (parallel
14071      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14072       (clobber (reg:CC FLAGS_REG))])]
14073   ""
14074   "")
14075
14076 (define_insn "*bsr"
14077   [(set (match_operand:SI 0 "register_operand" "=r")
14078         (minus:SI (const_int 31)
14079                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14080    (clobber (reg:CC FLAGS_REG))]
14081   ""
14082   "bsr{l}\t{%1, %0|%0, %1}"
14083   [(set_attr "prefix_0f" "1")])
14084
14085 (define_expand "clzdi2"
14086   [(parallel
14087      [(set (match_operand:DI 0 "register_operand" "")
14088            (minus:DI (const_int 63)
14089                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14090       (clobber (reg:CC FLAGS_REG))])
14091    (parallel
14092      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14093       (clobber (reg:CC FLAGS_REG))])]
14094   "TARGET_64BIT"
14095   "")
14096
14097 (define_insn "*bsr_rex64"
14098   [(set (match_operand:DI 0 "register_operand" "=r")
14099         (minus:DI (const_int 63)
14100                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14101    (clobber (reg:CC FLAGS_REG))]
14102   "TARGET_64BIT"
14103   "bsr{q}\t{%1, %0|%0, %1}"
14104   [(set_attr "prefix_0f" "1")])
14105 \f
14106 ;; Thread-local storage patterns for ELF.
14107 ;;
14108 ;; Note that these code sequences must appear exactly as shown
14109 ;; in order to allow linker relaxation.
14110
14111 (define_insn "*tls_global_dynamic_32_gnu"
14112   [(set (match_operand:SI 0 "register_operand" "=a")
14113         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14114                     (match_operand:SI 2 "tls_symbolic_operand" "")
14115                     (match_operand:SI 3 "call_insn_operand" "")]
14116                     UNSPEC_TLS_GD))
14117    (clobber (match_scratch:SI 4 "=d"))
14118    (clobber (match_scratch:SI 5 "=c"))
14119    (clobber (reg:CC FLAGS_REG))]
14120   "!TARGET_64BIT && TARGET_GNU_TLS"
14121   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14122   [(set_attr "type" "multi")
14123    (set_attr "length" "12")])
14124
14125 (define_insn "*tls_global_dynamic_32_sun"
14126   [(set (match_operand:SI 0 "register_operand" "=a")
14127         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14128                     (match_operand:SI 2 "tls_symbolic_operand" "")
14129                     (match_operand:SI 3 "call_insn_operand" "")]
14130                     UNSPEC_TLS_GD))
14131    (clobber (match_scratch:SI 4 "=d"))
14132    (clobber (match_scratch:SI 5 "=c"))
14133    (clobber (reg:CC FLAGS_REG))]
14134   "!TARGET_64BIT && TARGET_SUN_TLS"
14135   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14136         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14137   [(set_attr "type" "multi")
14138    (set_attr "length" "14")])
14139
14140 (define_expand "tls_global_dynamic_32"
14141   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14142                    (unspec:SI
14143                     [(match_dup 2)
14144                      (match_operand:SI 1 "tls_symbolic_operand" "")
14145                      (match_dup 3)]
14146                     UNSPEC_TLS_GD))
14147               (clobber (match_scratch:SI 4 ""))
14148               (clobber (match_scratch:SI 5 ""))
14149               (clobber (reg:CC FLAGS_REG))])]
14150   ""
14151 {
14152   if (flag_pic)
14153     operands[2] = pic_offset_table_rtx;
14154   else
14155     {
14156       operands[2] = gen_reg_rtx (Pmode);
14157       emit_insn (gen_set_got (operands[2]));
14158     }
14159   operands[3] = ix86_tls_get_addr ();
14160 })
14161
14162 (define_insn "*tls_global_dynamic_64"
14163   [(set (match_operand:DI 0 "register_operand" "=a")
14164         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14165                  (match_operand:DI 3 "" "")))
14166    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14167               UNSPEC_TLS_GD)]
14168   "TARGET_64BIT"
14169   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14170   [(set_attr "type" "multi")
14171    (set_attr "length" "16")])
14172
14173 (define_expand "tls_global_dynamic_64"
14174   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14175                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14176               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14177                          UNSPEC_TLS_GD)])]
14178   ""
14179 {
14180   operands[2] = ix86_tls_get_addr ();
14181 })
14182
14183 (define_insn "*tls_local_dynamic_base_32_gnu"
14184   [(set (match_operand:SI 0 "register_operand" "=a")
14185         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14186                     (match_operand:SI 2 "call_insn_operand" "")]
14187                    UNSPEC_TLS_LD_BASE))
14188    (clobber (match_scratch:SI 3 "=d"))
14189    (clobber (match_scratch:SI 4 "=c"))
14190    (clobber (reg:CC FLAGS_REG))]
14191   "!TARGET_64BIT && TARGET_GNU_TLS"
14192   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14193   [(set_attr "type" "multi")
14194    (set_attr "length" "11")])
14195
14196 (define_insn "*tls_local_dynamic_base_32_sun"
14197   [(set (match_operand:SI 0 "register_operand" "=a")
14198         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14199                     (match_operand:SI 2 "call_insn_operand" "")]
14200                    UNSPEC_TLS_LD_BASE))
14201    (clobber (match_scratch:SI 3 "=d"))
14202    (clobber (match_scratch:SI 4 "=c"))
14203    (clobber (reg:CC FLAGS_REG))]
14204   "!TARGET_64BIT && TARGET_SUN_TLS"
14205   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14206         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14207   [(set_attr "type" "multi")
14208    (set_attr "length" "13")])
14209
14210 (define_expand "tls_local_dynamic_base_32"
14211   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14212                    (unspec:SI [(match_dup 1) (match_dup 2)]
14213                               UNSPEC_TLS_LD_BASE))
14214               (clobber (match_scratch:SI 3 ""))
14215               (clobber (match_scratch:SI 4 ""))
14216               (clobber (reg:CC FLAGS_REG))])]
14217   ""
14218 {
14219   if (flag_pic)
14220     operands[1] = pic_offset_table_rtx;
14221   else
14222     {
14223       operands[1] = gen_reg_rtx (Pmode);
14224       emit_insn (gen_set_got (operands[1]));
14225     }
14226   operands[2] = ix86_tls_get_addr ();
14227 })
14228
14229 (define_insn "*tls_local_dynamic_base_64"
14230   [(set (match_operand:DI 0 "register_operand" "=a")
14231         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14232                  (match_operand:DI 2 "" "")))
14233    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14234   "TARGET_64BIT"
14235   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14236   [(set_attr "type" "multi")
14237    (set_attr "length" "12")])
14238
14239 (define_expand "tls_local_dynamic_base_64"
14240   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14241                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14242               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14243   ""
14244 {
14245   operands[1] = ix86_tls_get_addr ();
14246 })
14247
14248 ;; Local dynamic of a single variable is a lose.  Show combine how
14249 ;; to convert that back to global dynamic.
14250
14251 (define_insn_and_split "*tls_local_dynamic_32_once"
14252   [(set (match_operand:SI 0 "register_operand" "=a")
14253         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14254                              (match_operand:SI 2 "call_insn_operand" "")]
14255                             UNSPEC_TLS_LD_BASE)
14256                  (const:SI (unspec:SI
14257                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14258                             UNSPEC_DTPOFF))))
14259    (clobber (match_scratch:SI 4 "=d"))
14260    (clobber (match_scratch:SI 5 "=c"))
14261    (clobber (reg:CC FLAGS_REG))]
14262   ""
14263   "#"
14264   ""
14265   [(parallel [(set (match_dup 0)
14266                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14267                               UNSPEC_TLS_GD))
14268               (clobber (match_dup 4))
14269               (clobber (match_dup 5))
14270               (clobber (reg:CC FLAGS_REG))])]
14271   "")
14272
14273 ;; Load and add the thread base pointer from %gs:0.
14274
14275 (define_insn "*load_tp_si"
14276   [(set (match_operand:SI 0 "register_operand" "=r")
14277         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14278   "!TARGET_64BIT"
14279   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14280   [(set_attr "type" "imov")
14281    (set_attr "modrm" "0")
14282    (set_attr "length" "7")
14283    (set_attr "memory" "load")
14284    (set_attr "imm_disp" "false")])
14285
14286 (define_insn "*add_tp_si"
14287   [(set (match_operand:SI 0 "register_operand" "=r")
14288         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14289                  (match_operand:SI 1 "register_operand" "0")))
14290    (clobber (reg:CC FLAGS_REG))]
14291   "!TARGET_64BIT"
14292   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14293   [(set_attr "type" "alu")
14294    (set_attr "modrm" "0")
14295    (set_attr "length" "7")
14296    (set_attr "memory" "load")
14297    (set_attr "imm_disp" "false")])
14298
14299 (define_insn "*load_tp_di"
14300   [(set (match_operand:DI 0 "register_operand" "=r")
14301         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14302   "TARGET_64BIT"
14303   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14304   [(set_attr "type" "imov")
14305    (set_attr "modrm" "0")
14306    (set_attr "length" "7")
14307    (set_attr "memory" "load")
14308    (set_attr "imm_disp" "false")])
14309
14310 (define_insn "*add_tp_di"
14311   [(set (match_operand:DI 0 "register_operand" "=r")
14312         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14313                  (match_operand:DI 1 "register_operand" "0")))
14314    (clobber (reg:CC FLAGS_REG))]
14315   "TARGET_64BIT"
14316   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14317   [(set_attr "type" "alu")
14318    (set_attr "modrm" "0")
14319    (set_attr "length" "7")
14320    (set_attr "memory" "load")
14321    (set_attr "imm_disp" "false")])
14322 \f
14323 ;; These patterns match the binary 387 instructions for addM3, subM3,
14324 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14325 ;; SFmode.  The first is the normal insn, the second the same insn but
14326 ;; with one operand a conversion, and the third the same insn but with
14327 ;; the other operand a conversion.  The conversion may be SFmode or
14328 ;; SImode if the target mode DFmode, but only SImode if the target mode
14329 ;; is SFmode.
14330
14331 ;; Gcc is slightly more smart about handling normal two address instructions
14332 ;; so use special patterns for add and mull.
14333
14334 (define_insn "*fop_sf_comm_mixed"
14335   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14336         (match_operator:SF 3 "binary_fp_operator"
14337                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14338                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14339   "TARGET_MIX_SSE_I387
14340    && COMMUTATIVE_ARITH_P (operands[3])
14341    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14342   "* return output_387_binary_op (insn, operands);"
14343   [(set (attr "type") 
14344         (if_then_else (eq_attr "alternative" "1")
14345            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14346               (const_string "ssemul")
14347               (const_string "sseadd"))
14348            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14349               (const_string "fmul")
14350               (const_string "fop"))))
14351    (set_attr "mode" "SF")])
14352
14353 (define_insn "*fop_sf_comm_sse"
14354   [(set (match_operand:SF 0 "register_operand" "=x")
14355         (match_operator:SF 3 "binary_fp_operator"
14356                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14357                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14358   "TARGET_SSE_MATH
14359    && COMMUTATIVE_ARITH_P (operands[3])
14360    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14361   "* return output_387_binary_op (insn, operands);"
14362   [(set (attr "type") 
14363         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14364            (const_string "ssemul")
14365            (const_string "sseadd")))
14366    (set_attr "mode" "SF")])
14367
14368 (define_insn "*fop_sf_comm_i387"
14369   [(set (match_operand:SF 0 "register_operand" "=f")
14370         (match_operator:SF 3 "binary_fp_operator"
14371                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14372                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14373   "TARGET_80387
14374    && COMMUTATIVE_ARITH_P (operands[3])
14375    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376   "* return output_387_binary_op (insn, operands);"
14377   [(set (attr "type") 
14378         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14379            (const_string "fmul")
14380            (const_string "fop")))
14381    (set_attr "mode" "SF")])
14382
14383 (define_insn "*fop_sf_1_mixed"
14384   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14385         (match_operator:SF 3 "binary_fp_operator"
14386                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14387                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14388   "TARGET_MIX_SSE_I387
14389    && !COMMUTATIVE_ARITH_P (operands[3])
14390    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14391   "* return output_387_binary_op (insn, operands);"
14392   [(set (attr "type") 
14393         (cond [(and (eq_attr "alternative" "2")
14394                     (match_operand:SF 3 "mult_operator" ""))
14395                  (const_string "ssemul")
14396                (and (eq_attr "alternative" "2")
14397                     (match_operand:SF 3 "div_operator" ""))
14398                  (const_string "ssediv")
14399                (eq_attr "alternative" "2")
14400                  (const_string "sseadd")
14401                (match_operand:SF 3 "mult_operator" "") 
14402                  (const_string "fmul")
14403                (match_operand:SF 3 "div_operator" "") 
14404                  (const_string "fdiv")
14405               ]
14406               (const_string "fop")))
14407    (set_attr "mode" "SF")])
14408
14409 (define_insn "*fop_sf_1_sse"
14410   [(set (match_operand:SF 0 "register_operand" "=x")
14411         (match_operator:SF 3 "binary_fp_operator"
14412                         [(match_operand:SF 1 "register_operand" "0")
14413                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14414   "TARGET_SSE_MATH
14415    && !COMMUTATIVE_ARITH_P (operands[3])"
14416   "* return output_387_binary_op (insn, operands);"
14417   [(set (attr "type") 
14418         (cond [(match_operand:SF 3 "mult_operator" "")
14419                  (const_string "ssemul")
14420                (match_operand:SF 3 "div_operator" "")
14421                  (const_string "ssediv")
14422               ]
14423               (const_string "sseadd")))
14424    (set_attr "mode" "SF")])
14425
14426 ;; This pattern is not fully shadowed by the pattern above.
14427 (define_insn "*fop_sf_1_i387"
14428   [(set (match_operand:SF 0 "register_operand" "=f,f")
14429         (match_operator:SF 3 "binary_fp_operator"
14430                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14431                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14432   "TARGET_80387 && !TARGET_SSE_MATH
14433    && !COMMUTATIVE_ARITH_P (operands[3])
14434    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14435   "* return output_387_binary_op (insn, operands);"
14436   [(set (attr "type") 
14437         (cond [(match_operand:SF 3 "mult_operator" "") 
14438                  (const_string "fmul")
14439                (match_operand:SF 3 "div_operator" "") 
14440                  (const_string "fdiv")
14441               ]
14442               (const_string "fop")))
14443    (set_attr "mode" "SF")])
14444
14445 ;; ??? Add SSE splitters for these!
14446 (define_insn "*fop_sf_2<mode>_i387"
14447   [(set (match_operand:SF 0 "register_operand" "=f,f")
14448         (match_operator:SF 3 "binary_fp_operator"
14449           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14450            (match_operand:SF 2 "register_operand" "0,0")]))]
14451   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14452   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (cond [(match_operand:SF 3 "mult_operator" "") 
14455                  (const_string "fmul")
14456                (match_operand:SF 3 "div_operator" "") 
14457                  (const_string "fdiv")
14458               ]
14459               (const_string "fop")))
14460    (set_attr "fp_int_src" "true")
14461    (set_attr "mode" "<MODE>")])
14462
14463 (define_insn "*fop_sf_3<mode>_i387"
14464   [(set (match_operand:SF 0 "register_operand" "=f,f")
14465         (match_operator:SF 3 "binary_fp_operator"
14466           [(match_operand:SF 1 "register_operand" "0,0")
14467            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14468   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14469   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14470   [(set (attr "type") 
14471         (cond [(match_operand:SF 3 "mult_operator" "") 
14472                  (const_string "fmul")
14473                (match_operand:SF 3 "div_operator" "") 
14474                  (const_string "fdiv")
14475               ]
14476               (const_string "fop")))
14477    (set_attr "fp_int_src" "true")
14478    (set_attr "mode" "<MODE>")])
14479
14480 (define_insn "*fop_df_comm_mixed"
14481   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14482         (match_operator:DF 3 "binary_fp_operator"
14483                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14484                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14485   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14486    && COMMUTATIVE_ARITH_P (operands[3])
14487    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14488   "* return output_387_binary_op (insn, operands);"
14489   [(set (attr "type") 
14490         (if_then_else (eq_attr "alternative" "1")
14491            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14492               (const_string "ssemul")
14493               (const_string "sseadd"))
14494            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14495               (const_string "fmul")
14496               (const_string "fop"))))
14497    (set_attr "mode" "DF")])
14498
14499 (define_insn "*fop_df_comm_sse"
14500   [(set (match_operand:DF 0 "register_operand" "=Y")
14501         (match_operator:DF 3 "binary_fp_operator"
14502                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14503                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14504   "TARGET_SSE2 && TARGET_SSE_MATH
14505    && COMMUTATIVE_ARITH_P (operands[3])
14506    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14507   "* return output_387_binary_op (insn, operands);"
14508   [(set (attr "type") 
14509         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14510            (const_string "ssemul")
14511            (const_string "sseadd")))
14512    (set_attr "mode" "DF")])
14513
14514 (define_insn "*fop_df_comm_i387"
14515   [(set (match_operand:DF 0 "register_operand" "=f")
14516         (match_operator:DF 3 "binary_fp_operator"
14517                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14518                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14519   "TARGET_80387
14520    && COMMUTATIVE_ARITH_P (operands[3])
14521    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14522   "* return output_387_binary_op (insn, operands);"
14523   [(set (attr "type") 
14524         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14525            (const_string "fmul")
14526            (const_string "fop")))
14527    (set_attr "mode" "DF")])
14528
14529 (define_insn "*fop_df_1_mixed"
14530   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14531         (match_operator:DF 3 "binary_fp_operator"
14532                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14533                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14534   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14535    && !COMMUTATIVE_ARITH_P (operands[3])
14536    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14537   "* return output_387_binary_op (insn, operands);"
14538   [(set (attr "type") 
14539         (cond [(and (eq_attr "alternative" "2")
14540                     (match_operand:SF 3 "mult_operator" ""))
14541                  (const_string "ssemul")
14542                (and (eq_attr "alternative" "2")
14543                     (match_operand:SF 3 "div_operator" ""))
14544                  (const_string "ssediv")
14545                (eq_attr "alternative" "2")
14546                  (const_string "sseadd")
14547                (match_operand:DF 3 "mult_operator" "") 
14548                  (const_string "fmul")
14549                (match_operand:DF 3 "div_operator" "") 
14550                  (const_string "fdiv")
14551               ]
14552               (const_string "fop")))
14553    (set_attr "mode" "DF")])
14554
14555 (define_insn "*fop_df_1_sse"
14556   [(set (match_operand:DF 0 "register_operand" "=Y")
14557         (match_operator:DF 3 "binary_fp_operator"
14558                         [(match_operand:DF 1 "register_operand" "0")
14559                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14560   "TARGET_SSE2 && TARGET_SSE_MATH
14561    && !COMMUTATIVE_ARITH_P (operands[3])"
14562   "* return output_387_binary_op (insn, operands);"
14563   [(set_attr "mode" "DF")
14564    (set (attr "type") 
14565         (cond [(match_operand:SF 3 "mult_operator" "")
14566                  (const_string "ssemul")
14567                (match_operand:SF 3 "div_operator" "")
14568                  (const_string "ssediv")
14569               ]
14570               (const_string "sseadd")))])
14571
14572 ;; This pattern is not fully shadowed by the pattern above.
14573 (define_insn "*fop_df_1_i387"
14574   [(set (match_operand:DF 0 "register_operand" "=f,f")
14575         (match_operator:DF 3 "binary_fp_operator"
14576                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14577                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14578   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14579    && !COMMUTATIVE_ARITH_P (operands[3])
14580    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14581   "* return output_387_binary_op (insn, operands);"
14582   [(set (attr "type") 
14583         (cond [(match_operand:DF 3 "mult_operator" "") 
14584                  (const_string "fmul")
14585                (match_operand:DF 3 "div_operator" "")
14586                  (const_string "fdiv")
14587               ]
14588               (const_string "fop")))
14589    (set_attr "mode" "DF")])
14590
14591 ;; ??? Add SSE splitters for these!
14592 (define_insn "*fop_df_2<mode>_i387"
14593   [(set (match_operand:DF 0 "register_operand" "=f,f")
14594         (match_operator:DF 3 "binary_fp_operator"
14595            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14596             (match_operand:DF 2 "register_operand" "0,0")]))]
14597   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14598    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14599   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14600   [(set (attr "type") 
14601         (cond [(match_operand:DF 3 "mult_operator" "") 
14602                  (const_string "fmul")
14603                (match_operand:DF 3 "div_operator" "") 
14604                  (const_string "fdiv")
14605               ]
14606               (const_string "fop")))
14607    (set_attr "fp_int_src" "true")
14608    (set_attr "mode" "<MODE>")])
14609
14610 (define_insn "*fop_df_3<mode>_i387"
14611   [(set (match_operand:DF 0 "register_operand" "=f,f")
14612         (match_operator:DF 3 "binary_fp_operator"
14613            [(match_operand:DF 1 "register_operand" "0,0")
14614             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14615   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14616    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14617   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14618   [(set (attr "type") 
14619         (cond [(match_operand:DF 3 "mult_operator" "") 
14620                  (const_string "fmul")
14621                (match_operand:DF 3 "div_operator" "") 
14622                  (const_string "fdiv")
14623               ]
14624               (const_string "fop")))
14625    (set_attr "fp_int_src" "true")
14626    (set_attr "mode" "<MODE>")])
14627
14628 (define_insn "*fop_df_4_i387"
14629   [(set (match_operand:DF 0 "register_operand" "=f,f")
14630         (match_operator:DF 3 "binary_fp_operator"
14631            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14632             (match_operand:DF 2 "register_operand" "0,f")]))]
14633   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14635   "* return output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:DF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:DF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "mode" "SF")])
14644
14645 (define_insn "*fop_df_5_i387"
14646   [(set (match_operand:DF 0 "register_operand" "=f,f")
14647         (match_operator:DF 3 "binary_fp_operator"
14648           [(match_operand:DF 1 "register_operand" "0,f")
14649            (float_extend:DF
14650             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14651   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14652   "* return output_387_binary_op (insn, operands);"
14653   [(set (attr "type") 
14654         (cond [(match_operand:DF 3 "mult_operator" "") 
14655                  (const_string "fmul")
14656                (match_operand:DF 3 "div_operator" "") 
14657                  (const_string "fdiv")
14658               ]
14659               (const_string "fop")))
14660    (set_attr "mode" "SF")])
14661
14662 (define_insn "*fop_df_6_i387"
14663   [(set (match_operand:DF 0 "register_operand" "=f,f")
14664         (match_operator:DF 3 "binary_fp_operator"
14665           [(float_extend:DF
14666             (match_operand:SF 1 "register_operand" "0,f"))
14667            (float_extend:DF
14668             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:DF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:DF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14679
14680 (define_insn "*fop_xf_comm_i387"
14681   [(set (match_operand:XF 0 "register_operand" "=f")
14682         (match_operator:XF 3 "binary_fp_operator"
14683                         [(match_operand:XF 1 "register_operand" "%0")
14684                          (match_operand:XF 2 "register_operand" "f")]))]
14685   "TARGET_80387
14686    && COMMUTATIVE_ARITH_P (operands[3])"
14687   "* return output_387_binary_op (insn, operands);"
14688   [(set (attr "type") 
14689         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14690            (const_string "fmul")
14691            (const_string "fop")))
14692    (set_attr "mode" "XF")])
14693
14694 (define_insn "*fop_xf_1_i387"
14695   [(set (match_operand:XF 0 "register_operand" "=f,f")
14696         (match_operator:XF 3 "binary_fp_operator"
14697                         [(match_operand:XF 1 "register_operand" "0,f")
14698                          (match_operand:XF 2 "register_operand" "f,0")]))]
14699   "TARGET_80387
14700    && !COMMUTATIVE_ARITH_P (operands[3])"
14701   "* return output_387_binary_op (insn, operands);"
14702   [(set (attr "type") 
14703         (cond [(match_operand:XF 3 "mult_operator" "") 
14704                  (const_string "fmul")
14705                (match_operand:XF 3 "div_operator" "") 
14706                  (const_string "fdiv")
14707               ]
14708               (const_string "fop")))
14709    (set_attr "mode" "XF")])
14710
14711 (define_insn "*fop_xf_2<mode>_i387"
14712   [(set (match_operand:XF 0 "register_operand" "=f,f")
14713         (match_operator:XF 3 "binary_fp_operator"
14714            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14715             (match_operand:XF 2 "register_operand" "0,0")]))]
14716   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14717   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14718   [(set (attr "type") 
14719         (cond [(match_operand:XF 3 "mult_operator" "") 
14720                  (const_string "fmul")
14721                (match_operand:XF 3 "div_operator" "") 
14722                  (const_string "fdiv")
14723               ]
14724               (const_string "fop")))
14725    (set_attr "fp_int_src" "true")
14726    (set_attr "mode" "<MODE>")])
14727
14728 (define_insn "*fop_xf_3<mode>_i387"
14729   [(set (match_operand:XF 0 "register_operand" "=f,f")
14730         (match_operator:XF 3 "binary_fp_operator"
14731           [(match_operand:XF 1 "register_operand" "0,0")
14732            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14733   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14734   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14735   [(set (attr "type") 
14736         (cond [(match_operand:XF 3 "mult_operator" "") 
14737                  (const_string "fmul")
14738                (match_operand:XF 3 "div_operator" "") 
14739                  (const_string "fdiv")
14740               ]
14741               (const_string "fop")))
14742    (set_attr "fp_int_src" "true")
14743    (set_attr "mode" "<MODE>")])
14744
14745 (define_insn "*fop_xf_4_i387"
14746   [(set (match_operand:XF 0 "register_operand" "=f,f")
14747         (match_operator:XF 3 "binary_fp_operator"
14748            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14749             (match_operand:XF 2 "register_operand" "0,f")]))]
14750   "TARGET_80387"
14751   "* return output_387_binary_op (insn, operands);"
14752   [(set (attr "type") 
14753         (cond [(match_operand:XF 3 "mult_operator" "") 
14754                  (const_string "fmul")
14755                (match_operand:XF 3 "div_operator" "") 
14756                  (const_string "fdiv")
14757               ]
14758               (const_string "fop")))
14759    (set_attr "mode" "SF")])
14760
14761 (define_insn "*fop_xf_5_i387"
14762   [(set (match_operand:XF 0 "register_operand" "=f,f")
14763         (match_operator:XF 3 "binary_fp_operator"
14764           [(match_operand:XF 1 "register_operand" "0,f")
14765            (float_extend:XF
14766             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14767   "TARGET_80387"
14768   "* return output_387_binary_op (insn, operands);"
14769   [(set (attr "type") 
14770         (cond [(match_operand:XF 3 "mult_operator" "") 
14771                  (const_string "fmul")
14772                (match_operand:XF 3 "div_operator" "") 
14773                  (const_string "fdiv")
14774               ]
14775               (const_string "fop")))
14776    (set_attr "mode" "SF")])
14777
14778 (define_insn "*fop_xf_6_i387"
14779   [(set (match_operand:XF 0 "register_operand" "=f,f")
14780         (match_operator:XF 3 "binary_fp_operator"
14781           [(float_extend:XF
14782             (match_operand 1 "register_operand" "0,f"))
14783            (float_extend:XF
14784             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14785   "TARGET_80387"
14786   "* return output_387_binary_op (insn, operands);"
14787   [(set (attr "type") 
14788         (cond [(match_operand:XF 3 "mult_operator" "") 
14789                  (const_string "fmul")
14790                (match_operand:XF 3 "div_operator" "") 
14791                  (const_string "fdiv")
14792               ]
14793               (const_string "fop")))
14794    (set_attr "mode" "SF")])
14795
14796 (define_split
14797   [(set (match_operand 0 "register_operand" "")
14798         (match_operator 3 "binary_fp_operator"
14799            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14800             (match_operand 2 "register_operand" "")]))]
14801   "TARGET_80387 && reload_completed
14802    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14803   [(const_int 0)]
14804
14805   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14806   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14807   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14808                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14809                                           GET_MODE (operands[3]),
14810                                           operands[4],
14811                                           operands[2])));
14812   ix86_free_from_memory (GET_MODE (operands[1]));
14813   DONE;
14814 })
14815
14816 (define_split
14817   [(set (match_operand 0 "register_operand" "")
14818         (match_operator 3 "binary_fp_operator"
14819            [(match_operand 1 "register_operand" "")
14820             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14821   "TARGET_80387 && reload_completed
14822    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14823   [(const_int 0)]
14824 {
14825   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14826   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14827   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14828                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14829                                           GET_MODE (operands[3]),
14830                                           operands[1],
14831                                           operands[4])));
14832   ix86_free_from_memory (GET_MODE (operands[2]));
14833   DONE;
14834 })
14835 \f
14836 ;; FPU special functions.
14837
14838 (define_expand "sqrtsf2"
14839   [(set (match_operand:SF 0 "register_operand" "")
14840         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14841   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14842 {
14843   if (!TARGET_SSE_MATH)
14844     operands[1] = force_reg (SFmode, operands[1]);
14845 })
14846
14847 (define_insn "*sqrtsf2_mixed"
14848   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14849         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14850   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14851   "@
14852    fsqrt
14853    sqrtss\t{%1, %0|%0, %1}"
14854   [(set_attr "type" "fpspc,sse")
14855    (set_attr "mode" "SF,SF")
14856    (set_attr "athlon_decode" "direct,*")])
14857
14858 (define_insn "*sqrtsf2_sse"
14859   [(set (match_operand:SF 0 "register_operand" "=x")
14860         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14861   "TARGET_SSE_MATH"
14862   "sqrtss\t{%1, %0|%0, %1}"
14863   [(set_attr "type" "sse")
14864    (set_attr "mode" "SF")
14865    (set_attr "athlon_decode" "*")])
14866
14867 (define_insn "*sqrtsf2_i387"
14868   [(set (match_operand:SF 0 "register_operand" "=f")
14869         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14870   "TARGET_USE_FANCY_MATH_387"
14871   "fsqrt"
14872   [(set_attr "type" "fpspc")
14873    (set_attr "mode" "SF")
14874    (set_attr "athlon_decode" "direct")])
14875
14876 (define_expand "sqrtdf2"
14877   [(set (match_operand:DF 0 "register_operand" "")
14878         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14879   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14880 {
14881   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14882     operands[1] = force_reg (DFmode, operands[1]);
14883 })
14884
14885 (define_insn "*sqrtdf2_mixed"
14886   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14887         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14888   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14889   "@
14890    fsqrt
14891    sqrtsd\t{%1, %0|%0, %1}"
14892   [(set_attr "type" "fpspc,sse")
14893    (set_attr "mode" "DF,DF")
14894    (set_attr "athlon_decode" "direct,*")])
14895
14896 (define_insn "*sqrtdf2_sse"
14897   [(set (match_operand:DF 0 "register_operand" "=Y")
14898         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14899   "TARGET_SSE2 && TARGET_SSE_MATH"
14900   "sqrtsd\t{%1, %0|%0, %1}"
14901   [(set_attr "type" "sse")
14902    (set_attr "mode" "DF")
14903    (set_attr "athlon_decode" "*")])
14904
14905 (define_insn "*sqrtdf2_i387"
14906   [(set (match_operand:DF 0 "register_operand" "=f")
14907         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14908   "TARGET_USE_FANCY_MATH_387"
14909   "fsqrt"
14910   [(set_attr "type" "fpspc")
14911    (set_attr "mode" "DF")
14912    (set_attr "athlon_decode" "direct")])
14913
14914 (define_insn "*sqrtextendsfdf2_i387"
14915   [(set (match_operand:DF 0 "register_operand" "=f")
14916         (sqrt:DF (float_extend:DF
14917                   (match_operand:SF 1 "register_operand" "0"))))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14920   "fsqrt"
14921   [(set_attr "type" "fpspc")
14922    (set_attr "mode" "DF")
14923    (set_attr "athlon_decode" "direct")])
14924
14925 (define_insn "sqrtxf2"
14926   [(set (match_operand:XF 0 "register_operand" "=f")
14927         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14928   "TARGET_USE_FANCY_MATH_387 
14929    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14930   "fsqrt"
14931   [(set_attr "type" "fpspc")
14932    (set_attr "mode" "XF")
14933    (set_attr "athlon_decode" "direct")])
14934
14935 (define_insn "*sqrtextendsfxf2_i387"
14936   [(set (match_operand:XF 0 "register_operand" "=f")
14937         (sqrt:XF (float_extend:XF
14938                   (match_operand:SF 1 "register_operand" "0"))))]
14939   "TARGET_USE_FANCY_MATH_387"
14940   "fsqrt"
14941   [(set_attr "type" "fpspc")
14942    (set_attr "mode" "XF")
14943    (set_attr "athlon_decode" "direct")])
14944
14945 (define_insn "*sqrtextenddfxf2_i387"
14946   [(set (match_operand:XF 0 "register_operand" "=f")
14947         (sqrt:XF (float_extend:XF
14948                   (match_operand:DF 1 "register_operand" "0"))))]
14949   "TARGET_USE_FANCY_MATH_387"
14950   "fsqrt"
14951   [(set_attr "type" "fpspc")
14952    (set_attr "mode" "XF")
14953    (set_attr "athlon_decode" "direct")])
14954
14955 (define_insn "fpremxf4"
14956   [(set (match_operand:XF 0 "register_operand" "=f")
14957         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14958                     (match_operand:XF 3 "register_operand" "1")]
14959                    UNSPEC_FPREM_F))
14960    (set (match_operand:XF 1 "register_operand" "=u")
14961         (unspec:XF [(match_dup 2) (match_dup 3)]
14962                    UNSPEC_FPREM_U))
14963    (set (reg:CCFP FPSR_REG)
14964         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fprem"
14968   [(set_attr "type" "fpspc")
14969    (set_attr "mode" "XF")])
14970
14971 (define_expand "fmodsf3"
14972   [(use (match_operand:SF 0 "register_operand" ""))
14973    (use (match_operand:SF 1 "register_operand" ""))
14974    (use (match_operand:SF 2 "register_operand" ""))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14977    && flag_unsafe_math_optimizations"
14978 {
14979   rtx label = gen_label_rtx ();
14980
14981   rtx op1 = gen_reg_rtx (XFmode);
14982   rtx op2 = gen_reg_rtx (XFmode);
14983
14984   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14985   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14986
14987   emit_label (label);
14988
14989   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14990   ix86_emit_fp_unordered_jump (label);
14991
14992   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14993   DONE;
14994 })
14995
14996 (define_expand "fmoddf3"
14997   [(use (match_operand:DF 0 "register_operand" ""))
14998    (use (match_operand:DF 1 "register_operand" ""))
14999    (use (match_operand:DF 2 "register_operand" ""))]
15000   "TARGET_USE_FANCY_MATH_387
15001    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15002    && flag_unsafe_math_optimizations"
15003 {
15004   rtx label = gen_label_rtx ();
15005
15006   rtx op1 = gen_reg_rtx (XFmode);
15007   rtx op2 = gen_reg_rtx (XFmode);
15008
15009   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15010   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15011
15012   emit_label (label);
15013
15014   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15015   ix86_emit_fp_unordered_jump (label);
15016
15017   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15018   DONE;
15019 })
15020
15021 (define_expand "fmodxf3"
15022   [(use (match_operand:XF 0 "register_operand" ""))
15023    (use (match_operand:XF 1 "register_operand" ""))
15024    (use (match_operand:XF 2 "register_operand" ""))]
15025   "TARGET_USE_FANCY_MATH_387
15026    && flag_unsafe_math_optimizations"
15027 {
15028   rtx label = gen_label_rtx ();
15029
15030   emit_label (label);
15031
15032   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15033                            operands[1], operands[2]));
15034   ix86_emit_fp_unordered_jump (label);
15035
15036   emit_move_insn (operands[0], operands[1]);
15037   DONE;
15038 })
15039
15040 (define_insn "fprem1xf4"
15041   [(set (match_operand:XF 0 "register_operand" "=f")
15042         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15043                     (match_operand:XF 3 "register_operand" "1")]
15044                    UNSPEC_FPREM1_F))
15045    (set (match_operand:XF 1 "register_operand" "=u")
15046         (unspec:XF [(match_dup 2) (match_dup 3)]
15047                    UNSPEC_FPREM1_U))
15048    (set (reg:CCFP FPSR_REG)
15049         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15050   "TARGET_USE_FANCY_MATH_387
15051    && flag_unsafe_math_optimizations"
15052   "fprem1"
15053   [(set_attr "type" "fpspc")
15054    (set_attr "mode" "XF")])
15055
15056 (define_expand "dremsf3"
15057   [(use (match_operand:SF 0 "register_operand" ""))
15058    (use (match_operand:SF 1 "register_operand" ""))
15059    (use (match_operand:SF 2 "register_operand" ""))]
15060   "TARGET_USE_FANCY_MATH_387
15061    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15062    && flag_unsafe_math_optimizations"
15063 {
15064   rtx label = gen_label_rtx ();
15065
15066   rtx op1 = gen_reg_rtx (XFmode);
15067   rtx op2 = gen_reg_rtx (XFmode);
15068
15069   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15070   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15071
15072   emit_label (label);
15073
15074   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15075   ix86_emit_fp_unordered_jump (label);
15076
15077   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15078   DONE;
15079 })
15080
15081 (define_expand "dremdf3"
15082   [(use (match_operand:DF 0 "register_operand" ""))
15083    (use (match_operand:DF 1 "register_operand" ""))
15084    (use (match_operand:DF 2 "register_operand" ""))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15087    && flag_unsafe_math_optimizations"
15088 {
15089   rtx label = gen_label_rtx ();
15090
15091   rtx op1 = gen_reg_rtx (XFmode);
15092   rtx op2 = gen_reg_rtx (XFmode);
15093
15094   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15095   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15096
15097   emit_label (label);
15098
15099   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15100   ix86_emit_fp_unordered_jump (label);
15101
15102   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15103   DONE;
15104 })
15105
15106 (define_expand "dremxf3"
15107   [(use (match_operand:XF 0 "register_operand" ""))
15108    (use (match_operand:XF 1 "register_operand" ""))
15109    (use (match_operand:XF 2 "register_operand" ""))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && flag_unsafe_math_optimizations"
15112 {
15113   rtx label = gen_label_rtx ();
15114
15115   emit_label (label);
15116
15117   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15118                             operands[1], operands[2]));
15119   ix86_emit_fp_unordered_jump (label);
15120
15121   emit_move_insn (operands[0], operands[1]);
15122   DONE;
15123 })
15124
15125 (define_insn "*sindf2"
15126   [(set (match_operand:DF 0 "register_operand" "=f")
15127         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15128   "TARGET_USE_FANCY_MATH_387
15129    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15130    && flag_unsafe_math_optimizations"
15131   "fsin"
15132   [(set_attr "type" "fpspc")
15133    (set_attr "mode" "DF")])
15134
15135 (define_insn "*sinsf2"
15136   [(set (match_operand:SF 0 "register_operand" "=f")
15137         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15138   "TARGET_USE_FANCY_MATH_387
15139    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15140    && flag_unsafe_math_optimizations"
15141   "fsin"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "SF")])
15144
15145 (define_insn "*sinextendsfdf2"
15146   [(set (match_operand:DF 0 "register_operand" "=f")
15147         (unspec:DF [(float_extend:DF
15148                      (match_operand:SF 1 "register_operand" "0"))]
15149                    UNSPEC_SIN))]
15150   "TARGET_USE_FANCY_MATH_387
15151    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15153   "fsin"
15154   [(set_attr "type" "fpspc")
15155    (set_attr "mode" "DF")])
15156
15157 (define_insn "*sinxf2"
15158   [(set (match_operand:XF 0 "register_operand" "=f")
15159         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15160   "TARGET_USE_FANCY_MATH_387
15161    && flag_unsafe_math_optimizations"
15162   "fsin"
15163   [(set_attr "type" "fpspc")
15164    (set_attr "mode" "XF")])
15165
15166 (define_insn "*cosdf2"
15167   [(set (match_operand:DF 0 "register_operand" "=f")
15168         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15169   "TARGET_USE_FANCY_MATH_387
15170    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15171    && flag_unsafe_math_optimizations"
15172   "fcos"
15173   [(set_attr "type" "fpspc")
15174    (set_attr "mode" "DF")])
15175
15176 (define_insn "*cossf2"
15177   [(set (match_operand:SF 0 "register_operand" "=f")
15178         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15179   "TARGET_USE_FANCY_MATH_387
15180    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "SF")])
15185
15186 (define_insn "*cosextendsfdf2"
15187   [(set (match_operand:DF 0 "register_operand" "=f")
15188         (unspec:DF [(float_extend:DF
15189                      (match_operand:SF 1 "register_operand" "0"))]
15190                    UNSPEC_COS))]
15191   "TARGET_USE_FANCY_MATH_387
15192    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15193    && flag_unsafe_math_optimizations"
15194   "fcos"
15195   [(set_attr "type" "fpspc")
15196    (set_attr "mode" "DF")])
15197
15198 (define_insn "*cosxf2"
15199   [(set (match_operand:XF 0 "register_operand" "=f")
15200         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15201   "TARGET_USE_FANCY_MATH_387
15202    && flag_unsafe_math_optimizations"
15203   "fcos"
15204   [(set_attr "type" "fpspc")
15205    (set_attr "mode" "XF")])
15206
15207 ;; With sincos pattern defined, sin and cos builtin function will be
15208 ;; expanded to sincos pattern with one of its outputs left unused. 
15209 ;; Cse pass  will detected, if two sincos patterns can be combined,
15210 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15211 ;; depending on the unused output.
15212
15213 (define_insn "sincosdf3"
15214   [(set (match_operand:DF 0 "register_operand" "=f")
15215         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15216                    UNSPEC_SINCOS_COS))
15217    (set (match_operand:DF 1 "register_operand" "=u")
15218         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15221    && flag_unsafe_math_optimizations"
15222   "fsincos"
15223   [(set_attr "type" "fpspc")
15224    (set_attr "mode" "DF")])
15225
15226 (define_split
15227   [(set (match_operand:DF 0 "register_operand" "")
15228         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15229                    UNSPEC_SINCOS_COS))
15230    (set (match_operand:DF 1 "register_operand" "")
15231         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15232   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15233    && !reload_completed && !reload_in_progress"
15234   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15235   "")
15236
15237 (define_split
15238   [(set (match_operand:DF 0 "register_operand" "")
15239         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15240                    UNSPEC_SINCOS_COS))
15241    (set (match_operand:DF 1 "register_operand" "")
15242         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15243   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15244    && !reload_completed && !reload_in_progress"
15245   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15246   "")
15247
15248 (define_insn "sincossf3"
15249   [(set (match_operand:SF 0 "register_operand" "=f")
15250         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15251                    UNSPEC_SINCOS_COS))
15252    (set (match_operand:SF 1 "register_operand" "=u")
15253         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15254   "TARGET_USE_FANCY_MATH_387
15255    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15256    && flag_unsafe_math_optimizations"
15257   "fsincos"
15258   [(set_attr "type" "fpspc")
15259    (set_attr "mode" "SF")])
15260
15261 (define_split
15262   [(set (match_operand:SF 0 "register_operand" "")
15263         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15264                    UNSPEC_SINCOS_COS))
15265    (set (match_operand:SF 1 "register_operand" "")
15266         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15267   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15268    && !reload_completed && !reload_in_progress"
15269   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15270   "")
15271
15272 (define_split
15273   [(set (match_operand:SF 0 "register_operand" "")
15274         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15275                    UNSPEC_SINCOS_COS))
15276    (set (match_operand:SF 1 "register_operand" "")
15277         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15278   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15279    && !reload_completed && !reload_in_progress"
15280   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15281   "")
15282
15283 (define_insn "*sincosextendsfdf3"
15284   [(set (match_operand:DF 0 "register_operand" "=f")
15285         (unspec:DF [(float_extend:DF
15286                      (match_operand:SF 2 "register_operand" "0"))]
15287                    UNSPEC_SINCOS_COS))
15288    (set (match_operand:DF 1 "register_operand" "=u")
15289         (unspec:DF [(float_extend:DF
15290                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15291   "TARGET_USE_FANCY_MATH_387
15292    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15293    && flag_unsafe_math_optimizations"
15294   "fsincos"
15295   [(set_attr "type" "fpspc")
15296    (set_attr "mode" "DF")])
15297
15298 (define_split
15299   [(set (match_operand:DF 0 "register_operand" "")
15300         (unspec:DF [(float_extend:DF
15301                      (match_operand:SF 2 "register_operand" ""))]
15302                    UNSPEC_SINCOS_COS))
15303    (set (match_operand:DF 1 "register_operand" "")
15304         (unspec:DF [(float_extend:DF
15305                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15306   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15307    && !reload_completed && !reload_in_progress"
15308   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15309                                    (match_dup 2))] UNSPEC_SIN))]
15310   "")
15311
15312 (define_split
15313   [(set (match_operand:DF 0 "register_operand" "")
15314         (unspec:DF [(float_extend:DF
15315                      (match_operand:SF 2 "register_operand" ""))]
15316                    UNSPEC_SINCOS_COS))
15317    (set (match_operand:DF 1 "register_operand" "")
15318         (unspec:DF [(float_extend:DF
15319                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15320   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15321    && !reload_completed && !reload_in_progress"
15322   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15323                                    (match_dup 2))] UNSPEC_COS))]
15324   "")
15325
15326 (define_insn "sincosxf3"
15327   [(set (match_operand:XF 0 "register_operand" "=f")
15328         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15329                    UNSPEC_SINCOS_COS))
15330    (set (match_operand:XF 1 "register_operand" "=u")
15331         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15332   "TARGET_USE_FANCY_MATH_387
15333    && flag_unsafe_math_optimizations"
15334   "fsincos"
15335   [(set_attr "type" "fpspc")
15336    (set_attr "mode" "XF")])
15337
15338 (define_split
15339   [(set (match_operand:XF 0 "register_operand" "")
15340         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15341                    UNSPEC_SINCOS_COS))
15342    (set (match_operand:XF 1 "register_operand" "")
15343         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15344   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15345    && !reload_completed && !reload_in_progress"
15346   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15347   "")
15348
15349 (define_split
15350   [(set (match_operand:XF 0 "register_operand" "")
15351         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15352                    UNSPEC_SINCOS_COS))
15353    (set (match_operand:XF 1 "register_operand" "")
15354         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15355   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15356    && !reload_completed && !reload_in_progress"
15357   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15358   "")
15359
15360 (define_insn "*tandf3_1"
15361   [(set (match_operand:DF 0 "register_operand" "=f")
15362         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15363                    UNSPEC_TAN_ONE))
15364    (set (match_operand:DF 1 "register_operand" "=u")
15365         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15366   "TARGET_USE_FANCY_MATH_387
15367    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15368    && flag_unsafe_math_optimizations"
15369   "fptan"
15370   [(set_attr "type" "fpspc")
15371    (set_attr "mode" "DF")])
15372
15373 ;; optimize sequence: fptan
15374 ;;                    fstp    %st(0)
15375 ;;                    fld1
15376 ;; into fptan insn.
15377
15378 (define_peephole2
15379   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15380                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15381                              UNSPEC_TAN_ONE))
15382              (set (match_operand:DF 1 "register_operand" "")
15383                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15384    (set (match_dup 0)
15385         (match_operand:DF 3 "immediate_operand" ""))]
15386   "standard_80387_constant_p (operands[3]) == 2"
15387   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15388              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15389   "")
15390
15391 (define_expand "tandf2"
15392   [(parallel [(set (match_dup 2)
15393                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15394                               UNSPEC_TAN_ONE))
15395               (set (match_operand:DF 0 "register_operand" "")
15396                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15397   "TARGET_USE_FANCY_MATH_387
15398    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15399    && flag_unsafe_math_optimizations"
15400 {
15401   operands[2] = gen_reg_rtx (DFmode);
15402 })
15403
15404 (define_insn "*tansf3_1"
15405   [(set (match_operand:SF 0 "register_operand" "=f")
15406         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15407                    UNSPEC_TAN_ONE))
15408    (set (match_operand:SF 1 "register_operand" "=u")
15409         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15410   "TARGET_USE_FANCY_MATH_387
15411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15412    && flag_unsafe_math_optimizations"
15413   "fptan"
15414   [(set_attr "type" "fpspc")
15415    (set_attr "mode" "SF")])
15416
15417 ;; optimize sequence: fptan
15418 ;;                    fstp    %st(0)
15419 ;;                    fld1
15420 ;; into fptan insn.
15421
15422 (define_peephole2
15423   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15424                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15425                              UNSPEC_TAN_ONE))
15426              (set (match_operand:SF 1 "register_operand" "")
15427                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15428    (set (match_dup 0)
15429         (match_operand:SF 3 "immediate_operand" ""))]
15430   "standard_80387_constant_p (operands[3]) == 2"
15431   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15432              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15433   "")
15434
15435 (define_expand "tansf2"
15436   [(parallel [(set (match_dup 2)
15437                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15438                               UNSPEC_TAN_ONE))
15439               (set (match_operand:SF 0 "register_operand" "")
15440                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15441   "TARGET_USE_FANCY_MATH_387
15442    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15443    && flag_unsafe_math_optimizations"
15444 {
15445   operands[2] = gen_reg_rtx (SFmode);
15446 })
15447
15448 (define_insn "*tanxf3_1"
15449   [(set (match_operand:XF 0 "register_operand" "=f")
15450         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15451                    UNSPEC_TAN_ONE))
15452    (set (match_operand:XF 1 "register_operand" "=u")
15453         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15454   "TARGET_USE_FANCY_MATH_387
15455    && flag_unsafe_math_optimizations"
15456   "fptan"
15457   [(set_attr "type" "fpspc")
15458    (set_attr "mode" "XF")])
15459
15460 ;; optimize sequence: fptan
15461 ;;                    fstp    %st(0)
15462 ;;                    fld1
15463 ;; into fptan insn.
15464
15465 (define_peephole2
15466   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15467                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15468                              UNSPEC_TAN_ONE))
15469              (set (match_operand:XF 1 "register_operand" "")
15470                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15471    (set (match_dup 0)
15472         (match_operand:XF 3 "immediate_operand" ""))]
15473   "standard_80387_constant_p (operands[3]) == 2"
15474   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15475              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15476   "")
15477
15478 (define_expand "tanxf2"
15479   [(parallel [(set (match_dup 2)
15480                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15481                               UNSPEC_TAN_ONE))
15482               (set (match_operand:XF 0 "register_operand" "")
15483                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15484   "TARGET_USE_FANCY_MATH_387
15485    && flag_unsafe_math_optimizations"
15486 {
15487   operands[2] = gen_reg_rtx (XFmode);
15488 })
15489
15490 (define_insn "atan2df3_1"
15491   [(set (match_operand:DF 0 "register_operand" "=f")
15492         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15493                     (match_operand:DF 1 "register_operand" "u")]
15494                    UNSPEC_FPATAN))
15495    (clobber (match_scratch:DF 3 "=1"))]
15496   "TARGET_USE_FANCY_MATH_387
15497    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15498    && flag_unsafe_math_optimizations"
15499   "fpatan"
15500   [(set_attr "type" "fpspc")
15501    (set_attr "mode" "DF")])
15502
15503 (define_expand "atan2df3"
15504   [(use (match_operand:DF 0 "register_operand" ""))
15505    (use (match_operand:DF 2 "register_operand" ""))
15506    (use (match_operand:DF 1 "register_operand" ""))]
15507   "TARGET_USE_FANCY_MATH_387
15508    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15509    && flag_unsafe_math_optimizations"
15510 {
15511   rtx copy = gen_reg_rtx (DFmode);
15512   emit_move_insn (copy, operands[1]);
15513   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15514   DONE;
15515 })
15516
15517 (define_expand "atandf2"
15518   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15519                    (unspec:DF [(match_dup 2)
15520                                (match_operand:DF 1 "register_operand" "")]
15521                     UNSPEC_FPATAN))
15522               (clobber (match_scratch:DF 3 ""))])]
15523   "TARGET_USE_FANCY_MATH_387
15524    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15525    && flag_unsafe_math_optimizations"
15526 {
15527   operands[2] = gen_reg_rtx (DFmode);
15528   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15529 })
15530
15531 (define_insn "atan2sf3_1"
15532   [(set (match_operand:SF 0 "register_operand" "=f")
15533         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15534                     (match_operand:SF 1 "register_operand" "u")]
15535                    UNSPEC_FPATAN))
15536    (clobber (match_scratch:SF 3 "=1"))]
15537   "TARGET_USE_FANCY_MATH_387
15538    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15539    && flag_unsafe_math_optimizations"
15540   "fpatan"
15541   [(set_attr "type" "fpspc")
15542    (set_attr "mode" "SF")])
15543
15544 (define_expand "atan2sf3"
15545   [(use (match_operand:SF 0 "register_operand" ""))
15546    (use (match_operand:SF 2 "register_operand" ""))
15547    (use (match_operand:SF 1 "register_operand" ""))]
15548   "TARGET_USE_FANCY_MATH_387
15549    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15550    && flag_unsafe_math_optimizations"
15551 {
15552   rtx copy = gen_reg_rtx (SFmode);
15553   emit_move_insn (copy, operands[1]);
15554   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15555   DONE;
15556 })
15557
15558 (define_expand "atansf2"
15559   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15560                    (unspec:SF [(match_dup 2)
15561                                (match_operand:SF 1 "register_operand" "")]
15562                     UNSPEC_FPATAN))
15563               (clobber (match_scratch:SF 3 ""))])]
15564   "TARGET_USE_FANCY_MATH_387
15565    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15566    && flag_unsafe_math_optimizations"
15567 {
15568   operands[2] = gen_reg_rtx (SFmode);
15569   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15570 })
15571
15572 (define_insn "atan2xf3_1"
15573   [(set (match_operand:XF 0 "register_operand" "=f")
15574         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15575                     (match_operand:XF 1 "register_operand" "u")]
15576                    UNSPEC_FPATAN))
15577    (clobber (match_scratch:XF 3 "=1"))]
15578   "TARGET_USE_FANCY_MATH_387
15579    && flag_unsafe_math_optimizations"
15580   "fpatan"
15581   [(set_attr "type" "fpspc")
15582    (set_attr "mode" "XF")])
15583
15584 (define_expand "atan2xf3"
15585   [(use (match_operand:XF 0 "register_operand" ""))
15586    (use (match_operand:XF 2 "register_operand" ""))
15587    (use (match_operand:XF 1 "register_operand" ""))]
15588   "TARGET_USE_FANCY_MATH_387
15589    && flag_unsafe_math_optimizations"
15590 {
15591   rtx copy = gen_reg_rtx (XFmode);
15592   emit_move_insn (copy, operands[1]);
15593   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15594   DONE;
15595 })
15596
15597 (define_expand "atanxf2"
15598   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15599                    (unspec:XF [(match_dup 2)
15600                                (match_operand:XF 1 "register_operand" "")]
15601                     UNSPEC_FPATAN))
15602               (clobber (match_scratch:XF 3 ""))])]
15603   "TARGET_USE_FANCY_MATH_387
15604    && flag_unsafe_math_optimizations"
15605 {
15606   operands[2] = gen_reg_rtx (XFmode);
15607   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15608 })
15609
15610 (define_expand "asindf2"
15611   [(set (match_dup 2)
15612         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15613    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15614    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15615    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15616    (parallel [(set (match_dup 7)
15617                    (unspec:XF [(match_dup 6) (match_dup 2)]
15618                               UNSPEC_FPATAN))
15619               (clobber (match_scratch:XF 8 ""))])
15620    (set (match_operand:DF 0 "register_operand" "")
15621         (float_truncate:DF (match_dup 7)))]
15622   "TARGET_USE_FANCY_MATH_387
15623    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15624    && flag_unsafe_math_optimizations"
15625 {
15626   int i;
15627
15628   for (i=2; i<8; i++)
15629     operands[i] = gen_reg_rtx (XFmode);
15630
15631   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15632 })
15633
15634 (define_expand "asinsf2"
15635   [(set (match_dup 2)
15636         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15637    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15638    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15639    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15640    (parallel [(set (match_dup 7)
15641                    (unspec:XF [(match_dup 6) (match_dup 2)]
15642                               UNSPEC_FPATAN))
15643               (clobber (match_scratch:XF 8 ""))])
15644    (set (match_operand:SF 0 "register_operand" "")
15645         (float_truncate:SF (match_dup 7)))]
15646   "TARGET_USE_FANCY_MATH_387
15647    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15648    && flag_unsafe_math_optimizations"
15649 {
15650   int i;
15651
15652   for (i=2; i<8; i++)
15653     operands[i] = gen_reg_rtx (XFmode);
15654
15655   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15656 })
15657
15658 (define_expand "asinxf2"
15659   [(set (match_dup 2)
15660         (mult:XF (match_operand:XF 1 "register_operand" "")
15661                  (match_dup 1)))
15662    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15663    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15664    (parallel [(set (match_operand:XF 0 "register_operand" "")
15665                    (unspec:XF [(match_dup 5) (match_dup 1)]
15666                               UNSPEC_FPATAN))
15667               (clobber (match_scratch:XF 6 ""))])]
15668   "TARGET_USE_FANCY_MATH_387
15669    && flag_unsafe_math_optimizations"
15670 {
15671   int i;
15672
15673   for (i=2; i<6; i++)
15674     operands[i] = gen_reg_rtx (XFmode);
15675
15676   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15677 })
15678
15679 (define_expand "acosdf2"
15680   [(set (match_dup 2)
15681         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15682    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15683    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15684    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15685    (parallel [(set (match_dup 7)
15686                    (unspec:XF [(match_dup 2) (match_dup 6)]
15687                               UNSPEC_FPATAN))
15688               (clobber (match_scratch:XF 8 ""))])
15689    (set (match_operand:DF 0 "register_operand" "")
15690         (float_truncate:DF (match_dup 7)))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15693    && flag_unsafe_math_optimizations"
15694 {
15695   int i;
15696
15697   for (i=2; i<8; i++)
15698     operands[i] = gen_reg_rtx (XFmode);
15699
15700   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15701 })
15702
15703 (define_expand "acossf2"
15704   [(set (match_dup 2)
15705         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15706    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15707    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15708    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15709    (parallel [(set (match_dup 7)
15710                    (unspec:XF [(match_dup 2) (match_dup 6)]
15711                               UNSPEC_FPATAN))
15712               (clobber (match_scratch:XF 8 ""))])
15713    (set (match_operand:SF 0 "register_operand" "")
15714         (float_truncate:SF (match_dup 7)))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15717    && flag_unsafe_math_optimizations"
15718 {
15719   int i;
15720
15721   for (i=2; i<8; i++)
15722     operands[i] = gen_reg_rtx (XFmode);
15723
15724   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15725 })
15726
15727 (define_expand "acosxf2"
15728   [(set (match_dup 2)
15729         (mult:XF (match_operand:XF 1 "register_operand" "")
15730                  (match_dup 1)))
15731    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15732    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15733    (parallel [(set (match_operand:XF 0 "register_operand" "")
15734                    (unspec:XF [(match_dup 1) (match_dup 5)]
15735                               UNSPEC_FPATAN))
15736               (clobber (match_scratch:XF 6 ""))])]
15737   "TARGET_USE_FANCY_MATH_387
15738    && flag_unsafe_math_optimizations"
15739 {
15740   int i;
15741
15742   for (i=2; i<6; i++)
15743     operands[i] = gen_reg_rtx (XFmode);
15744
15745   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15746 })
15747
15748 (define_insn "fyl2x_xf3"
15749   [(set (match_operand:XF 0 "register_operand" "=f")
15750         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15751                     (match_operand:XF 1 "register_operand" "u")]
15752                    UNSPEC_FYL2X))
15753    (clobber (match_scratch:XF 3 "=1"))]
15754   "TARGET_USE_FANCY_MATH_387
15755    && flag_unsafe_math_optimizations"
15756   "fyl2x"
15757   [(set_attr "type" "fpspc")
15758    (set_attr "mode" "XF")])
15759
15760 (define_expand "logsf2"
15761   [(set (match_dup 2)
15762         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15763    (parallel [(set (match_dup 4)
15764                    (unspec:XF [(match_dup 2)
15765                                (match_dup 3)] UNSPEC_FYL2X))
15766               (clobber (match_scratch:XF 5 ""))])
15767    (set (match_operand:SF 0 "register_operand" "")
15768         (float_truncate:SF (match_dup 4)))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15771    && flag_unsafe_math_optimizations"
15772 {
15773   rtx temp;
15774
15775   operands[2] = gen_reg_rtx (XFmode);
15776   operands[3] = gen_reg_rtx (XFmode);
15777   operands[4] = gen_reg_rtx (XFmode);
15778
15779   temp = standard_80387_constant_rtx (4); /* fldln2 */
15780   emit_move_insn (operands[3], temp);
15781 })
15782
15783 (define_expand "logdf2"
15784   [(set (match_dup 2)
15785         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15786    (parallel [(set (match_dup 4)
15787                    (unspec:XF [(match_dup 2)
15788                                (match_dup 3)] UNSPEC_FYL2X))
15789               (clobber (match_scratch:XF 5 ""))])
15790    (set (match_operand:DF 0 "register_operand" "")
15791         (float_truncate:DF (match_dup 4)))]
15792   "TARGET_USE_FANCY_MATH_387
15793    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15794    && flag_unsafe_math_optimizations"
15795 {
15796   rtx temp;
15797
15798   operands[2] = gen_reg_rtx (XFmode);
15799   operands[3] = gen_reg_rtx (XFmode);
15800   operands[4] = gen_reg_rtx (XFmode);
15801
15802   temp = standard_80387_constant_rtx (4); /* fldln2 */
15803   emit_move_insn (operands[3], temp);
15804 })
15805
15806 (define_expand "logxf2"
15807   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15808                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15809                                (match_dup 2)] UNSPEC_FYL2X))
15810               (clobber (match_scratch:XF 3 ""))])]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813 {
15814   rtx temp;
15815
15816   operands[2] = gen_reg_rtx (XFmode);
15817   temp = standard_80387_constant_rtx (4); /* fldln2 */
15818   emit_move_insn (operands[2], temp);
15819 })
15820
15821 (define_expand "log10sf2"
15822   [(set (match_dup 2)
15823         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15824    (parallel [(set (match_dup 4)
15825                    (unspec:XF [(match_dup 2)
15826                                (match_dup 3)] UNSPEC_FYL2X))
15827               (clobber (match_scratch:XF 5 ""))])
15828    (set (match_operand:SF 0 "register_operand" "")
15829         (float_truncate:SF (match_dup 4)))]
15830   "TARGET_USE_FANCY_MATH_387
15831    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15832    && flag_unsafe_math_optimizations"
15833 {
15834   rtx temp;
15835
15836   operands[2] = gen_reg_rtx (XFmode);
15837   operands[3] = gen_reg_rtx (XFmode);
15838   operands[4] = gen_reg_rtx (XFmode);
15839
15840   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15841   emit_move_insn (operands[3], temp);
15842 })
15843
15844 (define_expand "log10df2"
15845   [(set (match_dup 2)
15846         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15847    (parallel [(set (match_dup 4)
15848                    (unspec:XF [(match_dup 2)
15849                                (match_dup 3)] UNSPEC_FYL2X))
15850               (clobber (match_scratch:XF 5 ""))])
15851    (set (match_operand:DF 0 "register_operand" "")
15852         (float_truncate:DF (match_dup 4)))]
15853   "TARGET_USE_FANCY_MATH_387
15854    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15855    && flag_unsafe_math_optimizations"
15856 {
15857   rtx temp;
15858
15859   operands[2] = gen_reg_rtx (XFmode);
15860   operands[3] = gen_reg_rtx (XFmode);
15861   operands[4] = gen_reg_rtx (XFmode);
15862
15863   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15864   emit_move_insn (operands[3], temp);
15865 })
15866
15867 (define_expand "log10xf2"
15868   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15869                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15870                                (match_dup 2)] UNSPEC_FYL2X))
15871               (clobber (match_scratch:XF 3 ""))])]
15872   "TARGET_USE_FANCY_MATH_387
15873    && flag_unsafe_math_optimizations"
15874 {
15875   rtx temp;
15876
15877   operands[2] = gen_reg_rtx (XFmode);
15878   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15879   emit_move_insn (operands[2], temp);
15880 })
15881
15882 (define_expand "log2sf2"
15883   [(set (match_dup 2)
15884         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15885    (parallel [(set (match_dup 4)
15886                    (unspec:XF [(match_dup 2)
15887                                (match_dup 3)] UNSPEC_FYL2X))
15888               (clobber (match_scratch:XF 5 ""))])
15889    (set (match_operand:SF 0 "register_operand" "")
15890         (float_truncate:SF (match_dup 4)))]
15891   "TARGET_USE_FANCY_MATH_387
15892    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15893    && flag_unsafe_math_optimizations"
15894 {
15895   operands[2] = gen_reg_rtx (XFmode);
15896   operands[3] = gen_reg_rtx (XFmode);
15897   operands[4] = gen_reg_rtx (XFmode);
15898
15899   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15900 })
15901
15902 (define_expand "log2df2"
15903   [(set (match_dup 2)
15904         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15905    (parallel [(set (match_dup 4)
15906                    (unspec:XF [(match_dup 2)
15907                                (match_dup 3)] UNSPEC_FYL2X))
15908               (clobber (match_scratch:XF 5 ""))])
15909    (set (match_operand:DF 0 "register_operand" "")
15910         (float_truncate:DF (match_dup 4)))]
15911   "TARGET_USE_FANCY_MATH_387
15912    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15913    && flag_unsafe_math_optimizations"
15914 {
15915   operands[2] = gen_reg_rtx (XFmode);
15916   operands[3] = gen_reg_rtx (XFmode);
15917   operands[4] = gen_reg_rtx (XFmode);
15918
15919   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15920 })
15921
15922 (define_expand "log2xf2"
15923   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15924                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15925                                (match_dup 2)] UNSPEC_FYL2X))
15926               (clobber (match_scratch:XF 3 ""))])]
15927   "TARGET_USE_FANCY_MATH_387
15928    && flag_unsafe_math_optimizations"
15929 {
15930   operands[2] = gen_reg_rtx (XFmode);
15931   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15932 })
15933
15934 (define_insn "fyl2xp1_xf3"
15935   [(set (match_operand:XF 0 "register_operand" "=f")
15936         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15937                     (match_operand:XF 1 "register_operand" "u")]
15938                    UNSPEC_FYL2XP1))
15939    (clobber (match_scratch:XF 3 "=1"))]
15940   "TARGET_USE_FANCY_MATH_387
15941    && flag_unsafe_math_optimizations"
15942   "fyl2xp1"
15943   [(set_attr "type" "fpspc")
15944    (set_attr "mode" "XF")])
15945
15946 (define_expand "log1psf2"
15947   [(use (match_operand:SF 0 "register_operand" ""))
15948    (use (match_operand:SF 1 "register_operand" ""))]
15949   "TARGET_USE_FANCY_MATH_387
15950    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15951    && flag_unsafe_math_optimizations"
15952 {
15953   rtx op0 = gen_reg_rtx (XFmode);
15954   rtx op1 = gen_reg_rtx (XFmode);
15955
15956   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15957   ix86_emit_i387_log1p (op0, op1);
15958   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15959   DONE;
15960 })
15961
15962 (define_expand "log1pdf2"
15963   [(use (match_operand:DF 0 "register_operand" ""))
15964    (use (match_operand:DF 1 "register_operand" ""))]
15965   "TARGET_USE_FANCY_MATH_387
15966    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15967    && flag_unsafe_math_optimizations"
15968 {
15969   rtx op0 = gen_reg_rtx (XFmode);
15970   rtx op1 = gen_reg_rtx (XFmode);
15971
15972   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15973   ix86_emit_i387_log1p (op0, op1);
15974   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15975   DONE;
15976 })
15977
15978 (define_expand "log1pxf2"
15979   [(use (match_operand:XF 0 "register_operand" ""))
15980    (use (match_operand:XF 1 "register_operand" ""))]
15981   "TARGET_USE_FANCY_MATH_387
15982    && flag_unsafe_math_optimizations"
15983 {
15984   ix86_emit_i387_log1p (operands[0], operands[1]);
15985   DONE;
15986 })
15987
15988 (define_insn "*fxtractxf3"
15989   [(set (match_operand:XF 0 "register_operand" "=f")
15990         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15991                    UNSPEC_XTRACT_FRACT))
15992    (set (match_operand:XF 1 "register_operand" "=u")
15993         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15994   "TARGET_USE_FANCY_MATH_387
15995    && flag_unsafe_math_optimizations"
15996   "fxtract"
15997   [(set_attr "type" "fpspc")
15998    (set_attr "mode" "XF")])
15999
16000 (define_expand "logbsf2"
16001   [(set (match_dup 2)
16002         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16003    (parallel [(set (match_dup 3)
16004                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16005               (set (match_dup 4)
16006                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16007    (set (match_operand:SF 0 "register_operand" "")
16008         (float_truncate:SF (match_dup 4)))]
16009   "TARGET_USE_FANCY_MATH_387
16010    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16011    && flag_unsafe_math_optimizations"
16012 {
16013   operands[2] = gen_reg_rtx (XFmode);
16014   operands[3] = gen_reg_rtx (XFmode);
16015   operands[4] = gen_reg_rtx (XFmode);
16016 })
16017
16018 (define_expand "logbdf2"
16019   [(set (match_dup 2)
16020         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16021    (parallel [(set (match_dup 3)
16022                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16023               (set (match_dup 4)
16024                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16025    (set (match_operand:DF 0 "register_operand" "")
16026         (float_truncate:DF (match_dup 4)))]
16027   "TARGET_USE_FANCY_MATH_387
16028    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16029    && flag_unsafe_math_optimizations"
16030 {
16031   operands[2] = gen_reg_rtx (XFmode);
16032   operands[3] = gen_reg_rtx (XFmode);
16033   operands[4] = gen_reg_rtx (XFmode);
16034 })
16035
16036 (define_expand "logbxf2"
16037   [(parallel [(set (match_dup 2)
16038                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16039                               UNSPEC_XTRACT_FRACT))
16040               (set (match_operand:XF 0 "register_operand" "")
16041                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16042   "TARGET_USE_FANCY_MATH_387
16043    && flag_unsafe_math_optimizations"
16044 {
16045   operands[2] = gen_reg_rtx (XFmode);
16046 })
16047
16048 (define_expand "ilogbsi2"
16049   [(parallel [(set (match_dup 2)
16050                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16051                               UNSPEC_XTRACT_FRACT))
16052               (set (match_operand:XF 3 "register_operand" "")
16053                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16054    (parallel [(set (match_operand:SI 0 "register_operand" "")
16055                    (fix:SI (match_dup 3)))
16056               (clobber (reg:CC FLAGS_REG))])]
16057   "TARGET_USE_FANCY_MATH_387
16058    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16059    && flag_unsafe_math_optimizations"
16060 {
16061   operands[2] = gen_reg_rtx (XFmode);
16062   operands[3] = gen_reg_rtx (XFmode);
16063 })
16064
16065 (define_insn "*f2xm1xf2"
16066   [(set (match_operand:XF 0 "register_operand" "=f")
16067         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16068          UNSPEC_F2XM1))]
16069   "TARGET_USE_FANCY_MATH_387
16070    && flag_unsafe_math_optimizations"
16071   "f2xm1"
16072   [(set_attr "type" "fpspc")
16073    (set_attr "mode" "XF")])
16074
16075 (define_insn "*fscalexf4"
16076   [(set (match_operand:XF 0 "register_operand" "=f")
16077         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16078                     (match_operand:XF 3 "register_operand" "1")]
16079                    UNSPEC_FSCALE_FRACT))
16080    (set (match_operand:XF 1 "register_operand" "=u")
16081         (unspec:XF [(match_dup 2) (match_dup 3)]
16082                    UNSPEC_FSCALE_EXP))]
16083   "TARGET_USE_FANCY_MATH_387
16084    && flag_unsafe_math_optimizations"
16085   "fscale"
16086   [(set_attr "type" "fpspc")
16087    (set_attr "mode" "XF")])
16088
16089 (define_expand "expsf2"
16090   [(set (match_dup 2)
16091         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16092    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16093    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16094    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16095    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16096    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16097    (parallel [(set (match_dup 10)
16098                    (unspec:XF [(match_dup 9) (match_dup 5)]
16099                               UNSPEC_FSCALE_FRACT))
16100               (set (match_dup 11)
16101                    (unspec:XF [(match_dup 9) (match_dup 5)]
16102                               UNSPEC_FSCALE_EXP))])
16103    (set (match_operand:SF 0 "register_operand" "")
16104         (float_truncate:SF (match_dup 10)))]
16105   "TARGET_USE_FANCY_MATH_387
16106    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16107    && flag_unsafe_math_optimizations"
16108 {
16109   rtx temp;
16110   int i;
16111
16112   for (i=2; i<12; i++)
16113     operands[i] = gen_reg_rtx (XFmode);
16114   temp = standard_80387_constant_rtx (5); /* fldl2e */
16115   emit_move_insn (operands[3], temp);
16116   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16117 })
16118
16119 (define_expand "expdf2"
16120   [(set (match_dup 2)
16121         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16122    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16123    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16124    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16125    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16126    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16127    (parallel [(set (match_dup 10)
16128                    (unspec:XF [(match_dup 9) (match_dup 5)]
16129                               UNSPEC_FSCALE_FRACT))
16130               (set (match_dup 11)
16131                    (unspec:XF [(match_dup 9) (match_dup 5)]
16132                               UNSPEC_FSCALE_EXP))])
16133    (set (match_operand:DF 0 "register_operand" "")
16134         (float_truncate:DF (match_dup 10)))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16137    && flag_unsafe_math_optimizations"
16138 {
16139   rtx temp;
16140   int i;
16141
16142   for (i=2; i<12; i++)
16143     operands[i] = gen_reg_rtx (XFmode);
16144   temp = standard_80387_constant_rtx (5); /* fldl2e */
16145   emit_move_insn (operands[3], temp);
16146   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16147 })
16148
16149 (define_expand "expxf2"
16150   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16151                                (match_dup 2)))
16152    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16153    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16154    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16155    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16156    (parallel [(set (match_operand:XF 0 "register_operand" "")
16157                    (unspec:XF [(match_dup 8) (match_dup 4)]
16158                               UNSPEC_FSCALE_FRACT))
16159               (set (match_dup 9)
16160                    (unspec:XF [(match_dup 8) (match_dup 4)]
16161                               UNSPEC_FSCALE_EXP))])]
16162   "TARGET_USE_FANCY_MATH_387
16163    && flag_unsafe_math_optimizations"
16164 {
16165   rtx temp;
16166   int i;
16167
16168   for (i=2; i<10; i++)
16169     operands[i] = gen_reg_rtx (XFmode);
16170   temp = standard_80387_constant_rtx (5); /* fldl2e */
16171   emit_move_insn (operands[2], temp);
16172   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16173 })
16174
16175 (define_expand "exp10sf2"
16176   [(set (match_dup 2)
16177         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16178    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16179    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16180    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16181    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16182    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16183    (parallel [(set (match_dup 10)
16184                    (unspec:XF [(match_dup 9) (match_dup 5)]
16185                               UNSPEC_FSCALE_FRACT))
16186               (set (match_dup 11)
16187                    (unspec:XF [(match_dup 9) (match_dup 5)]
16188                               UNSPEC_FSCALE_EXP))])
16189    (set (match_operand:SF 0 "register_operand" "")
16190         (float_truncate:SF (match_dup 10)))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16193    && flag_unsafe_math_optimizations"
16194 {
16195   rtx temp;
16196   int i;
16197
16198   for (i=2; i<12; i++)
16199     operands[i] = gen_reg_rtx (XFmode);
16200   temp = standard_80387_constant_rtx (6); /* fldl2t */
16201   emit_move_insn (operands[3], temp);
16202   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16203 })
16204
16205 (define_expand "exp10df2"
16206   [(set (match_dup 2)
16207         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16208    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16209    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16210    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16211    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16212    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16213    (parallel [(set (match_dup 10)
16214                    (unspec:XF [(match_dup 9) (match_dup 5)]
16215                               UNSPEC_FSCALE_FRACT))
16216               (set (match_dup 11)
16217                    (unspec:XF [(match_dup 9) (match_dup 5)]
16218                               UNSPEC_FSCALE_EXP))])
16219    (set (match_operand:DF 0 "register_operand" "")
16220         (float_truncate:DF (match_dup 10)))]
16221   "TARGET_USE_FANCY_MATH_387
16222    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16223    && flag_unsafe_math_optimizations"
16224 {
16225   rtx temp;
16226   int i;
16227
16228   for (i=2; i<12; i++)
16229     operands[i] = gen_reg_rtx (XFmode);
16230   temp = standard_80387_constant_rtx (6); /* fldl2t */
16231   emit_move_insn (operands[3], temp);
16232   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16233 })
16234
16235 (define_expand "exp10xf2"
16236   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16237                                (match_dup 2)))
16238    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16239    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16240    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16241    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16242    (parallel [(set (match_operand:XF 0 "register_operand" "")
16243                    (unspec:XF [(match_dup 8) (match_dup 4)]
16244                               UNSPEC_FSCALE_FRACT))
16245               (set (match_dup 9)
16246                    (unspec:XF [(match_dup 8) (match_dup 4)]
16247                               UNSPEC_FSCALE_EXP))])]
16248   "TARGET_USE_FANCY_MATH_387
16249    && flag_unsafe_math_optimizations"
16250 {
16251   rtx temp;
16252   int i;
16253
16254   for (i=2; i<10; i++)
16255     operands[i] = gen_reg_rtx (XFmode);
16256   temp = standard_80387_constant_rtx (6); /* fldl2t */
16257   emit_move_insn (operands[2], temp);
16258   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16259 })
16260
16261 (define_expand "exp2sf2"
16262   [(set (match_dup 2)
16263         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16264    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16265    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16266    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16267    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16268    (parallel [(set (match_dup 8)
16269                    (unspec:XF [(match_dup 7) (match_dup 3)]
16270                               UNSPEC_FSCALE_FRACT))
16271               (set (match_dup 9)
16272                    (unspec:XF [(match_dup 7) (match_dup 3)]
16273                               UNSPEC_FSCALE_EXP))])
16274    (set (match_operand:SF 0 "register_operand" "")
16275         (float_truncate:SF (match_dup 8)))]
16276   "TARGET_USE_FANCY_MATH_387
16277    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16278    && flag_unsafe_math_optimizations"
16279 {
16280   int i;
16281
16282   for (i=2; i<10; i++)
16283     operands[i] = gen_reg_rtx (XFmode);
16284   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16285 })
16286
16287 (define_expand "exp2df2"
16288   [(set (match_dup 2)
16289         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16290    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16291    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16292    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16293    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16294    (parallel [(set (match_dup 8)
16295                    (unspec:XF [(match_dup 7) (match_dup 3)]
16296                               UNSPEC_FSCALE_FRACT))
16297               (set (match_dup 9)
16298                    (unspec:XF [(match_dup 7) (match_dup 3)]
16299                               UNSPEC_FSCALE_EXP))])
16300    (set (match_operand:DF 0 "register_operand" "")
16301         (float_truncate:DF (match_dup 8)))]
16302   "TARGET_USE_FANCY_MATH_387
16303    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16304    && flag_unsafe_math_optimizations"
16305 {
16306   int i;
16307
16308   for (i=2; i<10; i++)
16309     operands[i] = gen_reg_rtx (XFmode);
16310   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16311 })
16312
16313 (define_expand "exp2xf2"
16314   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16315    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16316    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16317    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16318    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16319    (parallel [(set (match_operand:XF 0 "register_operand" "")
16320                    (unspec:XF [(match_dup 7) (match_dup 3)]
16321                               UNSPEC_FSCALE_FRACT))
16322               (set (match_dup 8)
16323                    (unspec:XF [(match_dup 7) (match_dup 3)]
16324                               UNSPEC_FSCALE_EXP))])]
16325   "TARGET_USE_FANCY_MATH_387
16326    && flag_unsafe_math_optimizations"
16327 {
16328   int i;
16329
16330   for (i=2; i<9; i++)
16331     operands[i] = gen_reg_rtx (XFmode);
16332   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16333 })
16334
16335 (define_expand "expm1df2"
16336   [(set (match_dup 2)
16337         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16338    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16339    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16340    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16341    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16342    (parallel [(set (match_dup 8)
16343                    (unspec:XF [(match_dup 7) (match_dup 5)]
16344                               UNSPEC_FSCALE_FRACT))
16345                    (set (match_dup 9)
16346                    (unspec:XF [(match_dup 7) (match_dup 5)]
16347                               UNSPEC_FSCALE_EXP))])
16348    (parallel [(set (match_dup 11)
16349                    (unspec:XF [(match_dup 10) (match_dup 9)]
16350                               UNSPEC_FSCALE_FRACT))
16351               (set (match_dup 12)
16352                    (unspec:XF [(match_dup 10) (match_dup 9)]
16353                               UNSPEC_FSCALE_EXP))])
16354    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16355    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16356    (set (match_operand:DF 0 "register_operand" "")
16357         (float_truncate:DF (match_dup 14)))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16360    && flag_unsafe_math_optimizations"
16361 {
16362   rtx temp;
16363   int i;
16364
16365   for (i=2; i<15; i++)
16366     operands[i] = gen_reg_rtx (XFmode);
16367   temp = standard_80387_constant_rtx (5); /* fldl2e */
16368   emit_move_insn (operands[3], temp);
16369   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16370 })
16371
16372 (define_expand "expm1sf2"
16373   [(set (match_dup 2)
16374         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16375    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16376    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16377    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16378    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16379    (parallel [(set (match_dup 8)
16380                    (unspec:XF [(match_dup 7) (match_dup 5)]
16381                               UNSPEC_FSCALE_FRACT))
16382                    (set (match_dup 9)
16383                    (unspec:XF [(match_dup 7) (match_dup 5)]
16384                               UNSPEC_FSCALE_EXP))])
16385    (parallel [(set (match_dup 11)
16386                    (unspec:XF [(match_dup 10) (match_dup 9)]
16387                               UNSPEC_FSCALE_FRACT))
16388               (set (match_dup 12)
16389                    (unspec:XF [(match_dup 10) (match_dup 9)]
16390                               UNSPEC_FSCALE_EXP))])
16391    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16392    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16393    (set (match_operand:SF 0 "register_operand" "")
16394         (float_truncate:SF (match_dup 14)))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16397    && flag_unsafe_math_optimizations"
16398 {
16399   rtx temp;
16400   int i;
16401
16402   for (i=2; i<15; i++)
16403     operands[i] = gen_reg_rtx (XFmode);
16404   temp = standard_80387_constant_rtx (5); /* fldl2e */
16405   emit_move_insn (operands[3], temp);
16406   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16407 })
16408
16409 (define_expand "expm1xf2"
16410   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16411                                (match_dup 2)))
16412    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16413    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16414    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16415    (parallel [(set (match_dup 7)
16416                    (unspec:XF [(match_dup 6) (match_dup 4)]
16417                               UNSPEC_FSCALE_FRACT))
16418                    (set (match_dup 8)
16419                    (unspec:XF [(match_dup 6) (match_dup 4)]
16420                               UNSPEC_FSCALE_EXP))])
16421    (parallel [(set (match_dup 10)
16422                    (unspec:XF [(match_dup 9) (match_dup 8)]
16423                               UNSPEC_FSCALE_FRACT))
16424               (set (match_dup 11)
16425                    (unspec:XF [(match_dup 9) (match_dup 8)]
16426                               UNSPEC_FSCALE_EXP))])
16427    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16428    (set (match_operand:XF 0 "register_operand" "")
16429         (plus:XF (match_dup 12) (match_dup 7)))]
16430   "TARGET_USE_FANCY_MATH_387
16431    && flag_unsafe_math_optimizations"
16432 {
16433   rtx temp;
16434   int i;
16435
16436   for (i=2; i<13; i++)
16437     operands[i] = gen_reg_rtx (XFmode);
16438   temp = standard_80387_constant_rtx (5); /* fldl2e */
16439   emit_move_insn (operands[2], temp);
16440   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16441 })
16442
16443 (define_expand "ldexpdf3"
16444   [(set (match_dup 3)
16445         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16446    (set (match_dup 4)
16447         (float:XF (match_operand:SI 2 "register_operand" "")))
16448    (parallel [(set (match_dup 5)
16449                    (unspec:XF [(match_dup 3) (match_dup 4)]
16450                               UNSPEC_FSCALE_FRACT))
16451               (set (match_dup 6)
16452                    (unspec:XF [(match_dup 3) (match_dup 4)]
16453                               UNSPEC_FSCALE_EXP))])
16454    (set (match_operand:DF 0 "register_operand" "")
16455         (float_truncate:DF (match_dup 5)))]
16456   "TARGET_USE_FANCY_MATH_387
16457    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16458    && flag_unsafe_math_optimizations"
16459 {
16460   int i;
16461
16462   for (i=3; i<7; i++)
16463     operands[i] = gen_reg_rtx (XFmode);
16464 })
16465
16466 (define_expand "ldexpsf3"
16467   [(set (match_dup 3)
16468         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16469    (set (match_dup 4)
16470         (float:XF (match_operand:SI 2 "register_operand" "")))
16471    (parallel [(set (match_dup 5)
16472                    (unspec:XF [(match_dup 3) (match_dup 4)]
16473                               UNSPEC_FSCALE_FRACT))
16474               (set (match_dup 6)
16475                    (unspec:XF [(match_dup 3) (match_dup 4)]
16476                               UNSPEC_FSCALE_EXP))])
16477    (set (match_operand:SF 0 "register_operand" "")
16478         (float_truncate:SF (match_dup 5)))]
16479   "TARGET_USE_FANCY_MATH_387
16480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16482 {
16483   int i;
16484
16485   for (i=3; i<7; i++)
16486     operands[i] = gen_reg_rtx (XFmode);
16487 })
16488
16489 (define_expand "ldexpxf3"
16490   [(set (match_dup 3)
16491         (float:XF (match_operand:SI 2 "register_operand" "")))
16492    (parallel [(set (match_operand:XF 0 " register_operand" "")
16493                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16494                                (match_dup 3)]
16495                               UNSPEC_FSCALE_FRACT))
16496               (set (match_dup 4)
16497                    (unspec:XF [(match_dup 1) (match_dup 3)]
16498                               UNSPEC_FSCALE_EXP))])]
16499   "TARGET_USE_FANCY_MATH_387
16500    && flag_unsafe_math_optimizations"
16501 {
16502   int i;
16503
16504   for (i=3; i<5; i++)
16505     operands[i] = gen_reg_rtx (XFmode);
16506 })
16507 \f
16508
16509 (define_insn "frndintxf2"
16510   [(set (match_operand:XF 0 "register_operand" "=f")
16511         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16512          UNSPEC_FRNDINT))]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16515   "frndint"
16516   [(set_attr "type" "fpspc")
16517    (set_attr "mode" "XF")])
16518
16519 (define_expand "rintdf2"
16520   [(use (match_operand:DF 0 "register_operand" ""))
16521    (use (match_operand:DF 1 "register_operand" ""))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16524    && flag_unsafe_math_optimizations"
16525 {
16526   rtx op0 = gen_reg_rtx (XFmode);
16527   rtx op1 = gen_reg_rtx (XFmode);
16528
16529   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16530   emit_insn (gen_frndintxf2 (op0, op1));
16531
16532   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16533   DONE;
16534 })
16535
16536 (define_expand "rintsf2"
16537   [(use (match_operand:SF 0 "register_operand" ""))
16538    (use (match_operand:SF 1 "register_operand" ""))]
16539   "TARGET_USE_FANCY_MATH_387
16540    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16541    && flag_unsafe_math_optimizations"
16542 {
16543   rtx op0 = gen_reg_rtx (XFmode);
16544   rtx op1 = gen_reg_rtx (XFmode);
16545
16546   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16547   emit_insn (gen_frndintxf2 (op0, op1));
16548
16549   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16550   DONE;
16551 })
16552
16553 (define_expand "rintxf2"
16554   [(use (match_operand:XF 0 "register_operand" ""))
16555    (use (match_operand:XF 1 "register_operand" ""))]
16556   "TARGET_USE_FANCY_MATH_387
16557    && flag_unsafe_math_optimizations"
16558 {
16559   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16560   DONE;
16561 })
16562
16563 (define_insn_and_split "*fistdi2_1"
16564   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16565         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16566          UNSPEC_FIST))]
16567   "TARGET_USE_FANCY_MATH_387
16568    && flag_unsafe_math_optimizations
16569    && !(reload_completed || reload_in_progress)"
16570   "#"
16571   "&& 1"
16572   [(const_int 0)]
16573 {
16574   if (memory_operand (operands[0], VOIDmode))
16575     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16576   else
16577     {
16578       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16579       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16580                                          operands[2]));
16581     }
16582   DONE;
16583 }
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "DI")])
16586
16587 (define_insn "fistdi2"
16588   [(set (match_operand:DI 0 "memory_operand" "=m")
16589         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16590          UNSPEC_FIST))
16591    (clobber (match_scratch:XF 2 "=&1f"))]
16592   "TARGET_USE_FANCY_MATH_387
16593    && flag_unsafe_math_optimizations"
16594   "* return output_fix_trunc (insn, operands, 0);"
16595   [(set_attr "type" "fpspc")
16596    (set_attr "mode" "DI")])
16597
16598 (define_insn "fistdi2_with_temp"
16599   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16600         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16601          UNSPEC_FIST))
16602    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16603    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16604   "TARGET_USE_FANCY_MATH_387
16605    && flag_unsafe_math_optimizations"
16606   "#"
16607   [(set_attr "type" "fpspc")
16608    (set_attr "mode" "DI")])
16609
16610 (define_split 
16611   [(set (match_operand:DI 0 "register_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 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16618               (clobber (match_dup 3))])
16619    (set (match_dup 0) (match_dup 2))]
16620   "")
16621
16622 (define_split 
16623   [(set (match_operand:DI 0 "memory_operand" "")
16624         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16625          UNSPEC_FIST))
16626    (clobber (match_operand:DI 2 "memory_operand" ""))
16627    (clobber (match_scratch 3 ""))]
16628   "reload_completed"
16629   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16630               (clobber (match_dup 3))])]
16631   "")
16632
16633 (define_insn_and_split "*fist<mode>2_1"
16634   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16635         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16636          UNSPEC_FIST))]
16637   "TARGET_USE_FANCY_MATH_387
16638    && flag_unsafe_math_optimizations
16639    && !(reload_completed || reload_in_progress)"
16640   "#"
16641   "&& 1"
16642   [(const_int 0)]
16643 {
16644   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16645   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16646                                         operands[2]));
16647   DONE;
16648 }
16649   [(set_attr "type" "fpspc")
16650    (set_attr "mode" "<MODE>")])
16651
16652 (define_insn "fist<mode>2"
16653   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16654         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16655          UNSPEC_FIST))]
16656   "TARGET_USE_FANCY_MATH_387
16657    && flag_unsafe_math_optimizations"
16658   "* return output_fix_trunc (insn, operands, 0);"
16659   [(set_attr "type" "fpspc")
16660    (set_attr "mode" "<MODE>")])
16661
16662 (define_insn "fist<mode>2_with_temp"
16663   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16664         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16665          UNSPEC_FIST))
16666    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16667   "TARGET_USE_FANCY_MATH_387
16668    && flag_unsafe_math_optimizations"
16669   "#"
16670   [(set_attr "type" "fpspc")
16671    (set_attr "mode" "<MODE>")])
16672
16673 (define_split 
16674   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16675         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16676          UNSPEC_FIST))
16677    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16678   "reload_completed"
16679   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16680                        UNSPEC_FIST))
16681    (set (match_dup 0) (match_dup 2))]
16682   "")
16683
16684 (define_split 
16685   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16686         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16687          UNSPEC_FIST))
16688    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16689   "reload_completed"
16690   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16691                        UNSPEC_FIST))]
16692   "")
16693
16694 (define_expand "lrint<mode>2"
16695   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16696         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16697          UNSPEC_FIST))]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16701   "")
16702
16703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16704 (define_insn_and_split "frndintxf2_floor"
16705   [(set (match_operand:XF 0 "register_operand" "=f")
16706         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16707          UNSPEC_FRNDINT_FLOOR))
16708    (clobber (reg:CC FLAGS_REG))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && flag_unsafe_math_optimizations
16711    && !(reload_completed || reload_in_progress)"
16712   "#"
16713   "&& 1"
16714   [(const_int 0)]
16715 {
16716   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16717
16718   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16719   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16720
16721   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16722                                         operands[2], operands[3]));
16723   DONE;
16724 }
16725   [(set_attr "type" "frndint")
16726    (set_attr "i387_cw" "floor")
16727    (set_attr "mode" "XF")])
16728
16729 (define_insn "frndintxf2_floor_i387"
16730   [(set (match_operand:XF 0 "register_operand" "=f")
16731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16732          UNSPEC_FRNDINT_FLOOR))
16733    (use (match_operand:HI 2 "memory_operand" "m"))
16734    (use (match_operand:HI 3 "memory_operand" "m"))]
16735   "TARGET_USE_FANCY_MATH_387
16736    && flag_unsafe_math_optimizations"
16737   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16738   [(set_attr "type" "frndint")
16739    (set_attr "i387_cw" "floor")
16740    (set_attr "mode" "XF")])
16741
16742 (define_expand "floorxf2"
16743   [(use (match_operand:XF 0 "register_operand" ""))
16744    (use (match_operand:XF 1 "register_operand" ""))]
16745   "TARGET_USE_FANCY_MATH_387
16746    && flag_unsafe_math_optimizations"
16747 {
16748   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16749   DONE;
16750 })
16751
16752 (define_expand "floordf2"
16753   [(use (match_operand:DF 0 "register_operand" ""))
16754    (use (match_operand:DF 1 "register_operand" ""))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16757    && flag_unsafe_math_optimizations"
16758 {
16759   rtx op0 = gen_reg_rtx (XFmode);
16760   rtx op1 = gen_reg_rtx (XFmode);
16761
16762   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16763   emit_insn (gen_frndintxf2_floor (op0, op1));
16764
16765   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16766   DONE;
16767 })
16768
16769 (define_expand "floorsf2"
16770   [(use (match_operand:SF 0 "register_operand" ""))
16771    (use (match_operand:SF 1 "register_operand" ""))]
16772   "TARGET_USE_FANCY_MATH_387
16773    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16774    && flag_unsafe_math_optimizations"
16775 {
16776   rtx op0 = gen_reg_rtx (XFmode);
16777   rtx op1 = gen_reg_rtx (XFmode);
16778
16779   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16780   emit_insn (gen_frndintxf2_floor (op0, op1));
16781
16782   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16783   DONE;
16784 })
16785
16786 (define_insn_and_split "*fist<mode>2_floor_1"
16787   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16788         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16789          UNSPEC_FIST_FLOOR))
16790    (clobber (reg:CC FLAGS_REG))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && flag_unsafe_math_optimizations
16793    && !(reload_completed || reload_in_progress)"
16794   "#"
16795   "&& 1"
16796   [(const_int 0)]
16797 {
16798   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16799
16800   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16801   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16802   if (memory_operand (operands[0], VOIDmode))
16803     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16804                                       operands[2], operands[3]));
16805   else
16806     {
16807       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16808       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16809                                                   operands[2], operands[3],
16810                                                   operands[4]));
16811     }
16812   DONE;
16813 }
16814   [(set_attr "type" "fistp")
16815    (set_attr "i387_cw" "floor")
16816    (set_attr "mode" "<MODE>")])
16817
16818 (define_insn "fistdi2_floor"
16819   [(set (match_operand:DI 0 "memory_operand" "=m")
16820         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16821          UNSPEC_FIST_FLOOR))
16822    (use (match_operand:HI 2 "memory_operand" "m"))
16823    (use (match_operand:HI 3 "memory_operand" "m"))
16824    (clobber (match_scratch:XF 4 "=&1f"))]
16825   "TARGET_USE_FANCY_MATH_387
16826    && flag_unsafe_math_optimizations"
16827   "* return output_fix_trunc (insn, operands, 0);"
16828   [(set_attr "type" "fistp")
16829    (set_attr "i387_cw" "floor")
16830    (set_attr "mode" "DI")])
16831
16832 (define_insn "fistdi2_floor_with_temp"
16833   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16834         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16835          UNSPEC_FIST_FLOOR))
16836    (use (match_operand:HI 2 "memory_operand" "m,m"))
16837    (use (match_operand:HI 3 "memory_operand" "m,m"))
16838    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16839    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "#"
16843   [(set_attr "type" "fistp")
16844    (set_attr "i387_cw" "floor")
16845    (set_attr "mode" "DI")])
16846
16847 (define_split 
16848   [(set (match_operand:DI 0 "register_operand" "")
16849         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16850          UNSPEC_FIST_FLOOR))
16851    (use (match_operand:HI 2 "memory_operand" ""))
16852    (use (match_operand:HI 3 "memory_operand" ""))
16853    (clobber (match_operand:DI 4 "memory_operand" ""))
16854    (clobber (match_scratch 5 ""))]
16855   "reload_completed"
16856   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16857               (use (match_dup 2))
16858               (use (match_dup 3))
16859               (clobber (match_dup 5))])
16860    (set (match_dup 0) (match_dup 4))]
16861   "")
16862
16863 (define_split 
16864   [(set (match_operand:DI 0 "memory_operand" "")
16865         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16866          UNSPEC_FIST_FLOOR))
16867    (use (match_operand:HI 2 "memory_operand" ""))
16868    (use (match_operand:HI 3 "memory_operand" ""))
16869    (clobber (match_operand:DI 4 "memory_operand" ""))
16870    (clobber (match_scratch 5 ""))]
16871   "reload_completed"
16872   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16873               (use (match_dup 2))
16874               (use (match_dup 3))
16875               (clobber (match_dup 5))])]
16876   "")
16877
16878 (define_insn "fist<mode>2_floor"
16879   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16880         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16881          UNSPEC_FIST_FLOOR))
16882    (use (match_operand:HI 2 "memory_operand" "m"))
16883    (use (match_operand:HI 3 "memory_operand" "m"))]
16884   "TARGET_USE_FANCY_MATH_387
16885    && flag_unsafe_math_optimizations"
16886   "* return output_fix_trunc (insn, operands, 0);"
16887   [(set_attr "type" "fistp")
16888    (set_attr "i387_cw" "floor")
16889    (set_attr "mode" "<MODE>")])
16890
16891 (define_insn "fist<mode>2_floor_with_temp"
16892   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16893         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16894          UNSPEC_FIST_FLOOR))
16895    (use (match_operand:HI 2 "memory_operand" "m,m"))
16896    (use (match_operand:HI 3 "memory_operand" "m,m"))
16897    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16898   "TARGET_USE_FANCY_MATH_387
16899    && flag_unsafe_math_optimizations"
16900   "#"
16901   [(set_attr "type" "fistp")
16902    (set_attr "i387_cw" "floor")
16903    (set_attr "mode" "<MODE>")])
16904
16905 (define_split 
16906   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16907         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16908          UNSPEC_FIST_FLOOR))
16909    (use (match_operand:HI 2 "memory_operand" ""))
16910    (use (match_operand:HI 3 "memory_operand" ""))
16911    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16912   "reload_completed"
16913   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16914                                   UNSPEC_FIST_FLOOR))
16915               (use (match_dup 2))
16916               (use (match_dup 3))])
16917    (set (match_dup 0) (match_dup 4))]
16918   "")
16919
16920 (define_split 
16921   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16922         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16923          UNSPEC_FIST_FLOOR))
16924    (use (match_operand:HI 2 "memory_operand" ""))
16925    (use (match_operand:HI 3 "memory_operand" ""))
16926    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16927   "reload_completed"
16928   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16929                                   UNSPEC_FIST_FLOOR))
16930               (use (match_dup 2))
16931               (use (match_dup 3))])]
16932   "")
16933
16934 (define_expand "lfloor<mode>2"
16935   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16936                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16937                     UNSPEC_FIST_FLOOR))
16938               (clobber (reg:CC FLAGS_REG))])]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16941    && flag_unsafe_math_optimizations"
16942   "")
16943
16944 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16945 (define_insn_and_split "frndintxf2_ceil"
16946   [(set (match_operand:XF 0 "register_operand" "=f")
16947         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16948          UNSPEC_FRNDINT_CEIL))
16949    (clobber (reg:CC FLAGS_REG))]
16950   "TARGET_USE_FANCY_MATH_387
16951    && flag_unsafe_math_optimizations
16952    && !(reload_completed || reload_in_progress)"
16953   "#"
16954   "&& 1"
16955   [(const_int 0)]
16956 {
16957   ix86_optimize_mode_switching[I387_CEIL] = 1;
16958
16959   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16960   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16961
16962   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16963                                        operands[2], operands[3]));
16964   DONE;
16965 }
16966   [(set_attr "type" "frndint")
16967    (set_attr "i387_cw" "ceil")
16968    (set_attr "mode" "XF")])
16969
16970 (define_insn "frndintxf2_ceil_i387"
16971   [(set (match_operand:XF 0 "register_operand" "=f")
16972         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16973          UNSPEC_FRNDINT_CEIL))
16974    (use (match_operand:HI 2 "memory_operand" "m"))
16975    (use (match_operand:HI 3 "memory_operand" "m"))]
16976   "TARGET_USE_FANCY_MATH_387
16977    && flag_unsafe_math_optimizations"
16978   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16979   [(set_attr "type" "frndint")
16980    (set_attr "i387_cw" "ceil")
16981    (set_attr "mode" "XF")])
16982
16983 (define_expand "ceilxf2"
16984   [(use (match_operand:XF 0 "register_operand" ""))
16985    (use (match_operand:XF 1 "register_operand" ""))]
16986   "TARGET_USE_FANCY_MATH_387
16987    && flag_unsafe_math_optimizations"
16988 {
16989   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16990   DONE;
16991 })
16992
16993 (define_expand "ceildf2"
16994   [(use (match_operand:DF 0 "register_operand" ""))
16995    (use (match_operand:DF 1 "register_operand" ""))]
16996   "TARGET_USE_FANCY_MATH_387
16997    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16998    && flag_unsafe_math_optimizations"
16999 {
17000   rtx op0 = gen_reg_rtx (XFmode);
17001   rtx op1 = gen_reg_rtx (XFmode);
17002
17003   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17004   emit_insn (gen_frndintxf2_ceil (op0, op1));
17005
17006   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17007   DONE;
17008 })
17009
17010 (define_expand "ceilsf2"
17011   [(use (match_operand:SF 0 "register_operand" ""))
17012    (use (match_operand:SF 1 "register_operand" ""))]
17013   "TARGET_USE_FANCY_MATH_387
17014    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17015    && flag_unsafe_math_optimizations"
17016 {
17017   rtx op0 = gen_reg_rtx (XFmode);
17018   rtx op1 = gen_reg_rtx (XFmode);
17019
17020   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17021   emit_insn (gen_frndintxf2_ceil (op0, op1));
17022
17023   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17024   DONE;
17025 })
17026
17027 (define_insn_and_split "*fist<mode>2_ceil_1"
17028   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17029         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17030          UNSPEC_FIST_CEIL))
17031    (clobber (reg:CC FLAGS_REG))]
17032   "TARGET_USE_FANCY_MATH_387
17033    && flag_unsafe_math_optimizations
17034    && !(reload_completed || reload_in_progress)"
17035   "#"
17036   "&& 1"
17037   [(const_int 0)]
17038 {
17039   ix86_optimize_mode_switching[I387_CEIL] = 1;
17040
17041   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17042   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17043   if (memory_operand (operands[0], VOIDmode))
17044     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17045                                      operands[2], operands[3]));
17046   else
17047     {
17048       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17049       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17050                                                  operands[2], operands[3],
17051                                                  operands[4]));
17052     }
17053   DONE;
17054 }
17055   [(set_attr "type" "fistp")
17056    (set_attr "i387_cw" "ceil")
17057    (set_attr "mode" "<MODE>")])
17058
17059 (define_insn "fistdi2_ceil"
17060   [(set (match_operand:DI 0 "memory_operand" "=m")
17061         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17062          UNSPEC_FIST_CEIL))
17063    (use (match_operand:HI 2 "memory_operand" "m"))
17064    (use (match_operand:HI 3 "memory_operand" "m"))
17065    (clobber (match_scratch:XF 4 "=&1f"))]
17066   "TARGET_USE_FANCY_MATH_387
17067    && flag_unsafe_math_optimizations"
17068   "* return output_fix_trunc (insn, operands, 0);"
17069   [(set_attr "type" "fistp")
17070    (set_attr "i387_cw" "ceil")
17071    (set_attr "mode" "DI")])
17072
17073 (define_insn "fistdi2_ceil_with_temp"
17074   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17075         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17076          UNSPEC_FIST_CEIL))
17077    (use (match_operand:HI 2 "memory_operand" "m,m"))
17078    (use (match_operand:HI 3 "memory_operand" "m,m"))
17079    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17080    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17081   "TARGET_USE_FANCY_MATH_387
17082    && flag_unsafe_math_optimizations"
17083   "#"
17084   [(set_attr "type" "fistp")
17085    (set_attr "i387_cw" "ceil")
17086    (set_attr "mode" "DI")])
17087
17088 (define_split 
17089   [(set (match_operand:DI 0 "register_operand" "")
17090         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17091          UNSPEC_FIST_CEIL))
17092    (use (match_operand:HI 2 "memory_operand" ""))
17093    (use (match_operand:HI 3 "memory_operand" ""))
17094    (clobber (match_operand:DI 4 "memory_operand" ""))
17095    (clobber (match_scratch 5 ""))]
17096   "reload_completed"
17097   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17098               (use (match_dup 2))
17099               (use (match_dup 3))
17100               (clobber (match_dup 5))])
17101    (set (match_dup 0) (match_dup 4))]
17102   "")
17103
17104 (define_split 
17105   [(set (match_operand:DI 0 "memory_operand" "")
17106         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17107          UNSPEC_FIST_CEIL))
17108    (use (match_operand:HI 2 "memory_operand" ""))
17109    (use (match_operand:HI 3 "memory_operand" ""))
17110    (clobber (match_operand:DI 4 "memory_operand" ""))
17111    (clobber (match_scratch 5 ""))]
17112   "reload_completed"
17113   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17114               (use (match_dup 2))
17115               (use (match_dup 3))
17116               (clobber (match_dup 5))])]
17117   "")
17118
17119 (define_insn "fist<mode>2_ceil"
17120   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17121         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17122          UNSPEC_FIST_CEIL))
17123    (use (match_operand:HI 2 "memory_operand" "m"))
17124    (use (match_operand:HI 3 "memory_operand" "m"))]
17125   "TARGET_USE_FANCY_MATH_387
17126    && flag_unsafe_math_optimizations"
17127   "* return output_fix_trunc (insn, operands, 0);"
17128   [(set_attr "type" "fistp")
17129    (set_attr "i387_cw" "ceil")
17130    (set_attr "mode" "<MODE>")])
17131
17132 (define_insn "fist<mode>2_ceil_with_temp"
17133   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17134         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17135          UNSPEC_FIST_CEIL))
17136    (use (match_operand:HI 2 "memory_operand" "m,m"))
17137    (use (match_operand:HI 3 "memory_operand" "m,m"))
17138    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && flag_unsafe_math_optimizations"
17141   "#"
17142   [(set_attr "type" "fistp")
17143    (set_attr "i387_cw" "ceil")
17144    (set_attr "mode" "<MODE>")])
17145
17146 (define_split 
17147   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17148         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17149          UNSPEC_FIST_CEIL))
17150    (use (match_operand:HI 2 "memory_operand" ""))
17151    (use (match_operand:HI 3 "memory_operand" ""))
17152    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17153   "reload_completed"
17154   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17155                                   UNSPEC_FIST_CEIL))
17156               (use (match_dup 2))
17157               (use (match_dup 3))])
17158    (set (match_dup 0) (match_dup 4))]
17159   "")
17160
17161 (define_split 
17162   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17163         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17164          UNSPEC_FIST_CEIL))
17165    (use (match_operand:HI 2 "memory_operand" ""))
17166    (use (match_operand:HI 3 "memory_operand" ""))
17167    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17168   "reload_completed"
17169   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17170                                   UNSPEC_FIST_CEIL))
17171               (use (match_dup 2))
17172               (use (match_dup 3))])]
17173   "")
17174
17175 (define_expand "lceil<mode>2"
17176   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17177                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17178                     UNSPEC_FIST_CEIL))
17179               (clobber (reg:CC FLAGS_REG))])]
17180   "TARGET_USE_FANCY_MATH_387
17181    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182    && flag_unsafe_math_optimizations"
17183   "")
17184
17185 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17186 (define_insn_and_split "frndintxf2_trunc"
17187   [(set (match_operand:XF 0 "register_operand" "=f")
17188         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17189          UNSPEC_FRNDINT_TRUNC))
17190    (clobber (reg:CC FLAGS_REG))]
17191   "TARGET_USE_FANCY_MATH_387
17192    && flag_unsafe_math_optimizations
17193    && !(reload_completed || reload_in_progress)"
17194   "#"
17195   "&& 1"
17196   [(const_int 0)]
17197 {
17198   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17199
17200   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17201   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17202
17203   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17204                                         operands[2], operands[3]));
17205   DONE;
17206 }
17207   [(set_attr "type" "frndint")
17208    (set_attr "i387_cw" "trunc")
17209    (set_attr "mode" "XF")])
17210
17211 (define_insn "frndintxf2_trunc_i387"
17212   [(set (match_operand:XF 0 "register_operand" "=f")
17213         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17214          UNSPEC_FRNDINT_TRUNC))
17215    (use (match_operand:HI 2 "memory_operand" "m"))
17216    (use (match_operand:HI 3 "memory_operand" "m"))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && flag_unsafe_math_optimizations"
17219   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17220   [(set_attr "type" "frndint")
17221    (set_attr "i387_cw" "trunc")
17222    (set_attr "mode" "XF")])
17223
17224 (define_expand "btruncxf2"
17225   [(use (match_operand:XF 0 "register_operand" ""))
17226    (use (match_operand:XF 1 "register_operand" ""))]
17227   "TARGET_USE_FANCY_MATH_387
17228    && flag_unsafe_math_optimizations"
17229 {
17230   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17231   DONE;
17232 })
17233
17234 (define_expand "btruncdf2"
17235   [(use (match_operand:DF 0 "register_operand" ""))
17236    (use (match_operand:DF 1 "register_operand" ""))]
17237   "TARGET_USE_FANCY_MATH_387
17238    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17239    && flag_unsafe_math_optimizations"
17240 {
17241   rtx op0 = gen_reg_rtx (XFmode);
17242   rtx op1 = gen_reg_rtx (XFmode);
17243
17244   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17245   emit_insn (gen_frndintxf2_trunc (op0, op1));
17246
17247   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17248   DONE;
17249 })
17250
17251 (define_expand "btruncsf2"
17252   [(use (match_operand:SF 0 "register_operand" ""))
17253    (use (match_operand:SF 1 "register_operand" ""))]
17254   "TARGET_USE_FANCY_MATH_387
17255    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17256    && flag_unsafe_math_optimizations"
17257 {
17258   rtx op0 = gen_reg_rtx (XFmode);
17259   rtx op1 = gen_reg_rtx (XFmode);
17260
17261   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17262   emit_insn (gen_frndintxf2_trunc (op0, op1));
17263
17264   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17265   DONE;
17266 })
17267
17268 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17269 (define_insn_and_split "frndintxf2_mask_pm"
17270   [(set (match_operand:XF 0 "register_operand" "=f")
17271         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17272          UNSPEC_FRNDINT_MASK_PM))
17273    (clobber (reg:CC FLAGS_REG))]
17274   "TARGET_USE_FANCY_MATH_387
17275    && flag_unsafe_math_optimizations
17276    && !(reload_completed || reload_in_progress)"
17277   "#"
17278   "&& 1"
17279   [(const_int 0)]
17280 {
17281   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17282
17283   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17284   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17285
17286   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17287                                           operands[2], operands[3]));
17288   DONE;
17289 }
17290   [(set_attr "type" "frndint")
17291    (set_attr "i387_cw" "mask_pm")
17292    (set_attr "mode" "XF")])
17293
17294 (define_insn "frndintxf2_mask_pm_i387"
17295   [(set (match_operand:XF 0 "register_operand" "=f")
17296         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17297          UNSPEC_FRNDINT_MASK_PM))
17298    (use (match_operand:HI 2 "memory_operand" "m"))
17299    (use (match_operand:HI 3 "memory_operand" "m"))]
17300   "TARGET_USE_FANCY_MATH_387
17301    && flag_unsafe_math_optimizations"
17302   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17303   [(set_attr "type" "frndint")
17304    (set_attr "i387_cw" "mask_pm")
17305    (set_attr "mode" "XF")])
17306
17307 (define_expand "nearbyintxf2"
17308   [(use (match_operand:XF 0 "register_operand" ""))
17309    (use (match_operand:XF 1 "register_operand" ""))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && flag_unsafe_math_optimizations"
17312 {
17313   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17314
17315   DONE;
17316 })
17317
17318 (define_expand "nearbyintdf2"
17319   [(use (match_operand:DF 0 "register_operand" ""))
17320    (use (match_operand:DF 1 "register_operand" ""))]
17321   "TARGET_USE_FANCY_MATH_387
17322    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17323    && flag_unsafe_math_optimizations"
17324 {
17325   rtx op0 = gen_reg_rtx (XFmode);
17326   rtx op1 = gen_reg_rtx (XFmode);
17327
17328   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17329   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17330
17331   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17332   DONE;
17333 })
17334
17335 (define_expand "nearbyintsf2"
17336   [(use (match_operand:SF 0 "register_operand" ""))
17337    (use (match_operand:SF 1 "register_operand" ""))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17340    && flag_unsafe_math_optimizations"
17341 {
17342   rtx op0 = gen_reg_rtx (XFmode);
17343   rtx op1 = gen_reg_rtx (XFmode);
17344
17345   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17346   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17347
17348   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17349   DONE;
17350 })
17351
17352 \f
17353 ;; Block operation instructions
17354
17355 (define_insn "cld"
17356  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17357  ""
17358  "cld"
17359   [(set_attr "type" "cld")])
17360
17361 (define_expand "movmemsi"
17362   [(use (match_operand:BLK 0 "memory_operand" ""))
17363    (use (match_operand:BLK 1 "memory_operand" ""))
17364    (use (match_operand:SI 2 "nonmemory_operand" ""))
17365    (use (match_operand:SI 3 "const_int_operand" ""))]
17366   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17367 {
17368  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17369    DONE;
17370  else
17371    FAIL;
17372 })
17373
17374 (define_expand "movmemdi"
17375   [(use (match_operand:BLK 0 "memory_operand" ""))
17376    (use (match_operand:BLK 1 "memory_operand" ""))
17377    (use (match_operand:DI 2 "nonmemory_operand" ""))
17378    (use (match_operand:DI 3 "const_int_operand" ""))]
17379   "TARGET_64BIT"
17380 {
17381  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17382    DONE;
17383  else
17384    FAIL;
17385 })
17386
17387 ;; Most CPUs don't like single string operations
17388 ;; Handle this case here to simplify previous expander.
17389
17390 (define_expand "strmov"
17391   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17392    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17393    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17394               (clobber (reg:CC FLAGS_REG))])
17395    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17396               (clobber (reg:CC FLAGS_REG))])]
17397   ""
17398 {
17399   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17400
17401   /* If .md ever supports :P for Pmode, these can be directly
17402      in the pattern above.  */
17403   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17404   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17405
17406   if (TARGET_SINGLE_STRINGOP || optimize_size)
17407     {
17408       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17409                                       operands[2], operands[3],
17410                                       operands[5], operands[6]));
17411       DONE;
17412     }
17413
17414   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17415 })
17416
17417 (define_expand "strmov_singleop"
17418   [(parallel [(set (match_operand 1 "memory_operand" "")
17419                    (match_operand 3 "memory_operand" ""))
17420               (set (match_operand 0 "register_operand" "")
17421                    (match_operand 4 "" ""))
17422               (set (match_operand 2 "register_operand" "")
17423                    (match_operand 5 "" ""))
17424               (use (reg:SI DIRFLAG_REG))])]
17425   "TARGET_SINGLE_STRINGOP || optimize_size"
17426   "")
17427
17428 (define_insn "*strmovdi_rex_1"
17429   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17430         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17431    (set (match_operand:DI 0 "register_operand" "=D")
17432         (plus:DI (match_dup 2)
17433                  (const_int 8)))
17434    (set (match_operand:DI 1 "register_operand" "=S")
17435         (plus:DI (match_dup 3)
17436                  (const_int 8)))
17437    (use (reg:SI DIRFLAG_REG))]
17438   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17439   "movsq"
17440   [(set_attr "type" "str")
17441    (set_attr "mode" "DI")
17442    (set_attr "memory" "both")])
17443
17444 (define_insn "*strmovsi_1"
17445   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17446         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17447    (set (match_operand:SI 0 "register_operand" "=D")
17448         (plus:SI (match_dup 2)
17449                  (const_int 4)))
17450    (set (match_operand:SI 1 "register_operand" "=S")
17451         (plus:SI (match_dup 3)
17452                  (const_int 4)))
17453    (use (reg:SI DIRFLAG_REG))]
17454   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17455   "{movsl|movsd}"
17456   [(set_attr "type" "str")
17457    (set_attr "mode" "SI")
17458    (set_attr "memory" "both")])
17459
17460 (define_insn "*strmovsi_rex_1"
17461   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17462         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17463    (set (match_operand:DI 0 "register_operand" "=D")
17464         (plus:DI (match_dup 2)
17465                  (const_int 4)))
17466    (set (match_operand:DI 1 "register_operand" "=S")
17467         (plus:DI (match_dup 3)
17468                  (const_int 4)))
17469    (use (reg:SI DIRFLAG_REG))]
17470   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17471   "{movsl|movsd}"
17472   [(set_attr "type" "str")
17473    (set_attr "mode" "SI")
17474    (set_attr "memory" "both")])
17475
17476 (define_insn "*strmovhi_1"
17477   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17478         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17479    (set (match_operand:SI 0 "register_operand" "=D")
17480         (plus:SI (match_dup 2)
17481                  (const_int 2)))
17482    (set (match_operand:SI 1 "register_operand" "=S")
17483         (plus:SI (match_dup 3)
17484                  (const_int 2)))
17485    (use (reg:SI DIRFLAG_REG))]
17486   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17487   "movsw"
17488   [(set_attr "type" "str")
17489    (set_attr "memory" "both")
17490    (set_attr "mode" "HI")])
17491
17492 (define_insn "*strmovhi_rex_1"
17493   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17494         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17495    (set (match_operand:DI 0 "register_operand" "=D")
17496         (plus:DI (match_dup 2)
17497                  (const_int 2)))
17498    (set (match_operand:DI 1 "register_operand" "=S")
17499         (plus:DI (match_dup 3)
17500                  (const_int 2)))
17501    (use (reg:SI DIRFLAG_REG))]
17502   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17503   "movsw"
17504   [(set_attr "type" "str")
17505    (set_attr "memory" "both")
17506    (set_attr "mode" "HI")])
17507
17508 (define_insn "*strmovqi_1"
17509   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17510         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17511    (set (match_operand:SI 0 "register_operand" "=D")
17512         (plus:SI (match_dup 2)
17513                  (const_int 1)))
17514    (set (match_operand:SI 1 "register_operand" "=S")
17515         (plus:SI (match_dup 3)
17516                  (const_int 1)))
17517    (use (reg:SI DIRFLAG_REG))]
17518   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17519   "movsb"
17520   [(set_attr "type" "str")
17521    (set_attr "memory" "both")
17522    (set_attr "mode" "QI")])
17523
17524 (define_insn "*strmovqi_rex_1"
17525   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17526         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17527    (set (match_operand:DI 0 "register_operand" "=D")
17528         (plus:DI (match_dup 2)
17529                  (const_int 1)))
17530    (set (match_operand:DI 1 "register_operand" "=S")
17531         (plus:DI (match_dup 3)
17532                  (const_int 1)))
17533    (use (reg:SI DIRFLAG_REG))]
17534   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17535   "movsb"
17536   [(set_attr "type" "str")
17537    (set_attr "memory" "both")
17538    (set_attr "mode" "QI")])
17539
17540 (define_expand "rep_mov"
17541   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17542               (set (match_operand 0 "register_operand" "")
17543                    (match_operand 5 "" ""))
17544               (set (match_operand 2 "register_operand" "")
17545                    (match_operand 6 "" ""))
17546               (set (match_operand 1 "memory_operand" "")
17547                    (match_operand 3 "memory_operand" ""))
17548               (use (match_dup 4))
17549               (use (reg:SI DIRFLAG_REG))])]
17550   ""
17551   "")
17552
17553 (define_insn "*rep_movdi_rex64"
17554   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17555    (set (match_operand:DI 0 "register_operand" "=D") 
17556         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17557                             (const_int 3))
17558                  (match_operand:DI 3 "register_operand" "0")))
17559    (set (match_operand:DI 1 "register_operand" "=S") 
17560         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17561                  (match_operand:DI 4 "register_operand" "1")))
17562    (set (mem:BLK (match_dup 3))
17563         (mem:BLK (match_dup 4)))
17564    (use (match_dup 5))
17565    (use (reg:SI DIRFLAG_REG))]
17566   "TARGET_64BIT"
17567   "{rep\;movsq|rep movsq}"
17568   [(set_attr "type" "str")
17569    (set_attr "prefix_rep" "1")
17570    (set_attr "memory" "both")
17571    (set_attr "mode" "DI")])
17572
17573 (define_insn "*rep_movsi"
17574   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17575    (set (match_operand:SI 0 "register_operand" "=D") 
17576         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17577                             (const_int 2))
17578                  (match_operand:SI 3 "register_operand" "0")))
17579    (set (match_operand:SI 1 "register_operand" "=S") 
17580         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17581                  (match_operand:SI 4 "register_operand" "1")))
17582    (set (mem:BLK (match_dup 3))
17583         (mem:BLK (match_dup 4)))
17584    (use (match_dup 5))
17585    (use (reg:SI DIRFLAG_REG))]
17586   "!TARGET_64BIT"
17587   "{rep\;movsl|rep movsd}"
17588   [(set_attr "type" "str")
17589    (set_attr "prefix_rep" "1")
17590    (set_attr "memory" "both")
17591    (set_attr "mode" "SI")])
17592
17593 (define_insn "*rep_movsi_rex64"
17594   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17595    (set (match_operand:DI 0 "register_operand" "=D") 
17596         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17597                             (const_int 2))
17598                  (match_operand:DI 3 "register_operand" "0")))
17599    (set (match_operand:DI 1 "register_operand" "=S") 
17600         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17601                  (match_operand:DI 4 "register_operand" "1")))
17602    (set (mem:BLK (match_dup 3))
17603         (mem:BLK (match_dup 4)))
17604    (use (match_dup 5))
17605    (use (reg:SI DIRFLAG_REG))]
17606   "TARGET_64BIT"
17607   "{rep\;movsl|rep movsd}"
17608   [(set_attr "type" "str")
17609    (set_attr "prefix_rep" "1")
17610    (set_attr "memory" "both")
17611    (set_attr "mode" "SI")])
17612
17613 (define_insn "*rep_movqi"
17614   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17615    (set (match_operand:SI 0 "register_operand" "=D") 
17616         (plus:SI (match_operand:SI 3 "register_operand" "0")
17617                  (match_operand:SI 5 "register_operand" "2")))
17618    (set (match_operand:SI 1 "register_operand" "=S") 
17619         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17620    (set (mem:BLK (match_dup 3))
17621         (mem:BLK (match_dup 4)))
17622    (use (match_dup 5))
17623    (use (reg:SI DIRFLAG_REG))]
17624   "!TARGET_64BIT"
17625   "{rep\;movsb|rep movsb}"
17626   [(set_attr "type" "str")
17627    (set_attr "prefix_rep" "1")
17628    (set_attr "memory" "both")
17629    (set_attr "mode" "SI")])
17630
17631 (define_insn "*rep_movqi_rex64"
17632   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17633    (set (match_operand:DI 0 "register_operand" "=D") 
17634         (plus:DI (match_operand:DI 3 "register_operand" "0")
17635                  (match_operand:DI 5 "register_operand" "2")))
17636    (set (match_operand:DI 1 "register_operand" "=S") 
17637         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17638    (set (mem:BLK (match_dup 3))
17639         (mem:BLK (match_dup 4)))
17640    (use (match_dup 5))
17641    (use (reg:SI DIRFLAG_REG))]
17642   "TARGET_64BIT"
17643   "{rep\;movsb|rep movsb}"
17644   [(set_attr "type" "str")
17645    (set_attr "prefix_rep" "1")
17646    (set_attr "memory" "both")
17647    (set_attr "mode" "SI")])
17648
17649 (define_expand "setmemsi"
17650    [(use (match_operand:BLK 0 "memory_operand" ""))
17651     (use (match_operand:SI 1 "nonmemory_operand" ""))
17652     (use (match_operand 2 "const_int_operand" ""))
17653     (use (match_operand 3 "const_int_operand" ""))]
17654   ""
17655 {
17656  /* If value to set is not zero, use the library routine.  */
17657  if (operands[2] != const0_rtx)
17658    FAIL;
17659
17660  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17661    DONE;
17662  else
17663    FAIL;
17664 })
17665
17666 (define_expand "setmemdi"
17667    [(use (match_operand:BLK 0 "memory_operand" ""))
17668     (use (match_operand:DI 1 "nonmemory_operand" ""))
17669     (use (match_operand 2 "const_int_operand" ""))
17670     (use (match_operand 3 "const_int_operand" ""))]
17671   "TARGET_64BIT"
17672 {
17673  /* If value to set is not zero, use the library routine.  */
17674  if (operands[2] != const0_rtx)
17675    FAIL;
17676
17677  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17678    DONE;
17679  else
17680    FAIL;
17681 })
17682
17683 ;; Most CPUs don't like single string operations
17684 ;; Handle this case here to simplify previous expander.
17685
17686 (define_expand "strset"
17687   [(set (match_operand 1 "memory_operand" "")
17688         (match_operand 2 "register_operand" ""))
17689    (parallel [(set (match_operand 0 "register_operand" "")
17690                    (match_dup 3))
17691               (clobber (reg:CC FLAGS_REG))])]
17692   ""
17693 {
17694   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17695     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17696
17697   /* If .md ever supports :P for Pmode, this can be directly
17698      in the pattern above.  */
17699   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17700                               GEN_INT (GET_MODE_SIZE (GET_MODE
17701                                                       (operands[2]))));
17702   if (TARGET_SINGLE_STRINGOP || optimize_size)
17703     {
17704       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17705                                       operands[3]));
17706       DONE;
17707     }
17708 })
17709
17710 (define_expand "strset_singleop"
17711   [(parallel [(set (match_operand 1 "memory_operand" "")
17712                    (match_operand 2 "register_operand" ""))
17713               (set (match_operand 0 "register_operand" "")
17714                    (match_operand 3 "" ""))
17715               (use (reg:SI DIRFLAG_REG))])]
17716   "TARGET_SINGLE_STRINGOP || optimize_size"
17717   "")
17718
17719 (define_insn "*strsetdi_rex_1"
17720   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17721         (match_operand:DI 2 "register_operand" "a"))
17722    (set (match_operand:DI 0 "register_operand" "=D")
17723         (plus:DI (match_dup 1)
17724                  (const_int 8)))
17725    (use (reg:SI DIRFLAG_REG))]
17726   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17727   "stosq"
17728   [(set_attr "type" "str")
17729    (set_attr "memory" "store")
17730    (set_attr "mode" "DI")])
17731
17732 (define_insn "*strsetsi_1"
17733   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17734         (match_operand:SI 2 "register_operand" "a"))
17735    (set (match_operand:SI 0 "register_operand" "=D")
17736         (plus:SI (match_dup 1)
17737                  (const_int 4)))
17738    (use (reg:SI DIRFLAG_REG))]
17739   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17740   "{stosl|stosd}"
17741   [(set_attr "type" "str")
17742    (set_attr "memory" "store")
17743    (set_attr "mode" "SI")])
17744
17745 (define_insn "*strsetsi_rex_1"
17746   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17747         (match_operand:SI 2 "register_operand" "a"))
17748    (set (match_operand:DI 0 "register_operand" "=D")
17749         (plus:DI (match_dup 1)
17750                  (const_int 4)))
17751    (use (reg:SI DIRFLAG_REG))]
17752   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17753   "{stosl|stosd}"
17754   [(set_attr "type" "str")
17755    (set_attr "memory" "store")
17756    (set_attr "mode" "SI")])
17757
17758 (define_insn "*strsethi_1"
17759   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17760         (match_operand:HI 2 "register_operand" "a"))
17761    (set (match_operand:SI 0 "register_operand" "=D")
17762         (plus:SI (match_dup 1)
17763                  (const_int 2)))
17764    (use (reg:SI DIRFLAG_REG))]
17765   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17766   "stosw"
17767   [(set_attr "type" "str")
17768    (set_attr "memory" "store")
17769    (set_attr "mode" "HI")])
17770
17771 (define_insn "*strsethi_rex_1"
17772   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17773         (match_operand:HI 2 "register_operand" "a"))
17774    (set (match_operand:DI 0 "register_operand" "=D")
17775         (plus:DI (match_dup 1)
17776                  (const_int 2)))
17777    (use (reg:SI DIRFLAG_REG))]
17778   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17779   "stosw"
17780   [(set_attr "type" "str")
17781    (set_attr "memory" "store")
17782    (set_attr "mode" "HI")])
17783
17784 (define_insn "*strsetqi_1"
17785   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17786         (match_operand:QI 2 "register_operand" "a"))
17787    (set (match_operand:SI 0 "register_operand" "=D")
17788         (plus:SI (match_dup 1)
17789                  (const_int 1)))
17790    (use (reg:SI DIRFLAG_REG))]
17791   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17792   "stosb"
17793   [(set_attr "type" "str")
17794    (set_attr "memory" "store")
17795    (set_attr "mode" "QI")])
17796
17797 (define_insn "*strsetqi_rex_1"
17798   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17799         (match_operand:QI 2 "register_operand" "a"))
17800    (set (match_operand:DI 0 "register_operand" "=D")
17801         (plus:DI (match_dup 1)
17802                  (const_int 1)))
17803    (use (reg:SI DIRFLAG_REG))]
17804   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17805   "stosb"
17806   [(set_attr "type" "str")
17807    (set_attr "memory" "store")
17808    (set_attr "mode" "QI")])
17809
17810 (define_expand "rep_stos"
17811   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17812               (set (match_operand 0 "register_operand" "")
17813                    (match_operand 4 "" ""))
17814               (set (match_operand 2 "memory_operand" "") (const_int 0))
17815               (use (match_operand 3 "register_operand" ""))
17816               (use (match_dup 1))
17817               (use (reg:SI DIRFLAG_REG))])]
17818   ""
17819   "")
17820
17821 (define_insn "*rep_stosdi_rex64"
17822   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17823    (set (match_operand:DI 0 "register_operand" "=D") 
17824         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17825                             (const_int 3))
17826                  (match_operand:DI 3 "register_operand" "0")))
17827    (set (mem:BLK (match_dup 3))
17828         (const_int 0))
17829    (use (match_operand:DI 2 "register_operand" "a"))
17830    (use (match_dup 4))
17831    (use (reg:SI DIRFLAG_REG))]
17832   "TARGET_64BIT"
17833   "{rep\;stosq|rep stosq}"
17834   [(set_attr "type" "str")
17835    (set_attr "prefix_rep" "1")
17836    (set_attr "memory" "store")
17837    (set_attr "mode" "DI")])
17838
17839 (define_insn "*rep_stossi"
17840   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17841    (set (match_operand:SI 0 "register_operand" "=D") 
17842         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17843                             (const_int 2))
17844                  (match_operand:SI 3 "register_operand" "0")))
17845    (set (mem:BLK (match_dup 3))
17846         (const_int 0))
17847    (use (match_operand:SI 2 "register_operand" "a"))
17848    (use (match_dup 4))
17849    (use (reg:SI DIRFLAG_REG))]
17850   "!TARGET_64BIT"
17851   "{rep\;stosl|rep stosd}"
17852   [(set_attr "type" "str")
17853    (set_attr "prefix_rep" "1")
17854    (set_attr "memory" "store")
17855    (set_attr "mode" "SI")])
17856
17857 (define_insn "*rep_stossi_rex64"
17858   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17859    (set (match_operand:DI 0 "register_operand" "=D") 
17860         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17861                             (const_int 2))
17862                  (match_operand:DI 3 "register_operand" "0")))
17863    (set (mem:BLK (match_dup 3))
17864         (const_int 0))
17865    (use (match_operand:SI 2 "register_operand" "a"))
17866    (use (match_dup 4))
17867    (use (reg:SI DIRFLAG_REG))]
17868   "TARGET_64BIT"
17869   "{rep\;stosl|rep stosd}"
17870   [(set_attr "type" "str")
17871    (set_attr "prefix_rep" "1")
17872    (set_attr "memory" "store")
17873    (set_attr "mode" "SI")])
17874
17875 (define_insn "*rep_stosqi"
17876   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17877    (set (match_operand:SI 0 "register_operand" "=D") 
17878         (plus:SI (match_operand:SI 3 "register_operand" "0")
17879                  (match_operand:SI 4 "register_operand" "1")))
17880    (set (mem:BLK (match_dup 3))
17881         (const_int 0))
17882    (use (match_operand:QI 2 "register_operand" "a"))
17883    (use (match_dup 4))
17884    (use (reg:SI DIRFLAG_REG))]
17885   "!TARGET_64BIT"
17886   "{rep\;stosb|rep stosb}"
17887   [(set_attr "type" "str")
17888    (set_attr "prefix_rep" "1")
17889    (set_attr "memory" "store")
17890    (set_attr "mode" "QI")])
17891
17892 (define_insn "*rep_stosqi_rex64"
17893   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17894    (set (match_operand:DI 0 "register_operand" "=D") 
17895         (plus:DI (match_operand:DI 3 "register_operand" "0")
17896                  (match_operand:DI 4 "register_operand" "1")))
17897    (set (mem:BLK (match_dup 3))
17898         (const_int 0))
17899    (use (match_operand:QI 2 "register_operand" "a"))
17900    (use (match_dup 4))
17901    (use (reg:SI DIRFLAG_REG))]
17902   "TARGET_64BIT"
17903   "{rep\;stosb|rep stosb}"
17904   [(set_attr "type" "str")
17905    (set_attr "prefix_rep" "1")
17906    (set_attr "memory" "store")
17907    (set_attr "mode" "QI")])
17908
17909 (define_expand "cmpstrnsi"
17910   [(set (match_operand:SI 0 "register_operand" "")
17911         (compare:SI (match_operand:BLK 1 "general_operand" "")
17912                     (match_operand:BLK 2 "general_operand" "")))
17913    (use (match_operand 3 "general_operand" ""))
17914    (use (match_operand 4 "immediate_operand" ""))]
17915   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17916 {
17917   rtx addr1, addr2, out, outlow, count, countreg, align;
17918
17919   /* Can't use this if the user has appropriated esi or edi.  */
17920   if (global_regs[4] || global_regs[5])
17921     FAIL;
17922
17923   out = operands[0];
17924   if (GET_CODE (out) != REG)
17925     out = gen_reg_rtx (SImode);
17926
17927   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17928   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17929   if (addr1 != XEXP (operands[1], 0))
17930     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17931   if (addr2 != XEXP (operands[2], 0))
17932     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17933
17934   count = operands[3];
17935   countreg = ix86_zero_extend_to_Pmode (count);
17936
17937   /* %%% Iff we are testing strict equality, we can use known alignment
17938      to good advantage.  This may be possible with combine, particularly
17939      once cc0 is dead.  */
17940   align = operands[4];
17941
17942   emit_insn (gen_cld ());
17943   if (GET_CODE (count) == CONST_INT)
17944     {
17945       if (INTVAL (count) == 0)
17946         {
17947           emit_move_insn (operands[0], const0_rtx);
17948           DONE;
17949         }
17950       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17951                                      operands[1], operands[2]));
17952     }
17953   else
17954     {
17955       if (TARGET_64BIT)
17956         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17957       else
17958         emit_insn (gen_cmpsi_1 (countreg, countreg));
17959       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17960                                   operands[1], operands[2]));
17961     }
17962
17963   outlow = gen_lowpart (QImode, out);
17964   emit_insn (gen_cmpintqi (outlow));
17965   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17966
17967   if (operands[0] != out)
17968     emit_move_insn (operands[0], out);
17969
17970   DONE;
17971 })
17972
17973 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17974
17975 (define_expand "cmpintqi"
17976   [(set (match_dup 1)
17977         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17978    (set (match_dup 2)
17979         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17980    (parallel [(set (match_operand:QI 0 "register_operand" "")
17981                    (minus:QI (match_dup 1)
17982                              (match_dup 2)))
17983               (clobber (reg:CC FLAGS_REG))])]
17984   ""
17985   "operands[1] = gen_reg_rtx (QImode);
17986    operands[2] = gen_reg_rtx (QImode);")
17987
17988 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17989 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17990
17991 (define_expand "cmpstrnqi_nz_1"
17992   [(parallel [(set (reg:CC FLAGS_REG)
17993                    (compare:CC (match_operand 4 "memory_operand" "")
17994                                (match_operand 5 "memory_operand" "")))
17995               (use (match_operand 2 "register_operand" ""))
17996               (use (match_operand:SI 3 "immediate_operand" ""))
17997               (use (reg:SI DIRFLAG_REG))
17998               (clobber (match_operand 0 "register_operand" ""))
17999               (clobber (match_operand 1 "register_operand" ""))
18000               (clobber (match_dup 2))])]
18001   ""
18002   "")
18003
18004 (define_insn "*cmpstrnqi_nz_1"
18005   [(set (reg:CC FLAGS_REG)
18006         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18007                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18008    (use (match_operand:SI 6 "register_operand" "2"))
18009    (use (match_operand:SI 3 "immediate_operand" "i"))
18010    (use (reg:SI DIRFLAG_REG))
18011    (clobber (match_operand:SI 0 "register_operand" "=S"))
18012    (clobber (match_operand:SI 1 "register_operand" "=D"))
18013    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18014   "!TARGET_64BIT"
18015   "repz{\;| }cmpsb"
18016   [(set_attr "type" "str")
18017    (set_attr "mode" "QI")
18018    (set_attr "prefix_rep" "1")])
18019
18020 (define_insn "*cmpstrnqi_nz_rex_1"
18021   [(set (reg:CC FLAGS_REG)
18022         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18023                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18024    (use (match_operand:DI 6 "register_operand" "2"))
18025    (use (match_operand:SI 3 "immediate_operand" "i"))
18026    (use (reg:SI DIRFLAG_REG))
18027    (clobber (match_operand:DI 0 "register_operand" "=S"))
18028    (clobber (match_operand:DI 1 "register_operand" "=D"))
18029    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18030   "TARGET_64BIT"
18031   "repz{\;| }cmpsb"
18032   [(set_attr "type" "str")
18033    (set_attr "mode" "QI")
18034    (set_attr "prefix_rep" "1")])
18035
18036 ;; The same, but the count is not known to not be zero.
18037
18038 (define_expand "cmpstrnqi_1"
18039   [(parallel [(set (reg:CC FLAGS_REG)
18040                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18041                                      (const_int 0))
18042                   (compare:CC (match_operand 4 "memory_operand" "")
18043                               (match_operand 5 "memory_operand" ""))
18044                   (const_int 0)))
18045               (use (match_operand:SI 3 "immediate_operand" ""))
18046               (use (reg:CC FLAGS_REG))
18047               (use (reg:SI DIRFLAG_REG))
18048               (clobber (match_operand 0 "register_operand" ""))
18049               (clobber (match_operand 1 "register_operand" ""))
18050               (clobber (match_dup 2))])]
18051   ""
18052   "")
18053
18054 (define_insn "*cmpstrnqi_1"
18055   [(set (reg:CC FLAGS_REG)
18056         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18057                              (const_int 0))
18058           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18059                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18060           (const_int 0)))
18061    (use (match_operand:SI 3 "immediate_operand" "i"))
18062    (use (reg:CC FLAGS_REG))
18063    (use (reg:SI DIRFLAG_REG))
18064    (clobber (match_operand:SI 0 "register_operand" "=S"))
18065    (clobber (match_operand:SI 1 "register_operand" "=D"))
18066    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18067   "!TARGET_64BIT"
18068   "repz{\;| }cmpsb"
18069   [(set_attr "type" "str")
18070    (set_attr "mode" "QI")
18071    (set_attr "prefix_rep" "1")])
18072
18073 (define_insn "*cmpstrnqi_rex_1"
18074   [(set (reg:CC FLAGS_REG)
18075         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18076                              (const_int 0))
18077           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18078                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18079           (const_int 0)))
18080    (use (match_operand:SI 3 "immediate_operand" "i"))
18081    (use (reg:CC FLAGS_REG))
18082    (use (reg:SI DIRFLAG_REG))
18083    (clobber (match_operand:DI 0 "register_operand" "=S"))
18084    (clobber (match_operand:DI 1 "register_operand" "=D"))
18085    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18086   "TARGET_64BIT"
18087   "repz{\;| }cmpsb"
18088   [(set_attr "type" "str")
18089    (set_attr "mode" "QI")
18090    (set_attr "prefix_rep" "1")])
18091
18092 (define_expand "strlensi"
18093   [(set (match_operand:SI 0 "register_operand" "")
18094         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18095                     (match_operand:QI 2 "immediate_operand" "")
18096                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18097   ""
18098 {
18099  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18100    DONE;
18101  else
18102    FAIL;
18103 })
18104
18105 (define_expand "strlendi"
18106   [(set (match_operand:DI 0 "register_operand" "")
18107         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18108                     (match_operand:QI 2 "immediate_operand" "")
18109                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18110   ""
18111 {
18112  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18113    DONE;
18114  else
18115    FAIL;
18116 })
18117
18118 (define_expand "strlenqi_1"
18119   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18120               (use (reg:SI DIRFLAG_REG))
18121               (clobber (match_operand 1 "register_operand" ""))
18122               (clobber (reg:CC FLAGS_REG))])]
18123   ""
18124   "")
18125
18126 (define_insn "*strlenqi_1"
18127   [(set (match_operand:SI 0 "register_operand" "=&c")
18128         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18129                     (match_operand:QI 2 "register_operand" "a")
18130                     (match_operand:SI 3 "immediate_operand" "i")
18131                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18132    (use (reg:SI DIRFLAG_REG))
18133    (clobber (match_operand:SI 1 "register_operand" "=D"))
18134    (clobber (reg:CC FLAGS_REG))]
18135   "!TARGET_64BIT"
18136   "repnz{\;| }scasb"
18137   [(set_attr "type" "str")
18138    (set_attr "mode" "QI")
18139    (set_attr "prefix_rep" "1")])
18140
18141 (define_insn "*strlenqi_rex_1"
18142   [(set (match_operand:DI 0 "register_operand" "=&c")
18143         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18144                     (match_operand:QI 2 "register_operand" "a")
18145                     (match_operand:DI 3 "immediate_operand" "i")
18146                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18147    (use (reg:SI DIRFLAG_REG))
18148    (clobber (match_operand:DI 1 "register_operand" "=D"))
18149    (clobber (reg:CC FLAGS_REG))]
18150   "TARGET_64BIT"
18151   "repnz{\;| }scasb"
18152   [(set_attr "type" "str")
18153    (set_attr "mode" "QI")
18154    (set_attr "prefix_rep" "1")])
18155
18156 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18157 ;; handled in combine, but it is not currently up to the task.
18158 ;; When used for their truth value, the cmpstrn* expanders generate
18159 ;; code like this:
18160 ;;
18161 ;;   repz cmpsb
18162 ;;   seta       %al
18163 ;;   setb       %dl
18164 ;;   cmpb       %al, %dl
18165 ;;   jcc        label
18166 ;;
18167 ;; The intermediate three instructions are unnecessary.
18168
18169 ;; This one handles cmpstrn*_nz_1...
18170 (define_peephole2
18171   [(parallel[
18172      (set (reg:CC FLAGS_REG)
18173           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18174                       (mem:BLK (match_operand 5 "register_operand" ""))))
18175      (use (match_operand 6 "register_operand" ""))
18176      (use (match_operand:SI 3 "immediate_operand" ""))
18177      (use (reg:SI DIRFLAG_REG))
18178      (clobber (match_operand 0 "register_operand" ""))
18179      (clobber (match_operand 1 "register_operand" ""))
18180      (clobber (match_operand 2 "register_operand" ""))])
18181    (set (match_operand:QI 7 "register_operand" "")
18182         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183    (set (match_operand:QI 8 "register_operand" "")
18184         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18185    (set (reg FLAGS_REG)
18186         (compare (match_dup 7) (match_dup 8)))
18187   ]
18188   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18189   [(parallel[
18190      (set (reg:CC FLAGS_REG)
18191           (compare:CC (mem:BLK (match_dup 4))
18192                       (mem:BLK (match_dup 5))))
18193      (use (match_dup 6))
18194      (use (match_dup 3))
18195      (use (reg:SI DIRFLAG_REG))
18196      (clobber (match_dup 0))
18197      (clobber (match_dup 1))
18198      (clobber (match_dup 2))])]
18199   "")
18200
18201 ;; ...and this one handles cmpstrn*_1.
18202 (define_peephole2
18203   [(parallel[
18204      (set (reg:CC FLAGS_REG)
18205           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18206                                (const_int 0))
18207             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18208                         (mem:BLK (match_operand 5 "register_operand" "")))
18209             (const_int 0)))
18210      (use (match_operand:SI 3 "immediate_operand" ""))
18211      (use (reg:CC FLAGS_REG))
18212      (use (reg:SI DIRFLAG_REG))
18213      (clobber (match_operand 0 "register_operand" ""))
18214      (clobber (match_operand 1 "register_operand" ""))
18215      (clobber (match_operand 2 "register_operand" ""))])
18216    (set (match_operand:QI 7 "register_operand" "")
18217         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18218    (set (match_operand:QI 8 "register_operand" "")
18219         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18220    (set (reg FLAGS_REG)
18221         (compare (match_dup 7) (match_dup 8)))
18222   ]
18223   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18224   [(parallel[
18225      (set (reg:CC FLAGS_REG)
18226           (if_then_else:CC (ne (match_dup 6)
18227                                (const_int 0))
18228             (compare:CC (mem:BLK (match_dup 4))
18229                         (mem:BLK (match_dup 5)))
18230             (const_int 0)))
18231      (use (match_dup 3))
18232      (use (reg:CC FLAGS_REG))
18233      (use (reg:SI DIRFLAG_REG))
18234      (clobber (match_dup 0))
18235      (clobber (match_dup 1))
18236      (clobber (match_dup 2))])]
18237   "")
18238
18239
18240 \f
18241 ;; Conditional move instructions.
18242
18243 (define_expand "movdicc"
18244   [(set (match_operand:DI 0 "register_operand" "")
18245         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18246                          (match_operand:DI 2 "general_operand" "")
18247                          (match_operand:DI 3 "general_operand" "")))]
18248   "TARGET_64BIT"
18249   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18250
18251 (define_insn "x86_movdicc_0_m1_rex64"
18252   [(set (match_operand:DI 0 "register_operand" "=r")
18253         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18254           (const_int -1)
18255           (const_int 0)))
18256    (clobber (reg:CC FLAGS_REG))]
18257   "TARGET_64BIT"
18258   "sbb{q}\t%0, %0"
18259   ; Since we don't have the proper number of operands for an alu insn,
18260   ; fill in all the blanks.
18261   [(set_attr "type" "alu")
18262    (set_attr "pent_pair" "pu")
18263    (set_attr "memory" "none")
18264    (set_attr "imm_disp" "false")
18265    (set_attr "mode" "DI")
18266    (set_attr "length_immediate" "0")])
18267
18268 (define_insn "*movdicc_c_rex64"
18269   [(set (match_operand:DI 0 "register_operand" "=r,r")
18270         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18271                                 [(reg FLAGS_REG) (const_int 0)])
18272                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18273                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18274   "TARGET_64BIT && TARGET_CMOVE
18275    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18276   "@
18277    cmov%O2%C1\t{%2, %0|%0, %2}
18278    cmov%O2%c1\t{%3, %0|%0, %3}"
18279   [(set_attr "type" "icmov")
18280    (set_attr "mode" "DI")])
18281
18282 (define_expand "movsicc"
18283   [(set (match_operand:SI 0 "register_operand" "")
18284         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18285                          (match_operand:SI 2 "general_operand" "")
18286                          (match_operand:SI 3 "general_operand" "")))]
18287   ""
18288   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18289
18290 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18291 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18292 ;; So just document what we're doing explicitly.
18293
18294 (define_insn "x86_movsicc_0_m1"
18295   [(set (match_operand:SI 0 "register_operand" "=r")
18296         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18297           (const_int -1)
18298           (const_int 0)))
18299    (clobber (reg:CC FLAGS_REG))]
18300   ""
18301   "sbb{l}\t%0, %0"
18302   ; Since we don't have the proper number of operands for an alu insn,
18303   ; fill in all the blanks.
18304   [(set_attr "type" "alu")
18305    (set_attr "pent_pair" "pu")
18306    (set_attr "memory" "none")
18307    (set_attr "imm_disp" "false")
18308    (set_attr "mode" "SI")
18309    (set_attr "length_immediate" "0")])
18310
18311 (define_insn "*movsicc_noc"
18312   [(set (match_operand:SI 0 "register_operand" "=r,r")
18313         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18314                                 [(reg FLAGS_REG) (const_int 0)])
18315                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18316                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18317   "TARGET_CMOVE
18318    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18319   "@
18320    cmov%O2%C1\t{%2, %0|%0, %2}
18321    cmov%O2%c1\t{%3, %0|%0, %3}"
18322   [(set_attr "type" "icmov")
18323    (set_attr "mode" "SI")])
18324
18325 (define_expand "movhicc"
18326   [(set (match_operand:HI 0 "register_operand" "")
18327         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18328                          (match_operand:HI 2 "general_operand" "")
18329                          (match_operand:HI 3 "general_operand" "")))]
18330   "TARGET_HIMODE_MATH"
18331   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18332
18333 (define_insn "*movhicc_noc"
18334   [(set (match_operand:HI 0 "register_operand" "=r,r")
18335         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18336                                 [(reg FLAGS_REG) (const_int 0)])
18337                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18338                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18339   "TARGET_CMOVE
18340    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18341   "@
18342    cmov%O2%C1\t{%2, %0|%0, %2}
18343    cmov%O2%c1\t{%3, %0|%0, %3}"
18344   [(set_attr "type" "icmov")
18345    (set_attr "mode" "HI")])
18346
18347 (define_expand "movqicc"
18348   [(set (match_operand:QI 0 "register_operand" "")
18349         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18350                          (match_operand:QI 2 "general_operand" "")
18351                          (match_operand:QI 3 "general_operand" "")))]
18352   "TARGET_QIMODE_MATH"
18353   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18354
18355 (define_insn_and_split "*movqicc_noc"
18356   [(set (match_operand:QI 0 "register_operand" "=r,r")
18357         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18358                                 [(match_operand 4 "flags_reg_operand" "")
18359                                  (const_int 0)])
18360                       (match_operand:QI 2 "register_operand" "r,0")
18361                       (match_operand:QI 3 "register_operand" "0,r")))]
18362   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18363   "#"
18364   "&& reload_completed"
18365   [(set (match_dup 0)
18366         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18367                       (match_dup 2)
18368                       (match_dup 3)))]
18369   "operands[0] = gen_lowpart (SImode, operands[0]);
18370    operands[2] = gen_lowpart (SImode, operands[2]);
18371    operands[3] = gen_lowpart (SImode, operands[3]);"
18372   [(set_attr "type" "icmov")
18373    (set_attr "mode" "SI")])
18374
18375 (define_expand "movsfcc"
18376   [(set (match_operand:SF 0 "register_operand" "")
18377         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18378                          (match_operand:SF 2 "register_operand" "")
18379                          (match_operand:SF 3 "register_operand" "")))]
18380   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18381   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18382
18383 (define_insn "*movsfcc_1_387"
18384   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18385         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18386                                 [(reg FLAGS_REG) (const_int 0)])
18387                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18388                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18389   "TARGET_80387 && TARGET_CMOVE
18390    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18391   "@
18392    fcmov%F1\t{%2, %0|%0, %2}
18393    fcmov%f1\t{%3, %0|%0, %3}
18394    cmov%O2%C1\t{%2, %0|%0, %2}
18395    cmov%O2%c1\t{%3, %0|%0, %3}"
18396   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18397    (set_attr "mode" "SF,SF,SI,SI")])
18398
18399 (define_expand "movdfcc"
18400   [(set (match_operand:DF 0 "register_operand" "")
18401         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18402                          (match_operand:DF 2 "register_operand" "")
18403                          (match_operand:DF 3 "register_operand" "")))]
18404   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18405   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18406
18407 (define_insn "*movdfcc_1"
18408   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18409         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18410                                 [(reg FLAGS_REG) (const_int 0)])
18411                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18412                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18413   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18414    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18415   "@
18416    fcmov%F1\t{%2, %0|%0, %2}
18417    fcmov%f1\t{%3, %0|%0, %3}
18418    #
18419    #"
18420   [(set_attr "type" "fcmov,fcmov,multi,multi")
18421    (set_attr "mode" "DF")])
18422
18423 (define_insn "*movdfcc_1_rex64"
18424   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18425         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18426                                 [(reg FLAGS_REG) (const_int 0)])
18427                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18428                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18429   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18430    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18431   "@
18432    fcmov%F1\t{%2, %0|%0, %2}
18433    fcmov%f1\t{%3, %0|%0, %3}
18434    cmov%O2%C1\t{%2, %0|%0, %2}
18435    cmov%O2%c1\t{%3, %0|%0, %3}"
18436   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18437    (set_attr "mode" "DF")])
18438
18439 (define_split
18440   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18441         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18442                                 [(match_operand 4 "flags_reg_operand" "")
18443                                  (const_int 0)])
18444                       (match_operand:DF 2 "nonimmediate_operand" "")
18445                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18446   "!TARGET_64BIT && reload_completed"
18447   [(set (match_dup 2)
18448         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18449                       (match_dup 5)
18450                       (match_dup 7)))
18451    (set (match_dup 3)
18452         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18453                       (match_dup 6)
18454                       (match_dup 8)))]
18455   "split_di (operands+2, 1, operands+5, operands+6);
18456    split_di (operands+3, 1, operands+7, operands+8);
18457    split_di (operands, 1, operands+2, operands+3);")
18458
18459 (define_expand "movxfcc"
18460   [(set (match_operand:XF 0 "register_operand" "")
18461         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18462                          (match_operand:XF 2 "register_operand" "")
18463                          (match_operand:XF 3 "register_operand" "")))]
18464   "TARGET_80387 && TARGET_CMOVE"
18465   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18466
18467 (define_insn "*movxfcc_1"
18468   [(set (match_operand:XF 0 "register_operand" "=f,f")
18469         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18470                                 [(reg FLAGS_REG) (const_int 0)])
18471                       (match_operand:XF 2 "register_operand" "f,0")
18472                       (match_operand:XF 3 "register_operand" "0,f")))]
18473   "TARGET_80387 && TARGET_CMOVE"
18474   "@
18475    fcmov%F1\t{%2, %0|%0, %2}
18476    fcmov%f1\t{%3, %0|%0, %3}"
18477   [(set_attr "type" "fcmov")
18478    (set_attr "mode" "XF")])
18479
18480 ;; These versions of the min/max patterns are intentionally ignorant of
18481 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18482 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18483 ;; are undefined in this condition, we're certain this is correct.
18484
18485 (define_insn "sminsf3"
18486   [(set (match_operand:SF 0 "register_operand" "=x")
18487         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18488                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18489   "TARGET_SSE_MATH"
18490   "minss\t{%2, %0|%0, %2}"
18491   [(set_attr "type" "sseadd")
18492    (set_attr "mode" "SF")])
18493
18494 (define_insn "smaxsf3"
18495   [(set (match_operand:SF 0 "register_operand" "=x")
18496         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18497                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18498   "TARGET_SSE_MATH"
18499   "maxss\t{%2, %0|%0, %2}"
18500   [(set_attr "type" "sseadd")
18501    (set_attr "mode" "SF")])
18502
18503 (define_insn "smindf3"
18504   [(set (match_operand:DF 0 "register_operand" "=x")
18505         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18506                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18507   "TARGET_SSE2 && TARGET_SSE_MATH"
18508   "minsd\t{%2, %0|%0, %2}"
18509   [(set_attr "type" "sseadd")
18510    (set_attr "mode" "DF")])
18511
18512 (define_insn "smaxdf3"
18513   [(set (match_operand:DF 0 "register_operand" "=x")
18514         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18515                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18516   "TARGET_SSE2 && TARGET_SSE_MATH"
18517   "maxsd\t{%2, %0|%0, %2}"
18518   [(set_attr "type" "sseadd")
18519    (set_attr "mode" "DF")])
18520
18521 ;; These versions of the min/max patterns implement exactly the operations
18522 ;;   min = (op1 < op2 ? op1 : op2)
18523 ;;   max = (!(op1 < op2) ? op1 : op2)
18524 ;; Their operands are not commutative, and thus they may be used in the
18525 ;; presence of -0.0 and NaN.
18526
18527 (define_insn "*ieee_sminsf3"
18528   [(set (match_operand:SF 0 "register_operand" "=x")
18529         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18530                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18531                    UNSPEC_IEEE_MIN))]
18532   "TARGET_SSE_MATH"
18533   "minss\t{%2, %0|%0, %2}"
18534   [(set_attr "type" "sseadd")
18535    (set_attr "mode" "SF")])
18536
18537 (define_insn "*ieee_smaxsf3"
18538   [(set (match_operand:SF 0 "register_operand" "=x")
18539         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18540                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18541                    UNSPEC_IEEE_MAX))]
18542   "TARGET_SSE_MATH"
18543   "maxss\t{%2, %0|%0, %2}"
18544   [(set_attr "type" "sseadd")
18545    (set_attr "mode" "SF")])
18546
18547 (define_insn "*ieee_smindf3"
18548   [(set (match_operand:DF 0 "register_operand" "=x")
18549         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18550                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18551                    UNSPEC_IEEE_MIN))]
18552   "TARGET_SSE2 && TARGET_SSE_MATH"
18553   "minsd\t{%2, %0|%0, %2}"
18554   [(set_attr "type" "sseadd")
18555    (set_attr "mode" "DF")])
18556
18557 (define_insn "*ieee_smaxdf3"
18558   [(set (match_operand:DF 0 "register_operand" "=x")
18559         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18560                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18561                    UNSPEC_IEEE_MAX))]
18562   "TARGET_SSE2 && TARGET_SSE_MATH"
18563   "maxsd\t{%2, %0|%0, %2}"
18564   [(set_attr "type" "sseadd")
18565    (set_attr "mode" "DF")])
18566
18567 ;; Conditional addition patterns
18568 (define_expand "addqicc"
18569   [(match_operand:QI 0 "register_operand" "")
18570    (match_operand 1 "comparison_operator" "")
18571    (match_operand:QI 2 "register_operand" "")
18572    (match_operand:QI 3 "const_int_operand" "")]
18573   ""
18574   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18575
18576 (define_expand "addhicc"
18577   [(match_operand:HI 0 "register_operand" "")
18578    (match_operand 1 "comparison_operator" "")
18579    (match_operand:HI 2 "register_operand" "")
18580    (match_operand:HI 3 "const_int_operand" "")]
18581   ""
18582   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18583
18584 (define_expand "addsicc"
18585   [(match_operand:SI 0 "register_operand" "")
18586    (match_operand 1 "comparison_operator" "")
18587    (match_operand:SI 2 "register_operand" "")
18588    (match_operand:SI 3 "const_int_operand" "")]
18589   ""
18590   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18591
18592 (define_expand "adddicc"
18593   [(match_operand:DI 0 "register_operand" "")
18594    (match_operand 1 "comparison_operator" "")
18595    (match_operand:DI 2 "register_operand" "")
18596    (match_operand:DI 3 "const_int_operand" "")]
18597   "TARGET_64BIT"
18598   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18599
18600 \f
18601 ;; Misc patterns (?)
18602
18603 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18604 ;; Otherwise there will be nothing to keep
18605 ;; 
18606 ;; [(set (reg ebp) (reg esp))]
18607 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18608 ;;  (clobber (eflags)]
18609 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18610 ;;
18611 ;; in proper program order.
18612 (define_insn "pro_epilogue_adjust_stack_1"
18613   [(set (match_operand:SI 0 "register_operand" "=r,r")
18614         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18615                  (match_operand:SI 2 "immediate_operand" "i,i")))
18616    (clobber (reg:CC FLAGS_REG))
18617    (clobber (mem:BLK (scratch)))]
18618   "!TARGET_64BIT"
18619 {
18620   switch (get_attr_type (insn))
18621     {
18622     case TYPE_IMOV:
18623       return "mov{l}\t{%1, %0|%0, %1}";
18624
18625     case TYPE_ALU:
18626       if (GET_CODE (operands[2]) == CONST_INT
18627           && (INTVAL (operands[2]) == 128
18628               || (INTVAL (operands[2]) < 0
18629                   && INTVAL (operands[2]) != -128)))
18630         {
18631           operands[2] = GEN_INT (-INTVAL (operands[2]));
18632           return "sub{l}\t{%2, %0|%0, %2}";
18633         }
18634       return "add{l}\t{%2, %0|%0, %2}";
18635
18636     case TYPE_LEA:
18637       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18638       return "lea{l}\t{%a2, %0|%0, %a2}";
18639
18640     default:
18641       gcc_unreachable ();
18642     }
18643 }
18644   [(set (attr "type")
18645         (cond [(eq_attr "alternative" "0")
18646                  (const_string "alu")
18647                (match_operand:SI 2 "const0_operand" "")
18648                  (const_string "imov")
18649               ]
18650               (const_string "lea")))
18651    (set_attr "mode" "SI")])
18652
18653 (define_insn "pro_epilogue_adjust_stack_rex64"
18654   [(set (match_operand:DI 0 "register_operand" "=r,r")
18655         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18656                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18657    (clobber (reg:CC FLAGS_REG))
18658    (clobber (mem:BLK (scratch)))]
18659   "TARGET_64BIT"
18660 {
18661   switch (get_attr_type (insn))
18662     {
18663     case TYPE_IMOV:
18664       return "mov{q}\t{%1, %0|%0, %1}";
18665
18666     case TYPE_ALU:
18667       if (GET_CODE (operands[2]) == CONST_INT
18668           /* Avoid overflows.  */
18669           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18670           && (INTVAL (operands[2]) == 128
18671               || (INTVAL (operands[2]) < 0
18672                   && INTVAL (operands[2]) != -128)))
18673         {
18674           operands[2] = GEN_INT (-INTVAL (operands[2]));
18675           return "sub{q}\t{%2, %0|%0, %2}";
18676         }
18677       return "add{q}\t{%2, %0|%0, %2}";
18678
18679     case TYPE_LEA:
18680       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18681       return "lea{q}\t{%a2, %0|%0, %a2}";
18682
18683     default:
18684       gcc_unreachable ();
18685     }
18686 }
18687   [(set (attr "type")
18688         (cond [(eq_attr "alternative" "0")
18689                  (const_string "alu")
18690                (match_operand:DI 2 "const0_operand" "")
18691                  (const_string "imov")
18692               ]
18693               (const_string "lea")))
18694    (set_attr "mode" "DI")])
18695
18696 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18697   [(set (match_operand:DI 0 "register_operand" "=r,r")
18698         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18699                  (match_operand:DI 3 "immediate_operand" "i,i")))
18700    (use (match_operand:DI 2 "register_operand" "r,r"))
18701    (clobber (reg:CC FLAGS_REG))
18702    (clobber (mem:BLK (scratch)))]
18703   "TARGET_64BIT"
18704 {
18705   switch (get_attr_type (insn))
18706     {
18707     case TYPE_ALU:
18708       return "add{q}\t{%2, %0|%0, %2}";
18709
18710     case TYPE_LEA:
18711       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18712       return "lea{q}\t{%a2, %0|%0, %a2}";
18713
18714     default:
18715       gcc_unreachable ();
18716     }
18717 }
18718   [(set_attr "type" "alu,lea")
18719    (set_attr "mode" "DI")])
18720
18721 (define_expand "allocate_stack_worker"
18722   [(match_operand:SI 0 "register_operand" "")]
18723   "TARGET_STACK_PROBE"
18724 {
18725   if (reload_completed)
18726     {
18727       if (TARGET_64BIT)
18728         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18729       else
18730         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18731     }
18732   else
18733     {
18734       if (TARGET_64BIT)
18735         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18736       else
18737         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18738     }
18739   DONE;
18740 })
18741
18742 (define_insn "allocate_stack_worker_1"
18743   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18744     UNSPECV_STACK_PROBE)
18745    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18746    (clobber (match_scratch:SI 1 "=0"))
18747    (clobber (reg:CC FLAGS_REG))]
18748   "!TARGET_64BIT && TARGET_STACK_PROBE"
18749   "call\t__alloca"
18750   [(set_attr "type" "multi")
18751    (set_attr "length" "5")])
18752
18753 (define_expand "allocate_stack_worker_postreload"
18754   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18755                                     UNSPECV_STACK_PROBE)
18756               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18757               (clobber (match_dup 0))
18758               (clobber (reg:CC FLAGS_REG))])]
18759   ""
18760   "")
18761
18762 (define_insn "allocate_stack_worker_rex64"
18763   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18764     UNSPECV_STACK_PROBE)
18765    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18766    (clobber (match_scratch:DI 1 "=0"))
18767    (clobber (reg:CC FLAGS_REG))]
18768   "TARGET_64BIT && TARGET_STACK_PROBE"
18769   "call\t__alloca"
18770   [(set_attr "type" "multi")
18771    (set_attr "length" "5")])
18772
18773 (define_expand "allocate_stack_worker_rex64_postreload"
18774   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18775                                     UNSPECV_STACK_PROBE)
18776               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18777               (clobber (match_dup 0))
18778               (clobber (reg:CC FLAGS_REG))])]
18779   ""
18780   "")
18781
18782 (define_expand "allocate_stack"
18783   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18784                    (minus:SI (reg:SI SP_REG)
18785                              (match_operand:SI 1 "general_operand" "")))
18786               (clobber (reg:CC FLAGS_REG))])
18787    (parallel [(set (reg:SI SP_REG)
18788                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18789               (clobber (reg:CC FLAGS_REG))])]
18790   "TARGET_STACK_PROBE"
18791 {
18792 #ifdef CHECK_STACK_LIMIT
18793   if (GET_CODE (operands[1]) == CONST_INT
18794       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18795     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18796                            operands[1]));
18797   else 
18798 #endif
18799     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18800                                                             operands[1])));
18801
18802   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18803   DONE;
18804 })
18805
18806 (define_expand "builtin_setjmp_receiver"
18807   [(label_ref (match_operand 0 "" ""))]
18808   "!TARGET_64BIT && flag_pic"
18809 {
18810   emit_insn (gen_set_got (pic_offset_table_rtx));
18811   DONE;
18812 })
18813 \f
18814 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18815
18816 (define_split
18817   [(set (match_operand 0 "register_operand" "")
18818         (match_operator 3 "promotable_binary_operator"
18819            [(match_operand 1 "register_operand" "")
18820             (match_operand 2 "aligned_operand" "")]))
18821    (clobber (reg:CC FLAGS_REG))]
18822   "! TARGET_PARTIAL_REG_STALL && reload_completed
18823    && ((GET_MODE (operands[0]) == HImode 
18824         && ((!optimize_size && !TARGET_FAST_PREFIX)
18825             || GET_CODE (operands[2]) != CONST_INT
18826             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18827        || (GET_MODE (operands[0]) == QImode 
18828            && (TARGET_PROMOTE_QImode || optimize_size)))"
18829   [(parallel [(set (match_dup 0)
18830                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18831               (clobber (reg:CC FLAGS_REG))])]
18832   "operands[0] = gen_lowpart (SImode, operands[0]);
18833    operands[1] = gen_lowpart (SImode, operands[1]);
18834    if (GET_CODE (operands[3]) != ASHIFT)
18835      operands[2] = gen_lowpart (SImode, operands[2]);
18836    PUT_MODE (operands[3], SImode);")
18837
18838 ; Promote the QImode tests, as i386 has encoding of the AND
18839 ; instruction with 32-bit sign-extended immediate and thus the
18840 ; instruction size is unchanged, except in the %eax case for
18841 ; which it is increased by one byte, hence the ! optimize_size.
18842 (define_split
18843   [(set (match_operand 0 "flags_reg_operand" "")
18844         (match_operator 2 "compare_operator"
18845           [(and (match_operand 3 "aligned_operand" "")
18846                 (match_operand 4 "const_int_operand" ""))
18847            (const_int 0)]))
18848    (set (match_operand 1 "register_operand" "")
18849         (and (match_dup 3) (match_dup 4)))]
18850   "! TARGET_PARTIAL_REG_STALL && reload_completed
18851    /* Ensure that the operand will remain sign-extended immediate.  */
18852    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18853    && ! optimize_size
18854    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18855        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18856   [(parallel [(set (match_dup 0)
18857                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18858                                     (const_int 0)]))
18859               (set (match_dup 1)
18860                    (and:SI (match_dup 3) (match_dup 4)))])]
18861 {
18862   operands[4]
18863     = gen_int_mode (INTVAL (operands[4])
18864                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18865   operands[1] = gen_lowpart (SImode, operands[1]);
18866   operands[3] = gen_lowpart (SImode, operands[3]);
18867 })
18868
18869 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18870 ; the TEST instruction with 32-bit sign-extended immediate and thus
18871 ; the instruction size would at least double, which is not what we
18872 ; want even with ! optimize_size.
18873 (define_split
18874   [(set (match_operand 0 "flags_reg_operand" "")
18875         (match_operator 1 "compare_operator"
18876           [(and (match_operand:HI 2 "aligned_operand" "")
18877                 (match_operand:HI 3 "const_int_operand" ""))
18878            (const_int 0)]))]
18879   "! TARGET_PARTIAL_REG_STALL && reload_completed
18880    /* Ensure that the operand will remain sign-extended immediate.  */
18881    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18882    && ! TARGET_FAST_PREFIX
18883    && ! optimize_size"
18884   [(set (match_dup 0)
18885         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18886                          (const_int 0)]))]
18887 {
18888   operands[3]
18889     = gen_int_mode (INTVAL (operands[3])
18890                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18891   operands[2] = gen_lowpart (SImode, operands[2]);
18892 })
18893
18894 (define_split
18895   [(set (match_operand 0 "register_operand" "")
18896         (neg (match_operand 1 "register_operand" "")))
18897    (clobber (reg:CC FLAGS_REG))]
18898   "! TARGET_PARTIAL_REG_STALL && reload_completed
18899    && (GET_MODE (operands[0]) == HImode
18900        || (GET_MODE (operands[0]) == QImode 
18901            && (TARGET_PROMOTE_QImode || optimize_size)))"
18902   [(parallel [(set (match_dup 0)
18903                    (neg:SI (match_dup 1)))
18904               (clobber (reg:CC FLAGS_REG))])]
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         (not (match_operand 1 "register_operand" "")))]
18911   "! TARGET_PARTIAL_REG_STALL && reload_completed
18912    && (GET_MODE (operands[0]) == HImode
18913        || (GET_MODE (operands[0]) == QImode 
18914            && (TARGET_PROMOTE_QImode || optimize_size)))"
18915   [(set (match_dup 0)
18916         (not:SI (match_dup 1)))]
18917   "operands[0] = gen_lowpart (SImode, operands[0]);
18918    operands[1] = gen_lowpart (SImode, operands[1]);")
18919
18920 (define_split 
18921   [(set (match_operand 0 "register_operand" "")
18922         (if_then_else (match_operator 1 "comparison_operator" 
18923                                 [(reg FLAGS_REG) (const_int 0)])
18924                       (match_operand 2 "register_operand" "")
18925                       (match_operand 3 "register_operand" "")))]
18926   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18927    && (GET_MODE (operands[0]) == HImode
18928        || (GET_MODE (operands[0]) == QImode 
18929            && (TARGET_PROMOTE_QImode || optimize_size)))"
18930   [(set (match_dup 0)
18931         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18932   "operands[0] = gen_lowpart (SImode, operands[0]);
18933    operands[2] = gen_lowpart (SImode, operands[2]);
18934    operands[3] = gen_lowpart (SImode, operands[3]);")
18935                         
18936 \f
18937 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18938 ;; transform a complex memory operation into two memory to register operations.
18939
18940 ;; Don't push memory operands
18941 (define_peephole2
18942   [(set (match_operand:SI 0 "push_operand" "")
18943         (match_operand:SI 1 "memory_operand" ""))
18944    (match_scratch:SI 2 "r")]
18945   "!optimize_size && !TARGET_PUSH_MEMORY
18946    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18947   [(set (match_dup 2) (match_dup 1))
18948    (set (match_dup 0) (match_dup 2))]
18949   "")
18950
18951 (define_peephole2
18952   [(set (match_operand:DI 0 "push_operand" "")
18953         (match_operand:DI 1 "memory_operand" ""))
18954    (match_scratch:DI 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 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18962 ;; SImode pushes.
18963 (define_peephole2
18964   [(set (match_operand:SF 0 "push_operand" "")
18965         (match_operand:SF 1 "memory_operand" ""))
18966    (match_scratch:SF 2 "r")]
18967   "!optimize_size && !TARGET_PUSH_MEMORY
18968    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18969   [(set (match_dup 2) (match_dup 1))
18970    (set (match_dup 0) (match_dup 2))]
18971   "")
18972
18973 (define_peephole2
18974   [(set (match_operand:HI 0 "push_operand" "")
18975         (match_operand:HI 1 "memory_operand" ""))
18976    (match_scratch:HI 2 "r")]
18977   "!optimize_size && !TARGET_PUSH_MEMORY
18978    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18979   [(set (match_dup 2) (match_dup 1))
18980    (set (match_dup 0) (match_dup 2))]
18981   "")
18982
18983 (define_peephole2
18984   [(set (match_operand:QI 0 "push_operand" "")
18985         (match_operand:QI 1 "memory_operand" ""))
18986    (match_scratch:QI 2 "q")]
18987   "!optimize_size && !TARGET_PUSH_MEMORY
18988    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18989   [(set (match_dup 2) (match_dup 1))
18990    (set (match_dup 0) (match_dup 2))]
18991   "")
18992
18993 ;; Don't move an immediate directly to memory when the instruction
18994 ;; gets too big.
18995 (define_peephole2
18996   [(match_scratch:SI 1 "r")
18997    (set (match_operand:SI 0 "memory_operand" "")
18998         (const_int 0))]
18999   "! optimize_size
19000    && ! TARGET_USE_MOV0
19001    && TARGET_SPLIT_LONG_MOVES
19002    && get_attr_length (insn) >= ix86_cost->large_insn
19003    && peep2_regno_dead_p (0, FLAGS_REG)"
19004   [(parallel [(set (match_dup 1) (const_int 0))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (set (match_dup 0) (match_dup 1))]
19007   "")
19008
19009 (define_peephole2
19010   [(match_scratch:HI 1 "r")
19011    (set (match_operand:HI 0 "memory_operand" "")
19012         (const_int 0))]
19013   "! optimize_size
19014    && ! TARGET_USE_MOV0
19015    && TARGET_SPLIT_LONG_MOVES
19016    && get_attr_length (insn) >= ix86_cost->large_insn
19017    && peep2_regno_dead_p (0, FLAGS_REG)"
19018   [(parallel [(set (match_dup 2) (const_int 0))
19019               (clobber (reg:CC FLAGS_REG))])
19020    (set (match_dup 0) (match_dup 1))]
19021   "operands[2] = gen_lowpart (SImode, operands[1]);")
19022
19023 (define_peephole2
19024   [(match_scratch:QI 1 "q")
19025    (set (match_operand:QI 0 "memory_operand" "")
19026         (const_int 0))]
19027   "! optimize_size
19028    && ! TARGET_USE_MOV0
19029    && TARGET_SPLIT_LONG_MOVES
19030    && get_attr_length (insn) >= ix86_cost->large_insn
19031    && peep2_regno_dead_p (0, FLAGS_REG)"
19032   [(parallel [(set (match_dup 2) (const_int 0))
19033               (clobber (reg:CC FLAGS_REG))])
19034    (set (match_dup 0) (match_dup 1))]
19035   "operands[2] = gen_lowpart (SImode, operands[1]);")
19036
19037 (define_peephole2
19038   [(match_scratch:SI 2 "r")
19039    (set (match_operand:SI 0 "memory_operand" "")
19040         (match_operand:SI 1 "immediate_operand" ""))]
19041   "! optimize_size
19042    && get_attr_length (insn) >= ix86_cost->large_insn
19043    && TARGET_SPLIT_LONG_MOVES"
19044   [(set (match_dup 2) (match_dup 1))
19045    (set (match_dup 0) (match_dup 2))]
19046   "")
19047
19048 (define_peephole2
19049   [(match_scratch:HI 2 "r")
19050    (set (match_operand:HI 0 "memory_operand" "")
19051         (match_operand:HI 1 "immediate_operand" ""))]
19052   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19053   && TARGET_SPLIT_LONG_MOVES"
19054   [(set (match_dup 2) (match_dup 1))
19055    (set (match_dup 0) (match_dup 2))]
19056   "")
19057
19058 (define_peephole2
19059   [(match_scratch:QI 2 "q")
19060    (set (match_operand:QI 0 "memory_operand" "")
19061         (match_operand:QI 1 "immediate_operand" ""))]
19062   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19063   && TARGET_SPLIT_LONG_MOVES"
19064   [(set (match_dup 2) (match_dup 1))
19065    (set (match_dup 0) (match_dup 2))]
19066   "")
19067
19068 ;; Don't compare memory with zero, load and use a test instead.
19069 (define_peephole2
19070   [(set (match_operand 0 "flags_reg_operand" "")
19071         (match_operator 1 "compare_operator"
19072           [(match_operand:SI 2 "memory_operand" "")
19073            (const_int 0)]))
19074    (match_scratch:SI 3 "r")]
19075   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19076   [(set (match_dup 3) (match_dup 2))
19077    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19078   "")
19079
19080 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19081 ;; Don't split NOTs with a displacement operand, because resulting XOR
19082 ;; will not be pairable anyway.
19083 ;;
19084 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19085 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19086 ;; so this split helps here as well.
19087 ;;
19088 ;; Note: Can't do this as a regular split because we can't get proper
19089 ;; lifetime information then.
19090
19091 (define_peephole2
19092   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19093         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19094   "!optimize_size
19095    && peep2_regno_dead_p (0, FLAGS_REG)
19096    && ((TARGET_PENTIUM 
19097         && (GET_CODE (operands[0]) != MEM
19098             || !memory_displacement_operand (operands[0], SImode)))
19099        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19100   [(parallel [(set (match_dup 0)
19101                    (xor:SI (match_dup 1) (const_int -1)))
19102               (clobber (reg:CC FLAGS_REG))])]
19103   "")
19104
19105 (define_peephole2
19106   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19107         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19108   "!optimize_size
19109    && peep2_regno_dead_p (0, FLAGS_REG)
19110    && ((TARGET_PENTIUM 
19111         && (GET_CODE (operands[0]) != MEM
19112             || !memory_displacement_operand (operands[0], HImode)))
19113        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19114   [(parallel [(set (match_dup 0)
19115                    (xor:HI (match_dup 1) (const_int -1)))
19116               (clobber (reg:CC FLAGS_REG))])]
19117   "")
19118
19119 (define_peephole2
19120   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19121         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19122   "!optimize_size
19123    && peep2_regno_dead_p (0, FLAGS_REG)
19124    && ((TARGET_PENTIUM 
19125         && (GET_CODE (operands[0]) != MEM
19126             || !memory_displacement_operand (operands[0], QImode)))
19127        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19128   [(parallel [(set (match_dup 0)
19129                    (xor:QI (match_dup 1) (const_int -1)))
19130               (clobber (reg:CC FLAGS_REG))])]
19131   "")
19132
19133 ;; Non pairable "test imm, reg" instructions can be translated to
19134 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19135 ;; byte opcode instead of two, have a short form for byte operands),
19136 ;; so do it for other CPUs as well.  Given that the value was dead,
19137 ;; this should not create any new dependencies.  Pass on the sub-word
19138 ;; versions if we're concerned about partial register stalls.
19139
19140 (define_peephole2
19141   [(set (match_operand 0 "flags_reg_operand" "")
19142         (match_operator 1 "compare_operator"
19143           [(and:SI (match_operand:SI 2 "register_operand" "")
19144                    (match_operand:SI 3 "immediate_operand" ""))
19145            (const_int 0)]))]
19146   "ix86_match_ccmode (insn, CCNOmode)
19147    && (true_regnum (operands[2]) != 0
19148        || (GET_CODE (operands[3]) == CONST_INT
19149            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19150    && peep2_reg_dead_p (1, operands[2])"
19151   [(parallel
19152      [(set (match_dup 0)
19153            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19154                             (const_int 0)]))
19155       (set (match_dup 2)
19156            (and:SI (match_dup 2) (match_dup 3)))])]
19157   "")
19158
19159 ;; We don't need to handle HImode case, because it will be promoted to SImode
19160 ;; on ! TARGET_PARTIAL_REG_STALL
19161
19162 (define_peephole2
19163   [(set (match_operand 0 "flags_reg_operand" "")
19164         (match_operator 1 "compare_operator"
19165           [(and:QI (match_operand:QI 2 "register_operand" "")
19166                    (match_operand:QI 3 "immediate_operand" ""))
19167            (const_int 0)]))]
19168   "! TARGET_PARTIAL_REG_STALL
19169    && ix86_match_ccmode (insn, CCNOmode)
19170    && true_regnum (operands[2]) != 0
19171    && peep2_reg_dead_p (1, operands[2])"
19172   [(parallel
19173      [(set (match_dup 0)
19174            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19175                             (const_int 0)]))
19176       (set (match_dup 2)
19177            (and:QI (match_dup 2) (match_dup 3)))])]
19178   "")
19179
19180 (define_peephole2
19181   [(set (match_operand 0 "flags_reg_operand" "")
19182         (match_operator 1 "compare_operator"
19183           [(and:SI
19184              (zero_extract:SI
19185                (match_operand 2 "ext_register_operand" "")
19186                (const_int 8)
19187                (const_int 8))
19188              (match_operand 3 "const_int_operand" ""))
19189            (const_int 0)]))]
19190   "! TARGET_PARTIAL_REG_STALL
19191    && ix86_match_ccmode (insn, CCNOmode)
19192    && true_regnum (operands[2]) != 0
19193    && peep2_reg_dead_p (1, operands[2])"
19194   [(parallel [(set (match_dup 0)
19195                    (match_op_dup 1
19196                      [(and:SI
19197                         (zero_extract:SI
19198                           (match_dup 2)
19199                           (const_int 8)
19200                           (const_int 8))
19201                         (match_dup 3))
19202                       (const_int 0)]))
19203               (set (zero_extract:SI (match_dup 2)
19204                                     (const_int 8)
19205                                     (const_int 8))
19206                    (and:SI 
19207                      (zero_extract:SI
19208                        (match_dup 2)
19209                        (const_int 8)
19210                        (const_int 8))
19211                      (match_dup 3)))])]
19212   "")
19213
19214 ;; Don't do logical operations with memory inputs.
19215 (define_peephole2
19216   [(match_scratch:SI 2 "r")
19217    (parallel [(set (match_operand:SI 0 "register_operand" "")
19218                    (match_operator:SI 3 "arith_or_logical_operator"
19219                      [(match_dup 0)
19220                       (match_operand:SI 1 "memory_operand" "")]))
19221               (clobber (reg:CC FLAGS_REG))])]
19222   "! optimize_size && ! TARGET_READ_MODIFY"
19223   [(set (match_dup 2) (match_dup 1))
19224    (parallel [(set (match_dup 0)
19225                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19226               (clobber (reg:CC FLAGS_REG))])]
19227   "")
19228
19229 (define_peephole2
19230   [(match_scratch:SI 2 "r")
19231    (parallel [(set (match_operand:SI 0 "register_operand" "")
19232                    (match_operator:SI 3 "arith_or_logical_operator"
19233                      [(match_operand:SI 1 "memory_operand" "")
19234                       (match_dup 0)]))
19235               (clobber (reg:CC FLAGS_REG))])]
19236   "! optimize_size && ! TARGET_READ_MODIFY"
19237   [(set (match_dup 2) (match_dup 1))
19238    (parallel [(set (match_dup 0)
19239                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19240               (clobber (reg:CC FLAGS_REG))])]
19241   "")
19242
19243 ; Don't do logical operations with memory outputs
19244 ;
19245 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19246 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19247 ; the same decoder scheduling characteristics as the original.
19248
19249 (define_peephole2
19250   [(match_scratch:SI 2 "r")
19251    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19252                    (match_operator:SI 3 "arith_or_logical_operator"
19253                      [(match_dup 0)
19254                       (match_operand:SI 1 "nonmemory_operand" "")]))
19255               (clobber (reg:CC FLAGS_REG))])]
19256   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19257   [(set (match_dup 2) (match_dup 0))
19258    (parallel [(set (match_dup 2)
19259                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19260               (clobber (reg:CC FLAGS_REG))])
19261    (set (match_dup 0) (match_dup 2))]
19262   "")
19263
19264 (define_peephole2
19265   [(match_scratch:SI 2 "r")
19266    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19267                    (match_operator:SI 3 "arith_or_logical_operator"
19268                      [(match_operand:SI 1 "nonmemory_operand" "")
19269                       (match_dup 0)]))
19270               (clobber (reg:CC FLAGS_REG))])]
19271   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19272   [(set (match_dup 2) (match_dup 0))
19273    (parallel [(set (match_dup 2)
19274                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19275               (clobber (reg:CC FLAGS_REG))])
19276    (set (match_dup 0) (match_dup 2))]
19277   "")
19278
19279 ;; Attempt to always use XOR for zeroing registers.
19280 (define_peephole2
19281   [(set (match_operand 0 "register_operand" "")
19282         (match_operand 1 "const0_operand" ""))]
19283   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19284    && (! TARGET_USE_MOV0 || optimize_size)
19285    && GENERAL_REG_P (operands[0])
19286    && peep2_regno_dead_p (0, FLAGS_REG)"
19287   [(parallel [(set (match_dup 0) (const_int 0))
19288               (clobber (reg:CC FLAGS_REG))])]
19289 {
19290   operands[0] = gen_lowpart (word_mode, operands[0]);
19291 })
19292
19293 (define_peephole2
19294   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19295         (const_int 0))]
19296   "(GET_MODE (operands[0]) == QImode
19297     || GET_MODE (operands[0]) == HImode)
19298    && (! TARGET_USE_MOV0 || optimize_size)
19299    && peep2_regno_dead_p (0, FLAGS_REG)"
19300   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19301               (clobber (reg:CC FLAGS_REG))])])
19302
19303 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19304 (define_peephole2
19305   [(set (match_operand 0 "register_operand" "")
19306         (const_int -1))]
19307   "(GET_MODE (operands[0]) == HImode
19308     || GET_MODE (operands[0]) == SImode 
19309     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19310    && (optimize_size || TARGET_PENTIUM)
19311    && peep2_regno_dead_p (0, FLAGS_REG)"
19312   [(parallel [(set (match_dup 0) (const_int -1))
19313               (clobber (reg:CC FLAGS_REG))])]
19314   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19315                               operands[0]);")
19316
19317 ;; Attempt to convert simple leas to adds. These can be created by
19318 ;; move expanders.
19319 (define_peephole2
19320   [(set (match_operand:SI 0 "register_operand" "")
19321         (plus:SI (match_dup 0)
19322                  (match_operand:SI 1 "nonmemory_operand" "")))]
19323   "peep2_regno_dead_p (0, FLAGS_REG)"
19324   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19325               (clobber (reg:CC FLAGS_REG))])]
19326   "")
19327
19328 (define_peephole2
19329   [(set (match_operand:SI 0 "register_operand" "")
19330         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19331                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19332   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19333   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19334               (clobber (reg:CC FLAGS_REG))])]
19335   "operands[2] = gen_lowpart (SImode, operands[2]);")
19336
19337 (define_peephole2
19338   [(set (match_operand:DI 0 "register_operand" "")
19339         (plus:DI (match_dup 0)
19340                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19341   "peep2_regno_dead_p (0, FLAGS_REG)"
19342   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19343               (clobber (reg:CC FLAGS_REG))])]
19344   "")
19345
19346 (define_peephole2
19347   [(set (match_operand:SI 0 "register_operand" "")
19348         (mult:SI (match_dup 0)
19349                  (match_operand:SI 1 "const_int_operand" "")))]
19350   "exact_log2 (INTVAL (operands[1])) >= 0
19351    && peep2_regno_dead_p (0, FLAGS_REG)"
19352   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19353               (clobber (reg:CC FLAGS_REG))])]
19354   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19355
19356 (define_peephole2
19357   [(set (match_operand:DI 0 "register_operand" "")
19358         (mult:DI (match_dup 0)
19359                  (match_operand:DI 1 "const_int_operand" "")))]
19360   "exact_log2 (INTVAL (operands[1])) >= 0
19361    && peep2_regno_dead_p (0, FLAGS_REG)"
19362   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19363               (clobber (reg:CC FLAGS_REG))])]
19364   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19365
19366 (define_peephole2
19367   [(set (match_operand:SI 0 "register_operand" "")
19368         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19369                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19370   "exact_log2 (INTVAL (operands[2])) >= 0
19371    && REGNO (operands[0]) == REGNO (operands[1])
19372    && peep2_regno_dead_p (0, FLAGS_REG)"
19373   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19374               (clobber (reg:CC FLAGS_REG))])]
19375   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19376
19377 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19378 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19379 ;; many CPUs it is also faster, since special hardware to avoid esp
19380 ;; dependencies is present.
19381
19382 ;; While some of these conversions may be done using splitters, we use peepholes
19383 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19384
19385 ;; Convert prologue esp subtractions to push.
19386 ;; We need register to push.  In order to keep verify_flow_info happy we have
19387 ;; two choices
19388 ;; - use scratch and clobber it in order to avoid dependencies
19389 ;; - use already live register
19390 ;; We can't use the second way right now, since there is no reliable way how to
19391 ;; verify that given register is live.  First choice will also most likely in
19392 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19393 ;; call clobbered registers are dead.  We may want to use base pointer as an
19394 ;; alternative when no register is available later.
19395
19396 (define_peephole2
19397   [(match_scratch:SI 0 "r")
19398    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19399               (clobber (reg:CC FLAGS_REG))
19400               (clobber (mem:BLK (scratch)))])]
19401   "optimize_size || !TARGET_SUB_ESP_4"
19402   [(clobber (match_dup 0))
19403    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19404               (clobber (mem:BLK (scratch)))])])
19405
19406 (define_peephole2
19407   [(match_scratch:SI 0 "r")
19408    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19409               (clobber (reg:CC FLAGS_REG))
19410               (clobber (mem:BLK (scratch)))])]
19411   "optimize_size || !TARGET_SUB_ESP_8"
19412   [(clobber (match_dup 0))
19413    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19414    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19415               (clobber (mem:BLK (scratch)))])])
19416
19417 ;; Convert esp subtractions to push.
19418 (define_peephole2
19419   [(match_scratch:SI 0 "r")
19420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19421               (clobber (reg:CC FLAGS_REG))])]
19422   "optimize_size || !TARGET_SUB_ESP_4"
19423   [(clobber (match_dup 0))
19424    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19425
19426 (define_peephole2
19427   [(match_scratch:SI 0 "r")
19428    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19429               (clobber (reg:CC FLAGS_REG))])]
19430   "optimize_size || !TARGET_SUB_ESP_8"
19431   [(clobber (match_dup 0))
19432    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19433    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19434
19435 ;; Convert epilogue deallocator to pop.
19436 (define_peephole2
19437   [(match_scratch:SI 0 "r")
19438    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19439               (clobber (reg:CC FLAGS_REG))
19440               (clobber (mem:BLK (scratch)))])]
19441   "optimize_size || !TARGET_ADD_ESP_4"
19442   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19443               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19444               (clobber (mem:BLK (scratch)))])]
19445   "")
19446
19447 ;; Two pops case is tricky, since pop causes dependency on destination register.
19448 ;; We use two registers if available.
19449 (define_peephole2
19450   [(match_scratch:SI 0 "r")
19451    (match_scratch:SI 1 "r")
19452    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19453               (clobber (reg:CC FLAGS_REG))
19454               (clobber (mem:BLK (scratch)))])]
19455   "optimize_size || !TARGET_ADD_ESP_8"
19456   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19457               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19458               (clobber (mem:BLK (scratch)))])
19459    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19460               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19461   "")
19462
19463 (define_peephole2
19464   [(match_scratch:SI 0 "r")
19465    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19466               (clobber (reg:CC FLAGS_REG))
19467               (clobber (mem:BLK (scratch)))])]
19468   "optimize_size"
19469   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19470               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19471               (clobber (mem:BLK (scratch)))])
19472    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19473               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19474   "")
19475
19476 ;; Convert esp additions to pop.
19477 (define_peephole2
19478   [(match_scratch:SI 0 "r")
19479    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
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   "")
19485
19486 ;; Two pops case is tricky, since pop causes dependency on destination register.
19487 ;; We use two registers if available.
19488 (define_peephole2
19489   [(match_scratch:SI 0 "r")
19490    (match_scratch:SI 1 "r")
19491    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19492               (clobber (reg:CC FLAGS_REG))])]
19493   ""
19494   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19495               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19496    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19497               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19498   "")
19499
19500 (define_peephole2
19501   [(match_scratch:SI 0 "r")
19502    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19503               (clobber (reg:CC FLAGS_REG))])]
19504   "optimize_size"
19505   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19506               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19507    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19508               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19509   "")
19510 \f
19511 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19512 ;; required and register dies.  Similarly for 128 to plus -128.
19513 (define_peephole2
19514   [(set (match_operand 0 "flags_reg_operand" "")
19515         (match_operator 1 "compare_operator"
19516           [(match_operand 2 "register_operand" "")
19517            (match_operand 3 "const_int_operand" "")]))]
19518   "(INTVAL (operands[3]) == -1
19519     || INTVAL (operands[3]) == 1
19520     || INTVAL (operands[3]) == 128)
19521    && ix86_match_ccmode (insn, CCGCmode)
19522    && peep2_reg_dead_p (1, operands[2])"
19523   [(parallel [(set (match_dup 0)
19524                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19525               (clobber (match_dup 2))])]
19526   "")
19527 \f
19528 (define_peephole2
19529   [(match_scratch:DI 0 "r")
19530    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19531               (clobber (reg:CC FLAGS_REG))
19532               (clobber (mem:BLK (scratch)))])]
19533   "optimize_size || !TARGET_SUB_ESP_4"
19534   [(clobber (match_dup 0))
19535    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19536               (clobber (mem:BLK (scratch)))])])
19537
19538 (define_peephole2
19539   [(match_scratch:DI 0 "r")
19540    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19541               (clobber (reg:CC FLAGS_REG))
19542               (clobber (mem:BLK (scratch)))])]
19543   "optimize_size || !TARGET_SUB_ESP_8"
19544   [(clobber (match_dup 0))
19545    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19546    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19547               (clobber (mem:BLK (scratch)))])])
19548
19549 ;; Convert esp subtractions to push.
19550 (define_peephole2
19551   [(match_scratch:DI 0 "r")
19552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19553               (clobber (reg:CC FLAGS_REG))])]
19554   "optimize_size || !TARGET_SUB_ESP_4"
19555   [(clobber (match_dup 0))
19556    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19557
19558 (define_peephole2
19559   [(match_scratch:DI 0 "r")
19560    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19561               (clobber (reg:CC FLAGS_REG))])]
19562   "optimize_size || !TARGET_SUB_ESP_8"
19563   [(clobber (match_dup 0))
19564    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19565    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19566
19567 ;; Convert epilogue deallocator to pop.
19568 (define_peephole2
19569   [(match_scratch:DI 0 "r")
19570    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19571               (clobber (reg:CC FLAGS_REG))
19572               (clobber (mem:BLK (scratch)))])]
19573   "optimize_size || !TARGET_ADD_ESP_4"
19574   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19575               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19576               (clobber (mem:BLK (scratch)))])]
19577   "")
19578
19579 ;; Two pops case is tricky, since pop causes dependency on destination register.
19580 ;; We use two registers if available.
19581 (define_peephole2
19582   [(match_scratch:DI 0 "r")
19583    (match_scratch:DI 1 "r")
19584    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19585               (clobber (reg:CC FLAGS_REG))
19586               (clobber (mem:BLK (scratch)))])]
19587   "optimize_size || !TARGET_ADD_ESP_8"
19588   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19589               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19590               (clobber (mem:BLK (scratch)))])
19591    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19592               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19593   "")
19594
19595 (define_peephole2
19596   [(match_scratch:DI 0 "r")
19597    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19598               (clobber (reg:CC FLAGS_REG))
19599               (clobber (mem:BLK (scratch)))])]
19600   "optimize_size"
19601   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19602               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19603               (clobber (mem:BLK (scratch)))])
19604    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19605               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19606   "")
19607
19608 ;; Convert esp additions to pop.
19609 (define_peephole2
19610   [(match_scratch:DI 0 "r")
19611    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
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   "")
19617
19618 ;; Two pops case is tricky, since pop causes dependency on destination register.
19619 ;; We use two registers if available.
19620 (define_peephole2
19621   [(match_scratch:DI 0 "r")
19622    (match_scratch:DI 1 "r")
19623    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19624               (clobber (reg:CC FLAGS_REG))])]
19625   ""
19626   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19627               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19628    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19629               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19630   "")
19631
19632 (define_peephole2
19633   [(match_scratch:DI 0 "r")
19634    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19635               (clobber (reg:CC FLAGS_REG))])]
19636   "optimize_size"
19637   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19638               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19639    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19640               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19641   "")
19642 \f
19643 ;; Convert imul by three, five and nine into lea
19644 (define_peephole2
19645   [(parallel
19646     [(set (match_operand:SI 0 "register_operand" "")
19647           (mult:SI (match_operand:SI 1 "register_operand" "")
19648                    (match_operand:SI 2 "const_int_operand" "")))
19649      (clobber (reg:CC FLAGS_REG))])]
19650   "INTVAL (operands[2]) == 3
19651    || INTVAL (operands[2]) == 5
19652    || INTVAL (operands[2]) == 9"
19653   [(set (match_dup 0)
19654         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19655                  (match_dup 1)))]
19656   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19657
19658 (define_peephole2
19659   [(parallel
19660     [(set (match_operand:SI 0 "register_operand" "")
19661           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19662                    (match_operand:SI 2 "const_int_operand" "")))
19663      (clobber (reg:CC FLAGS_REG))])]
19664   "!optimize_size 
19665    && (INTVAL (operands[2]) == 3
19666        || INTVAL (operands[2]) == 5
19667        || INTVAL (operands[2]) == 9)"
19668   [(set (match_dup 0) (match_dup 1))
19669    (set (match_dup 0)
19670         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19671                  (match_dup 0)))]
19672   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19673
19674 (define_peephole2
19675   [(parallel
19676     [(set (match_operand:DI 0 "register_operand" "")
19677           (mult:DI (match_operand:DI 1 "register_operand" "")
19678                    (match_operand:DI 2 "const_int_operand" "")))
19679      (clobber (reg:CC FLAGS_REG))])]
19680   "TARGET_64BIT
19681    && (INTVAL (operands[2]) == 3
19682        || INTVAL (operands[2]) == 5
19683        || INTVAL (operands[2]) == 9)"
19684   [(set (match_dup 0)
19685         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19686                  (match_dup 1)))]
19687   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19688
19689 (define_peephole2
19690   [(parallel
19691     [(set (match_operand:DI 0 "register_operand" "")
19692           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19693                    (match_operand:DI 2 "const_int_operand" "")))
19694      (clobber (reg:CC FLAGS_REG))])]
19695   "TARGET_64BIT
19696    && !optimize_size 
19697    && (INTVAL (operands[2]) == 3
19698        || INTVAL (operands[2]) == 5
19699        || INTVAL (operands[2]) == 9)"
19700   [(set (match_dup 0) (match_dup 1))
19701    (set (match_dup 0)
19702         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19703                  (match_dup 0)))]
19704   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19705
19706 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19707 ;; imul $32bit_imm, reg, reg is direct decoded.
19708 (define_peephole2
19709   [(match_scratch:DI 3 "r")
19710    (parallel [(set (match_operand:DI 0 "register_operand" "")
19711                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19712                             (match_operand:DI 2 "immediate_operand" "")))
19713               (clobber (reg:CC FLAGS_REG))])]
19714   "TARGET_K8 && !optimize_size
19715    && (GET_CODE (operands[2]) != CONST_INT
19716        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19717   [(set (match_dup 3) (match_dup 1))
19718    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19719               (clobber (reg:CC FLAGS_REG))])]
19720 "")
19721
19722 (define_peephole2
19723   [(match_scratch:SI 3 "r")
19724    (parallel [(set (match_operand:SI 0 "register_operand" "")
19725                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19726                             (match_operand:SI 2 "immediate_operand" "")))
19727               (clobber (reg:CC FLAGS_REG))])]
19728   "TARGET_K8 && !optimize_size
19729    && (GET_CODE (operands[2]) != CONST_INT
19730        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19731   [(set (match_dup 3) (match_dup 1))
19732    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19733               (clobber (reg:CC FLAGS_REG))])]
19734 "")
19735
19736 (define_peephole2
19737   [(match_scratch:SI 3 "r")
19738    (parallel [(set (match_operand:DI 0 "register_operand" "")
19739                    (zero_extend:DI
19740                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19741                               (match_operand:SI 2 "immediate_operand" ""))))
19742               (clobber (reg:CC FLAGS_REG))])]
19743   "TARGET_K8 && !optimize_size
19744    && (GET_CODE (operands[2]) != CONST_INT
19745        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19746   [(set (match_dup 3) (match_dup 1))
19747    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19748               (clobber (reg:CC FLAGS_REG))])]
19749 "")
19750
19751 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19752 ;; Convert it into imul reg, reg
19753 ;; It would be better to force assembler to encode instruction using long
19754 ;; immediate, but there is apparently no way to do so.
19755 (define_peephole2
19756   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19757                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19758                             (match_operand:DI 2 "const_int_operand" "")))
19759               (clobber (reg:CC FLAGS_REG))])
19760    (match_scratch:DI 3 "r")]
19761   "TARGET_K8 && !optimize_size
19762    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19763   [(set (match_dup 3) (match_dup 2))
19764    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19765               (clobber (reg:CC FLAGS_REG))])]
19766 {
19767   if (!rtx_equal_p (operands[0], operands[1]))
19768     emit_move_insn (operands[0], operands[1]);
19769 })
19770
19771 (define_peephole2
19772   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19773                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19774                             (match_operand:SI 2 "const_int_operand" "")))
19775               (clobber (reg:CC FLAGS_REG))])
19776    (match_scratch:SI 3 "r")]
19777   "TARGET_K8 && !optimize_size
19778    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19779   [(set (match_dup 3) (match_dup 2))
19780    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19781               (clobber (reg:CC FLAGS_REG))])]
19782 {
19783   if (!rtx_equal_p (operands[0], operands[1]))
19784     emit_move_insn (operands[0], operands[1]);
19785 })
19786
19787 (define_peephole2
19788   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19789                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19790                             (match_operand:HI 2 "immediate_operand" "")))
19791               (clobber (reg:CC FLAGS_REG))])
19792    (match_scratch:HI 3 "r")]
19793   "TARGET_K8 && !optimize_size"
19794   [(set (match_dup 3) (match_dup 2))
19795    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19796               (clobber (reg:CC FLAGS_REG))])]
19797 {
19798   if (!rtx_equal_p (operands[0], operands[1]))
19799     emit_move_insn (operands[0], operands[1]);
19800 })
19801
19802 ;; After splitting up read-modify operations, array accesses with memory
19803 ;; operands might end up in form:
19804 ;;  sall    $2, %eax
19805 ;;  movl    4(%esp), %edx
19806 ;;  addl    %edx, %eax
19807 ;; instead of pre-splitting:
19808 ;;  sall    $2, %eax
19809 ;;  addl    4(%esp), %eax
19810 ;; Turn it into:
19811 ;;  movl    4(%esp), %edx
19812 ;;  leal    (%edx,%eax,4), %eax
19813
19814 (define_peephole2
19815   [(parallel [(set (match_operand 0 "register_operand" "")
19816                    (ashift (match_operand 1 "register_operand" "")
19817                            (match_operand 2 "const_int_operand" "")))
19818                (clobber (reg:CC FLAGS_REG))])
19819    (set (match_operand 3 "register_operand")
19820         (match_operand 4 "x86_64_general_operand" ""))
19821    (parallel [(set (match_operand 5 "register_operand" "")
19822                    (plus (match_operand 6 "register_operand" "")
19823                          (match_operand 7 "register_operand" "")))
19824                    (clobber (reg:CC FLAGS_REG))])]
19825   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19826    /* Validate MODE for lea.  */
19827    && ((!TARGET_PARTIAL_REG_STALL
19828         && (GET_MODE (operands[0]) == QImode
19829             || GET_MODE (operands[0]) == HImode))
19830        || GET_MODE (operands[0]) == SImode 
19831        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19832    /* We reorder load and the shift.  */
19833    && !rtx_equal_p (operands[1], operands[3])
19834    && !reg_overlap_mentioned_p (operands[0], operands[4])
19835    /* Last PLUS must consist of operand 0 and 3.  */
19836    && !rtx_equal_p (operands[0], operands[3])
19837    && (rtx_equal_p (operands[3], operands[6])
19838        || rtx_equal_p (operands[3], operands[7]))
19839    && (rtx_equal_p (operands[0], operands[6])
19840        || rtx_equal_p (operands[0], operands[7]))
19841    /* The intermediate operand 0 must die or be same as output.  */
19842    && (rtx_equal_p (operands[0], operands[5])
19843        || peep2_reg_dead_p (3, operands[0]))"
19844   [(set (match_dup 3) (match_dup 4))
19845    (set (match_dup 0) (match_dup 1))]
19846 {
19847   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19848   int scale = 1 << INTVAL (operands[2]);
19849   rtx index = gen_lowpart (Pmode, operands[1]);
19850   rtx base = gen_lowpart (Pmode, operands[3]);
19851   rtx dest = gen_lowpart (mode, operands[5]);
19852
19853   operands[1] = gen_rtx_PLUS (Pmode, base,
19854                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19855   if (mode != Pmode)
19856     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19857   operands[0] = dest;
19858 })
19859 \f
19860 ;; Call-value patterns last so that the wildcard operand does not
19861 ;; disrupt insn-recog's switch tables.
19862
19863 (define_insn "*call_value_pop_0"
19864   [(set (match_operand 0 "" "")
19865         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19866               (match_operand:SI 2 "" "")))
19867    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19868                             (match_operand:SI 3 "immediate_operand" "")))]
19869   "!TARGET_64BIT"
19870 {
19871   if (SIBLING_CALL_P (insn))
19872     return "jmp\t%P1";
19873   else
19874     return "call\t%P1";
19875 }
19876   [(set_attr "type" "callv")])
19877
19878 (define_insn "*call_value_pop_1"
19879   [(set (match_operand 0 "" "")
19880         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19881               (match_operand:SI 2 "" "")))
19882    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19883                             (match_operand:SI 3 "immediate_operand" "i")))]
19884   "!TARGET_64BIT"
19885 {
19886   if (constant_call_address_operand (operands[1], Pmode))
19887     {
19888       if (SIBLING_CALL_P (insn))
19889         return "jmp\t%P1";
19890       else
19891         return "call\t%P1";
19892     }
19893   if (SIBLING_CALL_P (insn))
19894     return "jmp\t%A1";
19895   else
19896     return "call\t%A1";
19897 }
19898   [(set_attr "type" "callv")])
19899
19900 (define_insn "*call_value_0"
19901   [(set (match_operand 0 "" "")
19902         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19903               (match_operand:SI 2 "" "")))]
19904   "!TARGET_64BIT"
19905 {
19906   if (SIBLING_CALL_P (insn))
19907     return "jmp\t%P1";
19908   else
19909     return "call\t%P1";
19910 }
19911   [(set_attr "type" "callv")])
19912
19913 (define_insn "*call_value_0_rex64"
19914   [(set (match_operand 0 "" "")
19915         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19916               (match_operand:DI 2 "const_int_operand" "")))]
19917   "TARGET_64BIT"
19918 {
19919   if (SIBLING_CALL_P (insn))
19920     return "jmp\t%P1";
19921   else
19922     return "call\t%P1";
19923 }
19924   [(set_attr "type" "callv")])
19925
19926 (define_insn "*call_value_1"
19927   [(set (match_operand 0 "" "")
19928         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19929               (match_operand:SI 2 "" "")))]
19930   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19931 {
19932   if (constant_call_address_operand (operands[1], Pmode))
19933     return "call\t%P1";
19934   return "call\t%A1";
19935 }
19936   [(set_attr "type" "callv")])
19937
19938 (define_insn "*sibcall_value_1"
19939   [(set (match_operand 0 "" "")
19940         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19941               (match_operand:SI 2 "" "")))]
19942   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19943 {
19944   if (constant_call_address_operand (operands[1], Pmode))
19945     return "jmp\t%P1";
19946   return "jmp\t%A1";
19947 }
19948   [(set_attr "type" "callv")])
19949
19950 (define_insn "*call_value_1_rex64"
19951   [(set (match_operand 0 "" "")
19952         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19953               (match_operand:DI 2 "" "")))]
19954   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19955 {
19956   if (constant_call_address_operand (operands[1], Pmode))
19957     return "call\t%P1";
19958   return "call\t%A1";
19959 }
19960   [(set_attr "type" "callv")])
19961
19962 (define_insn "*sibcall_value_1_rex64"
19963   [(set (match_operand 0 "" "")
19964         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19965               (match_operand:DI 2 "" "")))]
19966   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19967   "jmp\t%P1"
19968   [(set_attr "type" "callv")])
19969
19970 (define_insn "*sibcall_value_1_rex64_v"
19971   [(set (match_operand 0 "" "")
19972         (call (mem:QI (reg:DI 40))
19973               (match_operand:DI 1 "" "")))]
19974   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19975   "jmp\t*%%r11"
19976   [(set_attr "type" "callv")])
19977 \f
19978 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19979 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19980 ;; caught for use by garbage collectors and the like.  Using an insn that
19981 ;; maps to SIGILL makes it more likely the program will rightfully die.
19982 ;; Keeping with tradition, "6" is in honor of #UD.
19983 (define_insn "trap"
19984   [(trap_if (const_int 1) (const_int 6))]
19985   ""
19986   ".word\t0x0b0f"
19987   [(set_attr "length" "2")])
19988
19989 (define_expand "sse_prologue_save"
19990   [(parallel [(set (match_operand:BLK 0 "" "")
19991                    (unspec:BLK [(reg:DI 21)
19992                                 (reg:DI 22)
19993                                 (reg:DI 23)
19994                                 (reg:DI 24)
19995                                 (reg:DI 25)
19996                                 (reg:DI 26)
19997                                 (reg:DI 27)
19998                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19999               (use (match_operand:DI 1 "register_operand" ""))
20000               (use (match_operand:DI 2 "immediate_operand" ""))
20001               (use (label_ref:DI (match_operand 3 "" "")))])]
20002   "TARGET_64BIT"
20003   "")
20004
20005 (define_insn "*sse_prologue_save_insn"
20006   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20007                           (match_operand:DI 4 "const_int_operand" "n")))
20008         (unspec:BLK [(reg:DI 21)
20009                      (reg:DI 22)
20010                      (reg:DI 23)
20011                      (reg:DI 24)
20012                      (reg:DI 25)
20013                      (reg:DI 26)
20014                      (reg:DI 27)
20015                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20016    (use (match_operand:DI 1 "register_operand" "r"))
20017    (use (match_operand:DI 2 "const_int_operand" "i"))
20018    (use (label_ref:DI (match_operand 3 "" "X")))]
20019   "TARGET_64BIT
20020    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20021    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20022   "*
20023 {
20024   int i;
20025   operands[0] = gen_rtx_MEM (Pmode,
20026                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20027   output_asm_insn (\"jmp\\t%A1\", operands);
20028   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20029     {
20030       operands[4] = adjust_address (operands[0], DImode, i*16);
20031       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20032       PUT_MODE (operands[4], TImode);
20033       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20034         output_asm_insn (\"rex\", operands);
20035       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20036     }
20037   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20038                              CODE_LABEL_NUMBER (operands[3]));
20039   RET;
20040 }
20041   "
20042   [(set_attr "type" "other")
20043    (set_attr "length_immediate" "0")
20044    (set_attr "length_address" "0")
20045    (set_attr "length" "135")
20046    (set_attr "memory" "store")
20047    (set_attr "modrm" "0")
20048    (set_attr "mode" "DI")])
20049
20050 (define_expand "prefetch"
20051   [(prefetch (match_operand 0 "address_operand" "")
20052              (match_operand:SI 1 "const_int_operand" "")
20053              (match_operand:SI 2 "const_int_operand" ""))]
20054   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20055 {
20056   int rw = INTVAL (operands[1]);
20057   int locality = INTVAL (operands[2]);
20058
20059   gcc_assert (rw == 0 || rw == 1);
20060   gcc_assert (locality >= 0 && locality <= 3);
20061   gcc_assert (GET_MODE (operands[0]) == Pmode
20062               || GET_MODE (operands[0]) == VOIDmode);
20063
20064   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20065      supported by SSE counterpart or the SSE prefetch is not available
20066      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20067      of locality.  */
20068   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20069     operands[2] = GEN_INT (3);
20070   else
20071     operands[1] = const0_rtx;
20072 })
20073
20074 (define_insn "*prefetch_sse"
20075   [(prefetch (match_operand:SI 0 "address_operand" "p")
20076              (const_int 0)
20077              (match_operand:SI 1 "const_int_operand" ""))]
20078   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20079 {
20080   static const char * const patterns[4] = {
20081    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20082   };
20083
20084   int locality = INTVAL (operands[1]);
20085   gcc_assert (locality >= 0 && locality <= 3);
20086
20087   return patterns[locality];  
20088 }
20089   [(set_attr "type" "sse")
20090    (set_attr "memory" "none")])
20091
20092 (define_insn "*prefetch_sse_rex"
20093   [(prefetch (match_operand:DI 0 "address_operand" "p")
20094              (const_int 0)
20095              (match_operand:SI 1 "const_int_operand" ""))]
20096   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20097 {
20098   static const char * const patterns[4] = {
20099    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20100   };
20101
20102   int locality = INTVAL (operands[1]);
20103   gcc_assert (locality >= 0 && locality <= 3);
20104
20105   return patterns[locality];  
20106 }
20107   [(set_attr "type" "sse")
20108    (set_attr "memory" "none")])
20109
20110 (define_insn "*prefetch_3dnow"
20111   [(prefetch (match_operand:SI 0 "address_operand" "p")
20112              (match_operand:SI 1 "const_int_operand" "n")
20113              (const_int 3))]
20114   "TARGET_3DNOW && !TARGET_64BIT"
20115 {
20116   if (INTVAL (operands[1]) == 0)
20117     return "prefetch\t%a0";
20118   else
20119     return "prefetchw\t%a0";
20120 }
20121   [(set_attr "type" "mmx")
20122    (set_attr "memory" "none")])
20123
20124 (define_insn "*prefetch_3dnow_rex"
20125   [(prefetch (match_operand:DI 0 "address_operand" "p")
20126              (match_operand:SI 1 "const_int_operand" "n")
20127              (const_int 3))]
20128   "TARGET_3DNOW && TARGET_64BIT"
20129 {
20130   if (INTVAL (operands[1]) == 0)
20131     return "prefetch\t%a0";
20132   else
20133     return "prefetchw\t%a0";
20134 }
20135   [(set_attr "type" "mmx")
20136    (set_attr "memory" "none")])
20137
20138 (define_expand "stack_protect_set"
20139   [(match_operand 0 "memory_operand" "")
20140    (match_operand 1 "memory_operand" "")]
20141   ""
20142 {
20143 #ifdef TARGET_THREAD_SSP_OFFSET
20144   if (TARGET_64BIT)
20145     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20146                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20147   else
20148     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20149                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20150 #else
20151   if (TARGET_64BIT)
20152     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20153   else
20154     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20155 #endif
20156   DONE;
20157 })
20158
20159 (define_insn "stack_protect_set_si"
20160   [(set (match_operand:SI 0 "memory_operand" "=m")
20161         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20162    (set (match_scratch:SI 2 "=&r") (const_int 0))
20163    (clobber (reg:CC FLAGS_REG))]
20164   ""
20165   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20166   [(set_attr "type" "multi")])
20167
20168 (define_insn "stack_protect_set_di"
20169   [(set (match_operand:DI 0 "memory_operand" "=m")
20170         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20171    (set (match_scratch:DI 2 "=&r") (const_int 0))
20172    (clobber (reg:CC FLAGS_REG))]
20173   "TARGET_64BIT"
20174   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20175   [(set_attr "type" "multi")])
20176
20177 (define_insn "stack_tls_protect_set_si"
20178   [(set (match_operand:SI 0 "memory_operand" "=m")
20179         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20180    (set (match_scratch:SI 2 "=&r") (const_int 0))
20181    (clobber (reg:CC FLAGS_REG))]
20182   ""
20183   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20184   [(set_attr "type" "multi")])
20185
20186 (define_insn "stack_tls_protect_set_di"
20187   [(set (match_operand:DI 0 "memory_operand" "=m")
20188         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20189    (set (match_scratch:DI 2 "=&r") (const_int 0))
20190    (clobber (reg:CC FLAGS_REG))]
20191   "TARGET_64BIT"
20192   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20193   [(set_attr "type" "multi")])
20194
20195 (define_expand "stack_protect_test"
20196   [(match_operand 0 "memory_operand" "")
20197    (match_operand 1 "memory_operand" "")
20198    (match_operand 2 "" "")]
20199   ""
20200 {
20201   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20202   ix86_compare_op0 = operands[0];
20203   ix86_compare_op1 = operands[1];
20204   ix86_compare_emitted = flags;
20205
20206 #ifdef TARGET_THREAD_SSP_OFFSET
20207   if (TARGET_64BIT)
20208     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20209                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20210   else
20211     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20212                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20213 #else
20214   if (TARGET_64BIT)
20215     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20216   else
20217     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20218 #endif
20219   emit_jump_insn (gen_beq (operands[2]));
20220   DONE;
20221 })
20222
20223 (define_insn "stack_protect_test_si"
20224   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20225         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20226                      (match_operand:SI 2 "memory_operand" "m")]
20227                     UNSPEC_SP_TEST))
20228    (clobber (match_scratch:SI 3 "=&r"))]
20229   ""
20230   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20231   [(set_attr "type" "multi")])
20232
20233 (define_insn "stack_protect_test_di"
20234   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20235         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20236                      (match_operand:DI 2 "memory_operand" "m")]
20237                     UNSPEC_SP_TEST))
20238    (clobber (match_scratch:DI 3 "=&r"))]
20239   "TARGET_64BIT"
20240   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20241   [(set_attr "type" "multi")])
20242
20243 (define_insn "stack_tls_protect_test_si"
20244   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20245         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20246                      (match_operand:SI 2 "const_int_operand" "i")]
20247                     UNSPEC_SP_TLS_TEST))
20248    (clobber (match_scratch:SI 3 "=r"))]
20249   ""
20250   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20251   [(set_attr "type" "multi")])
20252
20253 (define_insn "stack_tls_protect_test_di"
20254   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20255         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20256                      (match_operand:DI 2 "const_int_operand" "i")]
20257                     UNSPEC_SP_TLS_TEST))
20258    (clobber (match_scratch:DI 3 "=r"))]
20259   "TARGET_64BIT"
20260   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20261   [(set_attr "type" "multi")])
20262
20263 (include "sse.md")
20264 (include "mmx.md")
20265 (include "sync.md")