OSDN Git Service

997f051414932075c258a843d3ae45656f080594
[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, 2006
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    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151   ])
152
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
169
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191   (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456  
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465  
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates and constraints
479
480 (include "predicates.md")
481 (include "constraints.md")
482
483 \f
484 ;; Compare instructions.
485
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
489
490 (define_expand "cmpti"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493                     (match_operand:TI 1 "x86_64_general_operand" "")))]
494   "TARGET_64BIT"
495 {
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (TImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
501 })
502
503 (define_expand "cmpdi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506                     (match_operand:DI 1 "x86_64_general_operand" "")))]
507   ""
508 {
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (DImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
514 })
515
516 (define_expand "cmpsi"
517   [(set (reg:CC FLAGS_REG)
518         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519                     (match_operand:SI 1 "general_operand" "")))]
520   ""
521 {
522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523     operands[0] = force_reg (SImode, operands[0]);
524   ix86_compare_op0 = operands[0];
525   ix86_compare_op1 = operands[1];
526   DONE;
527 })
528
529 (define_expand "cmphi"
530   [(set (reg:CC FLAGS_REG)
531         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532                     (match_operand:HI 1 "general_operand" "")))]
533   ""
534 {
535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536     operands[0] = force_reg (HImode, operands[0]);
537   ix86_compare_op0 = operands[0];
538   ix86_compare_op1 = operands[1];
539   DONE;
540 })
541
542 (define_expand "cmpqi"
543   [(set (reg:CC FLAGS_REG)
544         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545                     (match_operand:QI 1 "general_operand" "")))]
546   "TARGET_QIMODE_MATH"
547 {
548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549     operands[0] = force_reg (QImode, operands[0]);
550   ix86_compare_op0 = operands[0];
551   ix86_compare_op1 = operands[1];
552   DONE;
553 })
554
555 (define_insn "cmpdi_ccno_1_rex64"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:DI 1 "const0_operand" "n,n")))]
559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{q}\t{%0, %0|%0, %0}
562    cmp{q}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "DI")])
566
567 (define_insn "*cmpdi_minus_1_rex64"
568   [(set (reg FLAGS_REG)
569         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571                  (const_int 0)))]
572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{q}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "DI")])
576
577 (define_expand "cmpdi_1_rex64"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580                     (match_operand:DI 1 "general_operand" "")))]
581   "TARGET_64BIT"
582   "")
583
584 (define_insn "cmpdi_1_insn_rex64"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589   "cmp{q}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "DI")])
592
593
594 (define_insn "*cmpsi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:SI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{l}\t{%0, %0|%0, %0}
601    cmp{l}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "SI")])
605
606 (define_insn "*cmpsi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:SI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{l}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "SI")])
615
616 (define_expand "cmpsi_1"
617   [(set (reg:CC FLAGS_REG)
618         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                     (match_operand:SI 1 "general_operand" "ri,mr")))]
620   ""
621   "")
622
623 (define_insn "*cmpsi_1_insn"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:SI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628     && ix86_match_ccmode (insn, CCmode)"
629   "cmp{l}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "SI")])
632
633 (define_insn "*cmphi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636                  (match_operand:HI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{w}\t{%0, %0|%0, %0}
640    cmp{w}\t{%1, %0|%0, %1}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "HI")])
644
645 (define_insn "*cmphi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648                            (match_operand:HI 1 "general_operand" "ri,mr"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{w}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "HI")])
654
655 (define_insn "*cmphi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658                  (match_operand:HI 1 "general_operand" "ri,mr")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660    && ix86_match_ccmode (insn, CCmode)"
661   "cmp{w}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "HI")])
664
665 (define_insn "*cmpqi_ccno_1"
666   [(set (reg FLAGS_REG)
667         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668                  (match_operand:QI 1 "const0_operand" "n,n")))]
669   "ix86_match_ccmode (insn, CCNOmode)"
670   "@
671    test{b}\t{%0, %0|%0, %0}
672    cmp{b}\t{$0, %0|%0, 0}"
673   [(set_attr "type" "test,icmp")
674    (set_attr "length_immediate" "0,1")
675    (set_attr "mode" "QI")])
676
677 (define_insn "*cmpqi_1"
678   [(set (reg FLAGS_REG)
679         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680                  (match_operand:QI 1 "general_operand" "qi,mq")))]
681   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682     && ix86_match_ccmode (insn, CCmode)"
683   "cmp{b}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "QI")])
686
687 (define_insn "*cmpqi_minus_1"
688   [(set (reg FLAGS_REG)
689         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690                            (match_operand:QI 1 "general_operand" "qi,mq"))
691                  (const_int 0)))]
692   "ix86_match_ccmode (insn, CCGOCmode)"
693   "cmp{b}\t{%1, %0|%0, %1}"
694   [(set_attr "type" "icmp")
695    (set_attr "mode" "QI")])
696
697 (define_insn "*cmpqi_ext_1"
698   [(set (reg FLAGS_REG)
699         (compare
700           (match_operand:QI 0 "general_operand" "Qm")
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 1 "ext_register_operand" "Q")
704               (const_int 8)
705               (const_int 8)) 0)))]
706   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707   "cmp{b}\t{%h1, %0|%0, %h1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1_rex64"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "register_operand" "Q")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_2"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "const0_operand" "n")))]
734   "ix86_match_ccmode (insn, CCNOmode)"
735   "test{b}\t%h0, %h0"
736   [(set_attr "type" "test")
737    (set_attr "length_immediate" "0")
738    (set_attr "mode" "QI")])
739
740 (define_expand "cmpqi_ext_3"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "general_operand" "")))]
749   ""
750   "")
751
752 (define_insn "cmpqi_ext_3_insn"
753   [(set (reg FLAGS_REG)
754         (compare
755           (subreg:QI
756             (zero_extract:SI
757               (match_operand 0 "ext_register_operand" "Q")
758               (const_int 8)
759               (const_int 8)) 0)
760           (match_operand:QI 1 "general_operand" "Qmn")))]
761   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%1, %h0|%h0, %1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
765
766 (define_insn "cmpqi_ext_3_insn_rex64"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
779
780 (define_insn "*cmpqi_ext_4"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (subreg:QI
789             (zero_extract:SI
790               (match_operand 1 "ext_register_operand" "Q")
791               (const_int 8)
792               (const_int 8)) 0)))]
793   "ix86_match_ccmode (insn, CCmode)"
794   "cmp{b}\t{%h1, %h0|%h0, %h1}"
795   [(set_attr "type" "icmp")
796    (set_attr "mode" "QI")])
797
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares.  Which is what
801 ;; the old patterns did, but with many more of them.
802
803 (define_expand "cmpxf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806                     (match_operand:XF 1 "nonmemory_operand" "")))]
807   "TARGET_80387"
808 {
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
812 })
813
814 (define_expand "cmpdf"
815   [(set (reg:CC FLAGS_REG)
816         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819 {
820   ix86_compare_op0 = operands[0];
821   ix86_compare_op1 = operands[1];
822   DONE;
823 })
824
825 (define_expand "cmpsf"
826   [(set (reg:CC FLAGS_REG)
827         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829   "TARGET_80387 || TARGET_SSE_MATH"
830 {
831   ix86_compare_op0 = operands[0];
832   ix86_compare_op1 = operands[1];
833   DONE;
834 })
835
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
838 ;;
839 ;; CCFPmode     compare with exceptions
840 ;; CCFPUmode    compare with no exceptions
841
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
844
845 (define_insn "*cmpfp_0"
846   [(set (match_operand:HI 0 "register_operand" "=a")
847         (unspec:HI
848           [(compare:CCFP
849              (match_operand 1 "register_operand" "f")
850              (match_operand 2 "const0_operand" "X"))]
851         UNSPEC_FNSTSW))]
852   "TARGET_80387
853    && FLOAT_MODE_P (GET_MODE (operands[1]))
854    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "unit" "i387")
858    (set (attr "mode")
859      (cond [(match_operand:SF 1 "" "")
860               (const_string "SF")
861             (match_operand:DF 1 "" "")
862               (const_string "DF")
863            ]
864            (const_string "XF")))])
865
866 (define_insn "*cmpfp_sf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:SF 1 "register_operand" "f")
871              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "unit" "i387")
877    (set_attr "mode" "SF")])
878
879 (define_insn "*cmpfp_df"
880   [(set (match_operand:HI 0 "register_operand" "=a")
881         (unspec:HI
882           [(compare:CCFP
883              (match_operand:DF 1 "register_operand" "f")
884              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885           UNSPEC_FNSTSW))]
886   "TARGET_80387"
887   "* return output_fp_compare (insn, operands, 0, 0);"
888   [(set_attr "type" "multi")
889    (set_attr "unit" "i387")
890    (set_attr "mode" "DF")])
891
892 (define_insn "*cmpfp_xf"
893   [(set (match_operand:HI 0 "register_operand" "=a")
894         (unspec:HI
895           [(compare:CCFP
896              (match_operand:XF 1 "register_operand" "f")
897              (match_operand:XF 2 "register_operand" "f"))]
898           UNSPEC_FNSTSW))]
899   "TARGET_80387"
900   "* return output_fp_compare (insn, operands, 0, 0);"
901   [(set_attr "type" "multi")
902    (set_attr "unit" "i387")
903    (set_attr "mode" "XF")])
904
905 (define_insn "*cmpfp_u"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFPU
909              (match_operand 1 "register_operand" "f")
910              (match_operand 2 "register_operand" "f"))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915   "* return output_fp_compare (insn, operands, 0, 1);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set (attr "mode")
919      (cond [(match_operand:SF 1 "" "")
920               (const_string "SF")
921             (match_operand:DF 1 "" "")
922               (const_string "DF")
923            ]
924            (const_string "XF")))])
925
926 (define_insn "*cmpfp_<mode>"
927   [(set (match_operand:HI 0 "register_operand" "=a")
928         (unspec:HI
929           [(compare:CCFP
930              (match_operand 1 "register_operand" "f")
931              (match_operator 3 "float_operator"
932                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933           UNSPEC_FNSTSW))]
934   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935    && FLOAT_MODE_P (GET_MODE (operands[1]))
936    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937   "* return output_fp_compare (insn, operands, 0, 0);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set_attr "fp_int_src" "true")
941    (set_attr "mode" "<MODE>")])
942
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
945
946 (define_insn "x86_fnstsw_1"
947   [(set (match_operand:HI 0 "register_operand" "=a")
948         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949   "TARGET_80387"
950   "fnstsw\t%0"
951   [(set_attr "length" "2")
952    (set_attr "mode" "SI")
953    (set_attr "unit" "i387")])
954
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
957
958 (define_insn "x86_sahf_1"
959   [(set (reg:CC FLAGS_REG)
960         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961   "!TARGET_64BIT"
962   "sahf"
963   [(set_attr "length" "1")
964    (set_attr "athlon_decode" "vector")
965    (set_attr "mode" "SI")])
966
967 ;; Pentium Pro can do steps 1 through 3 in one go.
968
969 (define_insn "*cmpfp_i_mixed"
970   [(set (reg:CCFP FLAGS_REG)
971         (compare:CCFP (match_operand 0 "register_operand" "f,x")
972                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
973   "TARGET_MIX_SSE_I387
974    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp,ssecomi")
978    (set (attr "mode")
979      (if_then_else (match_operand:SF 1 "" "")
980         (const_string "SF")
981         (const_string "DF")))
982    (set_attr "athlon_decode" "vector")])
983
984 (define_insn "*cmpfp_i_sse"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "x")
987                       (match_operand 1 "nonimmediate_operand" "xm")))]
988   "TARGET_SSE_MATH
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_i387"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "f")
1002                       (match_operand 1 "register_operand" "f")))]
1003   "TARGET_80387 && TARGET_CMOVE
1004    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005    && FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "fcmp")
1009    (set (attr "mode")
1010      (cond [(match_operand:SF 1 "" "")
1011               (const_string "SF")
1012             (match_operand:DF 1 "" "")
1013               (const_string "DF")
1014            ]
1015            (const_string "XF")))
1016    (set_attr "athlon_decode" "vector")])
1017
1018 (define_insn "*cmpfp_iu_mixed"
1019   [(set (reg:CCFPU FLAGS_REG)
1020         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022   "TARGET_MIX_SSE_I387
1023    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp,ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_sse"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "x")
1036                        (match_operand 1 "nonimmediate_operand" "xm")))]
1037   "TARGET_SSE_MATH
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_387"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "f")
1051                        (match_operand 1 "register_operand" "f")))]
1052   "TARGET_80387 && TARGET_CMOVE
1053    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054    && FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "fcmp")
1058    (set (attr "mode")
1059      (cond [(match_operand:SF 1 "" "")
1060               (const_string "SF")
1061             (match_operand:DF 1 "" "")
1062               (const_string "DF")
1063            ]
1064            (const_string "XF")))
1065    (set_attr "athlon_decode" "vector")])
1066 \f
1067 ;; Move instructions.
1068
1069 ;; General case of fullword move.
1070
1071 (define_expand "movsi"
1072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073         (match_operand:SI 1 "general_operand" ""))]
1074   ""
1075   "ix86_expand_move (SImode, operands); DONE;")
1076
1077 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1078 ;; general_operand.
1079 ;;
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1085
1086 (define_insn "*pushsi2"
1087   [(set (match_operand:SI 0 "push_operand" "=<")
1088         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089   "!TARGET_64BIT"
1090   "push{l}\t%1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1093
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096   [(set (match_operand:SI 0 "push_operand" "=X")
1097         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098   "TARGET_64BIT"
1099   "push{q}\t%q1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1102
1103 (define_insn "*pushsi2_prologue"
1104   [(set (match_operand:SI 0 "push_operand" "=<")
1105         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "push{l}\t%1"
1109   [(set_attr "type" "push")
1110    (set_attr "mode" "SI")])
1111
1112 (define_insn "*popsi1_epilogue"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI SP_REG)))
1115    (set (reg:SI SP_REG)
1116         (plus:SI (reg:SI SP_REG) (const_int 4)))
1117    (clobber (mem:BLK (scratch)))]
1118   "!TARGET_64BIT"
1119   "pop{l}\t%0"
1120   [(set_attr "type" "pop")
1121    (set_attr "mode" "SI")])
1122
1123 (define_insn "popsi1"
1124   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125         (mem:SI (reg:SI SP_REG)))
1126    (set (reg:SI SP_REG)
1127         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1128   "!TARGET_64BIT"
1129   "pop{l}\t%0"
1130   [(set_attr "type" "pop")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*movsi_xor"
1134   [(set (match_operand:SI 0 "register_operand" "=r")
1135         (match_operand:SI 1 "const0_operand" "i"))
1136    (clobber (reg:CC FLAGS_REG))]
1137   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138   "xor{l}\t{%0, %0|%0, %0}"
1139   [(set_attr "type" "alu1")
1140    (set_attr "mode" "SI")
1141    (set_attr "length_immediate" "0")])
1142  
1143 (define_insn "*movsi_or"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (match_operand:SI 1 "immediate_operand" "i"))
1146    (clobber (reg:CC FLAGS_REG))]
1147   "reload_completed
1148    && operands[1] == constm1_rtx
1149    && (TARGET_PENTIUM || optimize_size)"
1150 {
1151   operands[1] = constm1_rtx;
1152   return "or{l}\t{%1, %0|%0, %1}";
1153 }
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "1")])
1157
1158 (define_insn "*movsi_1"
1159   [(set (match_operand:SI 0 "nonimmediate_operand"
1160                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161         (match_operand:SI 1 "general_operand"
1162                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164 {
1165   switch (get_attr_type (insn))
1166     {
1167     case TYPE_SSELOG1:
1168       if (get_attr_mode (insn) == MODE_TI)
1169         return "pxor\t%0, %0";
1170       return "xorps\t%0, %0";
1171
1172     case TYPE_SSEMOV:
1173       switch (get_attr_mode (insn))
1174         {
1175         case MODE_TI:
1176           return "movdqa\t{%1, %0|%0, %1}";
1177         case MODE_V4SF:
1178           return "movaps\t{%1, %0|%0, %1}";
1179         case MODE_SI:
1180           return "movd\t{%1, %0|%0, %1}";
1181         case MODE_SF:
1182           return "movss\t{%1, %0|%0, %1}";
1183         default:
1184           gcc_unreachable ();
1185         }
1186
1187     case TYPE_MMXADD:
1188       return "pxor\t%0, %0";
1189
1190     case TYPE_MMXMOV:
1191       if (get_attr_mode (insn) == MODE_DI)
1192         return "movq\t{%1, %0|%0, %1}";
1193       return "movd\t{%1, %0|%0, %1}";
1194
1195     case TYPE_LEA:
1196       return "lea{l}\t{%1, %0|%0, %1}";
1197
1198     default:
1199       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200       return "mov{l}\t{%1, %0|%0, %1}";
1201     }
1202 }
1203   [(set (attr "type")
1204      (cond [(eq_attr "alternative" "2")
1205               (const_string "mmxadd")
1206             (eq_attr "alternative" "3,4,5")
1207               (const_string "mmxmov")
1208             (eq_attr "alternative" "6")
1209               (const_string "sselog1")
1210             (eq_attr "alternative" "7,8,9,10,11")
1211               (const_string "ssemov")
1212             (match_operand:DI 1 "pic_32bit_operand" "")
1213               (const_string "lea")
1214            ]
1215            (const_string "imov")))
1216    (set (attr "mode")
1217      (cond [(eq_attr "alternative" "2,3")
1218               (const_string "DI")
1219             (eq_attr "alternative" "6,7")
1220               (if_then_else
1221                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222                 (const_string "V4SF")
1223                 (const_string "TI"))
1224             (and (eq_attr "alternative" "8,9,10,11")
1225                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226               (const_string "SF")
1227            ]
1228            (const_string "SI")))])
1229
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237   "@
1238    movabs{l}\t{%1, %P0|%P0, %1}
1239    mov{l}\t{%1, %a0|%a0, %1}"
1240   [(set_attr "type" "imov")
1241    (set_attr "modrm" "0,*")
1242    (set_attr "length_address" "8,0")
1243    (set_attr "length_immediate" "0,*")
1244    (set_attr "memory" "store")
1245    (set_attr "mode" "SI")])
1246
1247 (define_insn "*movabssi_2_rex64"
1248   [(set (match_operand:SI 0 "register_operand" "=a,r")
1249         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251   "@
1252    movabs{l}\t{%P1, %0|%0, %P1}
1253    mov{l}\t{%a1, %0|%0, %a1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0")
1258    (set_attr "memory" "load")
1259    (set_attr "mode" "SI")])
1260
1261 (define_insn "*swapsi"
1262   [(set (match_operand:SI 0 "register_operand" "+r")
1263         (match_operand:SI 1 "register_operand" "+r"))
1264    (set (match_dup 1)
1265         (match_dup 0))]
1266   ""
1267   "xchg{l}\t%1, %0"
1268   [(set_attr "type" "imov")
1269    (set_attr "mode" "SI")
1270    (set_attr "pent_pair" "np")
1271    (set_attr "athlon_decode" "vector")])
1272
1273 (define_expand "movhi"
1274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275         (match_operand:HI 1 "general_operand" ""))]
1276   ""
1277   "ix86_expand_move (HImode, operands); DONE;")
1278
1279 (define_insn "*pushhi2"
1280   [(set (match_operand:HI 0 "push_operand" "=X")
1281         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282   "!TARGET_64BIT"
1283   "push{l}\t%k1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "SI")])
1286
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289   [(set (match_operand:HI 0 "push_operand" "=X")
1290         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291   "TARGET_64BIT"
1292   "push{q}\t%q1"
1293   [(set_attr "type" "push")
1294    (set_attr "mode" "DI")])
1295
1296 (define_insn "*movhi_1"
1297   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 {
1301   switch (get_attr_type (insn))
1302     {
1303     case TYPE_IMOVX:
1304       /* movzwl is faster than movw on p2 due to partial word stalls,
1305          though not as fast as an aligned movl.  */
1306       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307     default:
1308       if (get_attr_mode (insn) == MODE_SI)
1309         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310       else
1311         return "mov{w}\t{%1, %0|%0, %1}";
1312     }
1313 }
1314   [(set (attr "type")
1315      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316               (const_string "imov")
1317             (and (eq_attr "alternative" "0")
1318                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319                           (const_int 0))
1320                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1321                           (const_int 0))))
1322               (const_string "imov")
1323             (and (eq_attr "alternative" "1,2")
1324                  (match_operand:HI 1 "aligned_operand" ""))
1325               (const_string "imov")
1326             (and (ne (symbol_ref "TARGET_MOVX")
1327                      (const_int 0))
1328                  (eq_attr "alternative" "0,2"))
1329               (const_string "imovx")
1330            ]
1331            (const_string "imov")))
1332     (set (attr "mode")
1333       (cond [(eq_attr "type" "imovx")
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "1,2")
1336                   (match_operand:HI 1 "aligned_operand" ""))
1337                (const_string "SI")
1338              (and (eq_attr "alternative" "0")
1339                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                            (const_int 0))
1341                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                            (const_int 0))))
1343                (const_string "SI")
1344             ]
1345             (const_string "HI")))])
1346
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354   "@
1355    movabs{w}\t{%1, %P0|%P0, %1}
1356    mov{w}\t{%1, %a0|%a0, %1}"
1357   [(set_attr "type" "imov")
1358    (set_attr "modrm" "0,*")
1359    (set_attr "length_address" "8,0")
1360    (set_attr "length_immediate" "0,*")
1361    (set_attr "memory" "store")
1362    (set_attr "mode" "HI")])
1363
1364 (define_insn "*movabshi_2_rex64"
1365   [(set (match_operand:HI 0 "register_operand" "=a,r")
1366         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368   "@
1369    movabs{w}\t{%P1, %0|%0, %P1}
1370    mov{w}\t{%a1, %0|%0, %a1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0")
1375    (set_attr "memory" "load")
1376    (set_attr "mode" "HI")])
1377
1378 (define_insn "*swaphi_1"
1379   [(set (match_operand:HI 0 "register_operand" "+r")
1380         (match_operand:HI 1 "register_operand" "+r"))
1381    (set (match_dup 1)
1382         (match_dup 0))]
1383   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384   "xchg{l}\t%k1, %k0"
1385   [(set_attr "type" "imov")
1386    (set_attr "mode" "SI")
1387    (set_attr "pent_pair" "np")
1388    (set_attr "athlon_decode" "vector")])
1389
1390 (define_insn "*swaphi_2"
1391   [(set (match_operand:HI 0 "register_operand" "+r")
1392         (match_operand:HI 1 "register_operand" "+r"))
1393    (set (match_dup 1)
1394         (match_dup 0))]
1395   "TARGET_PARTIAL_REG_STALL"
1396   "xchg{w}\t%1, %0"
1397   [(set_attr "type" "imov")
1398    (set_attr "mode" "HI")
1399    (set_attr "pent_pair" "np")
1400    (set_attr "athlon_decode" "vector")])
1401
1402 (define_expand "movstricthi"
1403   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404         (match_operand:HI 1 "general_operand" ""))]
1405   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 {
1407   /* Don't generate memory->memory moves, go through a register */
1408   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409     operands[1] = force_reg (HImode, operands[1]);
1410 })
1411
1412 (define_insn "*movstricthi_1"
1413   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414         (match_operand:HI 1 "general_operand" "rn,m"))]
1415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417   "mov{w}\t{%1, %0|%0, %1}"
1418   [(set_attr "type" "imov")
1419    (set_attr "mode" "HI")])
1420
1421 (define_insn "*movstricthi_xor"
1422   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423         (match_operand:HI 1 "const0_operand" "i"))
1424    (clobber (reg:CC FLAGS_REG))]
1425   "reload_completed
1426    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427   "xor{w}\t{%0, %0|%0, %0}"
1428   [(set_attr "type" "alu1")
1429    (set_attr "mode" "HI")
1430    (set_attr "length_immediate" "0")])
1431
1432 (define_expand "movqi"
1433   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434         (match_operand:QI 1 "general_operand" ""))]
1435   ""
1436   "ix86_expand_move (QImode, operands); DONE;")
1437
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte".  But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1441
1442 (define_insn "*pushqi2"
1443   [(set (match_operand:QI 0 "push_operand" "=X")
1444         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445   "!TARGET_64BIT"
1446   "push{l}\t%k1"
1447   [(set_attr "type" "push")
1448    (set_attr "mode" "SI")])
1449
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452   [(set (match_operand:QI 0 "push_operand" "=X")
1453         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454   "TARGET_64BIT"
1455   "push{q}\t%q1"
1456   [(set_attr "type" "push")
1457    (set_attr "mode" "DI")])
1458
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1464 ;; instruction).
1465 ;;
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there.  Then we use movzx.
1469 (define_insn "*movqi_1"
1470   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473 {
1474   switch (get_attr_type (insn))
1475     {
1476     case TYPE_IMOVX:
1477       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479     default:
1480       if (get_attr_mode (insn) == MODE_SI)
1481         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482       else
1483         return "mov{b}\t{%1, %0|%0, %1}";
1484     }
1485 }
1486   [(set (attr "type")
1487      (cond [(and (eq_attr "alternative" "5")
1488                  (not (match_operand:QI 1 "aligned_operand" "")))
1489               (const_string "imovx")
1490             (ne (symbol_ref "optimize_size") (const_int 0))
1491               (const_string "imov")
1492             (and (eq_attr "alternative" "3")
1493                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494                           (const_int 0))
1495                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1496                           (const_int 0))))
1497               (const_string "imov")
1498             (eq_attr "alternative" "3,5")
1499               (const_string "imovx")
1500             (and (ne (symbol_ref "TARGET_MOVX")
1501                      (const_int 0))
1502                  (eq_attr "alternative" "2"))
1503               (const_string "imovx")
1504            ]
1505            (const_string "imov")))
1506    (set (attr "mode")
1507       (cond [(eq_attr "alternative" "3,4,5")
1508                (const_string "SI")
1509              (eq_attr "alternative" "6")
1510                (const_string "QI")
1511              (eq_attr "type" "imovx")
1512                (const_string "SI")
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                                 (const_int 0))
1517                             (and (eq (symbol_ref "optimize_size")
1518                                      (const_int 0))
1519                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520                                      (const_int 0))))))
1521                (const_string "SI")
1522              ;; Avoid partial register stalls when not using QImode arithmetic
1523              (and (eq_attr "type" "imov")
1524                   (and (eq_attr "alternative" "0,1")
1525                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                                 (const_int 0))
1527                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1528                                 (const_int 0)))))
1529                (const_string "SI")
1530            ]
1531            (const_string "QI")))])
1532
1533 (define_expand "reload_outqi"
1534   [(parallel [(match_operand:QI 0 "" "=m")
1535               (match_operand:QI 1 "register_operand" "r")
1536               (match_operand:QI 2 "register_operand" "=&q")])]
1537   ""
1538 {
1539   rtx op0, op1, op2;
1540   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541
1542   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543   if (! q_regs_operand (op1, QImode))
1544     {
1545       emit_insn (gen_movqi (op2, op1));
1546       op1 = op2;
1547     }
1548   emit_insn (gen_movqi (op0, op1));
1549   DONE;
1550 })
1551
1552 (define_insn "*swapqi_1"
1553   [(set (match_operand:QI 0 "register_operand" "+r")
1554         (match_operand:QI 1 "register_operand" "+r"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558   "xchg{l}\t%k1, %k0"
1559   [(set_attr "type" "imov")
1560    (set_attr "mode" "SI")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "athlon_decode" "vector")])
1563
1564 (define_insn "*swapqi_2"
1565   [(set (match_operand:QI 0 "register_operand" "+q")
1566         (match_operand:QI 1 "register_operand" "+q"))
1567    (set (match_dup 1)
1568         (match_dup 0))]
1569   "TARGET_PARTIAL_REG_STALL"
1570   "xchg{b}\t%1, %0"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")
1573    (set_attr "pent_pair" "np")
1574    (set_attr "athlon_decode" "vector")])
1575
1576 (define_expand "movstrictqi"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578         (match_operand:QI 1 "general_operand" ""))]
1579   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580 {
1581   /* Don't generate memory->memory moves, go through a register.  */
1582   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583     operands[1] = force_reg (QImode, operands[1]);
1584 })
1585
1586 (define_insn "*movstrictqi_1"
1587   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588         (match_operand:QI 1 "general_operand" "*qn,m"))]
1589   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591   "mov{b}\t{%1, %0|%0, %1}"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "QI")])
1594
1595 (define_insn "*movstrictqi_xor"
1596   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597         (match_operand:QI 1 "const0_operand" "i"))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600   "xor{b}\t{%0, %0|%0, %0}"
1601   [(set_attr "type" "alu1")
1602    (set_attr "mode" "QI")
1603    (set_attr "length_immediate" "0")])
1604
1605 (define_insn "*movsi_extv_1"
1606   [(set (match_operand:SI 0 "register_operand" "=R")
1607         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1614
1615 (define_insn "*movhi_extv_1"
1616   [(set (match_operand:HI 0 "register_operand" "=R")
1617         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   ""
1621   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622   [(set_attr "type" "imovx")
1623    (set_attr "mode" "SI")])
1624
1625 (define_insn "*movqi_extv_1"
1626   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628                          (const_int 8)
1629                          (const_int 8)))]
1630   "!TARGET_64BIT"
1631 {
1632   switch (get_attr_type (insn))
1633     {
1634     case TYPE_IMOVX:
1635       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636     default:
1637       return "mov{b}\t{%h1, %0|%0, %h1}";
1638     }
1639 }
1640   [(set (attr "type")
1641      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643                              (ne (symbol_ref "TARGET_MOVX")
1644                                  (const_int 0))))
1645         (const_string "imovx")
1646         (const_string "imov")))
1647    (set (attr "mode")
1648      (if_then_else (eq_attr "type" "imovx")
1649         (const_string "SI")
1650         (const_string "QI")))])
1651
1652 (define_insn "*movqi_extv_1_rex64"
1653   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "TARGET_64BIT"
1658 {
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1666 }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1678
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686   "@
1687    movabs{b}\t{%1, %P0|%P0, %1}
1688    mov{b}\t{%1, %a0|%a0, %1}"
1689   [(set_attr "type" "imov")
1690    (set_attr "modrm" "0,*")
1691    (set_attr "length_address" "8,0")
1692    (set_attr "length_immediate" "0,*")
1693    (set_attr "memory" "store")
1694    (set_attr "mode" "QI")])
1695
1696 (define_insn "*movabsqi_2_rex64"
1697   [(set (match_operand:QI 0 "register_operand" "=a,r")
1698         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700   "@
1701    movabs{b}\t{%P1, %0|%0, %P1}
1702    mov{b}\t{%a1, %0|%0, %a1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0")
1707    (set_attr "memory" "load")
1708    (set_attr "mode" "QI")])
1709
1710 (define_insn "*movdi_extzv_1"
1711   [(set (match_operand:DI 0 "register_operand" "=R")
1712         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   "TARGET_64BIT"
1716   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "DI")])
1719
1720 (define_insn "*movsi_extzv_1"
1721   [(set (match_operand:SI 0 "register_operand" "=R")
1722         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723                          (const_int 8)
1724                          (const_int 8)))]
1725   ""
1726   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727   [(set_attr "type" "imovx")
1728    (set_attr "mode" "SI")])
1729
1730 (define_insn "*movqi_extzv_2"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "!TARGET_64BIT"
1736 {
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1744 }
1745   [(set (attr "type")
1746      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748                              (ne (symbol_ref "TARGET_MOVX")
1749                                  (const_int 0))))
1750         (const_string "imovx")
1751         (const_string "imov")))
1752    (set (attr "mode")
1753      (if_then_else (eq_attr "type" "imovx")
1754         (const_string "SI")
1755         (const_string "QI")))])
1756
1757 (define_insn "*movqi_extzv_2_rex64"
1758   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760                                     (const_int 8)
1761                                     (const_int 8)) 0))]
1762   "TARGET_64BIT"
1763 {
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768     default:
1769       return "mov{b}\t{%h1, %0|%0, %h1}";
1770     }
1771 }
1772   [(set (attr "type")
1773      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                         (ne (symbol_ref "TARGET_MOVX")
1775                             (const_int 0)))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1782
1783 (define_insn "movsi_insv_1"
1784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:SI 1 "general_operand" "Qmn"))]
1788   "!TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_insn "movdi_insv_1_rex64"
1794   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798   "TARGET_64BIT"
1799   "mov{b}\t{%b1, %h0|%h0, %b1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1802
1803 (define_insn "*movqi_insv_2"
1804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805                          (const_int 8)
1806                          (const_int 8))
1807         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808                      (const_int 8)))]
1809   ""
1810   "mov{b}\t{%h1, %h0|%h0, %h1}"
1811   [(set_attr "type" "imov")
1812    (set_attr "mode" "QI")])
1813
1814 (define_expand "movdi"
1815   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816         (match_operand:DI 1 "general_operand" ""))]
1817   ""
1818   "ix86_expand_move (DImode, operands); DONE;")
1819
1820 (define_insn "*pushdi"
1821   [(set (match_operand:DI 0 "push_operand" "=<")
1822         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823   "!TARGET_64BIT"
1824   "#")
1825
1826 (define_insn "*pushdi2_rex64"
1827   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829   "TARGET_64BIT"
1830   "@
1831    push{q}\t%1
1832    #"
1833   [(set_attr "type" "push,multi")
1834    (set_attr "mode" "DI")])
1835
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it.  In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1840 (define_peephole2
1841   [(match_scratch:DI 2 "r")
1842    (set (match_operand:DI 0 "push_operand" "")
1843         (match_operand:DI 1 "immediate_operand" ""))]
1844   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845    && !x86_64_immediate_operand (operands[1], DImode)"
1846   [(set (match_dup 2) (match_dup 1))
1847    (set (match_dup 0) (match_dup 2))]
1848   "")
1849
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 (define_peephole2
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "immediate_operand" ""))]
1856   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858   [(set (match_dup 0) (match_dup 1))
1859    (set (match_dup 2) (match_dup 3))]
1860   "split_di (operands + 1, 1, operands + 2, operands + 3);
1861    operands[1] = gen_lowpart (DImode, operands[2]);
1862    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863                                                     GEN_INT (4)));
1864   ")
1865
1866 (define_split
1867   [(set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870                     ? flow2_completed : reload_completed)
1871    && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode)"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1880
1881 (define_insn "*pushdi2_prologue_rex64"
1882   [(set (match_operand:DI 0 "push_operand" "=<")
1883         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "push{q}\t%1"
1887   [(set_attr "type" "push")
1888    (set_attr "mode" "DI")])
1889
1890 (define_insn "*popdi1_epilogue_rex64"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))
1895    (clobber (mem:BLK (scratch)))]
1896   "TARGET_64BIT"
1897   "pop{q}\t%0"
1898   [(set_attr "type" "pop")
1899    (set_attr "mode" "DI")])
1900
1901 (define_insn "popdi1"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903         (mem:DI (reg:DI SP_REG)))
1904    (set (reg:DI SP_REG)
1905         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1906   "TARGET_64BIT"
1907   "pop{q}\t%0"
1908   [(set_attr "type" "pop")
1909    (set_attr "mode" "DI")])
1910
1911 (define_insn "*movdi_xor_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const0_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916    && reload_completed"
1917   "xor{l}\t{%k0, %k0|%k0, %k0}"
1918   [(set_attr "type" "alu1")
1919    (set_attr "mode" "SI")
1920    (set_attr "length_immediate" "0")])
1921
1922 (define_insn "*movdi_or_rex64"
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (match_operand:DI 1 "const_int_operand" "i"))
1925    (clobber (reg:CC FLAGS_REG))]
1926   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927    && reload_completed
1928    && operands[1] == constm1_rtx"
1929 {
1930   operands[1] = constm1_rtx;
1931   return "or{q}\t{%1, %0|%0, %1}";
1932 }
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "DI")
1935    (set_attr "length_immediate" "1")])
1936
1937 (define_insn "*movdi_2"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940         (match_operand:DI 1 "general_operand"
1941                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943   "@
1944    #
1945    #
1946    pxor\t%0, %0
1947    movq\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    pxor\t%0, %0
1950    movq\t{%1, %0|%0, %1}
1951    movdqa\t{%1, %0|%0, %1}
1952    movq\t{%1, %0|%0, %1}
1953    xorps\t%0, %0
1954    movlps\t{%1, %0|%0, %1}
1955    movaps\t{%1, %0|%0, %1}
1956    movlps\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1959
1960 (define_split
1961   [(set (match_operand:DI 0 "push_operand" "")
1962         (match_operand:DI 1 "general_operand" ""))]
1963   "!TARGET_64BIT && reload_completed
1964    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965   [(const_int 0)]
1966   "ix86_split_long_move (operands); DONE;")
1967
1968 ;; %%% This multiword shite has got to go.
1969 (define_split
1970   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971         (match_operand:DI 1 "general_operand" ""))]
1972   "!TARGET_64BIT && reload_completed
1973    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975   [(const_int 0)]
1976   "ix86_split_long_move (operands); DONE;")
1977
1978 (define_insn "*movdi_1_rex64"
1979   [(set (match_operand:DI 0 "nonimmediate_operand"
1980                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981         (match_operand:DI 1 "general_operand"
1982                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 {
1985   switch (get_attr_type (insn))
1986     {
1987     case TYPE_SSECVT:
1988       if (which_alternative == 13)
1989         return "movq2dq\t{%1, %0|%0, %1}";
1990       else
1991         return "movdq2q\t{%1, %0|%0, %1}";
1992     case TYPE_SSEMOV:
1993       if (get_attr_mode (insn) == MODE_TI)
1994           return "movdqa\t{%1, %0|%0, %1}";
1995       /* FALLTHRU */
1996     case TYPE_MMXMOV:
1997       /* Moves from and into integer register is done using movd opcode with
1998          REX prefix.  */
1999       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000           return "movd\t{%1, %0|%0, %1}";
2001       return "movq\t{%1, %0|%0, %1}";
2002     case TYPE_SSELOG1:
2003     case TYPE_MMXADD:
2004       return "pxor\t%0, %0";
2005     case TYPE_MULTI:
2006       return "#";
2007     case TYPE_LEA:
2008       return "lea{q}\t{%a1, %0|%0, %a1}";
2009     default:
2010       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011       if (get_attr_mode (insn) == MODE_SI)
2012         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013       else if (which_alternative == 2)
2014         return "movabs{q}\t{%1, %0|%0, %1}";
2015       else
2016         return "mov{q}\t{%1, %0|%0, %1}";
2017     }
2018 }
2019   [(set (attr "type")
2020      (cond [(eq_attr "alternative" "5")
2021               (const_string "mmxadd")
2022             (eq_attr "alternative" "6,7,8")
2023               (const_string "mmxmov")
2024             (eq_attr "alternative" "9")
2025               (const_string "sselog1")
2026             (eq_attr "alternative" "10,11,12")
2027               (const_string "ssemov")
2028             (eq_attr "alternative" "13,14")
2029               (const_string "ssecvt")
2030             (eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (match_operand:DI 1 "pic_32bit_operand" "")
2033               (const_string "lea")
2034            ]
2035            (const_string "imov")))
2036    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047   "@
2048    movabs{q}\t{%1, %P0|%P0, %1}
2049    mov{q}\t{%1, %a0|%a0, %1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "modrm" "0,*")
2052    (set_attr "length_address" "8,0")
2053    (set_attr "length_immediate" "0,*")
2054    (set_attr "memory" "store")
2055    (set_attr "mode" "DI")])
2056
2057 (define_insn "*movabsdi_2_rex64"
2058   [(set (match_operand:DI 0 "register_operand" "=a,r")
2059         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061   "@
2062    movabs{q}\t{%P1, %0|%0, %P1}
2063    mov{q}\t{%a1, %0|%0, %a1}"
2064   [(set_attr "type" "imov")
2065    (set_attr "modrm" "0,*")
2066    (set_attr "length_address" "8,0")
2067    (set_attr "length_immediate" "0")
2068    (set_attr "memory" "load")
2069    (set_attr "mode" "DI")])
2070
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it.  In case this
2073 ;; fails, move by 32bit parts.
2074 (define_peephole2
2075   [(match_scratch:DI 2 "r")
2076    (set (match_operand:DI 0 "memory_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode)"
2080   [(set (match_dup 2) (match_dup 1))
2081    (set (match_dup 0) (match_dup 2))]
2082   "")
2083
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088   [(set (match_operand:DI 0 "memory_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096 (define_split
2097   [(set (match_operand:DI 0 "memory_operand" "")
2098         (match_operand:DI 1 "immediate_operand" ""))]
2099   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100                     ? flow2_completed : reload_completed)
2101    && !symbolic_operand (operands[1], DImode)
2102    && !x86_64_immediate_operand (operands[1], DImode)"
2103   [(set (match_dup 2) (match_dup 3))
2104    (set (match_dup 4) (match_dup 5))]
2105   "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107 (define_insn "*swapdi_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "+r")
2109         (match_operand:DI 1 "register_operand" "+r"))
2110    (set (match_dup 1)
2111         (match_dup 0))]
2112   "TARGET_64BIT"
2113   "xchg{q}\t%1, %0"
2114   [(set_attr "type" "imov")
2115    (set_attr "mode" "DI")
2116    (set_attr "pent_pair" "np")
2117    (set_attr "athlon_decode" "vector")])
2118
2119 (define_expand "movti"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121         (match_operand:TI 1 "nonimmediate_operand" ""))]
2122   "TARGET_SSE || TARGET_64BIT"
2123 {
2124   if (TARGET_64BIT)
2125     ix86_expand_move (TImode, operands);
2126   else
2127     ix86_expand_vector_move (TImode, operands);
2128   DONE;
2129 })
2130
2131 (define_insn "*movti_internal"
2132   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134   "TARGET_SSE && !TARGET_64BIT
2135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136 {
2137   switch (which_alternative)
2138     {
2139     case 0:
2140       if (get_attr_mode (insn) == MODE_V4SF)
2141         return "xorps\t%0, %0";
2142       else
2143         return "pxor\t%0, %0";
2144     case 1:
2145     case 2:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "movaps\t{%1, %0|%0, %1}";
2148       else
2149         return "movdqa\t{%1, %0|%0, %1}";
2150     default:
2151       gcc_unreachable ();
2152     }
2153 }
2154   [(set_attr "type" "sselog1,ssemov,ssemov")
2155    (set (attr "mode")
2156         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157                     (ne (symbol_ref "optimize_size") (const_int 0)))
2158                  (const_string "V4SF")
2159                (and (eq_attr "alternative" "2")
2160                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161                         (const_int 0)))
2162                  (const_string "V4SF")]
2163               (const_string "TI")))])
2164
2165 (define_insn "*movti_rex64"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168   "TARGET_64BIT
2169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 {
2171   switch (which_alternative)
2172     {
2173     case 0:
2174     case 1:
2175       return "#";
2176     case 2:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "xorps\t%0, %0";
2179       else
2180         return "pxor\t%0, %0";
2181     case 3:
2182     case 4:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "movaps\t{%1, %0|%0, %1}";
2185       else
2186         return "movdqa\t{%1, %0|%0, %1}";
2187     default:
2188       gcc_unreachable ();
2189     }
2190 }
2191   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192    (set (attr "mode")
2193         (cond [(eq_attr "alternative" "2,3")
2194                  (if_then_else
2195                    (ne (symbol_ref "optimize_size")
2196                        (const_int 0))
2197                    (const_string "V4SF")
2198                    (const_string "TI"))
2199                (eq_attr "alternative" "4")
2200                  (if_then_else
2201                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202                             (const_int 0))
2203                         (ne (symbol_ref "optimize_size")
2204                             (const_int 0)))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))]
2207                (const_string "DI")))])
2208
2209 (define_split
2210   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211         (match_operand:TI 1 "general_operand" ""))]
2212   "reload_completed && !SSE_REG_P (operands[0])
2213    && !SSE_REG_P (operands[1])"
2214   [(const_int 0)]
2215   "ix86_split_long_move (operands); DONE;")
2216
2217 (define_expand "movsf"
2218   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219         (match_operand:SF 1 "general_operand" ""))]
2220   ""
2221   "ix86_expand_move (SFmode, operands); DONE;")
2222
2223 (define_insn "*pushsf"
2224   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226   "!TARGET_64BIT"
2227 {
2228   /* Anything else should be already split before reg-stack.  */
2229   gcc_assert (which_alternative == 1);
2230   return "push{l}\t%1";
2231 }
2232   [(set_attr "type" "multi,push,multi")
2233    (set_attr "unit" "i387,*,*")
2234    (set_attr "mode" "SF,SI,SF")])
2235
2236 (define_insn "*pushsf_rex64"
2237   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239   "TARGET_64BIT"
2240 {
2241   /* Anything else should be already split before reg-stack.  */
2242   gcc_assert (which_alternative == 1);
2243   return "push{q}\t%q1";
2244 }
2245   [(set_attr "type" "multi,push,multi")
2246    (set_attr "unit" "i387,*,*")
2247    (set_attr "mode" "SF,DI,SF")])
2248
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "memory_operand" ""))]
2252   "reload_completed
2253    && GET_CODE (operands[1]) == MEM
2254    && constant_pool_reference_p (operands[1])"
2255   [(set (match_dup 0)
2256         (match_dup 1))]
2257   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258
2259
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "!TARGET_64BIT"
2265   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267
2268 (define_split
2269   [(set (match_operand:SF 0 "push_operand" "")
2270         (match_operand:SF 1 "any_fp_register_operand" ""))]
2271   "TARGET_64BIT"
2272   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274
2275 (define_insn "*movsf_1"
2276   [(set (match_operand:SF 0 "nonimmediate_operand"
2277           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2278         (match_operand:SF 1 "general_operand"
2279           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281    && (reload_in_progress || reload_completed
2282        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283        || GET_CODE (operands[1]) != CONST_DOUBLE
2284        || memory_operand (operands[0], SFmode))" 
2285 {
2286   switch (which_alternative)
2287     {
2288     case 0:
2289       return output_387_reg_move (insn, operands);
2290
2291     case 1:
2292       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293         return "fstp%z0\t%y0";
2294       else
2295         return "fst%z0\t%y0";
2296
2297     case 2:
2298       return standard_80387_constant_opcode (operands[1]);
2299
2300     case 3:
2301     case 4:
2302       return "mov{l}\t{%1, %0|%0, %1}";
2303     case 5:
2304       if (get_attr_mode (insn) == MODE_TI)
2305         return "pxor\t%0, %0";
2306       else
2307         return "xorps\t%0, %0";
2308     case 6:
2309       if (get_attr_mode (insn) == MODE_V4SF)
2310         return "movaps\t{%1, %0|%0, %1}";
2311       else
2312         return "movss\t{%1, %0|%0, %1}";
2313     case 7:
2314     case 8:
2315       return "movss\t{%1, %0|%0, %1}";
2316
2317     case 9:
2318     case 10:
2319       return "movd\t{%1, %0|%0, %1}";
2320
2321     case 11:
2322       return "movq\t{%1, %0|%0, %1}";
2323
2324     default:
2325       gcc_unreachable ();
2326     }
2327 }
2328   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329    (set (attr "mode")
2330         (cond [(eq_attr "alternative" "3,4,9,10")
2331                  (const_string "SI")
2332                (eq_attr "alternative" "5")
2333                  (if_then_else
2334                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335                                  (const_int 0))
2336                              (ne (symbol_ref "TARGET_SSE2")
2337                                  (const_int 0)))
2338                         (eq (symbol_ref "optimize_size")
2339                             (const_int 0)))
2340                    (const_string "TI")
2341                    (const_string "V4SF"))
2342                /* For architectures resolving dependencies on
2343                   whole SSE registers use APS move to break dependency
2344                   chains, otherwise use short move to avoid extra work. 
2345
2346                   Do the same for architectures resolving dependencies on
2347                   the parts.  While in DF mode it is better to always handle
2348                   just register parts, the SF mode is different due to lack
2349                   of instructions to load just part of the register.  It is
2350                   better to maintain the whole registers in single format
2351                   to avoid problems on using packed logical operations.  */
2352                (eq_attr "alternative" "6")
2353                  (if_then_else
2354                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355                             (const_int 0))
2356                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357                             (const_int 0)))
2358                    (const_string "V4SF")
2359                    (const_string "SF"))
2360                (eq_attr "alternative" "11")
2361                  (const_string "DI")]
2362                (const_string "SF")))])
2363
2364 (define_insn "*swapsf"
2365   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366         (match_operand:SF 1 "fp_register_operand" "+f"))
2367    (set (match_dup 1)
2368         (match_dup 0))]
2369   "reload_completed || TARGET_80387"
2370 {
2371   if (STACK_TOP_P (operands[0]))
2372     return "fxch\t%1";
2373   else
2374     return "fxch\t%0";
2375 }
2376   [(set_attr "type" "fxch")
2377    (set_attr "mode" "SF")])
2378
2379 (define_expand "movdf"
2380   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381         (match_operand:DF 1 "general_operand" ""))]
2382   ""
2383   "ix86_expand_move (DFmode, operands); DONE;")
2384
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter.  Allow this
2388 ;; pattern for optimize_size too.
2389
2390 (define_insn "*pushdf_nointeger"
2391   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 {
2395   /* This insn should be already split before reg-stack.  */
2396   gcc_unreachable ();
2397 }
2398   [(set_attr "type" "multi")
2399    (set_attr "unit" "i387,*,*,*")
2400    (set_attr "mode" "DF,SI,SI,DF")])
2401
2402 (define_insn "*pushdf_integer"
2403   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 {
2407   /* This insn should be already split before reg-stack.  */
2408   gcc_unreachable ();
2409 }
2410   [(set_attr "type" "multi")
2411    (set_attr "unit" "i387,*,*")
2412    (set_attr "mode" "DF,SI,DF")])
2413
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416   [(set (match_operand:DF 0 "push_operand" "")
2417         (match_operand:DF 1 "any_fp_register_operand" ""))]
2418   "!TARGET_64BIT && reload_completed"
2419   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421   "")
2422
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "TARGET_64BIT && reload_completed"
2427   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429   "")
2430
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "general_operand" ""))]
2434   "reload_completed"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2437
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2441
2442 (define_insn "*movdf_nointeger"
2443   [(set (match_operand:DF 0 "nonimmediate_operand"
2444                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2445         (match_operand:DF 1 "general_operand"
2446                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2447   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449    && (reload_in_progress || reload_completed
2450        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451        || GET_CODE (operands[1]) != CONST_DOUBLE
2452        || memory_operand (operands[0], DFmode))" 
2453 {
2454   switch (which_alternative)
2455     {
2456     case 0:
2457       return output_387_reg_move (insn, operands);
2458
2459     case 1:
2460       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461         return "fstp%z0\t%y0";
2462       else
2463         return "fst%z0\t%y0";
2464
2465     case 2:
2466       return standard_80387_constant_opcode (operands[1]);
2467
2468     case 3:
2469     case 4:
2470       return "#";
2471     case 5:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "xorps\t%0, %0";
2476         case MODE_V2DF:
2477           return "xorpd\t%0, %0";
2478         case MODE_TI:
2479           return "pxor\t%0, %0";
2480         default:
2481           gcc_unreachable ();
2482         }
2483     case 6:
2484     case 7:
2485     case 8:
2486       switch (get_attr_mode (insn))
2487         {
2488         case MODE_V4SF:
2489           return "movaps\t{%1, %0|%0, %1}";
2490         case MODE_V2DF:
2491           return "movapd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "movdqa\t{%1, %0|%0, %1}";
2494         case MODE_DI:
2495           return "movq\t{%1, %0|%0, %1}";
2496         case MODE_DF:
2497           return "movsd\t{%1, %0|%0, %1}";
2498         case MODE_V1DF:
2499           return "movlpd\t{%1, %0|%0, %1}";
2500         case MODE_V2SF:
2501           return "movlps\t{%1, %0|%0, %1}";
2502         default:
2503           gcc_unreachable ();
2504         }
2505
2506     default:
2507       gcc_unreachable ();
2508     }
2509 }
2510   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511    (set (attr "mode")
2512         (cond [(eq_attr "alternative" "0,1,2")
2513                  (const_string "DF")
2514                (eq_attr "alternative" "3,4")
2515                  (const_string "SI")
2516
2517                /* For SSE1, we have many fewer alternatives.  */
2518                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519                  (cond [(eq_attr "alternative" "5,6")
2520                           (const_string "V4SF")
2521                        ]
2522                    (const_string "V2SF"))
2523
2524                /* xorps is one byte shorter.  */
2525                (eq_attr "alternative" "5")
2526                  (cond [(ne (symbol_ref "optimize_size")
2527                             (const_int 0))
2528                           (const_string "V4SF")
2529                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530                             (const_int 0))
2531                           (const_string "TI")
2532                        ]
2533                        (const_string "V2DF"))
2534
2535                /* For architectures resolving dependencies on
2536                   whole SSE registers use APD move to break dependency
2537                   chains, otherwise use short move to avoid extra work.
2538
2539                   movaps encodes one byte shorter.  */
2540                (eq_attr "alternative" "6")
2541                  (cond
2542                    [(ne (symbol_ref "optimize_size")
2543                         (const_int 0))
2544                       (const_string "V4SF")
2545                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546                         (const_int 0))
2547                       (const_string "V2DF")
2548                    ]
2549                    (const_string "DF"))
2550                /* For architectures resolving dependencies on register
2551                   parts we may avoid extra work to zero out upper part
2552                   of register.  */
2553                (eq_attr "alternative" "7")
2554                  (if_then_else
2555                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556                        (const_int 0))
2557                    (const_string "V1DF")
2558                    (const_string "DF"))
2559               ]
2560               (const_string "DF")))])
2561
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand"
2564                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2565         (match_operand:DF 1 "general_operand"
2566                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2567   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569    && (reload_in_progress || reload_completed
2570        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571        || GET_CODE (operands[1]) != CONST_DOUBLE
2572        || memory_operand (operands[0], DFmode))" 
2573 {
2574   switch (which_alternative)
2575     {
2576     case 0:
2577       return output_387_reg_move (insn, operands);
2578
2579     case 1:
2580       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581         return "fstp%z0\t%y0";
2582       else
2583         return "fst%z0\t%y0";
2584
2585     case 2:
2586       return standard_80387_constant_opcode (operands[1]);
2587
2588     case 3:
2589     case 4:
2590       return "#";
2591
2592     case 5:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "xorps\t%0, %0";
2597         case MODE_V2DF:
2598           return "xorpd\t%0, %0";
2599         case MODE_TI:
2600           return "pxor\t%0, %0";
2601         default:
2602           gcc_unreachable ();
2603         }
2604     case 6:
2605     case 7:
2606     case 8:
2607       switch (get_attr_mode (insn))
2608         {
2609         case MODE_V4SF:
2610           return "movaps\t{%1, %0|%0, %1}";
2611         case MODE_V2DF:
2612           return "movapd\t{%1, %0|%0, %1}";
2613         case MODE_TI:
2614           return "movdqa\t{%1, %0|%0, %1}";
2615         case MODE_DI:
2616           return "movq\t{%1, %0|%0, %1}";
2617         case MODE_DF:
2618           return "movsd\t{%1, %0|%0, %1}";
2619         case MODE_V1DF:
2620           return "movlpd\t{%1, %0|%0, %1}";
2621         case MODE_V2SF:
2622           return "movlps\t{%1, %0|%0, %1}";
2623         default:
2624           gcc_unreachable ();
2625         }
2626
2627     default:
2628       gcc_unreachable();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "0,1,2")
2634                  (const_string "DF")
2635                (eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2637
2638                /* For SSE1, we have many fewer alternatives.  */
2639                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640                  (cond [(eq_attr "alternative" "5,6")
2641                           (const_string "V4SF")
2642                        ]
2643                    (const_string "V2SF"))
2644
2645                /* xorps is one byte shorter.  */
2646                (eq_attr "alternative" "5")
2647                  (cond [(ne (symbol_ref "optimize_size")
2648                             (const_int 0))
2649                           (const_string "V4SF")
2650                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                             (const_int 0))
2652                           (const_string "TI")
2653                        ]
2654                        (const_string "V2DF"))
2655
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.
2659
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                    [(ne (symbol_ref "optimize_size")
2664                         (const_int 0))
2665                       (const_string "V4SF")
2666                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                         (const_int 0))
2668                       (const_string "V2DF")
2669                    ]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                        (const_int 0))
2678                    (const_string "V1DF")
2679                    (const_string "DF"))
2680               ]
2681               (const_string "DF")))])
2682
2683 (define_split
2684   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685         (match_operand:DF 1 "general_operand" ""))]
2686   "reload_completed
2687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688    && ! (ANY_FP_REG_P (operands[0]) || 
2689          (GET_CODE (operands[0]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691    && ! (ANY_FP_REG_P (operands[1]) || 
2692          (GET_CODE (operands[1]) == SUBREG
2693           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2696
2697 (define_insn "*swapdf"
2698   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699         (match_operand:DF 1 "fp_register_operand" "+f"))
2700    (set (match_dup 1)
2701         (match_dup 0))]
2702   "reload_completed || TARGET_80387"
2703 {
2704   if (STACK_TOP_P (operands[0]))
2705     return "fxch\t%1";
2706   else
2707     return "fxch\t%0";
2708 }
2709   [(set_attr "type" "fxch")
2710    (set_attr "mode" "DF")])
2711
2712 (define_expand "movxf"
2713   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714         (match_operand:XF 1 "general_operand" ""))]
2715   ""
2716   "ix86_expand_move (XFmode, operands); DONE;")
2717
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;;  handled elsewhere).
2724
2725 (define_insn "*pushxf_nointeger"
2726   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728   "optimize_size"
2729 {
2730   /* This insn should be already split before reg-stack.  */
2731   gcc_unreachable ();
2732 }
2733   [(set_attr "type" "multi")
2734    (set_attr "unit" "i387,*,*")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2784 {
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       return output_387_reg_move (insn, operands);
2789
2790     case 1:
2791       /* There is no non-popping store to memory for XFmode.  So if
2792          we need one, follow the store with a load.  */
2793       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794         return "fstp%z0\t%y0\;fld%z0\t%y0";
2795       else
2796         return "fstp%z0\t%y0";
2797
2798     case 2:
2799       return standard_80387_constant_opcode (operands[1]);
2800
2801     case 3: case 4:
2802       return "#";
2803     default:
2804       gcc_unreachable ();
2805     }
2806 }
2807   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808    (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810 (define_insn "*movxf_integer"
2811   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813   "!optimize_size
2814    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815    && (reload_in_progress || reload_completed
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], XFmode))" 
2818 {
2819   switch (which_alternative)
2820     {
2821     case 0:
2822       return output_387_reg_move (insn, operands);
2823
2824     case 1:
2825       /* There is no non-popping store to memory for XFmode.  So if
2826          we need one, follow the store with a load.  */
2827       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828         return "fstp%z0\t%y0\;fld%z0\t%y0";
2829       else
2830         return "fstp%z0\t%y0";
2831
2832     case 2:
2833       return standard_80387_constant_opcode (operands[1]);
2834
2835     case 3: case 4:
2836       return "#";
2837
2838     default:
2839       gcc_unreachable ();
2840     }
2841 }
2842   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843    (set_attr "mode" "XF,XF,XF,SI,SI")])
2844
2845 (define_split
2846   [(set (match_operand 0 "nonimmediate_operand" "")
2847         (match_operand 1 "general_operand" ""))]
2848   "reload_completed
2849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850    && GET_MODE (operands[0]) == XFmode
2851    && ! (ANY_FP_REG_P (operands[0]) || 
2852          (GET_CODE (operands[0]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854    && ! (ANY_FP_REG_P (operands[1]) || 
2855          (GET_CODE (operands[1]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857   [(const_int 0)]
2858   "ix86_split_long_move (operands); DONE;")
2859
2860 (define_split
2861   [(set (match_operand 0 "register_operand" "")
2862         (match_operand 1 "memory_operand" ""))]
2863   "reload_completed
2864    && GET_CODE (operands[1]) == MEM
2865    && (GET_MODE (operands[0]) == XFmode
2866        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867    && constant_pool_reference_p (operands[1])"
2868   [(set (match_dup 0) (match_dup 1))]
2869 {
2870   rtx c = avoid_constant_pool_reference (operands[1]);
2871   rtx r = operands[0];
2872
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2875
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2888
2889   operands[1] = c;
2890 })
2891
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2898 {
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2903 }
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2906
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2911 {
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2914 })
2915
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 {
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2941 }
2942   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2959
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2967 \f
2968 ;; Zero extension instructions
2969
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2974 {
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2981 })
2982
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2991
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3000
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3008
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3016
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3025
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3034
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037   [(set (match_operand:HI 0 "register_operand" "=r")
3038      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041   [(set_attr "type" "imovx")
3042    (set_attr "mode" "SI")])
3043
3044 ;; For the movzbw case strip only the clobber
3045 (define_split
3046   [(set (match_operand:HI 0 "register_operand" "")
3047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048    (clobber (reg:CC FLAGS_REG))]
3049   "reload_completed 
3050    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3057 (define_split
3058   [(set (match_operand:HI 0 "register_operand" "")
3059         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060    (clobber (reg:CC FLAGS_REG))]
3061   "reload_completed
3062    && ANY_QI_REG_P (operands[0])
3063    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065   [(set (match_dup 0) (const_int 0))
3066    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067   "operands[2] = gen_lowpart (QImode, operands[0]);")
3068
3069 ;; Rest is handled by single and.
3070 (define_split
3071   [(set (match_operand:HI 0 "register_operand" "")
3072         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && true_regnum (operands[0]) == true_regnum (operands[1])"
3076   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077               (clobber (reg:CC FLAGS_REG))])]
3078   "")
3079
3080 (define_expand "zero_extendqisi2"
3081   [(parallel
3082     [(set (match_operand:SI 0 "register_operand" "")
3083        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084      (clobber (reg:CC FLAGS_REG))])]
3085   ""
3086   "")
3087
3088 (define_insn "*zero_extendqisi2_and"
3089   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091    (clobber (reg:CC FLAGS_REG))]
3092   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093   "#"
3094   [(set_attr "type" "alu1")
3095    (set_attr "mode" "SI")])
3096
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098   [(set (match_operand:SI 0 "register_operand" "=r,r")
3099      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102   "#"
3103   [(set_attr "type" "imovx,alu1")
3104    (set_attr "mode" "SI")])
3105
3106 (define_insn "*zero_extendqisi2_movzbw"
3107   [(set (match_operand:SI 0 "register_operand" "=r")
3108      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110   "movz{bl|x}\t{%1, %0|%0, %1}"
3111   [(set_attr "type" "imovx")
3112    (set_attr "mode" "SI")])
3113
3114 ;; For the movzbl case strip only the clobber
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed 
3120    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122   [(set (match_dup 0)
3123         (zero_extend:SI (match_dup 1)))])
3124
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3127 (define_split
3128   [(set (match_operand:SI 0 "register_operand" "")
3129         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "reload_completed
3132    && ANY_QI_REG_P (operands[0])
3133    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136   [(set (match_dup 0) (const_int 0))
3137    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138   "operands[2] = gen_lowpart (QImode, operands[0]);")
3139
3140 ;; Rest is handled by single and.
3141 (define_split
3142   [(set (match_operand:SI 0 "register_operand" "")
3143         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144    (clobber (reg:CC FLAGS_REG))]
3145   "reload_completed
3146    && true_regnum (operands[0]) == true_regnum (operands[1])"
3147   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148               (clobber (reg:CC FLAGS_REG))])]
3149   "")
3150
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153   [(set (match_operand:DI 0 "register_operand" "=r")
3154      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155   ""
3156   "if (!TARGET_64BIT)
3157      {
3158        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159        DONE;
3160      }
3161   ")
3162
3163 (define_insn "zero_extendsidi2_32"
3164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166    (clobber (reg:CC FLAGS_REG))]
3167   "!TARGET_64BIT"
3168   "@
3169    #
3170    #
3171    #
3172    movd\t{%1, %0|%0, %1}
3173    movd\t{%1, %0|%0, %1}"
3174   [(set_attr "mode" "SI,SI,SI,DI,TI")
3175    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176
3177 (define_insn "zero_extendsidi2_rex64"
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180   "TARGET_64BIT"
3181   "@
3182    mov\t{%k1, %k0|%k0, %k1}
3183    #
3184    movd\t{%1, %0|%0, %1}
3185    movd\t{%1, %0|%0, %1}"
3186   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187    (set_attr "mode" "SI,DI,SI,SI")])
3188
3189 (define_split
3190   [(set (match_operand:DI 0 "memory_operand" "")
3191      (zero_extend:DI (match_dup 0)))]
3192   "TARGET_64BIT"
3193   [(set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196 (define_split 
3197   [(set (match_operand:DI 0 "register_operand" "")
3198         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "!TARGET_64BIT && reload_completed
3201    && true_regnum (operands[0]) == true_regnum (operands[1])"
3202   [(set (match_dup 4) (const_int 0))]
3203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205 (define_split 
3206   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208    (clobber (reg:CC FLAGS_REG))]
3209   "!TARGET_64BIT && reload_completed
3210    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211   [(set (match_dup 3) (match_dup 1))
3212    (set (match_dup 4) (const_int 0))]
3213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214
3215 (define_insn "zero_extendhidi2"
3216   [(set (match_operand:DI 0 "register_operand" "=r")
3217      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218   "TARGET_64BIT"
3219   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220   [(set_attr "type" "imovx")
3221    (set_attr "mode" "DI")])
3222
3223 (define_insn "zero_extendqidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3230 \f
3231 ;; Sign extension instructions
3232
3233 (define_expand "extendsidi2"
3234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236               (clobber (reg:CC FLAGS_REG))
3237               (clobber (match_scratch:SI 2 ""))])]
3238   ""
3239 {
3240   if (TARGET_64BIT)
3241     {
3242       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243       DONE;
3244     }
3245 })
3246
3247 (define_insn "*extendsidi2_1"
3248   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250    (clobber (reg:CC FLAGS_REG))
3251    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252   "!TARGET_64BIT"
3253   "#")
3254
3255 (define_insn "extendsidi2_rex64"
3256   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258   "TARGET_64BIT"
3259   "@
3260    {cltq|cdqe}
3261    movs{lq|x}\t{%1,%0|%0, %1}"
3262   [(set_attr "type" "imovx")
3263    (set_attr "mode" "DI")
3264    (set_attr "prefix_0f" "0")
3265    (set_attr "modrm" "0,1")])
3266
3267 (define_insn "extendhidi2"
3268   [(set (match_operand:DI 0 "register_operand" "=r")
3269         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270   "TARGET_64BIT"
3271   "movs{wq|x}\t{%1,%0|%0, %1}"
3272   [(set_attr "type" "imovx")
3273    (set_attr "mode" "DI")])
3274
3275 (define_insn "extendqidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "TARGET_64BIT"
3279   "movs{bq|x}\t{%1,%0|%0, %1}"
3280    [(set_attr "type" "imovx")
3281     (set_attr "mode" "DI")])
3282
3283 ;; Extend to memory case when source register does die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "(reload_completed
3290     && dead_or_set_p (insn, operands[1])
3291     && !reg_mentioned_p (operands[1], operands[0]))"
3292   [(set (match_dup 3) (match_dup 1))
3293    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294               (clobber (reg:CC FLAGS_REG))])
3295    (set (match_dup 4) (match_dup 1))]
3296   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297
3298 ;; Extend to memory case when source register does not die.
3299 (define_split 
3300   [(set (match_operand:DI 0 "memory_operand" "")
3301         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302    (clobber (reg:CC FLAGS_REG))
3303    (clobber (match_operand:SI 2 "register_operand" ""))]
3304   "reload_completed"
3305   [(const_int 0)]
3306 {
3307   split_di (&operands[0], 1, &operands[3], &operands[4]);
3308
3309   emit_move_insn (operands[3], operands[1]);
3310
3311   /* Generate a cltd if possible and doing so it profitable.  */
3312   if (true_regnum (operands[1]) == 0
3313       && true_regnum (operands[2]) == 1
3314       && (optimize_size || TARGET_USE_CLTD))
3315     {
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317     }
3318   else
3319     {
3320       emit_move_insn (operands[2], operands[1]);
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322     }
3323   emit_move_insn (operands[4], operands[2]);
3324   DONE;
3325 })
3326
3327 ;; Extend to register case.  Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3329 (define_split 
3330   [(set (match_operand:DI 0 "register_operand" "")
3331         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332    (clobber (reg:CC FLAGS_REG))
3333    (clobber (match_scratch:SI 2 ""))]
3334   "reload_completed"
3335   [(const_int 0)]
3336 {
3337   split_di (&operands[0], 1, &operands[3], &operands[4]);
3338
3339   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340     emit_move_insn (operands[3], operands[1]);
3341
3342   /* Generate a cltd if possible and doing so it profitable.  */
3343   if (true_regnum (operands[3]) == 0
3344       && (optimize_size || TARGET_USE_CLTD))
3345     {
3346       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347       DONE;
3348     }
3349
3350   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351     emit_move_insn (operands[4], operands[1]);
3352
3353   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354   DONE;
3355 })
3356
3357 (define_insn "extendhisi2"
3358   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360   ""
3361 {
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%0|%0, %1}";
3368     }
3369 }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3382
3383 (define_insn "*extendhisi2_zext"
3384   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385         (zero_extend:DI
3386           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387   "TARGET_64BIT"
3388 {
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395     }
3396 }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3409
3410 (define_insn "extendqihi2"
3411   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413   ""
3414 {
3415   switch (get_attr_prefix_0f (insn))
3416     {
3417     case 0:
3418       return "{cbtw|cbw}";
3419     default:
3420       return "movs{bw|x}\t{%1,%0|%0, %1}";
3421     }
3422 }
3423   [(set_attr "type" "imovx")
3424    (set_attr "mode" "HI")
3425    (set (attr "prefix_0f")
3426      ;; movsx is short decodable while cwtl is vector decoded.
3427      (if_then_else (and (eq_attr "cpu" "!k6")
3428                         (eq_attr "alternative" "0"))
3429         (const_string "0")
3430         (const_string "1")))
3431    (set (attr "modrm")
3432      (if_then_else (eq_attr "prefix_0f" "0")
3433         (const_string "0")
3434         (const_string "1")))])
3435
3436 (define_insn "extendqisi2"
3437   [(set (match_operand:SI 0 "register_operand" "=r")
3438         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439   ""
3440   "movs{bl|x}\t{%1,%0|%0, %1}"
3441    [(set_attr "type" "imovx")
3442     (set_attr "mode" "SI")])
3443
3444 (define_insn "*extendqisi2_zext"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448   "TARGET_64BIT"
3449   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450    [(set_attr "type" "imovx")
3451     (set_attr "mode" "SI")])
3452 \f
3453 ;; Conversions between float and double.
3454
3455 ;; These are all no-ops in the model used for the 80387.  So just
3456 ;; emit moves.
3457
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3459 (define_insn "*dummy_extendsfdf2"
3460   [(set (match_operand:DF 0 "push_operand" "=<")
3461         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462   "0"
3463   "#")
3464
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "!TARGET_64BIT"
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472 (define_split
3473   [(set (match_operand:DF 0 "push_operand" "")
3474         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475   "TARGET_64BIT"
3476   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478
3479 (define_insn "*dummy_extendsfxf2"
3480   [(set (match_operand:XF 0 "push_operand" "=<")
3481         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482   "0"
3483   "#")
3484
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488   ""
3489   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   "TARGET_64BIT"
3497   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504   ""
3505   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   "TARGET_64BIT"
3513   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517 (define_expand "extendsfdf2"
3518   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521 {
3522   /* ??? Needed for compress_float_constant since all fp constants
3523      are LEGITIMATE_CONSTANT_P.  */
3524   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525     {
3526       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527           && standard_80387_constant_p (operands[1]) > 0)
3528         {
3529           operands[1] = simplify_const_unary_operation
3530             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531           emit_move_insn_1 (operands[0], operands[1]);
3532           DONE;
3533         }
3534       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535     }
3536 })
3537
3538 (define_insn "*extendsfdf2_mixed"
3539   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3540         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3541   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3542 {
3543   switch (which_alternative)
3544     {
3545     case 0:
3546       return output_387_reg_move (insn, operands);
3547
3548     case 1:
3549       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3550         return "fstp%z0\t%y0";
3551       else
3552         return "fst%z0\t%y0";
3553
3554     case 2:
3555       return "cvtss2sd\t{%1, %0|%0, %1}";
3556
3557     default:
3558       gcc_unreachable ();
3559     }
3560 }
3561   [(set_attr "type" "fmov,fmov,ssecvt")
3562    (set_attr "mode" "SF,XF,DF")])
3563
3564 (define_insn "*extendsfdf2_sse"
3565   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3566         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3567   "TARGET_SSE2 && TARGET_SSE_MATH"
3568   "cvtss2sd\t{%1, %0|%0, %1}"
3569   [(set_attr "type" "ssecvt")
3570    (set_attr "mode" "DF")])
3571
3572 (define_insn "*extendsfdf2_i387"
3573   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3574         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3575   "TARGET_80387"
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     {
3604       if (standard_80387_constant_p (operands[1]) > 0)
3605         {
3606           operands[1] = simplify_const_unary_operation
3607             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3608           emit_move_insn_1 (operands[0], operands[1]);
3609           DONE;
3610         }
3611       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3612     }
3613 })
3614
3615 (define_insn "*extendsfxf2_i387"
3616   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3618   "TARGET_80387"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       return output_387_reg_move (insn, operands);
3624
3625     case 1:
3626       /* There is no non-popping store to memory for XFmode.  So if
3627          we need one, follow the store with a load.  */
3628       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629         return "fstp%z0\t%y0";
3630       else
3631         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3632
3633     default:
3634       gcc_unreachable ();
3635     }
3636 }
3637   [(set_attr "type" "fmov")
3638    (set_attr "mode" "SF,XF")])
3639
3640 (define_expand "extenddfxf2"
3641   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3642         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3643   "TARGET_80387"
3644 {
3645   /* ??? Needed for compress_float_constant since all fp constants
3646      are LEGITIMATE_CONSTANT_P.  */
3647   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3648     {
3649       if (standard_80387_constant_p (operands[1]) > 0)
3650         {
3651           operands[1] = simplify_const_unary_operation
3652             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3653           emit_move_insn_1 (operands[0], operands[1]);
3654           DONE;
3655         }
3656       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3657     }
3658 })
3659
3660 (define_insn "*extenddfxf2_i387"
3661   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3662         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3663   "TARGET_80387"
3664 {
3665   switch (which_alternative)
3666     {
3667     case 0:
3668       return output_387_reg_move (insn, operands);
3669
3670     case 1:
3671       /* There is no non-popping store to memory for XFmode.  So if
3672          we need one, follow the store with a load.  */
3673       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3674         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3675       else
3676         return "fstp%z0\t%y0";
3677
3678     default:
3679       gcc_unreachable ();
3680     }
3681 }
3682   [(set_attr "type" "fmov")
3683    (set_attr "mode" "DF,XF")])
3684
3685 ;; %%% This seems bad bad news.
3686 ;; This cannot output into an f-reg because there is no way to be sure
3687 ;; of truncating in that case.  Otherwise this is just like a simple move
3688 ;; insn.  So we pretend we can output to a reg in order to get better
3689 ;; register preferencing, but we really use a stack slot.
3690
3691 ;; Conversion from DFmode to SFmode.
3692
3693 (define_expand "truncdfsf2"
3694   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3695         (float_truncate:SF
3696           (match_operand:DF 1 "nonimmediate_operand" "")))]
3697   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3698 {
3699   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3700     ;
3701   else if (flag_unsafe_math_optimizations)
3702     ;
3703   else
3704     {
3705       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3706       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3707       DONE;
3708     }
3709 })
3710
3711 (define_expand "truncdfsf2_with_temp"
3712   [(parallel [(set (match_operand:SF 0 "" "")
3713                    (float_truncate:SF (match_operand:DF 1 "" "")))
3714               (clobber (match_operand:SF 2 "" ""))])]
3715   "")
3716
3717 (define_insn "*truncdfsf_fast_mixed"
3718   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3719         (float_truncate:SF
3720           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3721   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3722 {
3723   switch (which_alternative)
3724     {
3725     case 0:
3726       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3727         return "fstp%z0\t%y0";
3728       else
3729         return "fst%z0\t%y0";
3730     case 1:
3731       return output_387_reg_move (insn, operands);
3732     case 2:
3733       return "cvtsd2ss\t{%1, %0|%0, %1}";
3734     default:
3735       gcc_unreachable ();
3736     }
3737 }
3738   [(set_attr "type" "fmov,fmov,ssecvt")
3739    (set_attr "mode" "SF")])
3740
3741 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3742 ;; because nothing we do here is unsafe.
3743 (define_insn "*truncdfsf_fast_sse"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3747   "TARGET_SSE2 && TARGET_SSE_MATH"
3748   "cvtsd2ss\t{%1, %0|%0, %1}"
3749   [(set_attr "type" "ssecvt")
3750    (set_attr "mode" "SF")])
3751
3752 (define_insn "*truncdfsf_fast_i387"
3753   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3754         (float_truncate:SF
3755           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3756   "TARGET_80387 && flag_unsafe_math_optimizations"
3757   "* return output_387_reg_move (insn, operands);"
3758   [(set_attr "type" "fmov")
3759    (set_attr "mode" "SF")])
3760
3761 (define_insn "*truncdfsf_mixed"
3762   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3763         (float_truncate:SF
3764           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3765    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3766   "TARGET_MIX_SSE_I387"
3767 {
3768   switch (which_alternative)
3769     {
3770     case 0:
3771       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3772         return "fstp%z0\t%y0";
3773       else
3774         return "fst%z0\t%y0";
3775     case 1:
3776       return "#";
3777     case 2:
3778       return "cvtsd2ss\t{%1, %0|%0, %1}";
3779     default:
3780       gcc_unreachable ();
3781     }
3782 }
3783   [(set_attr "type" "fmov,multi,ssecvt")
3784    (set_attr "unit" "*,i387,*")
3785    (set_attr "mode" "SF")])
3786
3787 (define_insn "*truncdfsf_i387"
3788   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3789         (float_truncate:SF
3790           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3791    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3792   "TARGET_80387"
3793 {
3794   switch (which_alternative)
3795     {
3796     case 0:
3797       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3798         return "fstp%z0\t%y0";
3799       else
3800         return "fst%z0\t%y0";
3801     case 1:
3802       return "#";
3803     default:
3804       gcc_unreachable ();
3805     }
3806 }
3807   [(set_attr "type" "fmov,multi")
3808    (set_attr "unit" "*,i387")
3809    (set_attr "mode" "SF")])
3810
3811 (define_insn "*truncdfsf2_i387_1"
3812   [(set (match_operand:SF 0 "memory_operand" "=m")
3813         (float_truncate:SF
3814           (match_operand:DF 1 "register_operand" "f")))]
3815   "TARGET_80387
3816    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3817    && !TARGET_MIX_SSE_I387"
3818 {
3819   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3820     return "fstp%z0\t%y0";
3821   else
3822     return "fst%z0\t%y0";
3823 }
3824   [(set_attr "type" "fmov")
3825    (set_attr "mode" "SF")])
3826
3827 (define_split
3828   [(set (match_operand:SF 0 "register_operand" "")
3829         (float_truncate:SF
3830          (match_operand:DF 1 "fp_register_operand" "")))
3831    (clobber (match_operand 2 "" ""))]
3832   "reload_completed"
3833   [(set (match_dup 2) (match_dup 1))
3834    (set (match_dup 0) (match_dup 2))]
3835 {
3836   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3837 })
3838
3839 ;; Conversion from XFmode to SFmode.
3840
3841 (define_expand "truncxfsf2"
3842   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3843                    (float_truncate:SF
3844                     (match_operand:XF 1 "register_operand" "")))
3845               (clobber (match_dup 2))])]
3846   "TARGET_80387"
3847 {
3848   if (flag_unsafe_math_optimizations)
3849     {
3850       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3851       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3852       if (reg != operands[0])
3853         emit_move_insn (operands[0], reg);
3854       DONE;
3855     }
3856   else
3857     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3858 })
3859
3860 (define_insn "*truncxfsf2_mixed"
3861   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3864    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3865   "TARGET_MIX_SSE_I387"
3866 {
3867   gcc_assert (!which_alternative);
3868   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3869     return "fstp%z0\t%y0";
3870   else
3871     return "fst%z0\t%y0";
3872 }
3873   [(set_attr "type" "fmov,multi,multi,multi")
3874    (set_attr "unit" "*,i387,i387,i387")
3875    (set_attr "mode" "SF")])
3876
3877 (define_insn "truncxfsf2_i387_noop"
3878   [(set (match_operand:SF 0 "register_operand" "=f")
3879         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3880   "TARGET_80387 && flag_unsafe_math_optimizations"
3881 {
3882   return output_387_reg_move (insn, operands);
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF")])
3886
3887 (define_insn "*truncxfsf2_i387"
3888   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3889         (float_truncate:SF
3890          (match_operand:XF 1 "register_operand" "f,f,f")))
3891    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3892   "TARGET_80387"
3893 {
3894   gcc_assert (!which_alternative);
3895   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896     return "fstp%z0\t%y0";
3897    else
3898      return "fst%z0\t%y0";
3899 }
3900   [(set_attr "type" "fmov,multi,multi")
3901    (set_attr "unit" "*,i387,i387")
3902    (set_attr "mode" "SF")])
3903
3904 (define_insn "*truncxfsf2_i387_1"
3905   [(set (match_operand:SF 0 "memory_operand" "=m")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f")))]
3908   "TARGET_80387"
3909 {
3910   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911     return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3914 }
3915   [(set_attr "type" "fmov")
3916    (set_attr "mode" "SF")])
3917
3918 (define_split
3919   [(set (match_operand:SF 0 "register_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387 && reload_completed"
3924   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3925    (set (match_dup 0) (match_dup 2))]
3926   "")
3927
3928 (define_split
3929   [(set (match_operand:SF 0 "memory_operand" "")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "")))
3932    (clobber (match_operand:SF 2 "memory_operand" ""))]
3933   "TARGET_80387"
3934   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3935   "")
3936
3937 ;; Conversion from XFmode to DFmode.
3938
3939 (define_expand "truncxfdf2"
3940   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3941                    (float_truncate:DF
3942                     (match_operand:XF 1 "register_operand" "")))
3943               (clobber (match_dup 2))])]
3944   "TARGET_80387"
3945 {
3946   if (flag_unsafe_math_optimizations)
3947     {
3948       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3949       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3950       if (reg != operands[0])
3951         emit_move_insn (operands[0], reg);
3952       DONE;
3953     }
3954   else
3955     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3956 })
3957
3958 (define_insn "*truncxfdf2_mixed"
3959   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3962    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3963   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3964 {
3965   gcc_assert (!which_alternative);
3966   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3967     return "fstp%z0\t%y0";
3968   else
3969     return "fst%z0\t%y0";
3970 }
3971   [(set_attr "type" "fmov,multi,multi,multi")
3972    (set_attr "unit" "*,i387,i387,i387")
3973    (set_attr "mode" "DF")])
3974
3975 (define_insn "truncxfdf2_i387_noop"
3976   [(set (match_operand:DF 0 "register_operand" "=f")
3977         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3978   "TARGET_80387 && flag_unsafe_math_optimizations"
3979 {
3980   return output_387_reg_move (insn, operands);
3981 }
3982   [(set_attr "type" "fmov")
3983    (set_attr "mode" "DF")])
3984
3985 (define_insn "*truncxfdf2_i387"
3986   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3987         (float_truncate:DF
3988          (match_operand:XF 1 "register_operand" "f,f,f")))
3989    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3990   "TARGET_80387"
3991 {
3992   gcc_assert (!which_alternative);
3993   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994     return "fstp%z0\t%y0";
3995   else
3996     return "fst%z0\t%y0";
3997 }
3998   [(set_attr "type" "fmov,multi,multi")
3999    (set_attr "unit" "*,i387,i387")
4000    (set_attr "mode" "DF")])
4001
4002 (define_insn "*truncxfdf2_i387_1"
4003   [(set (match_operand:DF 0 "memory_operand" "=m")
4004         (float_truncate:DF
4005           (match_operand:XF 1 "register_operand" "f")))]
4006   "TARGET_80387"
4007 {
4008   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4009     return "fstp%z0\t%y0";
4010   else
4011     return "fst%z0\t%y0";
4012 }
4013   [(set_attr "type" "fmov")
4014    (set_attr "mode" "DF")])
4015
4016 (define_split
4017   [(set (match_operand:DF 0 "register_operand" "")
4018         (float_truncate:DF
4019          (match_operand:XF 1 "register_operand" "")))
4020    (clobber (match_operand:DF 2 "memory_operand" ""))]
4021   "TARGET_80387 && reload_completed"
4022   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4023    (set (match_dup 0) (match_dup 2))]
4024   "")
4025
4026 (define_split
4027   [(set (match_operand:DF 0 "memory_operand" "")
4028         (float_truncate:DF
4029          (match_operand:XF 1 "register_operand" "")))
4030    (clobber (match_operand:DF 2 "memory_operand" ""))]
4031   "TARGET_80387"
4032   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4033   "")
4034 \f
4035 ;; Signed conversion to DImode.
4036
4037 (define_expand "fix_truncxfdi2"
4038   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4039                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4040               (clobber (reg:CC FLAGS_REG))])]
4041   "TARGET_80387"
4042 {
4043   if (TARGET_FISTTP)
4044    {
4045      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4046      DONE;
4047    }
4048 })
4049
4050 (define_expand "fix_trunc<mode>di2"
4051   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4053               (clobber (reg:CC FLAGS_REG))])]
4054   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4055 {
4056   if (TARGET_FISTTP
4057       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4058    {
4059      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060      DONE;
4061    }
4062   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4063    {
4064      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4065      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4066      if (out != operands[0])
4067         emit_move_insn (operands[0], out);
4068      DONE;
4069    }
4070 })
4071
4072 ;; Signed conversion to SImode.
4073
4074 (define_expand "fix_truncxfsi2"
4075   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4076                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4077               (clobber (reg:CC FLAGS_REG))])]
4078   "TARGET_80387"
4079 {
4080   if (TARGET_FISTTP)
4081    {
4082      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4083      DONE;
4084    }
4085 })
4086
4087 (define_expand "fix_trunc<mode>si2"
4088   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4090               (clobber (reg:CC FLAGS_REG))])]
4091   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4092 {
4093   if (TARGET_FISTTP
4094       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4095    {
4096      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097      DONE;
4098    }
4099   if (SSE_FLOAT_MODE_P (<MODE>mode))
4100    {
4101      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4102      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4103      if (out != operands[0])
4104         emit_move_insn (operands[0], out);
4105      DONE;
4106    }
4107 })
4108
4109 ;; Signed conversion to HImode.
4110
4111 (define_expand "fix_trunc<mode>hi2"
4112   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4113                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4114               (clobber (reg:CC FLAGS_REG))])]
4115   "TARGET_80387
4116    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4117 {
4118   if (TARGET_FISTTP)
4119    {
4120      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4121      DONE;
4122    }
4123 })
4124
4125 ;; When SSE is available, it is always faster to use it!
4126 (define_insn "fix_truncsfdi_sse"
4127   [(set (match_operand:DI 0 "register_operand" "=r,r")
4128         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttss2si{q}\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "SF")
4133    (set_attr "athlon_decode" "double,vector")])
4134
4135 (define_insn "fix_truncdfdi_sse"
4136   [(set (match_operand:DI 0 "register_operand" "=r,r")
4137         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttsd2si{q}\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_truncsfsi_sse"
4145   [(set (match_operand:SI 0 "register_operand" "=r,r")
4146         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4147   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4148   "cvttss2si\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "sseicvt")
4150    (set_attr "mode" "DF")
4151    (set_attr "athlon_decode" "double,vector")])
4152
4153 (define_insn "fix_truncdfsi_sse"
4154   [(set (match_operand:SI 0 "register_operand" "=r,r")
4155         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4156   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4157   "cvttsd2si\t{%1, %0|%0, %1}"
4158   [(set_attr "type" "sseicvt")
4159    (set_attr "mode" "DF")
4160    (set_attr "athlon_decode" "double,vector")])
4161
4162 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4163 (define_peephole2
4164   [(set (match_operand:DF 0 "register_operand" "")
4165         (match_operand:DF 1 "memory_operand" ""))
4166    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4167         (fix:SSEMODEI24 (match_dup 0)))]
4168   "!TARGET_K8
4169    && peep2_reg_dead_p (2, operands[0])"
4170   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4171   "")
4172
4173 (define_peephole2
4174   [(set (match_operand:SF 0 "register_operand" "")
4175         (match_operand:SF 1 "memory_operand" ""))
4176    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4177         (fix:SSEMODEI24 (match_dup 0)))]
4178   "!TARGET_K8
4179    && peep2_reg_dead_p (2, operands[0])"
4180   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4181   "")
4182
4183 ;; Avoid vector decoded forms of the instruction.
4184 (define_peephole2
4185   [(match_scratch:DF 2 "Y")
4186    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4187         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4188   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4189   [(set (match_dup 2) (match_dup 1))
4190    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4191   "")
4192
4193 (define_peephole2
4194   [(match_scratch:SF 2 "x")
4195    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4196         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4197   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4198   [(set (match_dup 2) (match_dup 1))
4199    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4200   "")
4201
4202 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4205   "TARGET_FISTTP
4206    && FLOAT_MODE_P (GET_MODE (operands[1]))
4207    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208          && (TARGET_64BIT || <MODE>mode != DImode))
4209         && TARGET_SSE_MATH)
4210    && !(reload_completed || reload_in_progress)"
4211   "#"
4212   "&& 1"
4213   [(const_int 0)]
4214 {
4215   if (memory_operand (operands[0], VOIDmode))
4216     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4217   else
4218     {
4219       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4220       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4221                                                             operands[1],
4222                                                             operands[2]));
4223     }
4224   DONE;
4225 }
4226   [(set_attr "type" "fisttp")
4227    (set_attr "mode" "<MODE>")])
4228
4229 (define_insn "fix_trunc<mode>_i387_fisttp"
4230   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4231         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4232    (clobber (match_scratch:XF 2 "=&1f"))]
4233   "TARGET_FISTTP
4234    && FLOAT_MODE_P (GET_MODE (operands[1]))
4235    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4236          && (TARGET_64BIT || <MODE>mode != DImode))
4237         && TARGET_SSE_MATH)"
4238   "* return output_fix_trunc (insn, operands, 1);"
4239   [(set_attr "type" "fisttp")
4240    (set_attr "mode" "<MODE>")])
4241
4242 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4246    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4247   "TARGET_FISTTP
4248    && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250         && (TARGET_64BIT || <MODE>mode != DImode))
4251         && TARGET_SSE_MATH)"
4252   "#"
4253   [(set_attr "type" "fisttp")
4254    (set_attr "mode" "<MODE>")])
4255
4256 (define_split
4257   [(set (match_operand:X87MODEI 0 "register_operand" "")
4258         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4259    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4260    (clobber (match_scratch 3 ""))]
4261   "reload_completed"
4262   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4263               (clobber (match_dup 3))])
4264    (set (match_dup 0) (match_dup 2))]
4265   "")
4266
4267 (define_split
4268   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4269         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4270    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4271    (clobber (match_scratch 3 ""))]
4272   "reload_completed"
4273   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4274               (clobber (match_dup 3))])]
4275   "")
4276
4277 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4278 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4279 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4280 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4281 ;; function in i386.c.
4282 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4283   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4284         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4285    (clobber (reg:CC FLAGS_REG))]
4286   "TARGET_80387 && !TARGET_FISTTP
4287    && FLOAT_MODE_P (GET_MODE (operands[1]))
4288    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4289          && (TARGET_64BIT || <MODE>mode != DImode))
4290    && !(reload_completed || reload_in_progress)"
4291   "#"
4292   "&& 1"
4293   [(const_int 0)]
4294 {
4295   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4296
4297   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4298   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4299   if (memory_operand (operands[0], VOIDmode))
4300     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4301                                          operands[2], operands[3]));
4302   else
4303     {
4304       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4305       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4306                                                      operands[2], operands[3],
4307                                                      operands[4]));
4308     }
4309   DONE;
4310 }
4311   [(set_attr "type" "fistp")
4312    (set_attr "i387_cw" "trunc")
4313    (set_attr "mode" "<MODE>")])
4314
4315 (define_insn "fix_truncdi_i387"
4316   [(set (match_operand:DI 0 "memory_operand" "=m")
4317         (fix:DI (match_operand 1 "register_operand" "f")))
4318    (use (match_operand:HI 2 "memory_operand" "m"))
4319    (use (match_operand:HI 3 "memory_operand" "m"))
4320    (clobber (match_scratch:XF 4 "=&1f"))]
4321   "TARGET_80387 && !TARGET_FISTTP
4322    && FLOAT_MODE_P (GET_MODE (operands[1]))
4323    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4324   "* return output_fix_trunc (insn, operands, 0);"
4325   [(set_attr "type" "fistp")
4326    (set_attr "i387_cw" "trunc")
4327    (set_attr "mode" "DI")])
4328
4329 (define_insn "fix_truncdi_i387_with_temp"
4330   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4331         (fix:DI (match_operand 1 "register_operand" "f,f")))
4332    (use (match_operand:HI 2 "memory_operand" "m,m"))
4333    (use (match_operand:HI 3 "memory_operand" "m,m"))
4334    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4335    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4336   "TARGET_80387 && !TARGET_FISTTP
4337    && FLOAT_MODE_P (GET_MODE (operands[1]))
4338    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4339   "#"
4340   [(set_attr "type" "fistp")
4341    (set_attr "i387_cw" "trunc")
4342    (set_attr "mode" "DI")])
4343
4344 (define_split 
4345   [(set (match_operand:DI 0 "register_operand" "")
4346         (fix:DI (match_operand 1 "register_operand" "")))
4347    (use (match_operand:HI 2 "memory_operand" ""))
4348    (use (match_operand:HI 3 "memory_operand" ""))
4349    (clobber (match_operand:DI 4 "memory_operand" ""))
4350    (clobber (match_scratch 5 ""))]
4351   "reload_completed"
4352   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4353               (use (match_dup 2))
4354               (use (match_dup 3))
4355               (clobber (match_dup 5))])
4356    (set (match_dup 0) (match_dup 4))]
4357   "")
4358
4359 (define_split 
4360   [(set (match_operand:DI 0 "memory_operand" "")
4361         (fix:DI (match_operand 1 "register_operand" "")))
4362    (use (match_operand:HI 2 "memory_operand" ""))
4363    (use (match_operand:HI 3 "memory_operand" ""))
4364    (clobber (match_operand:DI 4 "memory_operand" ""))
4365    (clobber (match_scratch 5 ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))
4370               (clobber (match_dup 5))])]
4371   "")
4372
4373 (define_insn "fix_trunc<mode>_i387"
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4376    (use (match_operand:HI 2 "memory_operand" "m"))
4377    (use (match_operand:HI 3 "memory_operand" "m"))]
4378   "TARGET_80387 && !TARGET_FISTTP
4379    && FLOAT_MODE_P (GET_MODE (operands[1]))
4380    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4381   "* return output_fix_trunc (insn, operands, 0);"
4382   [(set_attr "type" "fistp")
4383    (set_attr "i387_cw" "trunc")
4384    (set_attr "mode" "<MODE>")])
4385
4386 (define_insn "fix_trunc<mode>_i387_with_temp"
4387   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4388         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4389    (use (match_operand:HI 2 "memory_operand" "m,m"))
4390    (use (match_operand:HI 3 "memory_operand" "m,m"))
4391    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4392   "TARGET_80387 && !TARGET_FISTTP
4393    && FLOAT_MODE_P (GET_MODE (operands[1]))
4394    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4395   "#"
4396   [(set_attr "type" "fistp")
4397    (set_attr "i387_cw" "trunc")
4398    (set_attr "mode" "<MODE>")])
4399
4400 (define_split 
4401   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4402         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4403    (use (match_operand:HI 2 "memory_operand" ""))
4404    (use (match_operand:HI 3 "memory_operand" ""))
4405    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4406   "reload_completed"
4407   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4408               (use (match_dup 2))
4409               (use (match_dup 3))])
4410    (set (match_dup 0) (match_dup 4))]
4411   "")
4412
4413 (define_split 
4414   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4415         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4416    (use (match_operand:HI 2 "memory_operand" ""))
4417    (use (match_operand:HI 3 "memory_operand" ""))
4418    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4419   "reload_completed"
4420   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4421               (use (match_dup 2))
4422               (use (match_dup 3))])]
4423   "")
4424
4425 (define_insn "x86_fnstcw_1"
4426   [(set (match_operand:HI 0 "memory_operand" "=m")
4427         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4428   "TARGET_80387"
4429   "fnstcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")])
4433
4434 (define_insn "x86_fldcw_1"
4435   [(set (reg:HI FPSR_REG)
4436         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4437   "TARGET_80387"
4438   "fldcw\t%0"
4439   [(set_attr "length" "2")
4440    (set_attr "mode" "HI")
4441    (set_attr "unit" "i387")
4442    (set_attr "athlon_decode" "vector")])
4443 \f
4444 ;; Conversion between fixed point and floating point.
4445
4446 ;; Even though we only accept memory inputs, the backend _really_
4447 ;; wants to be able to do this between registers.
4448
4449 (define_expand "floathisf2"
4450   [(set (match_operand:SF 0 "register_operand" "")
4451         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4452   "TARGET_80387 || TARGET_SSE_MATH"
4453 {
4454   if (TARGET_SSE_MATH)
4455     {
4456       emit_insn (gen_floatsisf2 (operands[0],
4457                                  convert_to_mode (SImode, operands[1], 0)));
4458       DONE;
4459     }
4460 })
4461
4462 (define_insn "*floathisf2_i387"
4463   [(set (match_operand:SF 0 "register_operand" "=f,f")
4464         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4465   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4466   "@
4467    fild%z1\t%1
4468    #"
4469   [(set_attr "type" "fmov,multi")
4470    (set_attr "mode" "SF")
4471    (set_attr "unit" "*,i387")
4472    (set_attr "fp_int_src" "true")])
4473
4474 (define_expand "floatsisf2"
4475   [(set (match_operand:SF 0 "register_operand" "")
4476         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4477   "TARGET_80387 || TARGET_SSE_MATH"
4478   "")
4479
4480 (define_insn "*floatsisf2_mixed"
4481   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4482         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4483   "TARGET_MIX_SSE_I387"
4484   "@
4485    fild%z1\t%1
4486    #
4487    cvtsi2ss\t{%1, %0|%0, %1}
4488    cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "unit" "*,i387,*,*")
4492    (set_attr "athlon_decode" "*,*,vector,double")
4493    (set_attr "fp_int_src" "true")])
4494
4495 (define_insn "*floatsisf2_sse"
4496   [(set (match_operand:SF 0 "register_operand" "=x,x")
4497         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4498   "TARGET_SSE_MATH"
4499   "cvtsi2ss\t{%1, %0|%0, %1}"
4500   [(set_attr "type" "sseicvt")
4501    (set_attr "mode" "SF")
4502    (set_attr "athlon_decode" "vector,double")
4503    (set_attr "fp_int_src" "true")])
4504
4505 (define_insn "*floatsisf2_i387"
4506   [(set (match_operand:SF 0 "register_operand" "=f,f")
4507         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4508   "TARGET_80387"
4509   "@
4510    fild%z1\t%1
4511    #"
4512   [(set_attr "type" "fmov,multi")
4513    (set_attr "mode" "SF")
4514    (set_attr "unit" "*,i387")
4515    (set_attr "fp_int_src" "true")])
4516
4517 (define_expand "floatdisf2"
4518   [(set (match_operand:SF 0 "register_operand" "")
4519         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4520   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4521   "")
4522
4523 (define_insn "*floatdisf2_mixed"
4524   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4525         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4526   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4527   "@
4528    fild%z1\t%1
4529    #
4530    cvtsi2ss{q}\t{%1, %0|%0, %1}
4531    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4532   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4533    (set_attr "mode" "SF")
4534    (set_attr "unit" "*,i387,*,*")
4535    (set_attr "athlon_decode" "*,*,vector,double")
4536    (set_attr "fp_int_src" "true")])
4537
4538 (define_insn "*floatdisf2_sse"
4539   [(set (match_operand:SF 0 "register_operand" "=x,x")
4540         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4541   "TARGET_64BIT && TARGET_SSE_MATH"
4542   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4543   [(set_attr "type" "sseicvt")
4544    (set_attr "mode" "SF")
4545    (set_attr "athlon_decode" "vector,double")
4546    (set_attr "fp_int_src" "true")])
4547
4548 (define_insn "*floatdisf2_i387"
4549   [(set (match_operand:SF 0 "register_operand" "=f,f")
4550         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4551   "TARGET_80387"
4552   "@
4553    fild%z1\t%1
4554    #"
4555   [(set_attr "type" "fmov,multi")
4556    (set_attr "mode" "SF")
4557    (set_attr "unit" "*,i387")
4558    (set_attr "fp_int_src" "true")])
4559
4560 (define_expand "floathidf2"
4561   [(set (match_operand:DF 0 "register_operand" "")
4562         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4563   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4564 {
4565   if (TARGET_SSE2 && TARGET_SSE_MATH)
4566     {
4567       emit_insn (gen_floatsidf2 (operands[0],
4568                                  convert_to_mode (SImode, operands[1], 0)));
4569       DONE;
4570     }
4571 })
4572
4573 (define_insn "*floathidf2_i387"
4574   [(set (match_operand:DF 0 "register_operand" "=f,f")
4575         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4576   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4577   "@
4578    fild%z1\t%1
4579    #"
4580   [(set_attr "type" "fmov,multi")
4581    (set_attr "mode" "DF")
4582    (set_attr "unit" "*,i387")
4583    (set_attr "fp_int_src" "true")])
4584
4585 (define_expand "floatsidf2"
4586   [(set (match_operand:DF 0 "register_operand" "")
4587         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4588   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4589   "")
4590
4591 (define_insn "*floatsidf2_mixed"
4592   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4593         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4594   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4595   "@
4596    fild%z1\t%1
4597    #
4598    cvtsi2sd\t{%1, %0|%0, %1}
4599    cvtsi2sd\t{%1, %0|%0, %1}"
4600   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4601    (set_attr "mode" "DF")
4602    (set_attr "unit" "*,i387,*,*")
4603    (set_attr "athlon_decode" "*,*,double,direct")
4604    (set_attr "fp_int_src" "true")])
4605
4606 (define_insn "*floatsidf2_sse"
4607   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4608         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4609   "TARGET_SSE2 && TARGET_SSE_MATH"
4610   "cvtsi2sd\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "sseicvt")
4612    (set_attr "mode" "DF")
4613    (set_attr "athlon_decode" "double,direct")
4614    (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "*floatsidf2_i387"
4617   [(set (match_operand:DF 0 "register_operand" "=f,f")
4618         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4619   "TARGET_80387"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "DF")
4625    (set_attr "unit" "*,i387")
4626    (set_attr "fp_int_src" "true")])
4627
4628 (define_expand "floatdidf2"
4629   [(set (match_operand:DF 0 "register_operand" "")
4630         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4631   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4632   "")
4633
4634 (define_insn "*floatdidf2_mixed"
4635   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4636         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4637   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4638   "@
4639    fild%z1\t%1
4640    #
4641    cvtsi2sd{q}\t{%1, %0|%0, %1}
4642    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4643   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4644    (set_attr "mode" "DF")
4645    (set_attr "unit" "*,i387,*,*")
4646    (set_attr "athlon_decode" "*,*,double,direct")
4647    (set_attr "fp_int_src" "true")])
4648
4649 (define_insn "*floatdidf2_sse"
4650   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4651         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4652   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4653   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4654   [(set_attr "type" "sseicvt")
4655    (set_attr "mode" "DF")
4656    (set_attr "athlon_decode" "double,direct")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "*floatdidf2_i387"
4660   [(set (match_operand:DF 0 "register_operand" "=f,f")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "DF")
4668    (set_attr "unit" "*,i387")
4669    (set_attr "fp_int_src" "true")])
4670
4671 (define_insn "floathixf2"
4672   [(set (match_operand:XF 0 "register_operand" "=f,f")
4673         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4674   "TARGET_80387"
4675   "@
4676    fild%z1\t%1
4677    #"
4678   [(set_attr "type" "fmov,multi")
4679    (set_attr "mode" "XF")
4680    (set_attr "unit" "*,i387")
4681    (set_attr "fp_int_src" "true")])
4682
4683 (define_insn "floatsixf2"
4684   [(set (match_operand:XF 0 "register_operand" "=f,f")
4685         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4686   "TARGET_80387"
4687   "@
4688    fild%z1\t%1
4689    #"
4690   [(set_attr "type" "fmov,multi")
4691    (set_attr "mode" "XF")
4692    (set_attr "unit" "*,i387")
4693    (set_attr "fp_int_src" "true")])
4694
4695 (define_insn "floatdixf2"
4696   [(set (match_operand:XF 0 "register_operand" "=f,f")
4697         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4698   "TARGET_80387"
4699   "@
4700    fild%z1\t%1
4701    #"
4702   [(set_attr "type" "fmov,multi")
4703    (set_attr "mode" "XF")
4704    (set_attr "unit" "*,i387")
4705    (set_attr "fp_int_src" "true")])
4706
4707 ;; %%% Kill these when reload knows how to do it.
4708 (define_split
4709   [(set (match_operand 0 "fp_register_operand" "")
4710         (float (match_operand 1 "register_operand" "")))]
4711   "reload_completed
4712    && TARGET_80387
4713    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4714   [(const_int 0)]
4715 {
4716   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4717   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4718   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4719   ix86_free_from_memory (GET_MODE (operands[1]));
4720   DONE;
4721 })
4722
4723 (define_expand "floatunssisf2"
4724   [(use (match_operand:SF 0 "register_operand" ""))
4725    (use (match_operand:SI 1 "register_operand" ""))]
4726   "!TARGET_64BIT && TARGET_SSE_MATH"
4727   "x86_emit_floatuns (operands); DONE;")
4728
4729 (define_expand "floatunsdisf2"
4730   [(use (match_operand:SF 0 "register_operand" ""))
4731    (use (match_operand:DI 1 "register_operand" ""))]
4732   "TARGET_64BIT && TARGET_SSE_MATH"
4733   "x86_emit_floatuns (operands); DONE;")
4734
4735 (define_expand "floatunsdidf2"
4736   [(use (match_operand:DF 0 "register_operand" ""))
4737    (use (match_operand:DI 1 "register_operand" ""))]
4738   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4739   "x86_emit_floatuns (operands); DONE;")
4740 \f
4741 ;; SSE extract/set expanders
4742
4743 \f
4744 ;; Add instructions
4745
4746 ;; %%% splits for addditi3
4747
4748 (define_expand "addti3"
4749   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4750         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4751                  (match_operand:TI 2 "x86_64_general_operand" "")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   "TARGET_64BIT"
4754   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4755
4756 (define_insn "*addti3_1"
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4759                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4762   "#")
4763
4764 (define_split
4765   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4766         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4767                  (match_operand:TI 2 "general_operand" "")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "TARGET_64BIT && reload_completed"
4770   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771                                           UNSPEC_ADD_CARRY))
4772               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4773    (parallel [(set (match_dup 3)
4774                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4775                                      (match_dup 4))
4776                             (match_dup 5)))
4777               (clobber (reg:CC FLAGS_REG))])]
4778   "split_ti (operands+0, 1, operands+0, operands+3);
4779    split_ti (operands+1, 1, operands+1, operands+4);
4780    split_ti (operands+2, 1, operands+2, operands+5);")
4781
4782 ;; %%% splits for addsidi3
4783 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4784 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4785 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4786
4787 (define_expand "adddi3"
4788   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4789         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4790                  (match_operand:DI 2 "x86_64_general_operand" "")))
4791    (clobber (reg:CC FLAGS_REG))]
4792   ""
4793   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4794
4795 (define_insn "*adddi3_1"
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4798                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "#")
4802
4803 (define_split
4804   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4805         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4806                  (match_operand:DI 2 "general_operand" "")))
4807    (clobber (reg:CC FLAGS_REG))]
4808   "!TARGET_64BIT && reload_completed"
4809   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4810                                           UNSPEC_ADD_CARRY))
4811               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4812    (parallel [(set (match_dup 3)
4813                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4814                                      (match_dup 4))
4815                             (match_dup 5)))
4816               (clobber (reg:CC FLAGS_REG))])]
4817   "split_di (operands+0, 1, operands+0, operands+3);
4818    split_di (operands+1, 1, operands+1, operands+4);
4819    split_di (operands+2, 1, operands+2, operands+5);")
4820
4821 (define_insn "adddi3_carry_rex64"
4822   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4823           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4824                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4825                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4826    (clobber (reg:CC FLAGS_REG))]
4827   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4828   "adc{q}\t{%2, %0|%0, %2}"
4829   [(set_attr "type" "alu")
4830    (set_attr "pent_pair" "pu")
4831    (set_attr "mode" "DI")])
4832
4833 (define_insn "*adddi3_cc_rex64"
4834   [(set (reg:CC FLAGS_REG)
4835         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4836                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4837                    UNSPEC_ADD_CARRY))
4838    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4839         (plus:DI (match_dup 1) (match_dup 2)))]
4840   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4841   "add{q}\t{%2, %0|%0, %2}"
4842   [(set_attr "type" "alu")
4843    (set_attr "mode" "DI")])
4844
4845 (define_insn "addqi3_carry"
4846   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4847           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4848                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4849                    (match_operand:QI 2 "general_operand" "qi,qm")))
4850    (clobber (reg:CC FLAGS_REG))]
4851   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4852   "adc{b}\t{%2, %0|%0, %2}"
4853   [(set_attr "type" "alu")
4854    (set_attr "pent_pair" "pu")
4855    (set_attr "mode" "QI")])
4856
4857 (define_insn "addhi3_carry"
4858   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4859           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4860                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4861                    (match_operand:HI 2 "general_operand" "ri,rm")))
4862    (clobber (reg:CC FLAGS_REG))]
4863   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4864   "adc{w}\t{%2, %0|%0, %2}"
4865   [(set_attr "type" "alu")
4866    (set_attr "pent_pair" "pu")
4867    (set_attr "mode" "HI")])
4868
4869 (define_insn "addsi3_carry"
4870   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:SI 2 "general_operand" "ri,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4876   "adc{l}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "SI")])
4880
4881 (define_insn "*addsi3_carry_zext"
4882   [(set (match_operand:DI 0 "register_operand" "=r")
4883           (zero_extend:DI 
4884             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4885                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4886                      (match_operand:SI 2 "general_operand" "rim"))))
4887    (clobber (reg:CC FLAGS_REG))]
4888   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4889   "adc{l}\t{%2, %k0|%k0, %2}"
4890   [(set_attr "type" "alu")
4891    (set_attr "pent_pair" "pu")
4892    (set_attr "mode" "SI")])
4893
4894 (define_insn "*addsi3_cc"
4895   [(set (reg:CC FLAGS_REG)
4896         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4897                     (match_operand:SI 2 "general_operand" "ri,rm")]
4898                    UNSPEC_ADD_CARRY))
4899    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4900         (plus:SI (match_dup 1) (match_dup 2)))]
4901   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4902   "add{l}\t{%2, %0|%0, %2}"
4903   [(set_attr "type" "alu")
4904    (set_attr "mode" "SI")])
4905
4906 (define_insn "addqi3_cc"
4907   [(set (reg:CC FLAGS_REG)
4908         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4909                     (match_operand:QI 2 "general_operand" "qi,qm")]
4910                    UNSPEC_ADD_CARRY))
4911    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4912         (plus:QI (match_dup 1) (match_dup 2)))]
4913   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4914   "add{b}\t{%2, %0|%0, %2}"
4915   [(set_attr "type" "alu")
4916    (set_attr "mode" "QI")])
4917
4918 (define_expand "addsi3"
4919   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4920                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4921                             (match_operand:SI 2 "general_operand" "")))
4922               (clobber (reg:CC FLAGS_REG))])]
4923   ""
4924   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4925
4926 (define_insn "*lea_1"
4927   [(set (match_operand:SI 0 "register_operand" "=r")
4928         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4929   "!TARGET_64BIT"
4930   "lea{l}\t{%a1, %0|%0, %a1}"
4931   [(set_attr "type" "lea")
4932    (set_attr "mode" "SI")])
4933
4934 (define_insn "*lea_1_rex64"
4935   [(set (match_operand:SI 0 "register_operand" "=r")
4936         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4937   "TARGET_64BIT"
4938   "lea{l}\t{%a1, %0|%0, %a1}"
4939   [(set_attr "type" "lea")
4940    (set_attr "mode" "SI")])
4941
4942 (define_insn "*lea_1_zext"
4943   [(set (match_operand:DI 0 "register_operand" "=r")
4944         (zero_extend:DI
4945          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4946   "TARGET_64BIT"
4947   "lea{l}\t{%a1, %k0|%k0, %a1}"
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "SI")])
4950
4951 (define_insn "*lea_2_rex64"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4954   "TARGET_64BIT"
4955   "lea{q}\t{%a1, %0|%0, %a1}"
4956   [(set_attr "type" "lea")
4957    (set_attr "mode" "DI")])
4958
4959 ;; The lea patterns for non-Pmodes needs to be matched by several
4960 ;; insns converted to real lea by splitters.
4961
4962 (define_insn_and_split "*lea_general_1"
4963   [(set (match_operand 0 "register_operand" "=r")
4964         (plus (plus (match_operand 1 "index_register_operand" "l")
4965                     (match_operand 2 "register_operand" "r"))
4966               (match_operand 3 "immediate_operand" "i")))]
4967   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4968     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4969    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4970    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4971    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4972    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4973        || GET_MODE (operands[3]) == VOIDmode)"
4974   "#"
4975   "&& reload_completed"
4976   [(const_int 0)]
4977 {
4978   rtx pat;
4979   operands[0] = gen_lowpart (SImode, operands[0]);
4980   operands[1] = gen_lowpart (Pmode, operands[1]);
4981   operands[2] = gen_lowpart (Pmode, operands[2]);
4982   operands[3] = gen_lowpart (Pmode, operands[3]);
4983   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4984                       operands[3]);
4985   if (Pmode != SImode)
4986     pat = gen_rtx_SUBREG (SImode, pat, 0);
4987   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4988   DONE;
4989 }
4990   [(set_attr "type" "lea")
4991    (set_attr "mode" "SI")])
4992
4993 (define_insn_and_split "*lea_general_1_zext"
4994   [(set (match_operand:DI 0 "register_operand" "=r")
4995         (zero_extend:DI
4996           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4997                             (match_operand:SI 2 "register_operand" "r"))
4998                    (match_operand:SI 3 "immediate_operand" "i"))))]
4999   "TARGET_64BIT"
5000   "#"
5001   "&& reload_completed"
5002   [(set (match_dup 0)
5003         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5004                                                      (match_dup 2))
5005                                             (match_dup 3)) 0)))]
5006 {
5007   operands[1] = gen_lowpart (Pmode, operands[1]);
5008   operands[2] = gen_lowpart (Pmode, operands[2]);
5009   operands[3] = gen_lowpart (Pmode, operands[3]);
5010 }
5011   [(set_attr "type" "lea")
5012    (set_attr "mode" "SI")])
5013
5014 (define_insn_and_split "*lea_general_2"
5015   [(set (match_operand 0 "register_operand" "=r")
5016         (plus (mult (match_operand 1 "index_register_operand" "l")
5017                     (match_operand 2 "const248_operand" "i"))
5018               (match_operand 3 "nonmemory_operand" "ri")))]
5019   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5020     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5021    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5022    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5023    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5024        || GET_MODE (operands[3]) == VOIDmode)"
5025   "#"
5026   "&& reload_completed"
5027   [(const_int 0)]
5028 {
5029   rtx pat;
5030   operands[0] = gen_lowpart (SImode, operands[0]);
5031   operands[1] = gen_lowpart (Pmode, operands[1]);
5032   operands[3] = gen_lowpart (Pmode, operands[3]);
5033   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5034                       operands[3]);
5035   if (Pmode != SImode)
5036     pat = gen_rtx_SUBREG (SImode, pat, 0);
5037   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5038   DONE;
5039 }
5040   [(set_attr "type" "lea")
5041    (set_attr "mode" "SI")])
5042
5043 (define_insn_and_split "*lea_general_2_zext"
5044   [(set (match_operand:DI 0 "register_operand" "=r")
5045         (zero_extend:DI
5046           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5047                             (match_operand:SI 2 "const248_operand" "n"))
5048                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5049   "TARGET_64BIT"
5050   "#"
5051   "&& reload_completed"
5052   [(set (match_dup 0)
5053         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5054                                                      (match_dup 2))
5055                                             (match_dup 3)) 0)))]
5056 {
5057   operands[1] = gen_lowpart (Pmode, operands[1]);
5058   operands[3] = gen_lowpart (Pmode, operands[3]);
5059 }
5060   [(set_attr "type" "lea")
5061    (set_attr "mode" "SI")])
5062
5063 (define_insn_and_split "*lea_general_3"
5064   [(set (match_operand 0 "register_operand" "=r")
5065         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5066                           (match_operand 2 "const248_operand" "i"))
5067                     (match_operand 3 "register_operand" "r"))
5068               (match_operand 4 "immediate_operand" "i")))]
5069   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5070     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5071    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5072    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5073    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5074   "#"
5075   "&& reload_completed"
5076   [(const_int 0)]
5077 {
5078   rtx pat;
5079   operands[0] = gen_lowpart (SImode, operands[0]);
5080   operands[1] = gen_lowpart (Pmode, operands[1]);
5081   operands[3] = gen_lowpart (Pmode, operands[3]);
5082   operands[4] = gen_lowpart (Pmode, operands[4]);
5083   pat = gen_rtx_PLUS (Pmode,
5084                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5085                                                          operands[2]),
5086                                     operands[3]),
5087                       operands[4]);
5088   if (Pmode != SImode)
5089     pat = gen_rtx_SUBREG (SImode, pat, 0);
5090   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5091   DONE;
5092 }
5093   [(set_attr "type" "lea")
5094    (set_attr "mode" "SI")])
5095
5096 (define_insn_and_split "*lea_general_3_zext"
5097   [(set (match_operand:DI 0 "register_operand" "=r")
5098         (zero_extend:DI
5099           (plus:SI (plus:SI (mult:SI
5100                               (match_operand:SI 1 "index_register_operand" "l")
5101                               (match_operand:SI 2 "const248_operand" "n"))
5102                             (match_operand:SI 3 "register_operand" "r"))
5103                    (match_operand:SI 4 "immediate_operand" "i"))))]
5104   "TARGET_64BIT"
5105   "#"
5106   "&& reload_completed"
5107   [(set (match_dup 0)
5108         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5109                                                               (match_dup 2))
5110                                                      (match_dup 3))
5111                                             (match_dup 4)) 0)))]
5112 {
5113   operands[1] = gen_lowpart (Pmode, operands[1]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5115   operands[4] = gen_lowpart (Pmode, operands[4]);
5116 }
5117   [(set_attr "type" "lea")
5118    (set_attr "mode" "SI")])
5119
5120 (define_insn "*adddi_1_rex64"
5121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5122         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5123                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5124    (clobber (reg:CC FLAGS_REG))]
5125   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5126 {
5127   switch (get_attr_type (insn))
5128     {
5129     case TYPE_LEA:
5130       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5131       return "lea{q}\t{%a2, %0|%0, %a2}";
5132
5133     case TYPE_INCDEC:
5134       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5135       if (operands[2] == const1_rtx)
5136         return "inc{q}\t%0";
5137       else
5138         {
5139           gcc_assert (operands[2] == constm1_rtx);
5140           return "dec{q}\t%0";
5141         }
5142
5143     default:
5144       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5145
5146       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5147          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5148       if (GET_CODE (operands[2]) == CONST_INT
5149           /* Avoid overflows.  */
5150           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5151           && (INTVAL (operands[2]) == 128
5152               || (INTVAL (operands[2]) < 0
5153                   && INTVAL (operands[2]) != -128)))
5154         {
5155           operands[2] = GEN_INT (-INTVAL (operands[2]));
5156           return "sub{q}\t{%2, %0|%0, %2}";
5157         }
5158       return "add{q}\t{%2, %0|%0, %2}";
5159     }
5160 }
5161   [(set (attr "type")
5162      (cond [(eq_attr "alternative" "2")
5163               (const_string "lea")
5164             ; Current assemblers are broken and do not allow @GOTOFF in
5165             ; ought but a memory context.
5166             (match_operand:DI 2 "pic_symbolic_operand" "")
5167               (const_string "lea")
5168             (match_operand:DI 2 "incdec_operand" "")
5169               (const_string "incdec")
5170            ]
5171            (const_string "alu")))
5172    (set_attr "mode" "DI")])
5173
5174 ;; Convert lea to the lea pattern to avoid flags dependency.
5175 (define_split
5176   [(set (match_operand:DI 0 "register_operand" "")
5177         (plus:DI (match_operand:DI 1 "register_operand" "")
5178                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5179    (clobber (reg:CC FLAGS_REG))]
5180   "TARGET_64BIT && reload_completed
5181    && true_regnum (operands[0]) != true_regnum (operands[1])"
5182   [(set (match_dup 0)
5183         (plus:DI (match_dup 1)
5184                  (match_dup 2)))]
5185   "")
5186
5187 (define_insn "*adddi_2_rex64"
5188   [(set (reg FLAGS_REG)
5189         (compare
5190           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5191                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5192           (const_int 0)))                       
5193    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5194         (plus:DI (match_dup 1) (match_dup 2)))]
5195   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5196    && ix86_binary_operator_ok (PLUS, DImode, operands)
5197    /* Current assemblers are broken and do not allow @GOTOFF in
5198       ought but a memory context.  */
5199    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5200 {
5201   switch (get_attr_type (insn))
5202     {
5203     case TYPE_INCDEC:
5204       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5205       if (operands[2] == const1_rtx)
5206         return "inc{q}\t%0";
5207       else
5208         {
5209           gcc_assert (operands[2] == constm1_rtx);
5210           return "dec{q}\t%0";
5211         }
5212
5213     default:
5214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5215       /* ???? We ought to handle there the 32bit case too
5216          - do we need new constraint?  */
5217       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5218          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5219       if (GET_CODE (operands[2]) == CONST_INT
5220           /* Avoid overflows.  */
5221           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5222           && (INTVAL (operands[2]) == 128
5223               || (INTVAL (operands[2]) < 0
5224                   && INTVAL (operands[2]) != -128)))
5225         {
5226           operands[2] = GEN_INT (-INTVAL (operands[2]));
5227           return "sub{q}\t{%2, %0|%0, %2}";
5228         }
5229       return "add{q}\t{%2, %0|%0, %2}";
5230     }
5231 }
5232   [(set (attr "type")
5233      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5234         (const_string "incdec")
5235         (const_string "alu")))
5236    (set_attr "mode" "DI")])
5237
5238 (define_insn "*adddi_3_rex64"
5239   [(set (reg FLAGS_REG)
5240         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5241                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5242    (clobber (match_scratch:DI 0 "=r"))]
5243   "TARGET_64BIT
5244    && ix86_match_ccmode (insn, CCZmode)
5245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5246    /* Current assemblers are broken and do not allow @GOTOFF in
5247       ought but a memory context.  */
5248    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249 {
5250   switch (get_attr_type (insn))
5251     {
5252     case TYPE_INCDEC:
5253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5254       if (operands[2] == const1_rtx)
5255         return "inc{q}\t%0";
5256       else
5257         {
5258           gcc_assert (operands[2] == constm1_rtx);
5259           return "dec{q}\t%0";
5260         }
5261
5262     default:
5263       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5264       /* ???? We ought to handle there the 32bit case too
5265          - do we need new constraint?  */
5266       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5267          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5268       if (GET_CODE (operands[2]) == CONST_INT
5269           /* Avoid overflows.  */
5270           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5271           && (INTVAL (operands[2]) == 128
5272               || (INTVAL (operands[2]) < 0
5273                   && INTVAL (operands[2]) != -128)))
5274         {
5275           operands[2] = GEN_INT (-INTVAL (operands[2]));
5276           return "sub{q}\t{%2, %0|%0, %2}";
5277         }
5278       return "add{q}\t{%2, %0|%0, %2}";
5279     }
5280 }
5281   [(set (attr "type")
5282      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5283         (const_string "incdec")
5284         (const_string "alu")))
5285    (set_attr "mode" "DI")])
5286
5287 ; For comparisons against 1, -1 and 128, we may generate better code
5288 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5289 ; is matched then.  We can't accept general immediate, because for
5290 ; case of overflows,  the result is messed up.
5291 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5292 ; when negated.
5293 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5294 ; only for comparisons not depending on it.
5295 (define_insn "*adddi_4_rex64"
5296   [(set (reg FLAGS_REG)
5297         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5298                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5299    (clobber (match_scratch:DI 0 "=rm"))]
5300   "TARGET_64BIT
5301    &&  ix86_match_ccmode (insn, CCGCmode)"
5302 {
5303   switch (get_attr_type (insn))
5304     {
5305     case TYPE_INCDEC:
5306       if (operands[2] == constm1_rtx)
5307         return "inc{q}\t%0";
5308       else
5309         {
5310           gcc_assert (operands[2] == const1_rtx);
5311           return "dec{q}\t%0";
5312         }
5313
5314     default:
5315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5317          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5318       if ((INTVAL (operands[2]) == -128
5319            || (INTVAL (operands[2]) > 0
5320                && INTVAL (operands[2]) != 128))
5321           /* Avoid overflows.  */
5322           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5323         return "sub{q}\t{%2, %0|%0, %2}";
5324       operands[2] = GEN_INT (-INTVAL (operands[2]));
5325       return "add{q}\t{%2, %0|%0, %2}";
5326     }
5327 }
5328   [(set (attr "type")
5329      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5330         (const_string "incdec")
5331         (const_string "alu")))
5332    (set_attr "mode" "DI")])
5333
5334 (define_insn "*adddi_5_rex64"
5335   [(set (reg FLAGS_REG)
5336         (compare
5337           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5338                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5339           (const_int 0)))                       
5340    (clobber (match_scratch:DI 0 "=r"))]
5341   "TARGET_64BIT
5342    && ix86_match_ccmode (insn, CCGOCmode)
5343    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5344    /* Current assemblers are broken and do not allow @GOTOFF in
5345       ought but a memory context.  */
5346    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5347 {
5348   switch (get_attr_type (insn))
5349     {
5350     case TYPE_INCDEC:
5351       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5352       if (operands[2] == const1_rtx)
5353         return "inc{q}\t%0";
5354       else
5355         {
5356           gcc_assert (operands[2] == constm1_rtx);
5357           return "dec{q}\t%0";
5358         }
5359
5360     default:
5361       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5362       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5363          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5364       if (GET_CODE (operands[2]) == CONST_INT
5365           /* Avoid overflows.  */
5366           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5367           && (INTVAL (operands[2]) == 128
5368               || (INTVAL (operands[2]) < 0
5369                   && INTVAL (operands[2]) != -128)))
5370         {
5371           operands[2] = GEN_INT (-INTVAL (operands[2]));
5372           return "sub{q}\t{%2, %0|%0, %2}";
5373         }
5374       return "add{q}\t{%2, %0|%0, %2}";
5375     }
5376 }
5377   [(set (attr "type")
5378      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5379         (const_string "incdec")
5380         (const_string "alu")))
5381    (set_attr "mode" "DI")])
5382
5383
5384 (define_insn "*addsi_1"
5385   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5386         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5387                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5388    (clobber (reg:CC FLAGS_REG))]
5389   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5390 {
5391   switch (get_attr_type (insn))
5392     {
5393     case TYPE_LEA:
5394       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5395       return "lea{l}\t{%a2, %0|%0, %a2}";
5396
5397     case TYPE_INCDEC:
5398       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399       if (operands[2] == const1_rtx)
5400         return "inc{l}\t%0";
5401       else
5402         {
5403           gcc_assert (operands[2] == constm1_rtx);
5404           return "dec{l}\t%0";
5405         }
5406
5407     default:
5408       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5409
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (GET_CODE (operands[2]) == CONST_INT
5413           && (INTVAL (operands[2]) == 128
5414               || (INTVAL (operands[2]) < 0
5415                   && INTVAL (operands[2]) != -128)))
5416         {
5417           operands[2] = GEN_INT (-INTVAL (operands[2]));
5418           return "sub{l}\t{%2, %0|%0, %2}";
5419         }
5420       return "add{l}\t{%2, %0|%0, %2}";
5421     }
5422 }
5423   [(set (attr "type")
5424      (cond [(eq_attr "alternative" "2")
5425               (const_string "lea")
5426             ; Current assemblers are broken and do not allow @GOTOFF in
5427             ; ought but a memory context.
5428             (match_operand:SI 2 "pic_symbolic_operand" "")
5429               (const_string "lea")
5430             (match_operand:SI 2 "incdec_operand" "")
5431               (const_string "incdec")
5432            ]
5433            (const_string "alu")))
5434    (set_attr "mode" "SI")])
5435
5436 ;; Convert lea to the lea pattern to avoid flags dependency.
5437 (define_split
5438   [(set (match_operand 0 "register_operand" "")
5439         (plus (match_operand 1 "register_operand" "")
5440               (match_operand 2 "nonmemory_operand" "")))
5441    (clobber (reg:CC FLAGS_REG))]
5442   "reload_completed
5443    && true_regnum (operands[0]) != true_regnum (operands[1])"
5444   [(const_int 0)]
5445 {
5446   rtx pat;
5447   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5448      may confuse gen_lowpart.  */
5449   if (GET_MODE (operands[0]) != Pmode)
5450     {
5451       operands[1] = gen_lowpart (Pmode, operands[1]);
5452       operands[2] = gen_lowpart (Pmode, operands[2]);
5453     }
5454   operands[0] = gen_lowpart (SImode, operands[0]);
5455   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5456   if (Pmode != SImode)
5457     pat = gen_rtx_SUBREG (SImode, pat, 0);
5458   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5459   DONE;
5460 })
5461
5462 ;; It may seem that nonimmediate operand is proper one for operand 1.
5463 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5464 ;; we take care in ix86_binary_operator_ok to not allow two memory
5465 ;; operands so proper swapping will be done in reload.  This allow
5466 ;; patterns constructed from addsi_1 to match.
5467 (define_insn "addsi_1_zext"
5468   [(set (match_operand:DI 0 "register_operand" "=r,r")
5469         (zero_extend:DI
5470           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5471                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5472    (clobber (reg:CC FLAGS_REG))]
5473   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5474 {
5475   switch (get_attr_type (insn))
5476     {
5477     case TYPE_LEA:
5478       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5479       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5480
5481     case TYPE_INCDEC:
5482       if (operands[2] == const1_rtx)
5483         return "inc{l}\t%k0";
5484       else
5485         {
5486           gcc_assert (operands[2] == constm1_rtx);
5487           return "dec{l}\t%k0";
5488         }
5489
5490     default:
5491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5492          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5493       if (GET_CODE (operands[2]) == CONST_INT
5494           && (INTVAL (operands[2]) == 128
5495               || (INTVAL (operands[2]) < 0
5496                   && INTVAL (operands[2]) != -128)))
5497         {
5498           operands[2] = GEN_INT (-INTVAL (operands[2]));
5499           return "sub{l}\t{%2, %k0|%k0, %2}";
5500         }
5501       return "add{l}\t{%2, %k0|%k0, %2}";
5502     }
5503 }
5504   [(set (attr "type")
5505      (cond [(eq_attr "alternative" "1")
5506               (const_string "lea")
5507             ; Current assemblers are broken and do not allow @GOTOFF in
5508             ; ought but a memory context.
5509             (match_operand:SI 2 "pic_symbolic_operand" "")
5510               (const_string "lea")
5511             (match_operand:SI 2 "incdec_operand" "")
5512               (const_string "incdec")
5513            ]
5514            (const_string "alu")))
5515    (set_attr "mode" "SI")])
5516
5517 ;; Convert lea to the lea pattern to avoid flags dependency.
5518 (define_split
5519   [(set (match_operand:DI 0 "register_operand" "")
5520         (zero_extend:DI
5521           (plus:SI (match_operand:SI 1 "register_operand" "")
5522                    (match_operand:SI 2 "nonmemory_operand" ""))))
5523    (clobber (reg:CC FLAGS_REG))]
5524   "TARGET_64BIT && reload_completed
5525    && true_regnum (operands[0]) != true_regnum (operands[1])"
5526   [(set (match_dup 0)
5527         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5528 {
5529   operands[1] = gen_lowpart (Pmode, operands[1]);
5530   operands[2] = gen_lowpart (Pmode, operands[2]);
5531 })
5532
5533 (define_insn "*addsi_2"
5534   [(set (reg FLAGS_REG)
5535         (compare
5536           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5537                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5538           (const_int 0)))                       
5539    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5540         (plus:SI (match_dup 1) (match_dup 2)))]
5541   "ix86_match_ccmode (insn, CCGOCmode)
5542    && ix86_binary_operator_ok (PLUS, SImode, operands)
5543    /* Current assemblers are broken and do not allow @GOTOFF in
5544       ought but a memory context.  */
5545    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5546 {
5547   switch (get_attr_type (insn))
5548     {
5549     case TYPE_INCDEC:
5550       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5551       if (operands[2] == const1_rtx)
5552         return "inc{l}\t%0";
5553       else
5554         {
5555           gcc_assert (operands[2] == constm1_rtx);
5556           return "dec{l}\t%0";
5557         }
5558
5559     default:
5560       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5561       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5562          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5563       if (GET_CODE (operands[2]) == CONST_INT
5564           && (INTVAL (operands[2]) == 128
5565               || (INTVAL (operands[2]) < 0
5566                   && INTVAL (operands[2]) != -128)))
5567         {
5568           operands[2] = GEN_INT (-INTVAL (operands[2]));
5569           return "sub{l}\t{%2, %0|%0, %2}";
5570         }
5571       return "add{l}\t{%2, %0|%0, %2}";
5572     }
5573 }
5574   [(set (attr "type")
5575      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5576         (const_string "incdec")
5577         (const_string "alu")))
5578    (set_attr "mode" "SI")])
5579
5580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5581 (define_insn "*addsi_2_zext"
5582   [(set (reg FLAGS_REG)
5583         (compare
5584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5585                    (match_operand:SI 2 "general_operand" "rmni"))
5586           (const_int 0)))                       
5587    (set (match_operand:DI 0 "register_operand" "=r")
5588         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5589   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5590    && ix86_binary_operator_ok (PLUS, SImode, operands)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       if (operands[2] == const1_rtx)
5599         return "inc{l}\t%k0";
5600       else
5601         {
5602           gcc_assert (operands[2] == constm1_rtx);
5603           return "dec{l}\t%k0";
5604         }
5605
5606     default:
5607       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5609       if (GET_CODE (operands[2]) == CONST_INT
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{l}\t{%2, %k0|%k0, %2}";
5616         }
5617       return "add{l}\t{%2, %k0|%k0, %2}";
5618     }
5619 }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "SI")])
5625
5626 (define_insn "*addsi_3"
5627   [(set (reg FLAGS_REG)
5628         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5629                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5630    (clobber (match_scratch:SI 0 "=r"))]
5631   "ix86_match_ccmode (insn, CCZmode)
5632    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5633    /* Current assemblers are broken and do not allow @GOTOFF in
5634       ought but a memory context.  */
5635    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5636 {
5637   switch (get_attr_type (insn))
5638     {
5639     case TYPE_INCDEC:
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       if (operands[2] == const1_rtx)
5642         return "inc{l}\t%0";
5643       else
5644         {
5645           gcc_assert (operands[2] == constm1_rtx);
5646           return "dec{l}\t%0";
5647         }
5648
5649     default:
5650       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5651       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5652          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5653       if (GET_CODE (operands[2]) == CONST_INT
5654           && (INTVAL (operands[2]) == 128
5655               || (INTVAL (operands[2]) < 0
5656                   && INTVAL (operands[2]) != -128)))
5657         {
5658           operands[2] = GEN_INT (-INTVAL (operands[2]));
5659           return "sub{l}\t{%2, %0|%0, %2}";
5660         }
5661       return "add{l}\t{%2, %0|%0, %2}";
5662     }
5663 }
5664   [(set (attr "type")
5665      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5666         (const_string "incdec")
5667         (const_string "alu")))
5668    (set_attr "mode" "SI")])
5669
5670 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5671 (define_insn "*addsi_3_zext"
5672   [(set (reg FLAGS_REG)
5673         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5674                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5675    (set (match_operand:DI 0 "register_operand" "=r")
5676         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5677   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5678    && ix86_binary_operator_ok (PLUS, SImode, operands)
5679    /* Current assemblers are broken and do not allow @GOTOFF in
5680       ought but a memory context.  */
5681    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5682 {
5683   switch (get_attr_type (insn))
5684     {
5685     case TYPE_INCDEC:
5686       if (operands[2] == const1_rtx)
5687         return "inc{l}\t%k0";
5688       else
5689         {
5690           gcc_assert (operands[2] == constm1_rtx);
5691           return "dec{l}\t%k0";
5692         }
5693
5694     default:
5695       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5696          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5697       if (GET_CODE (operands[2]) == CONST_INT
5698           && (INTVAL (operands[2]) == 128
5699               || (INTVAL (operands[2]) < 0
5700                   && INTVAL (operands[2]) != -128)))
5701         {
5702           operands[2] = GEN_INT (-INTVAL (operands[2]));
5703           return "sub{l}\t{%2, %k0|%k0, %2}";
5704         }
5705       return "add{l}\t{%2, %k0|%k0, %2}";
5706     }
5707 }
5708   [(set (attr "type")
5709      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5710         (const_string "incdec")
5711         (const_string "alu")))
5712    (set_attr "mode" "SI")])
5713
5714 ; For comparisons against 1, -1 and 128, we may generate better code
5715 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5716 ; is matched then.  We can't accept general immediate, because for
5717 ; case of overflows,  the result is messed up.
5718 ; This pattern also don't hold of 0x80000000, since the value overflows
5719 ; when negated.
5720 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5721 ; only for comparisons not depending on it.
5722 (define_insn "*addsi_4"
5723   [(set (reg FLAGS_REG)
5724         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5725                  (match_operand:SI 2 "const_int_operand" "n")))
5726    (clobber (match_scratch:SI 0 "=rm"))]
5727   "ix86_match_ccmode (insn, CCGCmode)
5728    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5729 {
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_INCDEC:
5733       if (operands[2] == constm1_rtx)
5734         return "inc{l}\t%0";
5735       else
5736         {
5737           gcc_assert (operands[2] == const1_rtx);
5738           return "dec{l}\t%0";
5739         }
5740
5741     default:
5742       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if ((INTVAL (operands[2]) == -128
5746            || (INTVAL (operands[2]) > 0
5747                && INTVAL (operands[2]) != 128)))
5748         return "sub{l}\t{%2, %0|%0, %2}";
5749       operands[2] = GEN_INT (-INTVAL (operands[2]));
5750       return "add{l}\t{%2, %0|%0, %2}";
5751     }
5752 }
5753   [(set (attr "type")
5754      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5755         (const_string "incdec")
5756         (const_string "alu")))
5757    (set_attr "mode" "SI")])
5758
5759 (define_insn "*addsi_5"
5760   [(set (reg FLAGS_REG)
5761         (compare
5762           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5763                    (match_operand:SI 2 "general_operand" "rmni"))
5764           (const_int 0)))                       
5765    (clobber (match_scratch:SI 0 "=r"))]
5766   "ix86_match_ccmode (insn, CCGOCmode)
5767    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5768    /* Current assemblers are broken and do not allow @GOTOFF in
5769       ought but a memory context.  */
5770    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5771 {
5772   switch (get_attr_type (insn))
5773     {
5774     case TYPE_INCDEC:
5775       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776       if (operands[2] == const1_rtx)
5777         return "inc{l}\t%0";
5778       else
5779         {
5780           gcc_assert (operands[2] == constm1_rtx);
5781           return "dec{l}\t%0";
5782         }
5783
5784     default:
5785       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5787          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5788       if (GET_CODE (operands[2]) == CONST_INT
5789           && (INTVAL (operands[2]) == 128
5790               || (INTVAL (operands[2]) < 0
5791                   && INTVAL (operands[2]) != -128)))
5792         {
5793           operands[2] = GEN_INT (-INTVAL (operands[2]));
5794           return "sub{l}\t{%2, %0|%0, %2}";
5795         }
5796       return "add{l}\t{%2, %0|%0, %2}";
5797     }
5798 }
5799   [(set (attr "type")
5800      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5801         (const_string "incdec")
5802         (const_string "alu")))
5803    (set_attr "mode" "SI")])
5804
5805 (define_expand "addhi3"
5806   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5807                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5808                             (match_operand:HI 2 "general_operand" "")))
5809               (clobber (reg:CC FLAGS_REG))])]
5810   "TARGET_HIMODE_MATH"
5811   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5812
5813 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5814 ;; type optimizations enabled by define-splits.  This is not important
5815 ;; for PII, and in fact harmful because of partial register stalls.
5816
5817 (define_insn "*addhi_1_lea"
5818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5819         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5820                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5821    (clobber (reg:CC FLAGS_REG))]
5822   "!TARGET_PARTIAL_REG_STALL
5823    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5824 {
5825   switch (get_attr_type (insn))
5826     {
5827     case TYPE_LEA:
5828       return "#";
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{w}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{w}\t%0";
5836         }
5837
5838     default:
5839       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5840          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5841       if (GET_CODE (operands[2]) == CONST_INT
5842           && (INTVAL (operands[2]) == 128
5843               || (INTVAL (operands[2]) < 0
5844                   && INTVAL (operands[2]) != -128)))
5845         {
5846           operands[2] = GEN_INT (-INTVAL (operands[2]));
5847           return "sub{w}\t{%2, %0|%0, %2}";
5848         }
5849       return "add{w}\t{%2, %0|%0, %2}";
5850     }
5851 }
5852   [(set (attr "type")
5853      (if_then_else (eq_attr "alternative" "2")
5854         (const_string "lea")
5855         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856            (const_string "incdec")
5857            (const_string "alu"))))
5858    (set_attr "mode" "HI,HI,SI")])
5859
5860 (define_insn "*addhi_1"
5861   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5862         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                  (match_operand:HI 2 "general_operand" "ri,rm")))
5864    (clobber (reg:CC FLAGS_REG))]
5865   "TARGET_PARTIAL_REG_STALL
5866    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5867 {
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{w}\t%0";
5873       else
5874         {
5875           gcc_assert (operands[2] == constm1_rtx);
5876           return "dec{w}\t%0";
5877         }
5878
5879     default:
5880       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5882       if (GET_CODE (operands[2]) == CONST_INT
5883           && (INTVAL (operands[2]) == 128
5884               || (INTVAL (operands[2]) < 0
5885                   && INTVAL (operands[2]) != -128)))
5886         {
5887           operands[2] = GEN_INT (-INTVAL (operands[2]));
5888           return "sub{w}\t{%2, %0|%0, %2}";
5889         }
5890       return "add{w}\t{%2, %0|%0, %2}";
5891     }
5892 }
5893   [(set (attr "type")
5894      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5895         (const_string "incdec")
5896         (const_string "alu")))
5897    (set_attr "mode" "HI")])
5898
5899 (define_insn "*addhi_2"
5900   [(set (reg FLAGS_REG)
5901         (compare
5902           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5903                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5904           (const_int 0)))                       
5905    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5906         (plus:HI (match_dup 1) (match_dup 2)))]
5907   "ix86_match_ccmode (insn, CCGOCmode)
5908    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5909 {
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return "dec{w}\t%0";
5919         }
5920
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{w}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{w}\t{%2, %0|%0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "HI")])
5940
5941 (define_insn "*addhi_3"
5942   [(set (reg FLAGS_REG)
5943         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5944                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5945    (clobber (match_scratch:HI 0 "=r"))]
5946   "ix86_match_ccmode (insn, CCZmode)
5947    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5948 {
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == const1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == constm1_rtx);
5957           return "dec{w}\t%0";
5958         }
5959
5960     default:
5961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5963       if (GET_CODE (operands[2]) == CONST_INT
5964           && (INTVAL (operands[2]) == 128
5965               || (INTVAL (operands[2]) < 0
5966                   && INTVAL (operands[2]) != -128)))
5967         {
5968           operands[2] = GEN_INT (-INTVAL (operands[2]));
5969           return "sub{w}\t{%2, %0|%0, %2}";
5970         }
5971       return "add{w}\t{%2, %0|%0, %2}";
5972     }
5973 }
5974   [(set (attr "type")
5975      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5976         (const_string "incdec")
5977         (const_string "alu")))
5978    (set_attr "mode" "HI")])
5979
5980 ; See comments above addsi_4 for details.
5981 (define_insn "*addhi_4"
5982   [(set (reg FLAGS_REG)
5983         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5984                  (match_operand:HI 2 "const_int_operand" "n")))
5985    (clobber (match_scratch:HI 0 "=rm"))]
5986   "ix86_match_ccmode (insn, CCGCmode)
5987    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == constm1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == const1_rtx);
5997           return "dec{w}\t%0";
5998         }
5999
6000     default:
6001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004       if ((INTVAL (operands[2]) == -128
6005            || (INTVAL (operands[2]) > 0
6006                && INTVAL (operands[2]) != 128)))
6007         return "sub{w}\t{%2, %0|%0, %2}";
6008       operands[2] = GEN_INT (-INTVAL (operands[2]));
6009       return "add{w}\t{%2, %0|%0, %2}";
6010     }
6011 }
6012   [(set (attr "type")
6013      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6014         (const_string "incdec")
6015         (const_string "alu")))
6016    (set_attr "mode" "SI")])
6017
6018
6019 (define_insn "*addhi_5"
6020   [(set (reg FLAGS_REG)
6021         (compare
6022           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6023                    (match_operand:HI 2 "general_operand" "rmni"))
6024           (const_int 0)))                       
6025    (clobber (match_scratch:HI 0 "=r"))]
6026   "ix86_match_ccmode (insn, CCGOCmode)
6027    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6028 {
6029   switch (get_attr_type (insn))
6030     {
6031     case TYPE_INCDEC:
6032       if (operands[2] == const1_rtx)
6033         return "inc{w}\t%0";
6034       else
6035         {
6036           gcc_assert (operands[2] == constm1_rtx);
6037           return "dec{w}\t%0";
6038         }
6039
6040     default:
6041       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6042          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6043       if (GET_CODE (operands[2]) == CONST_INT
6044           && (INTVAL (operands[2]) == 128
6045               || (INTVAL (operands[2]) < 0
6046                   && INTVAL (operands[2]) != -128)))
6047         {
6048           operands[2] = GEN_INT (-INTVAL (operands[2]));
6049           return "sub{w}\t{%2, %0|%0, %2}";
6050         }
6051       return "add{w}\t{%2, %0|%0, %2}";
6052     }
6053 }
6054   [(set (attr "type")
6055      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6056         (const_string "incdec")
6057         (const_string "alu")))
6058    (set_attr "mode" "HI")])
6059
6060 (define_expand "addqi3"
6061   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6062                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6063                             (match_operand:QI 2 "general_operand" "")))
6064               (clobber (reg:CC FLAGS_REG))])]
6065   "TARGET_QIMODE_MATH"
6066   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6067
6068 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6069 (define_insn "*addqi_1_lea"
6070   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6071         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6072                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6073    (clobber (reg:CC FLAGS_REG))]
6074   "!TARGET_PARTIAL_REG_STALL
6075    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6076 {
6077   int widen = (which_alternative == 2);
6078   switch (get_attr_type (insn))
6079     {
6080     case TYPE_LEA:
6081       return "#";
6082     case TYPE_INCDEC:
6083       if (operands[2] == const1_rtx)
6084         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6085       else
6086         {
6087           gcc_assert (operands[2] == constm1_rtx);
6088           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6089         }
6090
6091     default:
6092       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6094       if (GET_CODE (operands[2]) == CONST_INT
6095           && (INTVAL (operands[2]) == 128
6096               || (INTVAL (operands[2]) < 0
6097                   && INTVAL (operands[2]) != -128)))
6098         {
6099           operands[2] = GEN_INT (-INTVAL (operands[2]));
6100           if (widen)
6101             return "sub{l}\t{%2, %k0|%k0, %2}";
6102           else
6103             return "sub{b}\t{%2, %0|%0, %2}";
6104         }
6105       if (widen)
6106         return "add{l}\t{%k2, %k0|%k0, %k2}";
6107       else
6108         return "add{b}\t{%2, %0|%0, %2}";
6109     }
6110 }
6111   [(set (attr "type")
6112      (if_then_else (eq_attr "alternative" "3")
6113         (const_string "lea")
6114         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6115            (const_string "incdec")
6116            (const_string "alu"))))
6117    (set_attr "mode" "QI,QI,SI,SI")])
6118
6119 (define_insn "*addqi_1"
6120   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6121         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6122                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6123    (clobber (reg:CC FLAGS_REG))]
6124   "TARGET_PARTIAL_REG_STALL
6125    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6126 {
6127   int widen = (which_alternative == 2);
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137         }
6138
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (GET_CODE (operands[2]) == CONST_INT
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           if (widen)
6149             return "sub{l}\t{%2, %k0|%k0, %2}";
6150           else
6151             return "sub{b}\t{%2, %0|%0, %2}";
6152         }
6153       if (widen)
6154         return "add{l}\t{%k2, %k0|%k0, %k2}";
6155       else
6156         return "add{b}\t{%2, %0|%0, %2}";
6157     }
6158 }
6159   [(set (attr "type")
6160      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6161         (const_string "incdec")
6162         (const_string "alu")))
6163    (set_attr "mode" "QI,QI,SI")])
6164
6165 (define_insn "*addqi_1_slp"
6166   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6167         (plus:QI (match_dup 0)
6168                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6169    (clobber (reg:CC FLAGS_REG))]
6170   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6172 {
6173   switch (get_attr_type (insn))
6174     {
6175     case TYPE_INCDEC:
6176       if (operands[1] == const1_rtx)
6177         return "inc{b}\t%0";
6178       else
6179         {
6180           gcc_assert (operands[1] == constm1_rtx);
6181           return "dec{b}\t%0";
6182         }
6183
6184     default:
6185       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6186       if (GET_CODE (operands[1]) == CONST_INT
6187           && INTVAL (operands[1]) < 0)
6188         {
6189           operands[1] = GEN_INT (-INTVAL (operands[1]));
6190           return "sub{b}\t{%1, %0|%0, %1}";
6191         }
6192       return "add{b}\t{%1, %0|%0, %1}";
6193     }
6194 }
6195   [(set (attr "type")
6196      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6197         (const_string "incdec")
6198         (const_string "alu1")))
6199    (set (attr "memory")
6200      (if_then_else (match_operand 1 "memory_operand" "")
6201         (const_string "load")
6202         (const_string "none")))
6203    (set_attr "mode" "QI")])
6204
6205 (define_insn "*addqi_2"
6206   [(set (reg FLAGS_REG)
6207         (compare
6208           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6209                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6210           (const_int 0)))
6211    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6212         (plus:QI (match_dup 1) (match_dup 2)))]
6213   "ix86_match_ccmode (insn, CCGOCmode)
6214    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return "inc{b}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx
6224                       || (GET_CODE (operands[2]) == CONST_INT
6225                           && INTVAL (operands[2]) == 255));
6226           return "dec{b}\t%0";
6227         }
6228
6229     default:
6230       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6231       if (GET_CODE (operands[2]) == CONST_INT
6232           && INTVAL (operands[2]) < 0)
6233         {
6234           operands[2] = GEN_INT (-INTVAL (operands[2]));
6235           return "sub{b}\t{%2, %0|%0, %2}";
6236         }
6237       return "add{b}\t{%2, %0|%0, %2}";
6238     }
6239 }
6240   [(set (attr "type")
6241      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242         (const_string "incdec")
6243         (const_string "alu")))
6244    (set_attr "mode" "QI")])
6245
6246 (define_insn "*addqi_3"
6247   [(set (reg FLAGS_REG)
6248         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6249                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6250    (clobber (match_scratch:QI 0 "=q"))]
6251   "ix86_match_ccmode (insn, CCZmode)
6252    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6253 {
6254   switch (get_attr_type (insn))
6255     {
6256     case TYPE_INCDEC:
6257       if (operands[2] == const1_rtx)
6258         return "inc{b}\t%0";
6259       else
6260         {
6261           gcc_assert (operands[2] == constm1_rtx
6262                       || (GET_CODE (operands[2]) == CONST_INT
6263                           && INTVAL (operands[2]) == 255));
6264           return "dec{b}\t%0";
6265         }
6266
6267     default:
6268       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6269       if (GET_CODE (operands[2]) == CONST_INT
6270           && INTVAL (operands[2]) < 0)
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           return "sub{b}\t{%2, %0|%0, %2}";
6274         }
6275       return "add{b}\t{%2, %0|%0, %2}";
6276     }
6277 }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set_attr "mode" "QI")])
6283
6284 ; See comments above addsi_4 for details.
6285 (define_insn "*addqi_4"
6286   [(set (reg FLAGS_REG)
6287         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6288                  (match_operand:QI 2 "const_int_operand" "n")))
6289    (clobber (match_scratch:QI 0 "=qm"))]
6290   "ix86_match_ccmode (insn, CCGCmode)
6291    && (INTVAL (operands[2]) & 0xff) != 0x80"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == constm1_rtx
6297           || (GET_CODE (operands[2]) == CONST_INT
6298               && INTVAL (operands[2]) == 255))
6299         return "inc{b}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == const1_rtx);
6303           return "dec{b}\t%0";
6304         }
6305
6306     default:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       if (INTVAL (operands[2]) < 0)
6309         {
6310           operands[2] = GEN_INT (-INTVAL (operands[2]));
6311           return "add{b}\t{%2, %0|%0, %2}";
6312         }
6313       return "sub{b}\t{%2, %0|%0, %2}";
6314     }
6315 }
6316   [(set (attr "type")
6317      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6318         (const_string "incdec")
6319         (const_string "alu")))
6320    (set_attr "mode" "QI")])
6321
6322
6323 (define_insn "*addqi_5"
6324   [(set (reg FLAGS_REG)
6325         (compare
6326           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6327                    (match_operand:QI 2 "general_operand" "qmni"))
6328           (const_int 0)))
6329    (clobber (match_scratch:QI 0 "=q"))]
6330   "ix86_match_ccmode (insn, CCGOCmode)
6331    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6332 {
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[2] == const1_rtx)
6337         return "inc{b}\t%0";
6338       else
6339         {
6340           gcc_assert (operands[2] == constm1_rtx
6341                       || (GET_CODE (operands[2]) == CONST_INT
6342                           && INTVAL (operands[2]) == 255));
6343           return "dec{b}\t%0";
6344         }
6345
6346     default:
6347       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6348       if (GET_CODE (operands[2]) == CONST_INT
6349           && INTVAL (operands[2]) < 0)
6350         {
6351           operands[2] = GEN_INT (-INTVAL (operands[2]));
6352           return "sub{b}\t{%2, %0|%0, %2}";
6353         }
6354       return "add{b}\t{%2, %0|%0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "QI")])
6362
6363
6364 (define_insn "addqi_ext_1"
6365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366                          (const_int 8)
6367                          (const_int 8))
6368         (plus:SI
6369           (zero_extract:SI
6370             (match_operand 1 "ext_register_operand" "0")
6371             (const_int 8)
6372             (const_int 8))
6373           (match_operand:QI 2 "general_operand" "Qmn")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "!TARGET_64BIT"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%h0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx
6385                       || (GET_CODE (operands[2]) == CONST_INT
6386                           && INTVAL (operands[2]) == 255));
6387           return "dec{b}\t%h0";
6388         }
6389
6390     default:
6391       return "add{b}\t{%2, %h0|%h0, %2}";
6392     }
6393 }
6394   [(set (attr "type")
6395      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396         (const_string "incdec")
6397         (const_string "alu")))
6398    (set_attr "mode" "QI")])
6399
6400 (define_insn "*addqi_ext_1_rex64"
6401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402                          (const_int 8)
6403                          (const_int 8))
6404         (plus:SI
6405           (zero_extract:SI
6406             (match_operand 1 "ext_register_operand" "0")
6407             (const_int 8)
6408             (const_int 8))
6409           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6410    (clobber (reg:CC FLAGS_REG))]
6411   "TARGET_64BIT"
6412 {
6413   switch (get_attr_type (insn))
6414     {
6415     case TYPE_INCDEC:
6416       if (operands[2] == const1_rtx)
6417         return "inc{b}\t%h0";
6418       else
6419         {
6420           gcc_assert (operands[2] == constm1_rtx
6421                       || (GET_CODE (operands[2]) == CONST_INT
6422                           && INTVAL (operands[2]) == 255));
6423           return "dec{b}\t%h0";
6424         }
6425
6426     default:
6427       return "add{b}\t{%2, %h0|%h0, %2}";
6428     }
6429 }
6430   [(set (attr "type")
6431      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6432         (const_string "incdec")
6433         (const_string "alu")))
6434    (set_attr "mode" "QI")])
6435
6436 (define_insn "*addqi_ext_2"
6437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6438                          (const_int 8)
6439                          (const_int 8))
6440         (plus:SI
6441           (zero_extract:SI
6442             (match_operand 1 "ext_register_operand" "%0")
6443             (const_int 8)
6444             (const_int 8))
6445           (zero_extract:SI
6446             (match_operand 2 "ext_register_operand" "Q")
6447             (const_int 8)
6448             (const_int 8))))
6449    (clobber (reg:CC FLAGS_REG))]
6450   ""
6451   "add{b}\t{%h2, %h0|%h0, %h2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "QI")])
6454
6455 ;; The patterns that match these are at the end of this file.
6456
6457 (define_expand "addxf3"
6458   [(set (match_operand:XF 0 "register_operand" "")
6459         (plus:XF (match_operand:XF 1 "register_operand" "")
6460                  (match_operand:XF 2 "register_operand" "")))]
6461   "TARGET_80387"
6462   "")
6463
6464 (define_expand "adddf3"
6465   [(set (match_operand:DF 0 "register_operand" "")
6466         (plus:DF (match_operand:DF 1 "register_operand" "")
6467                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6468   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6469   "")
6470
6471 (define_expand "addsf3"
6472   [(set (match_operand:SF 0 "register_operand" "")
6473         (plus:SF (match_operand:SF 1 "register_operand" "")
6474                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6475   "TARGET_80387 || TARGET_SSE_MATH"
6476   "")
6477 \f
6478 ;; Subtract instructions
6479
6480 ;; %%% splits for subditi3
6481
6482 (define_expand "subti3"
6483   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6484                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6485                              (match_operand:TI 2 "x86_64_general_operand" "")))
6486               (clobber (reg:CC FLAGS_REG))])]
6487   "TARGET_64BIT"
6488   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6489
6490 (define_insn "*subti3_1"
6491   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6492         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6493                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6494    (clobber (reg:CC FLAGS_REG))]
6495   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6496   "#")
6497
6498 (define_split
6499   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6500         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6501                   (match_operand:TI 2 "general_operand" "")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT && reload_completed"
6504   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6505               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6506    (parallel [(set (match_dup 3)
6507                    (minus:DI (match_dup 4)
6508                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6509                                       (match_dup 5))))
6510               (clobber (reg:CC FLAGS_REG))])]
6511   "split_ti (operands+0, 1, operands+0, operands+3);
6512    split_ti (operands+1, 1, operands+1, operands+4);
6513    split_ti (operands+2, 1, operands+2, operands+5);")
6514
6515 ;; %%% splits for subsidi3
6516
6517 (define_expand "subdi3"
6518   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6519                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6520                              (match_operand:DI 2 "x86_64_general_operand" "")))
6521               (clobber (reg:CC FLAGS_REG))])]
6522   ""
6523   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6524
6525 (define_insn "*subdi3_1"
6526   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6527         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6528                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6531   "#")
6532
6533 (define_split
6534   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6535         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6536                   (match_operand:DI 2 "general_operand" "")))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "!TARGET_64BIT && reload_completed"
6539   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6540               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6541    (parallel [(set (match_dup 3)
6542                    (minus:SI (match_dup 4)
6543                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6544                                       (match_dup 5))))
6545               (clobber (reg:CC FLAGS_REG))])]
6546   "split_di (operands+0, 1, operands+0, operands+3);
6547    split_di (operands+1, 1, operands+1, operands+4);
6548    split_di (operands+2, 1, operands+2, operands+5);")
6549
6550 (define_insn "subdi3_carry_rex64"
6551   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6552           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6554                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6555    (clobber (reg:CC FLAGS_REG))]
6556   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6557   "sbb{q}\t{%2, %0|%0, %2}"
6558   [(set_attr "type" "alu")
6559    (set_attr "pent_pair" "pu")
6560    (set_attr "mode" "DI")])
6561
6562 (define_insn "*subdi_1_rex64"
6563   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6564         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6565                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6566    (clobber (reg:CC FLAGS_REG))]
6567   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6568   "sub{q}\t{%2, %0|%0, %2}"
6569   [(set_attr "type" "alu")
6570    (set_attr "mode" "DI")])
6571
6572 (define_insn "*subdi_2_rex64"
6573   [(set (reg FLAGS_REG)
6574         (compare
6575           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6577           (const_int 0)))
6578    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6579         (minus:DI (match_dup 1) (match_dup 2)))]
6580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6581    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6582   "sub{q}\t{%2, %0|%0, %2}"
6583   [(set_attr "type" "alu")
6584    (set_attr "mode" "DI")])
6585
6586 (define_insn "*subdi_3_rex63"
6587   [(set (reg FLAGS_REG)
6588         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6589                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6590    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6591         (minus:DI (match_dup 1) (match_dup 2)))]
6592   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6593    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6594   "sub{q}\t{%2, %0|%0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "DI")])
6597
6598 (define_insn "subqi3_carry"
6599   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6600           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6601             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6602                (match_operand:QI 2 "general_operand" "qi,qm"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6605   "sbb{b}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "QI")])
6609
6610 (define_insn "subhi3_carry"
6611   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6612           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6613             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6614                (match_operand:HI 2 "general_operand" "ri,rm"))))
6615    (clobber (reg:CC FLAGS_REG))]
6616   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6617   "sbb{w}\t{%2, %0|%0, %2}"
6618   [(set_attr "type" "alu")
6619    (set_attr "pent_pair" "pu")
6620    (set_attr "mode" "HI")])
6621
6622 (define_insn "subsi3_carry"
6623   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6624           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6625             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6626                (match_operand:SI 2 "general_operand" "ri,rm"))))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6629   "sbb{l}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "pent_pair" "pu")
6632    (set_attr "mode" "SI")])
6633
6634 (define_insn "subsi3_carry_zext"
6635   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6636           (zero_extend:DI
6637             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6638               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6639                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6640    (clobber (reg:CC FLAGS_REG))]
6641   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sbb{l}\t{%2, %k0|%k0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "pent_pair" "pu")
6645    (set_attr "mode" "SI")])
6646
6647 (define_expand "subsi3"
6648   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6649                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6650                              (match_operand:SI 2 "general_operand" "")))
6651               (clobber (reg:CC FLAGS_REG))])]
6652   ""
6653   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6654
6655 (define_insn "*subsi_1"
6656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658                   (match_operand:SI 2 "general_operand" "ri,rm")))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6661   "sub{l}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "SI")])
6664
6665 (define_insn "*subsi_1_zext"
6666   [(set (match_operand:DI 0 "register_operand" "=r")
6667         (zero_extend:DI
6668           (minus:SI (match_operand:SI 1 "register_operand" "0")
6669                     (match_operand:SI 2 "general_operand" "rim"))))
6670    (clobber (reg:CC FLAGS_REG))]
6671   "TARGET_64BIT && 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_2"
6677   [(set (reg FLAGS_REG)
6678         (compare
6679           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6680                     (match_operand:SI 2 "general_operand" "ri,rm"))
6681           (const_int 0)))
6682    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6683         (minus:SI (match_dup 1) (match_dup 2)))]
6684   "ix86_match_ccmode (insn, CCGOCmode)
6685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686   "sub{l}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "SI")])
6689
6690 (define_insn "*subsi_2_zext"
6691   [(set (reg FLAGS_REG)
6692         (compare
6693           (minus:SI (match_operand:SI 1 "register_operand" "0")
6694                     (match_operand:SI 2 "general_operand" "rim"))
6695           (const_int 0)))
6696    (set (match_operand:DI 0 "register_operand" "=r")
6697         (zero_extend:DI
6698           (minus:SI (match_dup 1)
6699                     (match_dup 2))))]
6700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702   "sub{l}\t{%2, %k0|%k0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "SI")])
6705
6706 (define_insn "*subsi_3"
6707   [(set (reg FLAGS_REG)
6708         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6709                  (match_operand:SI 2 "general_operand" "ri,rm")))
6710    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6711         (minus:SI (match_dup 1) (match_dup 2)))]
6712   "ix86_match_ccmode (insn, CCmode)
6713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714   "sub{l}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "SI")])
6717
6718 (define_insn "*subsi_3_zext"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "register_operand" "0")
6721                  (match_operand:SI 2 "general_operand" "rim")))
6722    (set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_dup 1)
6725                     (match_dup 2))))]
6726   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6727    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %1|%1, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "DI")])
6731
6732 (define_expand "subhi3"
6733   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6734                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6735                              (match_operand:HI 2 "general_operand" "")))
6736               (clobber (reg:CC FLAGS_REG))])]
6737   "TARGET_HIMODE_MATH"
6738   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6739
6740 (define_insn "*subhi_1"
6741   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6742         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6743                   (match_operand:HI 2 "general_operand" "ri,rm")))
6744    (clobber (reg:CC FLAGS_REG))]
6745   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6746   "sub{w}\t{%2, %0|%0, %2}"
6747   [(set_attr "type" "alu")
6748    (set_attr "mode" "HI")])
6749
6750 (define_insn "*subhi_2"
6751   [(set (reg FLAGS_REG)
6752         (compare
6753           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6754                     (match_operand:HI 2 "general_operand" "ri,rm"))
6755           (const_int 0)))
6756    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6757         (minus:HI (match_dup 1) (match_dup 2)))]
6758   "ix86_match_ccmode (insn, CCGOCmode)
6759    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6760   "sub{w}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "HI")])
6763
6764 (define_insn "*subhi_3"
6765   [(set (reg FLAGS_REG)
6766         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6767                  (match_operand:HI 2 "general_operand" "ri,rm")))
6768    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6769         (minus:HI (match_dup 1) (match_dup 2)))]
6770   "ix86_match_ccmode (insn, CCmode)
6771    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6772   "sub{w}\t{%2, %0|%0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "mode" "HI")])
6775
6776 (define_expand "subqi3"
6777   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6778                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6779                              (match_operand:QI 2 "general_operand" "")))
6780               (clobber (reg:CC FLAGS_REG))])]
6781   "TARGET_QIMODE_MATH"
6782   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6783
6784 (define_insn "*subqi_1"
6785   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6786         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6787                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6790   "sub{b}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "alu")
6792    (set_attr "mode" "QI")])
6793
6794 (define_insn "*subqi_1_slp"
6795   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6796         (minus:QI (match_dup 0)
6797                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6798    (clobber (reg:CC FLAGS_REG))]
6799   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6801   "sub{b}\t{%1, %0|%0, %1}"
6802   [(set_attr "type" "alu1")
6803    (set_attr "mode" "QI")])
6804
6805 (define_insn "*subqi_2"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6809                     (match_operand:QI 2 "general_operand" "qi,qm"))
6810           (const_int 0)))
6811    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6812         (minus:HI (match_dup 1) (match_dup 2)))]
6813   "ix86_match_ccmode (insn, CCGOCmode)
6814    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6815   "sub{b}\t{%2, %0|%0, %2}"
6816   [(set_attr "type" "alu")
6817    (set_attr "mode" "QI")])
6818
6819 (define_insn "*subqi_3"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6822                  (match_operand:QI 2 "general_operand" "qi,qm")))
6823    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6824         (minus:HI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCmode)
6826    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6827   "sub{b}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "QI")])
6830
6831 ;; The patterns that match these are at the end of this file.
6832
6833 (define_expand "subxf3"
6834   [(set (match_operand:XF 0 "register_operand" "")
6835         (minus:XF (match_operand:XF 1 "register_operand" "")
6836                   (match_operand:XF 2 "register_operand" "")))]
6837   "TARGET_80387"
6838   "")
6839
6840 (define_expand "subdf3"
6841   [(set (match_operand:DF 0 "register_operand" "")
6842         (minus:DF (match_operand:DF 1 "register_operand" "")
6843                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6844   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6845   "")
6846
6847 (define_expand "subsf3"
6848   [(set (match_operand:SF 0 "register_operand" "")
6849         (minus:SF (match_operand:SF 1 "register_operand" "")
6850                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6851   "TARGET_80387 || TARGET_SSE_MATH"
6852   "")
6853 \f
6854 ;; Multiply instructions
6855
6856 (define_expand "muldi3"
6857   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6858                    (mult:DI (match_operand:DI 1 "register_operand" "")
6859                             (match_operand:DI 2 "x86_64_general_operand" "")))
6860               (clobber (reg:CC FLAGS_REG))])]
6861   "TARGET_64BIT"
6862   "")
6863
6864 (define_insn "*muldi3_1_rex64"
6865   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6866         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6867                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6868    (clobber (reg:CC FLAGS_REG))]
6869   "TARGET_64BIT
6870    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6871   "@
6872    imul{q}\t{%2, %1, %0|%0, %1, %2}
6873    imul{q}\t{%2, %1, %0|%0, %1, %2}
6874    imul{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "imul")
6876    (set_attr "prefix_0f" "0,0,1")
6877    (set (attr "athlon_decode")
6878         (cond [(eq_attr "cpu" "athlon")
6879                   (const_string "vector")
6880                (eq_attr "alternative" "1")
6881                   (const_string "vector")
6882                (and (eq_attr "alternative" "2")
6883                     (match_operand 1 "memory_operand" ""))
6884                   (const_string "vector")]
6885               (const_string "direct")))
6886    (set_attr "mode" "DI")])
6887
6888 (define_expand "mulsi3"
6889   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6890                    (mult:SI (match_operand:SI 1 "register_operand" "")
6891                             (match_operand:SI 2 "general_operand" "")))
6892               (clobber (reg:CC FLAGS_REG))])]
6893   ""
6894   "")
6895
6896 (define_insn "*mulsi3_1"
6897   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6898         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6899                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6900    (clobber (reg:CC FLAGS_REG))]
6901   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6902   "@
6903    imul{l}\t{%2, %1, %0|%0, %1, %2}
6904    imul{l}\t{%2, %1, %0|%0, %1, %2}
6905    imul{l}\t{%2, %0|%0, %2}"
6906   [(set_attr "type" "imul")
6907    (set_attr "prefix_0f" "0,0,1")
6908    (set (attr "athlon_decode")
6909         (cond [(eq_attr "cpu" "athlon")
6910                   (const_string "vector")
6911                (eq_attr "alternative" "1")
6912                   (const_string "vector")
6913                (and (eq_attr "alternative" "2")
6914                     (match_operand 1 "memory_operand" ""))
6915                   (const_string "vector")]
6916               (const_string "direct")))
6917    (set_attr "mode" "SI")])
6918
6919 (define_insn "*mulsi3_1_zext"
6920   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6921         (zero_extend:DI
6922           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6923                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_64BIT
6926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927   "@
6928    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6930    imul{l}\t{%2, %k0|%k0, %2}"
6931   [(set_attr "type" "imul")
6932    (set_attr "prefix_0f" "0,0,1")
6933    (set (attr "athlon_decode")
6934         (cond [(eq_attr "cpu" "athlon")
6935                   (const_string "vector")
6936                (eq_attr "alternative" "1")
6937                   (const_string "vector")
6938                (and (eq_attr "alternative" "2")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "SI")])
6943
6944 (define_expand "mulhi3"
6945   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6946                    (mult:HI (match_operand:HI 1 "register_operand" "")
6947                             (match_operand:HI 2 "general_operand" "")))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   "TARGET_HIMODE_MATH"
6950   "")
6951
6952 (define_insn "*mulhi3_1"
6953   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6954         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958   "@
6959    imul{w}\t{%2, %1, %0|%0, %1, %2}
6960    imul{w}\t{%2, %1, %0|%0, %1, %2}
6961    imul{w}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "imul")
6963    (set_attr "prefix_0f" "0,0,1")
6964    (set (attr "athlon_decode")
6965         (cond [(eq_attr "cpu" "athlon")
6966                   (const_string "vector")
6967                (eq_attr "alternative" "1,2")
6968                   (const_string "vector")]
6969               (const_string "direct")))
6970    (set_attr "mode" "HI")])
6971
6972 (define_expand "mulqi3"
6973   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6974                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6975                             (match_operand:QI 2 "register_operand" "")))
6976               (clobber (reg:CC FLAGS_REG))])]
6977   "TARGET_QIMODE_MATH"
6978   "")
6979
6980 (define_insn "*mulqi3_1"
6981   [(set (match_operand:QI 0 "register_operand" "=a")
6982         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6983                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6984    (clobber (reg:CC FLAGS_REG))]
6985   "TARGET_QIMODE_MATH
6986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6987   "mul{b}\t%2"
6988   [(set_attr "type" "imul")
6989    (set_attr "length_immediate" "0")
6990    (set (attr "athlon_decode")
6991      (if_then_else (eq_attr "cpu" "athlon")
6992         (const_string "vector")
6993         (const_string "direct")))
6994    (set_attr "mode" "QI")])
6995
6996 (define_expand "umulqihi3"
6997   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6998                    (mult:HI (zero_extend:HI
6999                               (match_operand:QI 1 "nonimmediate_operand" ""))
7000                             (zero_extend:HI
7001                               (match_operand:QI 2 "register_operand" ""))))
7002               (clobber (reg:CC FLAGS_REG))])]
7003   "TARGET_QIMODE_MATH"
7004   "")
7005
7006 (define_insn "*umulqihi3_1"
7007   [(set (match_operand:HI 0 "register_operand" "=a")
7008         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7009                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7010    (clobber (reg:CC FLAGS_REG))]
7011   "TARGET_QIMODE_MATH
7012    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7013   "mul{b}\t%2"
7014   [(set_attr "type" "imul")
7015    (set_attr "length_immediate" "0")
7016    (set (attr "athlon_decode")
7017      (if_then_else (eq_attr "cpu" "athlon")
7018         (const_string "vector")
7019         (const_string "direct")))
7020    (set_attr "mode" "QI")])
7021
7022 (define_expand "mulqihi3"
7023   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7024                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7025                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7026               (clobber (reg:CC FLAGS_REG))])]
7027   "TARGET_QIMODE_MATH"
7028   "")
7029
7030 (define_insn "*mulqihi3_insn"
7031   [(set (match_operand:HI 0 "register_operand" "=a")
7032         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7033                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_QIMODE_MATH
7036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7037   "imul{b}\t%2"
7038   [(set_attr "type" "imul")
7039    (set_attr "length_immediate" "0")
7040    (set (attr "athlon_decode")
7041      (if_then_else (eq_attr "cpu" "athlon")
7042         (const_string "vector")
7043         (const_string "direct")))
7044    (set_attr "mode" "QI")])
7045
7046 (define_expand "umulditi3"
7047   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7048                    (mult:TI (zero_extend:TI
7049                               (match_operand:DI 1 "nonimmediate_operand" ""))
7050                             (zero_extend:TI
7051                               (match_operand:DI 2 "register_operand" ""))))
7052               (clobber (reg:CC FLAGS_REG))])]
7053   "TARGET_64BIT"
7054   "")
7055
7056 (define_insn "*umulditi3_insn"
7057   [(set (match_operand:TI 0 "register_operand" "=A")
7058         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7059                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7060    (clobber (reg:CC FLAGS_REG))]
7061   "TARGET_64BIT
7062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7063   "mul{q}\t%2"
7064   [(set_attr "type" "imul")
7065    (set_attr "length_immediate" "0")
7066    (set (attr "athlon_decode")
7067      (if_then_else (eq_attr "cpu" "athlon")
7068         (const_string "vector")
7069         (const_string "double")))
7070    (set_attr "mode" "DI")])
7071
7072 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7073 (define_expand "umulsidi3"
7074   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7075                    (mult:DI (zero_extend:DI
7076                               (match_operand:SI 1 "nonimmediate_operand" ""))
7077                             (zero_extend:DI
7078                               (match_operand:SI 2 "register_operand" ""))))
7079               (clobber (reg:CC FLAGS_REG))])]
7080   "!TARGET_64BIT"
7081   "")
7082
7083 (define_insn "*umulsidi3_insn"
7084   [(set (match_operand:DI 0 "register_operand" "=A")
7085         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7086                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "!TARGET_64BIT
7089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090   "mul{l}\t%2"
7091   [(set_attr "type" "imul")
7092    (set_attr "length_immediate" "0")
7093    (set (attr "athlon_decode")
7094      (if_then_else (eq_attr "cpu" "athlon")
7095         (const_string "vector")
7096         (const_string "double")))
7097    (set_attr "mode" "SI")])
7098
7099 (define_expand "mulditi3"
7100   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7101                    (mult:TI (sign_extend:TI
7102                               (match_operand:DI 1 "nonimmediate_operand" ""))
7103                             (sign_extend:TI
7104                               (match_operand:DI 2 "register_operand" ""))))
7105               (clobber (reg:CC FLAGS_REG))])]
7106   "TARGET_64BIT"
7107   "")
7108
7109 (define_insn "*mulditi3_insn"
7110   [(set (match_operand:TI 0 "register_operand" "=A")
7111         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7112                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7113    (clobber (reg:CC FLAGS_REG))]
7114   "TARGET_64BIT
7115    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7116   "imul{q}\t%2"
7117   [(set_attr "type" "imul")
7118    (set_attr "length_immediate" "0")
7119    (set (attr "athlon_decode")
7120      (if_then_else (eq_attr "cpu" "athlon")
7121         (const_string "vector")
7122         (const_string "double")))
7123    (set_attr "mode" "DI")])
7124
7125 (define_expand "mulsidi3"
7126   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7127                    (mult:DI (sign_extend:DI
7128                               (match_operand:SI 1 "nonimmediate_operand" ""))
7129                             (sign_extend:DI
7130                               (match_operand:SI 2 "register_operand" ""))))
7131               (clobber (reg:CC FLAGS_REG))])]
7132   "!TARGET_64BIT"
7133   "")
7134
7135 (define_insn "*mulsidi3_insn"
7136   [(set (match_operand:DI 0 "register_operand" "=A")
7137         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7138                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7139    (clobber (reg:CC FLAGS_REG))]
7140   "!TARGET_64BIT
7141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142   "imul{l}\t%2"
7143   [(set_attr "type" "imul")
7144    (set_attr "length_immediate" "0")
7145    (set (attr "athlon_decode")
7146      (if_then_else (eq_attr "cpu" "athlon")
7147         (const_string "vector")
7148         (const_string "double")))
7149    (set_attr "mode" "SI")])
7150
7151 (define_expand "umuldi3_highpart"
7152   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7153                    (truncate:DI
7154                      (lshiftrt:TI
7155                        (mult:TI (zero_extend:TI
7156                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7157                                 (zero_extend:TI
7158                                   (match_operand:DI 2 "register_operand" "")))
7159                        (const_int 64))))
7160               (clobber (match_scratch:DI 3 ""))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*umuldi3_highpart_rex64"
7166   [(set (match_operand:DI 0 "register_operand" "=d")
7167         (truncate:DI
7168           (lshiftrt:TI
7169             (mult:TI (zero_extend:TI
7170                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7171                      (zero_extend:TI
7172                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7173             (const_int 64))))
7174    (clobber (match_scratch:DI 3 "=1"))
7175    (clobber (reg:CC FLAGS_REG))]
7176   "TARGET_64BIT
7177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7178   "mul{q}\t%2"
7179   [(set_attr "type" "imul")
7180    (set_attr "length_immediate" "0")
7181    (set (attr "athlon_decode")
7182      (if_then_else (eq_attr "cpu" "athlon")
7183         (const_string "vector")
7184         (const_string "double")))
7185    (set_attr "mode" "DI")])
7186
7187 (define_expand "umulsi3_highpart"
7188   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7189                    (truncate:SI
7190                      (lshiftrt:DI
7191                        (mult:DI (zero_extend:DI
7192                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7193                                 (zero_extend:DI
7194                                   (match_operand:SI 2 "register_operand" "")))
7195                        (const_int 32))))
7196               (clobber (match_scratch:SI 3 ""))
7197               (clobber (reg:CC FLAGS_REG))])]
7198   ""
7199   "")
7200
7201 (define_insn "*umulsi3_highpart_insn"
7202   [(set (match_operand:SI 0 "register_operand" "=d")
7203         (truncate:SI
7204           (lshiftrt:DI
7205             (mult:DI (zero_extend:DI
7206                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7207                      (zero_extend:DI
7208                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7209             (const_int 32))))
7210    (clobber (match_scratch:SI 3 "=1"))
7211    (clobber (reg:CC FLAGS_REG))]
7212   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7213   "mul{l}\t%2"
7214   [(set_attr "type" "imul")
7215    (set_attr "length_immediate" "0")
7216    (set (attr "athlon_decode")
7217      (if_then_else (eq_attr "cpu" "athlon")
7218         (const_string "vector")
7219         (const_string "double")))
7220    (set_attr "mode" "SI")])
7221
7222 (define_insn "*umulsi3_highpart_zext"
7223   [(set (match_operand:DI 0 "register_operand" "=d")
7224         (zero_extend:DI (truncate:SI
7225           (lshiftrt:DI
7226             (mult:DI (zero_extend:DI
7227                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7228                      (zero_extend:DI
7229                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7230             (const_int 32)))))
7231    (clobber (match_scratch:SI 3 "=1"))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_64BIT
7234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235   "mul{l}\t%2"
7236   [(set_attr "type" "imul")
7237    (set_attr "length_immediate" "0")
7238    (set (attr "athlon_decode")
7239      (if_then_else (eq_attr "cpu" "athlon")
7240         (const_string "vector")
7241         (const_string "double")))
7242    (set_attr "mode" "SI")])
7243
7244 (define_expand "smuldi3_highpart"
7245   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7246                    (truncate:DI
7247                      (lshiftrt:TI
7248                        (mult:TI (sign_extend:TI
7249                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7250                                 (sign_extend:TI
7251                                   (match_operand:DI 2 "register_operand" "")))
7252                        (const_int 64))))
7253               (clobber (match_scratch:DI 3 ""))
7254               (clobber (reg:CC FLAGS_REG))])]
7255   "TARGET_64BIT"
7256   "")
7257
7258 (define_insn "*smuldi3_highpart_rex64"
7259   [(set (match_operand:DI 0 "register_operand" "=d")
7260         (truncate:DI
7261           (lshiftrt:TI
7262             (mult:TI (sign_extend:TI
7263                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264                      (sign_extend:TI
7265                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266             (const_int 64))))
7267    (clobber (match_scratch:DI 3 "=1"))
7268    (clobber (reg:CC FLAGS_REG))]
7269   "TARGET_64BIT
7270    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271   "imul{q}\t%2"
7272   [(set_attr "type" "imul")
7273    (set (attr "athlon_decode")
7274      (if_then_else (eq_attr "cpu" "athlon")
7275         (const_string "vector")
7276         (const_string "double")))
7277    (set_attr "mode" "DI")])
7278
7279 (define_expand "smulsi3_highpart"
7280   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7281                    (truncate:SI
7282                      (lshiftrt:DI
7283                        (mult:DI (sign_extend:DI
7284                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7285                                 (sign_extend:DI
7286                                   (match_operand:SI 2 "register_operand" "")))
7287                        (const_int 32))))
7288               (clobber (match_scratch:SI 3 ""))
7289               (clobber (reg:CC FLAGS_REG))])]
7290   ""
7291   "")
7292
7293 (define_insn "*smulsi3_highpart_insn"
7294   [(set (match_operand:SI 0 "register_operand" "=d")
7295         (truncate:SI
7296           (lshiftrt:DI
7297             (mult:DI (sign_extend:DI
7298                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7299                      (sign_extend:DI
7300                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7301             (const_int 32))))
7302    (clobber (match_scratch:SI 3 "=1"))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7305   "imul{l}\t%2"
7306   [(set_attr "type" "imul")
7307    (set (attr "athlon_decode")
7308      (if_then_else (eq_attr "cpu" "athlon")
7309         (const_string "vector")
7310         (const_string "double")))
7311    (set_attr "mode" "SI")])
7312
7313 (define_insn "*smulsi3_highpart_zext"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (zero_extend:DI (truncate:SI
7316           (lshiftrt:DI
7317             (mult:DI (sign_extend:DI
7318                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319                      (sign_extend:DI
7320                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321             (const_int 32)))))
7322    (clobber (match_scratch:SI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "imul{l}\t%2"
7327   [(set_attr "type" "imul")
7328    (set (attr "athlon_decode")
7329      (if_then_else (eq_attr "cpu" "athlon")
7330         (const_string "vector")
7331         (const_string "double")))
7332    (set_attr "mode" "SI")])
7333
7334 ;; The patterns that match these are at the end of this file.
7335
7336 (define_expand "mulxf3"
7337   [(set (match_operand:XF 0 "register_operand" "")
7338         (mult:XF (match_operand:XF 1 "register_operand" "")
7339                  (match_operand:XF 2 "register_operand" "")))]
7340   "TARGET_80387"
7341   "")
7342
7343 (define_expand "muldf3"
7344   [(set (match_operand:DF 0 "register_operand" "")
7345         (mult:DF (match_operand:DF 1 "register_operand" "")
7346                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7347   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7348   "")
7349
7350 (define_expand "mulsf3"
7351   [(set (match_operand:SF 0 "register_operand" "")
7352         (mult:SF (match_operand:SF 1 "register_operand" "")
7353                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7354   "TARGET_80387 || TARGET_SSE_MATH"
7355   "")
7356 \f
7357 ;; Divide instructions
7358
7359 (define_insn "divqi3"
7360   [(set (match_operand:QI 0 "register_operand" "=a")
7361         (div:QI (match_operand:HI 1 "register_operand" "0")
7362                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_QIMODE_MATH"
7365   "idiv{b}\t%2"
7366   [(set_attr "type" "idiv")
7367    (set_attr "mode" "QI")])
7368
7369 (define_insn "udivqi3"
7370   [(set (match_operand:QI 0 "register_operand" "=a")
7371         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7372                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7373    (clobber (reg:CC FLAGS_REG))]
7374   "TARGET_QIMODE_MATH"
7375   "div{b}\t%2"
7376   [(set_attr "type" "idiv")
7377    (set_attr "mode" "QI")])
7378
7379 ;; The patterns that match these are at the end of this file.
7380
7381 (define_expand "divxf3"
7382   [(set (match_operand:XF 0 "register_operand" "")
7383         (div:XF (match_operand:XF 1 "register_operand" "")
7384                 (match_operand:XF 2 "register_operand" "")))]
7385   "TARGET_80387"
7386   "")
7387
7388 (define_expand "divdf3"
7389   [(set (match_operand:DF 0 "register_operand" "")
7390         (div:DF (match_operand:DF 1 "register_operand" "")
7391                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7392    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7393    "")
7394  
7395 (define_expand "divsf3"
7396   [(set (match_operand:SF 0 "register_operand" "")
7397         (div:SF (match_operand:SF 1 "register_operand" "")
7398                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7399   "TARGET_80387 || TARGET_SSE_MATH"
7400   "")
7401 \f
7402 ;; Remainder instructions.
7403
7404 (define_expand "divmoddi4"
7405   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7406                    (div:DI (match_operand:DI 1 "register_operand" "")
7407                            (match_operand:DI 2 "nonimmediate_operand" "")))
7408               (set (match_operand:DI 3 "register_operand" "")
7409                    (mod:DI (match_dup 1) (match_dup 2)))
7410               (clobber (reg:CC FLAGS_REG))])]
7411   "TARGET_64BIT"
7412   "")
7413
7414 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7415 ;; Penalize eax case slightly because it results in worse scheduling
7416 ;; of code.
7417 (define_insn "*divmoddi4_nocltd_rex64"
7418   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7419         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7420                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7421    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7422         (mod:DI (match_dup 2) (match_dup 3)))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7425   "#"
7426   [(set_attr "type" "multi")])
7427
7428 (define_insn "*divmoddi4_cltd_rex64"
7429   [(set (match_operand:DI 0 "register_operand" "=a")
7430         (div:DI (match_operand:DI 2 "register_operand" "a")
7431                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7432    (set (match_operand:DI 1 "register_operand" "=&d")
7433         (mod:DI (match_dup 2) (match_dup 3)))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7436   "#"
7437   [(set_attr "type" "multi")])
7438
7439 (define_insn "*divmoddi_noext_rex64"
7440   [(set (match_operand:DI 0 "register_operand" "=a")
7441         (div:DI (match_operand:DI 1 "register_operand" "0")
7442                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7443    (set (match_operand:DI 3 "register_operand" "=d")
7444         (mod:DI (match_dup 1) (match_dup 2)))
7445    (use (match_operand:DI 4 "register_operand" "3"))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_64BIT"
7448   "idiv{q}\t%2"
7449   [(set_attr "type" "idiv")
7450    (set_attr "mode" "DI")])
7451
7452 (define_split
7453   [(set (match_operand:DI 0 "register_operand" "")
7454         (div:DI (match_operand:DI 1 "register_operand" "")
7455                 (match_operand:DI 2 "nonimmediate_operand" "")))
7456    (set (match_operand:DI 3 "register_operand" "")
7457         (mod:DI (match_dup 1) (match_dup 2)))
7458    (clobber (reg:CC FLAGS_REG))]
7459   "TARGET_64BIT && reload_completed"
7460   [(parallel [(set (match_dup 3)
7461                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7462               (clobber (reg:CC FLAGS_REG))])
7463    (parallel [(set (match_dup 0)
7464                    (div:DI (reg:DI 0) (match_dup 2)))
7465               (set (match_dup 3)
7466                    (mod:DI (reg:DI 0) (match_dup 2)))
7467               (use (match_dup 3))
7468               (clobber (reg:CC FLAGS_REG))])]
7469 {
7470   /* Avoid use of cltd in favor of a mov+shift.  */
7471   if (!TARGET_USE_CLTD && !optimize_size)
7472     {
7473       if (true_regnum (operands[1]))
7474         emit_move_insn (operands[0], operands[1]);
7475       else
7476         emit_move_insn (operands[3], operands[1]);
7477       operands[4] = operands[3];
7478     }
7479   else
7480     {
7481       gcc_assert (!true_regnum (operands[1]));
7482       operands[4] = operands[1];
7483     }
7484 })
7485
7486
7487 (define_expand "divmodsi4"
7488   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7489                    (div:SI (match_operand:SI 1 "register_operand" "")
7490                            (match_operand:SI 2 "nonimmediate_operand" "")))
7491               (set (match_operand:SI 3 "register_operand" "")
7492                    (mod:SI (match_dup 1) (match_dup 2)))
7493               (clobber (reg:CC FLAGS_REG))])]
7494   ""
7495   "")
7496
7497 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7498 ;; Penalize eax case slightly because it results in worse scheduling
7499 ;; of code.
7500 (define_insn "*divmodsi4_nocltd"
7501   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7502         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7503                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7504    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7505         (mod:SI (match_dup 2) (match_dup 3)))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "!optimize_size && !TARGET_USE_CLTD"
7508   "#"
7509   [(set_attr "type" "multi")])
7510
7511 (define_insn "*divmodsi4_cltd"
7512   [(set (match_operand:SI 0 "register_operand" "=a")
7513         (div:SI (match_operand:SI 2 "register_operand" "a")
7514                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7515    (set (match_operand:SI 1 "register_operand" "=&d")
7516         (mod:SI (match_dup 2) (match_dup 3)))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "optimize_size || TARGET_USE_CLTD"
7519   "#"
7520   [(set_attr "type" "multi")])
7521
7522 (define_insn "*divmodsi_noext"
7523   [(set (match_operand:SI 0 "register_operand" "=a")
7524         (div:SI (match_operand:SI 1 "register_operand" "0")
7525                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7526    (set (match_operand:SI 3 "register_operand" "=d")
7527         (mod:SI (match_dup 1) (match_dup 2)))
7528    (use (match_operand:SI 4 "register_operand" "3"))
7529    (clobber (reg:CC FLAGS_REG))]
7530   ""
7531   "idiv{l}\t%2"
7532   [(set_attr "type" "idiv")
7533    (set_attr "mode" "SI")])
7534
7535 (define_split
7536   [(set (match_operand:SI 0 "register_operand" "")
7537         (div:SI (match_operand:SI 1 "register_operand" "")
7538                 (match_operand:SI 2 "nonimmediate_operand" "")))
7539    (set (match_operand:SI 3 "register_operand" "")
7540         (mod:SI (match_dup 1) (match_dup 2)))
7541    (clobber (reg:CC FLAGS_REG))]
7542   "reload_completed"
7543   [(parallel [(set (match_dup 3)
7544                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7545               (clobber (reg:CC FLAGS_REG))])
7546    (parallel [(set (match_dup 0)
7547                    (div:SI (reg:SI 0) (match_dup 2)))
7548               (set (match_dup 3)
7549                    (mod:SI (reg:SI 0) (match_dup 2)))
7550               (use (match_dup 3))
7551               (clobber (reg:CC FLAGS_REG))])]
7552 {
7553   /* Avoid use of cltd in favor of a mov+shift.  */
7554   if (!TARGET_USE_CLTD && !optimize_size)
7555     {
7556       if (true_regnum (operands[1]))
7557         emit_move_insn (operands[0], operands[1]);
7558       else
7559         emit_move_insn (operands[3], operands[1]);
7560       operands[4] = operands[3];
7561     }
7562   else
7563     {
7564       gcc_assert (!true_regnum (operands[1]));
7565       operands[4] = operands[1];
7566     }
7567 })
7568 ;; %%% Split me.
7569 (define_insn "divmodhi4"
7570   [(set (match_operand:HI 0 "register_operand" "=a")
7571         (div:HI (match_operand:HI 1 "register_operand" "0")
7572                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7573    (set (match_operand:HI 3 "register_operand" "=&d")
7574         (mod:HI (match_dup 1) (match_dup 2)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "TARGET_HIMODE_MATH"
7577   "cwtd\;idiv{w}\t%2"
7578   [(set_attr "type" "multi")
7579    (set_attr "length_immediate" "0")
7580    (set_attr "mode" "SI")])
7581
7582 (define_insn "udivmoddi4"
7583   [(set (match_operand:DI 0 "register_operand" "=a")
7584         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7585                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7586    (set (match_operand:DI 3 "register_operand" "=&d")
7587         (umod:DI (match_dup 1) (match_dup 2)))
7588    (clobber (reg:CC FLAGS_REG))]
7589   "TARGET_64BIT"
7590   "xor{q}\t%3, %3\;div{q}\t%2"
7591   [(set_attr "type" "multi")
7592    (set_attr "length_immediate" "0")
7593    (set_attr "mode" "DI")])
7594
7595 (define_insn "*udivmoddi4_noext"
7596   [(set (match_operand:DI 0 "register_operand" "=a")
7597         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7598                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7599    (set (match_operand:DI 3 "register_operand" "=d")
7600         (umod:DI (match_dup 1) (match_dup 2)))
7601    (use (match_dup 3))
7602    (clobber (reg:CC FLAGS_REG))]
7603   "TARGET_64BIT"
7604   "div{q}\t%2"
7605   [(set_attr "type" "idiv")
7606    (set_attr "mode" "DI")])
7607
7608 (define_split
7609   [(set (match_operand:DI 0 "register_operand" "")
7610         (udiv:DI (match_operand:DI 1 "register_operand" "")
7611                  (match_operand:DI 2 "nonimmediate_operand" "")))
7612    (set (match_operand:DI 3 "register_operand" "")
7613         (umod:DI (match_dup 1) (match_dup 2)))
7614    (clobber (reg:CC FLAGS_REG))]
7615   "TARGET_64BIT && reload_completed"
7616   [(set (match_dup 3) (const_int 0))
7617    (parallel [(set (match_dup 0)
7618                    (udiv:DI (match_dup 1) (match_dup 2)))
7619               (set (match_dup 3)
7620                    (umod:DI (match_dup 1) (match_dup 2)))
7621               (use (match_dup 3))
7622               (clobber (reg:CC FLAGS_REG))])]
7623   "")
7624
7625 (define_insn "udivmodsi4"
7626   [(set (match_operand:SI 0 "register_operand" "=a")
7627         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7628                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7629    (set (match_operand:SI 3 "register_operand" "=&d")
7630         (umod:SI (match_dup 1) (match_dup 2)))
7631    (clobber (reg:CC FLAGS_REG))]
7632   ""
7633   "xor{l}\t%3, %3\;div{l}\t%2"
7634   [(set_attr "type" "multi")
7635    (set_attr "length_immediate" "0")
7636    (set_attr "mode" "SI")])
7637
7638 (define_insn "*udivmodsi4_noext"
7639   [(set (match_operand:SI 0 "register_operand" "=a")
7640         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7641                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7642    (set (match_operand:SI 3 "register_operand" "=d")
7643         (umod:SI (match_dup 1) (match_dup 2)))
7644    (use (match_dup 3))
7645    (clobber (reg:CC FLAGS_REG))]
7646   ""
7647   "div{l}\t%2"
7648   [(set_attr "type" "idiv")
7649    (set_attr "mode" "SI")])
7650
7651 (define_split
7652   [(set (match_operand:SI 0 "register_operand" "")
7653         (udiv:SI (match_operand:SI 1 "register_operand" "")
7654                  (match_operand:SI 2 "nonimmediate_operand" "")))
7655    (set (match_operand:SI 3 "register_operand" "")
7656         (umod:SI (match_dup 1) (match_dup 2)))
7657    (clobber (reg:CC FLAGS_REG))]
7658   "reload_completed"
7659   [(set (match_dup 3) (const_int 0))
7660    (parallel [(set (match_dup 0)
7661                    (udiv:SI (match_dup 1) (match_dup 2)))
7662               (set (match_dup 3)
7663                    (umod:SI (match_dup 1) (match_dup 2)))
7664               (use (match_dup 3))
7665               (clobber (reg:CC FLAGS_REG))])]
7666   "")
7667
7668 (define_expand "udivmodhi4"
7669   [(set (match_dup 4) (const_int 0))
7670    (parallel [(set (match_operand:HI 0 "register_operand" "")
7671                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7672                             (match_operand:HI 2 "nonimmediate_operand" "")))
7673               (set (match_operand:HI 3 "register_operand" "")
7674                    (umod:HI (match_dup 1) (match_dup 2)))
7675               (use (match_dup 4))
7676               (clobber (reg:CC FLAGS_REG))])]
7677   "TARGET_HIMODE_MATH"
7678   "operands[4] = gen_reg_rtx (HImode);")
7679
7680 (define_insn "*udivmodhi_noext"
7681   [(set (match_operand:HI 0 "register_operand" "=a")
7682         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7683                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7684    (set (match_operand:HI 3 "register_operand" "=d")
7685         (umod:HI (match_dup 1) (match_dup 2)))
7686    (use (match_operand:HI 4 "register_operand" "3"))
7687    (clobber (reg:CC FLAGS_REG))]
7688   ""
7689   "div{w}\t%2"
7690   [(set_attr "type" "idiv")
7691    (set_attr "mode" "HI")])
7692
7693 ;; We cannot use div/idiv for double division, because it causes
7694 ;; "division by zero" on the overflow and that's not what we expect
7695 ;; from truncate.  Because true (non truncating) double division is
7696 ;; never generated, we can't create this insn anyway.
7697 ;
7698 ;(define_insn ""
7699 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7700 ;       (truncate:SI
7701 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7702 ;                  (zero_extend:DI
7703 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7704 ;   (set (match_operand:SI 3 "register_operand" "=d")
7705 ;       (truncate:SI
7706 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7707 ;   (clobber (reg:CC FLAGS_REG))]
7708 ;  ""
7709 ;  "div{l}\t{%2, %0|%0, %2}"
7710 ;  [(set_attr "type" "idiv")])
7711 \f
7712 ;;- Logical AND instructions
7713
7714 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7715 ;; Note that this excludes ah.
7716
7717 (define_insn "*testdi_1_rex64"
7718   [(set (reg FLAGS_REG)
7719         (compare
7720           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7721                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7722           (const_int 0)))]
7723   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7724    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7725   "@
7726    test{l}\t{%k1, %k0|%k0, %k1}
7727    test{l}\t{%k1, %k0|%k0, %k1}
7728    test{q}\t{%1, %0|%0, %1}
7729    test{q}\t{%1, %0|%0, %1}
7730    test{q}\t{%1, %0|%0, %1}"
7731   [(set_attr "type" "test")
7732    (set_attr "modrm" "0,1,0,1,1")
7733    (set_attr "mode" "SI,SI,DI,DI,DI")
7734    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7735
7736 (define_insn "testsi_1"
7737   [(set (reg FLAGS_REG)
7738         (compare
7739           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7740                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7741           (const_int 0)))]
7742   "ix86_match_ccmode (insn, CCNOmode)
7743    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7744   "test{l}\t{%1, %0|%0, %1}"
7745   [(set_attr "type" "test")
7746    (set_attr "modrm" "0,1,1")
7747    (set_attr "mode" "SI")
7748    (set_attr "pent_pair" "uv,np,uv")])
7749
7750 (define_expand "testsi_ccno_1"
7751   [(set (reg:CCNO FLAGS_REG)
7752         (compare:CCNO
7753           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7754                   (match_operand:SI 1 "nonmemory_operand" ""))
7755           (const_int 0)))]
7756   ""
7757   "")
7758
7759 (define_insn "*testhi_1"
7760   [(set (reg FLAGS_REG)
7761         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7762                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7763                  (const_int 0)))]
7764   "ix86_match_ccmode (insn, CCNOmode)
7765    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7766   "test{w}\t{%1, %0|%0, %1}"
7767   [(set_attr "type" "test")
7768    (set_attr "modrm" "0,1,1")
7769    (set_attr "mode" "HI")
7770    (set_attr "pent_pair" "uv,np,uv")])
7771
7772 (define_expand "testqi_ccz_1"
7773   [(set (reg:CCZ FLAGS_REG)
7774         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7775                              (match_operand:QI 1 "nonmemory_operand" ""))
7776                  (const_int 0)))]
7777   ""
7778   "")
7779
7780 (define_insn "*testqi_1_maybe_si"
7781   [(set (reg FLAGS_REG)
7782         (compare
7783           (and:QI
7784             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7785             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7786           (const_int 0)))]
7787    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7788     && ix86_match_ccmode (insn,
7789                          GET_CODE (operands[1]) == CONST_INT
7790                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7791 {
7792   if (which_alternative == 3)
7793     {
7794       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7795         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7796       return "test{l}\t{%1, %k0|%k0, %1}";
7797     }
7798   return "test{b}\t{%1, %0|%0, %1}";
7799 }
7800   [(set_attr "type" "test")
7801    (set_attr "modrm" "0,1,1,1")
7802    (set_attr "mode" "QI,QI,QI,SI")
7803    (set_attr "pent_pair" "uv,np,uv,np")])
7804
7805 (define_insn "*testqi_1"
7806   [(set (reg FLAGS_REG)
7807         (compare
7808           (and:QI
7809             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7810             (match_operand:QI 1 "general_operand" "n,n,qn"))
7811           (const_int 0)))]
7812   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7813    && ix86_match_ccmode (insn, CCNOmode)"
7814   "test{b}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "QI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7819
7820 (define_expand "testqi_ext_ccno_0"
7821   [(set (reg:CCNO FLAGS_REG)
7822         (compare:CCNO
7823           (and:SI
7824             (zero_extract:SI
7825               (match_operand 0 "ext_register_operand" "")
7826               (const_int 8)
7827               (const_int 8))
7828             (match_operand 1 "const_int_operand" ""))
7829           (const_int 0)))]
7830   ""
7831   "")
7832
7833 (define_insn "*testqi_ext_0"
7834   [(set (reg FLAGS_REG)
7835         (compare
7836           (and:SI
7837             (zero_extract:SI
7838               (match_operand 0 "ext_register_operand" "Q")
7839               (const_int 8)
7840               (const_int 8))
7841             (match_operand 1 "const_int_operand" "n"))
7842           (const_int 0)))]
7843   "ix86_match_ccmode (insn, CCNOmode)"
7844   "test{b}\t{%1, %h0|%h0, %1}"
7845   [(set_attr "type" "test")
7846    (set_attr "mode" "QI")
7847    (set_attr "length_immediate" "1")
7848    (set_attr "pent_pair" "np")])
7849
7850 (define_insn "*testqi_ext_1"
7851   [(set (reg FLAGS_REG)
7852         (compare
7853           (and:SI
7854             (zero_extract:SI
7855               (match_operand 0 "ext_register_operand" "Q")
7856               (const_int 8)
7857               (const_int 8))
7858             (zero_extend:SI
7859               (match_operand:QI 1 "general_operand" "Qm")))
7860           (const_int 0)))]
7861   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7862    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7863   "test{b}\t{%1, %h0|%h0, %1}"
7864   [(set_attr "type" "test")
7865    (set_attr "mode" "QI")])
7866
7867 (define_insn "*testqi_ext_1_rex64"
7868   [(set (reg FLAGS_REG)
7869         (compare
7870           (and:SI
7871             (zero_extract:SI
7872               (match_operand 0 "ext_register_operand" "Q")
7873               (const_int 8)
7874               (const_int 8))
7875             (zero_extend:SI
7876               (match_operand:QI 1 "register_operand" "Q")))
7877           (const_int 0)))]
7878   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7879   "test{b}\t{%1, %h0|%h0, %1}"
7880   [(set_attr "type" "test")
7881    (set_attr "mode" "QI")])
7882
7883 (define_insn "*testqi_ext_2"
7884   [(set (reg FLAGS_REG)
7885         (compare
7886           (and:SI
7887             (zero_extract:SI
7888               (match_operand 0 "ext_register_operand" "Q")
7889               (const_int 8)
7890               (const_int 8))
7891             (zero_extract:SI
7892               (match_operand 1 "ext_register_operand" "Q")
7893               (const_int 8)
7894               (const_int 8)))
7895           (const_int 0)))]
7896   "ix86_match_ccmode (insn, CCNOmode)"
7897   "test{b}\t{%h1, %h0|%h0, %h1}"
7898   [(set_attr "type" "test")
7899    (set_attr "mode" "QI")])
7900
7901 ;; Combine likes to form bit extractions for some tests.  Humor it.
7902 (define_insn "*testqi_ext_3"
7903   [(set (reg FLAGS_REG)
7904         (compare (zero_extract:SI
7905                    (match_operand 0 "nonimmediate_operand" "rm")
7906                    (match_operand:SI 1 "const_int_operand" "")
7907                    (match_operand:SI 2 "const_int_operand" ""))
7908                  (const_int 0)))]
7909   "ix86_match_ccmode (insn, CCNOmode)
7910    && INTVAL (operands[1]) > 0
7911    && INTVAL (operands[2]) >= 0
7912    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7913    && (GET_MODE (operands[0]) == SImode
7914        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7915        || GET_MODE (operands[0]) == HImode
7916        || GET_MODE (operands[0]) == QImode)"
7917   "#")
7918
7919 (define_insn "*testqi_ext_3_rex64"
7920   [(set (reg FLAGS_REG)
7921         (compare (zero_extract:DI
7922                    (match_operand 0 "nonimmediate_operand" "rm")
7923                    (match_operand:DI 1 "const_int_operand" "")
7924                    (match_operand:DI 2 "const_int_operand" ""))
7925                  (const_int 0)))]
7926   "TARGET_64BIT
7927    && ix86_match_ccmode (insn, CCNOmode)
7928    && INTVAL (operands[1]) > 0
7929    && INTVAL (operands[2]) >= 0
7930    /* Ensure that resulting mask is zero or sign extended operand.  */
7931    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7932        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7933            && INTVAL (operands[1]) > 32))
7934    && (GET_MODE (operands[0]) == SImode
7935        || GET_MODE (operands[0]) == DImode
7936        || GET_MODE (operands[0]) == HImode
7937        || GET_MODE (operands[0]) == QImode)"
7938   "#")
7939
7940 (define_split
7941   [(set (match_operand 0 "flags_reg_operand" "")
7942         (match_operator 1 "compare_operator"
7943           [(zero_extract
7944              (match_operand 2 "nonimmediate_operand" "")
7945              (match_operand 3 "const_int_operand" "")
7946              (match_operand 4 "const_int_operand" ""))
7947            (const_int 0)]))]
7948   "ix86_match_ccmode (insn, CCNOmode)"
7949   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7950 {
7951   rtx val = operands[2];
7952   HOST_WIDE_INT len = INTVAL (operands[3]);
7953   HOST_WIDE_INT pos = INTVAL (operands[4]);
7954   HOST_WIDE_INT mask;
7955   enum machine_mode mode, submode;
7956
7957   mode = GET_MODE (val);
7958   if (GET_CODE (val) == MEM)
7959     {
7960       /* ??? Combine likes to put non-volatile mem extractions in QImode
7961          no matter the size of the test.  So find a mode that works.  */
7962       if (! MEM_VOLATILE_P (val))
7963         {
7964           mode = smallest_mode_for_size (pos + len, MODE_INT);
7965           val = adjust_address (val, mode, 0);
7966         }
7967     }
7968   else if (GET_CODE (val) == SUBREG
7969            && (submode = GET_MODE (SUBREG_REG (val)),
7970                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7971            && pos + len <= GET_MODE_BITSIZE (submode))
7972     {
7973       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7974       mode = submode;
7975       val = SUBREG_REG (val);
7976     }
7977   else if (mode == HImode && pos + len <= 8)
7978     {
7979       /* Small HImode tests can be converted to QImode.  */
7980       mode = QImode;
7981       val = gen_lowpart (QImode, val);
7982     }
7983
7984   if (len == HOST_BITS_PER_WIDE_INT)
7985     mask = -1;
7986   else
7987     mask = ((HOST_WIDE_INT)1 << len) - 1;
7988   mask <<= pos;
7989
7990   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7991 })
7992
7993 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7994 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7995 ;; this is relatively important trick.
7996 ;; Do the conversion only post-reload to avoid limiting of the register class
7997 ;; to QI regs.
7998 (define_split
7999   [(set (match_operand 0 "flags_reg_operand" "")
8000         (match_operator 1 "compare_operator"
8001           [(and (match_operand 2 "register_operand" "")
8002                 (match_operand 3 "const_int_operand" ""))
8003            (const_int 0)]))]
8004    "reload_completed
8005     && QI_REG_P (operands[2])
8006     && GET_MODE (operands[2]) != QImode
8007     && ((ix86_match_ccmode (insn, CCZmode)
8008          && !(INTVAL (operands[3]) & ~(255 << 8)))
8009         || (ix86_match_ccmode (insn, CCNOmode)
8010             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8011   [(set (match_dup 0)
8012         (match_op_dup 1
8013           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8014                    (match_dup 3))
8015            (const_int 0)]))]
8016   "operands[2] = gen_lowpart (SImode, operands[2]);
8017    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8018
8019 (define_split
8020   [(set (match_operand 0 "flags_reg_operand" "")
8021         (match_operator 1 "compare_operator"
8022           [(and (match_operand 2 "nonimmediate_operand" "")
8023                 (match_operand 3 "const_int_operand" ""))
8024            (const_int 0)]))]
8025    "reload_completed
8026     && GET_MODE (operands[2]) != QImode
8027     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8028     && ((ix86_match_ccmode (insn, CCZmode)
8029          && !(INTVAL (operands[3]) & ~255))
8030         || (ix86_match_ccmode (insn, CCNOmode)
8031             && !(INTVAL (operands[3]) & ~127)))"
8032   [(set (match_dup 0)
8033         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8034                          (const_int 0)]))]
8035   "operands[2] = gen_lowpart (QImode, operands[2]);
8036    operands[3] = gen_lowpart (QImode, operands[3]);")
8037
8038
8039 ;; %%% This used to optimize known byte-wide and operations to memory,
8040 ;; and sometimes to QImode registers.  If this is considered useful,
8041 ;; it should be done with splitters.
8042
8043 (define_expand "anddi3"
8044   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8045         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8046                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT"
8049   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8050
8051 (define_insn "*anddi_1_rex64"
8052   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8053         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8054                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8057 {
8058   switch (get_attr_type (insn))
8059     {
8060     case TYPE_IMOVX:
8061       {
8062         enum machine_mode mode;
8063
8064         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8065         if (INTVAL (operands[2]) == 0xff)
8066           mode = QImode;
8067         else
8068           {
8069             gcc_assert (INTVAL (operands[2]) == 0xffff);
8070             mode = HImode;
8071           }
8072         
8073         operands[1] = gen_lowpart (mode, operands[1]);
8074         if (mode == QImode)
8075           return "movz{bq|x}\t{%1,%0|%0, %1}";
8076         else
8077           return "movz{wq|x}\t{%1,%0|%0, %1}";
8078       }
8079
8080     default:
8081       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8082       if (get_attr_mode (insn) == MODE_SI)
8083         return "and{l}\t{%k2, %k0|%k0, %k2}";
8084       else
8085         return "and{q}\t{%2, %0|%0, %2}";
8086     }
8087 }
8088   [(set_attr "type" "alu,alu,alu,imovx")
8089    (set_attr "length_immediate" "*,*,*,0")
8090    (set_attr "mode" "SI,DI,DI,DI")])
8091
8092 (define_insn "*anddi_2"
8093   [(set (reg FLAGS_REG)
8094         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8095                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8096                  (const_int 0)))
8097    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8098         (and:DI (match_dup 1) (match_dup 2)))]
8099   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8100    && ix86_binary_operator_ok (AND, DImode, operands)"
8101   "@
8102    and{l}\t{%k2, %k0|%k0, %k2}
8103    and{q}\t{%2, %0|%0, %2}
8104    and{q}\t{%2, %0|%0, %2}"
8105   [(set_attr "type" "alu")
8106    (set_attr "mode" "SI,DI,DI")])
8107
8108 (define_expand "andsi3"
8109   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8110         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8111                 (match_operand:SI 2 "general_operand" "")))
8112    (clobber (reg:CC FLAGS_REG))]
8113   ""
8114   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8115
8116 (define_insn "*andsi_1"
8117   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8118         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8119                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8120    (clobber (reg:CC FLAGS_REG))]
8121   "ix86_binary_operator_ok (AND, SImode, operands)"
8122 {
8123   switch (get_attr_type (insn))
8124     {
8125     case TYPE_IMOVX:
8126       {
8127         enum machine_mode mode;
8128
8129         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8130         if (INTVAL (operands[2]) == 0xff)
8131           mode = QImode;
8132         else
8133           {
8134             gcc_assert (INTVAL (operands[2]) == 0xffff);
8135             mode = HImode;
8136           }
8137         
8138         operands[1] = gen_lowpart (mode, operands[1]);
8139         if (mode == QImode)
8140           return "movz{bl|x}\t{%1,%0|%0, %1}";
8141         else
8142           return "movz{wl|x}\t{%1,%0|%0, %1}";
8143       }
8144
8145     default:
8146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8147       return "and{l}\t{%2, %0|%0, %2}";
8148     }
8149 }
8150   [(set_attr "type" "alu,alu,imovx")
8151    (set_attr "length_immediate" "*,*,0")
8152    (set_attr "mode" "SI")])
8153
8154 (define_split
8155   [(set (match_operand 0 "register_operand" "")
8156         (and (match_dup 0)
8157              (const_int -65536)))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8160   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8161   "operands[1] = gen_lowpart (HImode, operands[0]);")
8162
8163 (define_split
8164   [(set (match_operand 0 "ext_register_operand" "")
8165         (and (match_dup 0)
8166              (const_int -256)))
8167    (clobber (reg:CC FLAGS_REG))]
8168   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8169   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8170   "operands[1] = gen_lowpart (QImode, operands[0]);")
8171
8172 (define_split
8173   [(set (match_operand 0 "ext_register_operand" "")
8174         (and (match_dup 0)
8175              (const_int -65281)))
8176    (clobber (reg:CC FLAGS_REG))]
8177   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8178   [(parallel [(set (zero_extract:SI (match_dup 0)
8179                                     (const_int 8)
8180                                     (const_int 8))
8181                    (xor:SI 
8182                      (zero_extract:SI (match_dup 0)
8183                                       (const_int 8)
8184                                       (const_int 8))
8185                      (zero_extract:SI (match_dup 0)
8186                                       (const_int 8)
8187                                       (const_int 8))))
8188               (clobber (reg:CC FLAGS_REG))])]
8189   "operands[0] = gen_lowpart (SImode, operands[0]);")
8190
8191 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8192 (define_insn "*andsi_1_zext"
8193   [(set (match_operand:DI 0 "register_operand" "=r")
8194         (zero_extend:DI
8195           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8196                   (match_operand:SI 2 "general_operand" "rim"))))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8199   "and{l}\t{%2, %k0|%k0, %2}"
8200   [(set_attr "type" "alu")
8201    (set_attr "mode" "SI")])
8202
8203 (define_insn "*andsi_2"
8204   [(set (reg FLAGS_REG)
8205         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8206                          (match_operand:SI 2 "general_operand" "rim,ri"))
8207                  (const_int 0)))
8208    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8209         (and:SI (match_dup 1) (match_dup 2)))]
8210   "ix86_match_ccmode (insn, CCNOmode)
8211    && ix86_binary_operator_ok (AND, SImode, operands)"
8212   "and{l}\t{%2, %0|%0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "mode" "SI")])
8215
8216 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8217 (define_insn "*andsi_2_zext"
8218   [(set (reg FLAGS_REG)
8219         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8220                          (match_operand:SI 2 "general_operand" "rim"))
8221                  (const_int 0)))
8222    (set (match_operand:DI 0 "register_operand" "=r")
8223         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8224   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8225    && ix86_binary_operator_ok (AND, SImode, operands)"
8226   "and{l}\t{%2, %k0|%k0, %2}"
8227   [(set_attr "type" "alu")
8228    (set_attr "mode" "SI")])
8229
8230 (define_expand "andhi3"
8231   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8232         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8233                 (match_operand:HI 2 "general_operand" "")))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "TARGET_HIMODE_MATH"
8236   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8237
8238 (define_insn "*andhi_1"
8239   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8240         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8241                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "ix86_binary_operator_ok (AND, HImode, operands)"
8244 {
8245   switch (get_attr_type (insn))
8246     {
8247     case TYPE_IMOVX:
8248       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8249       gcc_assert (INTVAL (operands[2]) == 0xff);
8250       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8251
8252     default:
8253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8254
8255       return "and{w}\t{%2, %0|%0, %2}";
8256     }
8257 }
8258   [(set_attr "type" "alu,alu,imovx")
8259    (set_attr "length_immediate" "*,*,0")
8260    (set_attr "mode" "HI,HI,SI")])
8261
8262 (define_insn "*andhi_2"
8263   [(set (reg FLAGS_REG)
8264         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8265                          (match_operand:HI 2 "general_operand" "rim,ri"))
8266                  (const_int 0)))
8267    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8268         (and:HI (match_dup 1) (match_dup 2)))]
8269   "ix86_match_ccmode (insn, CCNOmode)
8270    && ix86_binary_operator_ok (AND, HImode, operands)"
8271   "and{w}\t{%2, %0|%0, %2}"
8272   [(set_attr "type" "alu")
8273    (set_attr "mode" "HI")])
8274
8275 (define_expand "andqi3"
8276   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8277         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8278                 (match_operand:QI 2 "general_operand" "")))
8279    (clobber (reg:CC FLAGS_REG))]
8280   "TARGET_QIMODE_MATH"
8281   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8282
8283 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8284 (define_insn "*andqi_1"
8285   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8286         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8287                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "ix86_binary_operator_ok (AND, QImode, operands)"
8290   "@
8291    and{b}\t{%2, %0|%0, %2}
8292    and{b}\t{%2, %0|%0, %2}
8293    and{l}\t{%k2, %k0|%k0, %k2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "QI,QI,SI")])
8296
8297 (define_insn "*andqi_1_slp"
8298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8299         (and:QI (match_dup 0)
8300                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8303    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8304   "and{b}\t{%1, %0|%0, %1}"
8305   [(set_attr "type" "alu1")
8306    (set_attr "mode" "QI")])
8307
8308 (define_insn "*andqi_2_maybe_si"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:QI
8311                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8312                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8313                  (const_int 0)))
8314    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8315         (and:QI (match_dup 1) (match_dup 2)))]
8316   "ix86_binary_operator_ok (AND, QImode, operands)
8317    && ix86_match_ccmode (insn,
8318                          GET_CODE (operands[2]) == CONST_INT
8319                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8320 {
8321   if (which_alternative == 2)
8322     {
8323       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8324         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8325       return "and{l}\t{%2, %k0|%k0, %2}";
8326     }
8327   return "and{b}\t{%2, %0|%0, %2}";
8328 }
8329   [(set_attr "type" "alu")
8330    (set_attr "mode" "QI,QI,SI")])
8331
8332 (define_insn "*andqi_2"
8333   [(set (reg FLAGS_REG)
8334         (compare (and:QI
8335                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8336                    (match_operand:QI 2 "general_operand" "qim,qi"))
8337                  (const_int 0)))
8338    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8339         (and:QI (match_dup 1) (match_dup 2)))]
8340   "ix86_match_ccmode (insn, CCNOmode)
8341    && ix86_binary_operator_ok (AND, QImode, operands)"
8342   "and{b}\t{%2, %0|%0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "mode" "QI")])
8345
8346 (define_insn "*andqi_2_slp"
8347   [(set (reg FLAGS_REG)
8348         (compare (and:QI
8349                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8350                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8351                  (const_int 0)))
8352    (set (strict_low_part (match_dup 0))
8353         (and:QI (match_dup 0) (match_dup 1)))]
8354   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8355    && ix86_match_ccmode (insn, CCNOmode)
8356    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8357   "and{b}\t{%1, %0|%0, %1}"
8358   [(set_attr "type" "alu1")
8359    (set_attr "mode" "QI")])
8360
8361 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8362 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8363 ;; for a QImode operand, which of course failed.
8364
8365 (define_insn "andqi_ext_0"
8366   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8367                          (const_int 8)
8368                          (const_int 8))
8369         (and:SI 
8370           (zero_extract:SI
8371             (match_operand 1 "ext_register_operand" "0")
8372             (const_int 8)
8373             (const_int 8))
8374           (match_operand 2 "const_int_operand" "n")))
8375    (clobber (reg:CC FLAGS_REG))]
8376   ""
8377   "and{b}\t{%2, %h0|%h0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "1")
8380    (set_attr "mode" "QI")])
8381
8382 ;; Generated by peephole translating test to and.  This shows up
8383 ;; often in fp comparisons.
8384
8385 (define_insn "*andqi_ext_0_cc"
8386   [(set (reg FLAGS_REG)
8387         (compare
8388           (and:SI
8389             (zero_extract:SI
8390               (match_operand 1 "ext_register_operand" "0")
8391               (const_int 8)
8392               (const_int 8))
8393             (match_operand 2 "const_int_operand" "n"))
8394           (const_int 0)))
8395    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396                          (const_int 8)
8397                          (const_int 8))
8398         (and:SI 
8399           (zero_extract:SI
8400             (match_dup 1)
8401             (const_int 8)
8402             (const_int 8))
8403           (match_dup 2)))]
8404   "ix86_match_ccmode (insn, CCNOmode)"
8405   "and{b}\t{%2, %h0|%h0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "length_immediate" "1")
8408    (set_attr "mode" "QI")])
8409
8410 (define_insn "*andqi_ext_1"
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_extend:SI
8420             (match_operand:QI 2 "general_operand" "Qm"))))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "!TARGET_64BIT"
8423   "and{b}\t{%2, %h0|%h0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "0")
8426    (set_attr "mode" "QI")])
8427
8428 (define_insn "*andqi_ext_1_rex64"
8429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8430                          (const_int 8)
8431                          (const_int 8))
8432         (and:SI 
8433           (zero_extract:SI
8434             (match_operand 1 "ext_register_operand" "0")
8435             (const_int 8)
8436             (const_int 8))
8437           (zero_extend:SI
8438             (match_operand 2 "ext_register_operand" "Q"))))
8439    (clobber (reg:CC FLAGS_REG))]
8440   "TARGET_64BIT"
8441   "and{b}\t{%2, %h0|%h0, %2}"
8442   [(set_attr "type" "alu")
8443    (set_attr "length_immediate" "0")
8444    (set_attr "mode" "QI")])
8445
8446 (define_insn "*andqi_ext_2"
8447   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448                          (const_int 8)
8449                          (const_int 8))
8450         (and:SI
8451           (zero_extract:SI
8452             (match_operand 1 "ext_register_operand" "%0")
8453             (const_int 8)
8454             (const_int 8))
8455           (zero_extract:SI
8456             (match_operand 2 "ext_register_operand" "Q")
8457             (const_int 8)
8458             (const_int 8))))
8459    (clobber (reg:CC FLAGS_REG))]
8460   ""
8461   "and{b}\t{%h2, %h0|%h0, %h2}"
8462   [(set_attr "type" "alu")
8463    (set_attr "length_immediate" "0")
8464    (set_attr "mode" "QI")])
8465
8466 ;; Convert wide AND instructions with immediate operand to shorter QImode
8467 ;; equivalents when possible.
8468 ;; Don't do the splitting with memory operands, since it introduces risk
8469 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8470 ;; for size, but that can (should?) be handled by generic code instead.
8471 (define_split
8472   [(set (match_operand 0 "register_operand" "")
8473         (and (match_operand 1 "register_operand" "")
8474              (match_operand 2 "const_int_operand" "")))
8475    (clobber (reg:CC FLAGS_REG))]
8476    "reload_completed
8477     && QI_REG_P (operands[0])
8478     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8479     && !(~INTVAL (operands[2]) & ~(255 << 8))
8480     && GET_MODE (operands[0]) != QImode"
8481   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8482                    (and:SI (zero_extract:SI (match_dup 1)
8483                                             (const_int 8) (const_int 8))
8484                            (match_dup 2)))
8485               (clobber (reg:CC FLAGS_REG))])]
8486   "operands[0] = gen_lowpart (SImode, operands[0]);
8487    operands[1] = gen_lowpart (SImode, operands[1]);
8488    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8489
8490 ;; Since AND can be encoded with sign extended immediate, this is only
8491 ;; profitable when 7th bit is not set.
8492 (define_split
8493   [(set (match_operand 0 "register_operand" "")
8494         (and (match_operand 1 "general_operand" "")
8495              (match_operand 2 "const_int_operand" "")))
8496    (clobber (reg:CC FLAGS_REG))]
8497    "reload_completed
8498     && ANY_QI_REG_P (operands[0])
8499     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8500     && !(~INTVAL (operands[2]) & ~255)
8501     && !(INTVAL (operands[2]) & 128)
8502     && GET_MODE (operands[0]) != QImode"
8503   [(parallel [(set (strict_low_part (match_dup 0))
8504                    (and:QI (match_dup 1)
8505                            (match_dup 2)))
8506               (clobber (reg:CC FLAGS_REG))])]
8507   "operands[0] = gen_lowpart (QImode, operands[0]);
8508    operands[1] = gen_lowpart (QImode, operands[1]);
8509    operands[2] = gen_lowpart (QImode, operands[2]);")
8510 \f
8511 ;; Logical inclusive OR instructions
8512
8513 ;; %%% This used to optimize known byte-wide and operations to memory.
8514 ;; If this is considered useful, it should be done with splitters.
8515
8516 (define_expand "iordi3"
8517   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8518         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8519                 (match_operand:DI 2 "x86_64_general_operand" "")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT"
8522   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8523
8524 (define_insn "*iordi_1_rex64"
8525   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8526         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8527                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_64BIT
8530    && ix86_binary_operator_ok (IOR, DImode, operands)"
8531   "or{q}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "DI")])
8534
8535 (define_insn "*iordi_2_rex64"
8536   [(set (reg FLAGS_REG)
8537         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8538                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8539                  (const_int 0)))
8540    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8541         (ior:DI (match_dup 1) (match_dup 2)))]
8542   "TARGET_64BIT
8543    && ix86_match_ccmode (insn, CCNOmode)
8544    && ix86_binary_operator_ok (IOR, DImode, operands)"
8545   "or{q}\t{%2, %0|%0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "DI")])
8548
8549 (define_insn "*iordi_3_rex64"
8550   [(set (reg FLAGS_REG)
8551         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8552                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8553                  (const_int 0)))
8554    (clobber (match_scratch:DI 0 "=r"))]
8555   "TARGET_64BIT
8556    && ix86_match_ccmode (insn, CCNOmode)
8557    && ix86_binary_operator_ok (IOR, DImode, operands)"
8558   "or{q}\t{%2, %0|%0, %2}"
8559   [(set_attr "type" "alu")
8560    (set_attr "mode" "DI")])
8561
8562
8563 (define_expand "iorsi3"
8564   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8565         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8566                 (match_operand:SI 2 "general_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   ""
8569   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8570
8571 (define_insn "*iorsi_1"
8572   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8573         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8574                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "ix86_binary_operator_ok (IOR, SImode, operands)"
8577   "or{l}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8580
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*iorsi_1_zext"
8583   [(set (match_operand:DI 0 "register_operand" "=rm")
8584         (zero_extend:DI
8585           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8586                   (match_operand:SI 2 "general_operand" "rim"))))
8587    (clobber (reg:CC FLAGS_REG))]
8588   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8589   "or{l}\t{%2, %k0|%k0, %2}"
8590   [(set_attr "type" "alu")
8591    (set_attr "mode" "SI")])
8592
8593 (define_insn "*iorsi_1_zext_imm"
8594   [(set (match_operand:DI 0 "register_operand" "=rm")
8595         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8596                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_64BIT"
8599   "or{l}\t{%2, %k0|%k0, %2}"
8600   [(set_attr "type" "alu")
8601    (set_attr "mode" "SI")])
8602
8603 (define_insn "*iorsi_2"
8604   [(set (reg FLAGS_REG)
8605         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8606                          (match_operand:SI 2 "general_operand" "rim,ri"))
8607                  (const_int 0)))
8608    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8609         (ior:SI (match_dup 1) (match_dup 2)))]
8610   "ix86_match_ccmode (insn, CCNOmode)
8611    && ix86_binary_operator_ok (IOR, SImode, operands)"
8612   "or{l}\t{%2, %0|%0, %2}"
8613   [(set_attr "type" "alu")
8614    (set_attr "mode" "SI")])
8615
8616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8617 ;; ??? Special case for immediate operand is missing - it is tricky.
8618 (define_insn "*iorsi_2_zext"
8619   [(set (reg FLAGS_REG)
8620         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8621                          (match_operand:SI 2 "general_operand" "rim"))
8622                  (const_int 0)))
8623    (set (match_operand:DI 0 "register_operand" "=r")
8624         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8625   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8626    && ix86_binary_operator_ok (IOR, SImode, operands)"
8627   "or{l}\t{%2, %k0|%k0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "mode" "SI")])
8630
8631 (define_insn "*iorsi_2_zext_imm"
8632   [(set (reg FLAGS_REG)
8633         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8635                  (const_int 0)))
8636    (set (match_operand:DI 0 "register_operand" "=r")
8637         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8638   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8639    && ix86_binary_operator_ok (IOR, SImode, operands)"
8640   "or{l}\t{%2, %k0|%k0, %2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "mode" "SI")])
8643
8644 (define_insn "*iorsi_3"
8645   [(set (reg FLAGS_REG)
8646         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8647                          (match_operand:SI 2 "general_operand" "rim"))
8648                  (const_int 0)))
8649    (clobber (match_scratch:SI 0 "=r"))]
8650   "ix86_match_ccmode (insn, CCNOmode)
8651    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8652   "or{l}\t{%2, %0|%0, %2}"
8653   [(set_attr "type" "alu")
8654    (set_attr "mode" "SI")])
8655
8656 (define_expand "iorhi3"
8657   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8658         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8659                 (match_operand:HI 2 "general_operand" "")))
8660    (clobber (reg:CC FLAGS_REG))]
8661   "TARGET_HIMODE_MATH"
8662   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8663
8664 (define_insn "*iorhi_1"
8665   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8666         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8667                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "ix86_binary_operator_ok (IOR, HImode, operands)"
8670   "or{w}\t{%2, %0|%0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "HI")])
8673
8674 (define_insn "*iorhi_2"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8677                          (match_operand:HI 2 "general_operand" "rim,ri"))
8678                  (const_int 0)))
8679    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8680         (ior:HI (match_dup 1) (match_dup 2)))]
8681   "ix86_match_ccmode (insn, CCNOmode)
8682    && ix86_binary_operator_ok (IOR, HImode, operands)"
8683   "or{w}\t{%2, %0|%0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "mode" "HI")])
8686
8687 (define_insn "*iorhi_3"
8688   [(set (reg FLAGS_REG)
8689         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8690                          (match_operand:HI 2 "general_operand" "rim"))
8691                  (const_int 0)))
8692    (clobber (match_scratch:HI 0 "=r"))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8695   "or{w}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "HI")])
8698
8699 (define_expand "iorqi3"
8700   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8701         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8702                 (match_operand:QI 2 "general_operand" "")))
8703    (clobber (reg:CC FLAGS_REG))]
8704   "TARGET_QIMODE_MATH"
8705   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8706
8707 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8708 (define_insn "*iorqi_1"
8709   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8710         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8711                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8712    (clobber (reg:CC FLAGS_REG))]
8713   "ix86_binary_operator_ok (IOR, QImode, operands)"
8714   "@
8715    or{b}\t{%2, %0|%0, %2}
8716    or{b}\t{%2, %0|%0, %2}
8717    or{l}\t{%k2, %k0|%k0, %k2}"
8718   [(set_attr "type" "alu")
8719    (set_attr "mode" "QI,QI,SI")])
8720
8721 (define_insn "*iorqi_1_slp"
8722   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8723         (ior:QI (match_dup 0)
8724                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8727    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8728   "or{b}\t{%1, %0|%0, %1}"
8729   [(set_attr "type" "alu1")
8730    (set_attr "mode" "QI")])
8731
8732 (define_insn "*iorqi_2"
8733   [(set (reg FLAGS_REG)
8734         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8735                          (match_operand:QI 2 "general_operand" "qim,qi"))
8736                  (const_int 0)))
8737    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8738         (ior:QI (match_dup 1) (match_dup 2)))]
8739   "ix86_match_ccmode (insn, CCNOmode)
8740    && ix86_binary_operator_ok (IOR, QImode, operands)"
8741   "or{b}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "QI")])
8744
8745 (define_insn "*iorqi_2_slp"
8746   [(set (reg FLAGS_REG)
8747         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8748                          (match_operand:QI 1 "general_operand" "qim,qi"))
8749                  (const_int 0)))
8750    (set (strict_low_part (match_dup 0))
8751         (ior:QI (match_dup 0) (match_dup 1)))]
8752   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8753    && ix86_match_ccmode (insn, CCNOmode)
8754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8755   "or{b}\t{%1, %0|%0, %1}"
8756   [(set_attr "type" "alu1")
8757    (set_attr "mode" "QI")])
8758
8759 (define_insn "*iorqi_3"
8760   [(set (reg FLAGS_REG)
8761         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8762                          (match_operand:QI 2 "general_operand" "qim"))
8763                  (const_int 0)))
8764    (clobber (match_scratch:QI 0 "=q"))]
8765   "ix86_match_ccmode (insn, CCNOmode)
8766    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8767   "or{b}\t{%2, %0|%0, %2}"
8768   [(set_attr "type" "alu")
8769    (set_attr "mode" "QI")])
8770
8771 (define_insn "iorqi_ext_0"
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           (match_operand 2 "const_int_operand" "n")))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8783   "or{b}\t{%2, %h0|%h0, %2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "length_immediate" "1")
8786    (set_attr "mode" "QI")])
8787
8788 (define_insn "*iorqi_ext_1"
8789   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790                          (const_int 8)
8791                          (const_int 8))
8792         (ior:SI 
8793           (zero_extract:SI
8794             (match_operand 1 "ext_register_operand" "0")
8795             (const_int 8)
8796             (const_int 8))
8797           (zero_extend:SI
8798             (match_operand:QI 2 "general_operand" "Qm"))))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "!TARGET_64BIT
8801    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8802   "or{b}\t{%2, %h0|%h0, %2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "length_immediate" "0")
8805    (set_attr "mode" "QI")])
8806
8807 (define_insn "*iorqi_ext_1_rex64"
8808   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8809                          (const_int 8)
8810                          (const_int 8))
8811         (ior:SI 
8812           (zero_extract:SI
8813             (match_operand 1 "ext_register_operand" "0")
8814             (const_int 8)
8815             (const_int 8))
8816           (zero_extend:SI
8817             (match_operand 2 "ext_register_operand" "Q"))))
8818    (clobber (reg:CC FLAGS_REG))]
8819   "TARGET_64BIT
8820    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8821   "or{b}\t{%2, %h0|%h0, %2}"
8822   [(set_attr "type" "alu")
8823    (set_attr "length_immediate" "0")
8824    (set_attr "mode" "QI")])
8825
8826 (define_insn "*iorqi_ext_2"
8827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8828                          (const_int 8)
8829                          (const_int 8))
8830         (ior:SI 
8831           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8832                            (const_int 8)
8833                            (const_int 8))
8834           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8835                            (const_int 8)
8836                            (const_int 8))))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8839   "ior{b}\t{%h2, %h0|%h0, %h2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "length_immediate" "0")
8842    (set_attr "mode" "QI")])
8843
8844 (define_split
8845   [(set (match_operand 0 "register_operand" "")
8846         (ior (match_operand 1 "register_operand" "")
8847              (match_operand 2 "const_int_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849    "reload_completed
8850     && QI_REG_P (operands[0])
8851     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8852     && !(INTVAL (operands[2]) & ~(255 << 8))
8853     && GET_MODE (operands[0]) != QImode"
8854   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8855                    (ior:SI (zero_extract:SI (match_dup 1)
8856                                             (const_int 8) (const_int 8))
8857                            (match_dup 2)))
8858               (clobber (reg:CC FLAGS_REG))])]
8859   "operands[0] = gen_lowpart (SImode, operands[0]);
8860    operands[1] = gen_lowpart (SImode, operands[1]);
8861    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8862
8863 ;; Since OR can be encoded with sign extended immediate, this is only
8864 ;; profitable when 7th bit is set.
8865 (define_split
8866   [(set (match_operand 0 "register_operand" "")
8867         (ior (match_operand 1 "general_operand" "")
8868              (match_operand 2 "const_int_operand" "")))
8869    (clobber (reg:CC FLAGS_REG))]
8870    "reload_completed
8871     && ANY_QI_REG_P (operands[0])
8872     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8873     && !(INTVAL (operands[2]) & ~255)
8874     && (INTVAL (operands[2]) & 128)
8875     && GET_MODE (operands[0]) != QImode"
8876   [(parallel [(set (strict_low_part (match_dup 0))
8877                    (ior:QI (match_dup 1)
8878                            (match_dup 2)))
8879               (clobber (reg:CC FLAGS_REG))])]
8880   "operands[0] = gen_lowpart (QImode, operands[0]);
8881    operands[1] = gen_lowpart (QImode, operands[1]);
8882    operands[2] = gen_lowpart (QImode, operands[2]);")
8883 \f
8884 ;; Logical XOR instructions
8885
8886 ;; %%% This used to optimize known byte-wide and operations to memory.
8887 ;; If this is considered useful, it should be done with splitters.
8888
8889 (define_expand "xordi3"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8891         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8892                 (match_operand:DI 2 "x86_64_general_operand" "")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT"
8895   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8896
8897 (define_insn "*xordi_1_rex64"
8898   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8899         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8900                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT
8903    && ix86_binary_operator_ok (XOR, DImode, operands)"
8904   "@
8905    xor{q}\t{%2, %0|%0, %2}
8906    xor{q}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "DI,DI")])
8909
8910 (define_insn "*xordi_2_rex64"
8911   [(set (reg FLAGS_REG)
8912         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8913                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8914                  (const_int 0)))
8915    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8916         (xor:DI (match_dup 1) (match_dup 2)))]
8917   "TARGET_64BIT
8918    && ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (XOR, DImode, operands)"
8920   "@
8921    xor{q}\t{%2, %0|%0, %2}
8922    xor{q}\t{%2, %0|%0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "mode" "DI,DI")])
8925
8926 (define_insn "*xordi_3_rex64"
8927   [(set (reg FLAGS_REG)
8928         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8929                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8930                  (const_int 0)))
8931    (clobber (match_scratch:DI 0 "=r"))]
8932   "TARGET_64BIT
8933    && ix86_match_ccmode (insn, CCNOmode)
8934    && ix86_binary_operator_ok (XOR, DImode, operands)"
8935   "xor{q}\t{%2, %0|%0, %2}"
8936   [(set_attr "type" "alu")
8937    (set_attr "mode" "DI")])
8938
8939 (define_expand "xorsi3"
8940   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8941         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8942                 (match_operand:SI 2 "general_operand" "")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   ""
8945   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8946
8947 (define_insn "*xorsi_1"
8948   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8949         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8950                 (match_operand:SI 2 "general_operand" "ri,rm")))
8951    (clobber (reg:CC FLAGS_REG))]
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 ;; Add speccase for immediates
8959 (define_insn "*xorsi_1_zext"
8960   [(set (match_operand:DI 0 "register_operand" "=r")
8961         (zero_extend:DI
8962           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8963                   (match_operand:SI 2 "general_operand" "rim"))))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8966   "xor{l}\t{%2, %k0|%k0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "SI")])
8969
8970 (define_insn "*xorsi_1_zext_imm"
8971   [(set (match_operand:DI 0 "register_operand" "=r")
8972         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8973                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8974    (clobber (reg:CC FLAGS_REG))]
8975   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8976   "xor{l}\t{%2, %k0|%k0, %2}"
8977   [(set_attr "type" "alu")
8978    (set_attr "mode" "SI")])
8979
8980 (define_insn "*xorsi_2"
8981   [(set (reg FLAGS_REG)
8982         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983                          (match_operand:SI 2 "general_operand" "rim,ri"))
8984                  (const_int 0)))
8985    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8986         (xor:SI (match_dup 1) (match_dup 2)))]
8987   "ix86_match_ccmode (insn, CCNOmode)
8988    && ix86_binary_operator_ok (XOR, SImode, operands)"
8989   "xor{l}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "SI")])
8992
8993 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8994 ;; ??? Special case for immediate operand is missing - it is tricky.
8995 (define_insn "*xorsi_2_zext"
8996   [(set (reg FLAGS_REG)
8997         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8998                          (match_operand:SI 2 "general_operand" "rim"))
8999                  (const_int 0)))
9000    (set (match_operand:DI 0 "register_operand" "=r")
9001         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9002   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9003    && ix86_binary_operator_ok (XOR, SImode, operands)"
9004   "xor{l}\t{%2, %k0|%k0, %2}"
9005   [(set_attr "type" "alu")
9006    (set_attr "mode" "SI")])
9007
9008 (define_insn "*xorsi_2_zext_imm"
9009   [(set (reg FLAGS_REG)
9010         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9012                  (const_int 0)))
9013    (set (match_operand:DI 0 "register_operand" "=r")
9014         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9015   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9016    && ix86_binary_operator_ok (XOR, SImode, operands)"
9017   "xor{l}\t{%2, %k0|%k0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "SI")])
9020
9021 (define_insn "*xorsi_3"
9022   [(set (reg FLAGS_REG)
9023         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024                          (match_operand:SI 2 "general_operand" "rim"))
9025                  (const_int 0)))
9026    (clobber (match_scratch:SI 0 "=r"))]
9027   "ix86_match_ccmode (insn, CCNOmode)
9028    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9029   "xor{l}\t{%2, %0|%0, %2}"
9030   [(set_attr "type" "alu")
9031    (set_attr "mode" "SI")])
9032
9033 (define_expand "xorhi3"
9034   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9035         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9036                 (match_operand:HI 2 "general_operand" "")))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "TARGET_HIMODE_MATH"
9039   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9040
9041 (define_insn "*xorhi_1"
9042   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9043         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9044                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "ix86_binary_operator_ok (XOR, HImode, operands)"
9047   "xor{w}\t{%2, %0|%0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "HI")])
9050
9051 (define_insn "*xorhi_2"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9054                          (match_operand:HI 2 "general_operand" "rim,ri"))
9055                  (const_int 0)))
9056    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9057         (xor:HI (match_dup 1) (match_dup 2)))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, HImode, operands)"
9060   "xor{w}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "HI")])
9063
9064 (define_insn "*xorhi_3"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9067                          (match_operand:HI 2 "general_operand" "rim"))
9068                  (const_int 0)))
9069    (clobber (match_scratch:HI 0 "=r"))]
9070   "ix86_match_ccmode (insn, CCNOmode)
9071    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9072   "xor{w}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "HI")])
9075
9076 (define_expand "xorqi3"
9077   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9078         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9079                 (match_operand:QI 2 "general_operand" "")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "TARGET_QIMODE_MATH"
9082   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9083
9084 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9085 (define_insn "*xorqi_1"
9086   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9087         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9088                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9089    (clobber (reg:CC FLAGS_REG))]
9090   "ix86_binary_operator_ok (XOR, QImode, operands)"
9091   "@
9092    xor{b}\t{%2, %0|%0, %2}
9093    xor{b}\t{%2, %0|%0, %2}
9094    xor{l}\t{%k2, %k0|%k0, %k2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "QI,QI,SI")])
9097
9098 (define_insn "*xorqi_1_slp"
9099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9100         (xor:QI (match_dup 0)
9101                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9104    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9105   "xor{b}\t{%1, %0|%0, %1}"
9106   [(set_attr "type" "alu1")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "xorqi_ext_0"
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           (match_operand 2 "const_int_operand" "n")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121   "xor{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "length_immediate" "1")
9124    (set_attr "mode" "QI")])
9125
9126 (define_insn "*xorqi_ext_1"
9127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128                          (const_int 8)
9129                          (const_int 8))
9130         (xor:SI 
9131           (zero_extract:SI
9132             (match_operand 1 "ext_register_operand" "0")
9133             (const_int 8)
9134             (const_int 8))
9135           (zero_extend:SI
9136             (match_operand:QI 2 "general_operand" "Qm"))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "!TARGET_64BIT
9139    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140   "xor{b}\t{%2, %h0|%h0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9144
9145 (define_insn "*xorqi_ext_1_rex64"
9146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147                          (const_int 8)
9148                          (const_int 8))
9149         (xor:SI 
9150           (zero_extract:SI
9151             (match_operand 1 "ext_register_operand" "0")
9152             (const_int 8)
9153             (const_int 8))
9154           (zero_extend:SI
9155             (match_operand 2 "ext_register_operand" "Q"))))
9156    (clobber (reg:CC FLAGS_REG))]
9157   "TARGET_64BIT
9158    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159   "xor{b}\t{%2, %h0|%h0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "length_immediate" "0")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*xorqi_ext_2"
9165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166                          (const_int 8)
9167                          (const_int 8))
9168         (xor:SI 
9169           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9170                            (const_int 8)
9171                            (const_int 8))
9172           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9173                            (const_int 8)
9174                            (const_int 8))))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "xor{b}\t{%h2, %h0|%h0, %h2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "0")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*xorqi_cc_1"
9183   [(set (reg FLAGS_REG)
9184         (compare
9185           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9186                   (match_operand:QI 2 "general_operand" "qim,qi"))
9187           (const_int 0)))
9188    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9189         (xor:QI (match_dup 1) (match_dup 2)))]
9190   "ix86_match_ccmode (insn, CCNOmode)
9191    && ix86_binary_operator_ok (XOR, QImode, operands)"
9192   "xor{b}\t{%2, %0|%0, %2}"
9193   [(set_attr "type" "alu")
9194    (set_attr "mode" "QI")])
9195
9196 (define_insn "*xorqi_2_slp"
9197   [(set (reg FLAGS_REG)
9198         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9199                          (match_operand:QI 1 "general_operand" "qim,qi"))
9200                  (const_int 0)))
9201    (set (strict_low_part (match_dup 0))
9202         (xor:QI (match_dup 0) (match_dup 1)))]
9203   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9204    && ix86_match_ccmode (insn, CCNOmode)
9205    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9206   "xor{b}\t{%1, %0|%0, %1}"
9207   [(set_attr "type" "alu1")
9208    (set_attr "mode" "QI")])
9209
9210 (define_insn "*xorqi_cc_2"
9211   [(set (reg FLAGS_REG)
9212         (compare
9213           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9214                   (match_operand:QI 2 "general_operand" "qim"))
9215           (const_int 0)))
9216    (clobber (match_scratch:QI 0 "=q"))]
9217   "ix86_match_ccmode (insn, CCNOmode)
9218    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9219   "xor{b}\t{%2, %0|%0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9222
9223 (define_insn "*xorqi_cc_ext_1"
9224   [(set (reg FLAGS_REG)
9225         (compare
9226           (xor:SI
9227             (zero_extract:SI
9228               (match_operand 1 "ext_register_operand" "0")
9229               (const_int 8)
9230               (const_int 8))
9231             (match_operand:QI 2 "general_operand" "qmn"))
9232           (const_int 0)))
9233    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9234                          (const_int 8)
9235                          (const_int 8))
9236         (xor:SI 
9237           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9238           (match_dup 2)))]
9239   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9240   "xor{b}\t{%2, %h0|%h0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9243
9244 (define_insn "*xorqi_cc_ext_1_rex64"
9245   [(set (reg FLAGS_REG)
9246         (compare
9247           (xor:SI
9248             (zero_extract:SI
9249               (match_operand 1 "ext_register_operand" "0")
9250               (const_int 8)
9251               (const_int 8))
9252             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9253           (const_int 0)))
9254    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255                          (const_int 8)
9256                          (const_int 8))
9257         (xor:SI 
9258           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9259           (match_dup 2)))]
9260   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9261   "xor{b}\t{%2, %h0|%h0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "QI")])
9264
9265 (define_expand "xorqi_cc_ext_1"
9266   [(parallel [
9267      (set (reg:CCNO FLAGS_REG)
9268           (compare:CCNO
9269             (xor:SI
9270               (zero_extract:SI
9271                 (match_operand 1 "ext_register_operand" "")
9272                 (const_int 8)
9273                 (const_int 8))
9274               (match_operand:QI 2 "general_operand" ""))
9275             (const_int 0)))
9276      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9277                            (const_int 8)
9278                            (const_int 8))
9279           (xor:SI 
9280             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9281             (match_dup 2)))])]
9282   ""
9283   "")
9284
9285 (define_split
9286   [(set (match_operand 0 "register_operand" "")
9287         (xor (match_operand 1 "register_operand" "")
9288              (match_operand 2 "const_int_operand" "")))
9289    (clobber (reg:CC FLAGS_REG))]
9290    "reload_completed
9291     && QI_REG_P (operands[0])
9292     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9293     && !(INTVAL (operands[2]) & ~(255 << 8))
9294     && GET_MODE (operands[0]) != QImode"
9295   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9296                    (xor:SI (zero_extract:SI (match_dup 1)
9297                                             (const_int 8) (const_int 8))
9298                            (match_dup 2)))
9299               (clobber (reg:CC FLAGS_REG))])]
9300   "operands[0] = gen_lowpart (SImode, operands[0]);
9301    operands[1] = gen_lowpart (SImode, operands[1]);
9302    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9303
9304 ;; Since XOR can be encoded with sign extended immediate, this is only
9305 ;; profitable when 7th bit is set.
9306 (define_split
9307   [(set (match_operand 0 "register_operand" "")
9308         (xor (match_operand 1 "general_operand" "")
9309              (match_operand 2 "const_int_operand" "")))
9310    (clobber (reg:CC FLAGS_REG))]
9311    "reload_completed
9312     && ANY_QI_REG_P (operands[0])
9313     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9314     && !(INTVAL (operands[2]) & ~255)
9315     && (INTVAL (operands[2]) & 128)
9316     && GET_MODE (operands[0]) != QImode"
9317   [(parallel [(set (strict_low_part (match_dup 0))
9318                    (xor:QI (match_dup 1)
9319                            (match_dup 2)))
9320               (clobber (reg:CC FLAGS_REG))])]
9321   "operands[0] = gen_lowpart (QImode, operands[0]);
9322    operands[1] = gen_lowpart (QImode, operands[1]);
9323    operands[2] = gen_lowpart (QImode, operands[2]);")
9324 \f
9325 ;; Negation instructions
9326
9327 (define_expand "negti2"
9328   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9329                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9330               (clobber (reg:CC FLAGS_REG))])]
9331   "TARGET_64BIT"
9332   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9333
9334 (define_insn "*negti2_1"
9335   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9336         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "TARGET_64BIT
9339    && ix86_unary_operator_ok (NEG, TImode, operands)"
9340   "#")
9341
9342 (define_split
9343   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9344         (neg:TI (match_operand:TI 1 "general_operand" "")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "TARGET_64BIT && reload_completed"
9347   [(parallel
9348     [(set (reg:CCZ FLAGS_REG)
9349           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9350      (set (match_dup 0) (neg:DI (match_dup 2)))])
9351    (parallel
9352     [(set (match_dup 1)
9353           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9354                             (match_dup 3))
9355                    (const_int 0)))
9356      (clobber (reg:CC FLAGS_REG))])
9357    (parallel
9358     [(set (match_dup 1)
9359           (neg:DI (match_dup 1)))
9360      (clobber (reg:CC FLAGS_REG))])]
9361   "split_ti (operands+1, 1, operands+2, operands+3);
9362    split_ti (operands+0, 1, operands+0, operands+1);")
9363
9364 (define_expand "negdi2"
9365   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9366                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9367               (clobber (reg:CC FLAGS_REG))])]
9368   ""
9369   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9370
9371 (define_insn "*negdi2_1"
9372   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9373         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9374    (clobber (reg:CC FLAGS_REG))]
9375   "!TARGET_64BIT
9376    && ix86_unary_operator_ok (NEG, DImode, operands)"
9377   "#")
9378
9379 (define_split
9380   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9381         (neg:DI (match_operand:DI 1 "general_operand" "")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "!TARGET_64BIT && reload_completed"
9384   [(parallel
9385     [(set (reg:CCZ FLAGS_REG)
9386           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9387      (set (match_dup 0) (neg:SI (match_dup 2)))])
9388    (parallel
9389     [(set (match_dup 1)
9390           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9391                             (match_dup 3))
9392                    (const_int 0)))
9393      (clobber (reg:CC FLAGS_REG))])
9394    (parallel
9395     [(set (match_dup 1)
9396           (neg:SI (match_dup 1)))
9397      (clobber (reg:CC FLAGS_REG))])]
9398   "split_di (operands+1, 1, operands+2, operands+3);
9399    split_di (operands+0, 1, operands+0, operands+1);")
9400
9401 (define_insn "*negdi2_1_rex64"
9402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9403         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9406   "neg{q}\t%0"
9407   [(set_attr "type" "negnot")
9408    (set_attr "mode" "DI")])
9409
9410 ;; The problem with neg is that it does not perform (compare x 0),
9411 ;; it really performs (compare 0 x), which leaves us with the zero
9412 ;; flag being the only useful item.
9413
9414 (define_insn "*negdi2_cmpz_rex64"
9415   [(set (reg:CCZ FLAGS_REG)
9416         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9417                      (const_int 0)))
9418    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9419         (neg:DI (match_dup 1)))]
9420   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9421   "neg{q}\t%0"
9422   [(set_attr "type" "negnot")
9423    (set_attr "mode" "DI")])
9424
9425
9426 (define_expand "negsi2"
9427   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9428                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9429               (clobber (reg:CC FLAGS_REG))])]
9430   ""
9431   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9432
9433 (define_insn "*negsi2_1"
9434   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9435         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9436    (clobber (reg:CC FLAGS_REG))]
9437   "ix86_unary_operator_ok (NEG, SImode, operands)"
9438   "neg{l}\t%0"
9439   [(set_attr "type" "negnot")
9440    (set_attr "mode" "SI")])
9441
9442 ;; Combine is quite creative about this pattern.
9443 (define_insn "*negsi2_1_zext"
9444   [(set (match_operand:DI 0 "register_operand" "=r")
9445         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9446                                         (const_int 32)))
9447                      (const_int 32)))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9450   "neg{l}\t%k0"
9451   [(set_attr "type" "negnot")
9452    (set_attr "mode" "SI")])
9453
9454 ;; The problem with neg is that it does not perform (compare x 0),
9455 ;; it really performs (compare 0 x), which leaves us with the zero
9456 ;; flag being the only useful item.
9457
9458 (define_insn "*negsi2_cmpz"
9459   [(set (reg:CCZ FLAGS_REG)
9460         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9461                      (const_int 0)))
9462    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9463         (neg:SI (match_dup 1)))]
9464   "ix86_unary_operator_ok (NEG, SImode, operands)"
9465   "neg{l}\t%0"
9466   [(set_attr "type" "negnot")
9467    (set_attr "mode" "SI")])
9468
9469 (define_insn "*negsi2_cmpz_zext"
9470   [(set (reg:CCZ FLAGS_REG)
9471         (compare:CCZ (lshiftrt:DI
9472                        (neg:DI (ashift:DI
9473                                  (match_operand:DI 1 "register_operand" "0")
9474                                  (const_int 32)))
9475                        (const_int 32))
9476                      (const_int 0)))
9477    (set (match_operand:DI 0 "register_operand" "=r")
9478         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9479                                         (const_int 32)))
9480                      (const_int 32)))]
9481   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9482   "neg{l}\t%k0"
9483   [(set_attr "type" "negnot")
9484    (set_attr "mode" "SI")])
9485
9486 (define_expand "neghi2"
9487   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9488                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9489               (clobber (reg:CC FLAGS_REG))])]
9490   "TARGET_HIMODE_MATH"
9491   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9492
9493 (define_insn "*neghi2_1"
9494   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9495         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "ix86_unary_operator_ok (NEG, HImode, operands)"
9498   "neg{w}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "HI")])
9501
9502 (define_insn "*neghi2_cmpz"
9503   [(set (reg:CCZ FLAGS_REG)
9504         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9505                      (const_int 0)))
9506    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9507         (neg:HI (match_dup 1)))]
9508   "ix86_unary_operator_ok (NEG, HImode, operands)"
9509   "neg{w}\t%0"
9510   [(set_attr "type" "negnot")
9511    (set_attr "mode" "HI")])
9512
9513 (define_expand "negqi2"
9514   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9515                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9516               (clobber (reg:CC FLAGS_REG))])]
9517   "TARGET_QIMODE_MATH"
9518   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9519
9520 (define_insn "*negqi2_1"
9521   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9522         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "ix86_unary_operator_ok (NEG, QImode, operands)"
9525   "neg{b}\t%0"
9526   [(set_attr "type" "negnot")
9527    (set_attr "mode" "QI")])
9528
9529 (define_insn "*negqi2_cmpz"
9530   [(set (reg:CCZ FLAGS_REG)
9531         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9532                      (const_int 0)))
9533    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9534         (neg:QI (match_dup 1)))]
9535   "ix86_unary_operator_ok (NEG, QImode, operands)"
9536   "neg{b}\t%0"
9537   [(set_attr "type" "negnot")
9538    (set_attr "mode" "QI")])
9539
9540 ;; Changing of sign for FP values is doable using integer unit too.
9541
9542 (define_expand "negsf2"
9543   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9544         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9545   "TARGET_80387 || TARGET_SSE_MATH"
9546   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9547
9548 (define_expand "abssf2"
9549   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9550         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9551   "TARGET_80387 || TARGET_SSE_MATH"
9552   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9553
9554 (define_insn "*absnegsf2_mixed"
9555   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9556         (match_operator:SF 3 "absneg_operator"
9557           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9558    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9559    (clobber (reg:CC FLAGS_REG))]
9560   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9561    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9562   "#")
9563
9564 (define_insn "*absnegsf2_sse"
9565   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9566         (match_operator:SF 3 "absneg_operator"
9567           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9568    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "TARGET_SSE_MATH
9571    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9572   "#")
9573
9574 (define_insn "*absnegsf2_i387"
9575   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9576         (match_operator:SF 3 "absneg_operator"
9577           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9578    (use (match_operand 2 "" ""))
9579    (clobber (reg:CC FLAGS_REG))]
9580   "TARGET_80387 && !TARGET_SSE_MATH
9581    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582   "#")
9583
9584 (define_expand "copysignsf3"
9585   [(match_operand:SF 0 "register_operand" "")
9586    (match_operand:SF 1 "nonmemory_operand" "")
9587    (match_operand:SF 2 "register_operand" "")]
9588   "TARGET_SSE_MATH"
9589 {
9590   ix86_expand_copysign (operands);
9591   DONE;
9592 })
9593
9594 (define_insn_and_split "copysignsf3_const"
9595   [(set (match_operand:SF 0 "register_operand"          "=x")
9596         (unspec:SF
9597           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9598            (match_operand:SF 2 "register_operand"       "0")
9599            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9600           UNSPEC_COPYSIGN))]
9601   "TARGET_SSE_MATH"
9602   "#"
9603   "&& reload_completed"
9604   [(const_int 0)]
9605 {
9606   ix86_split_copysign_const (operands);
9607   DONE;
9608 })
9609
9610 (define_insn "copysignsf3_var"
9611   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9612         (unspec:SF
9613           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9614            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9615            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9616            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9617           UNSPEC_COPYSIGN))
9618    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9619   "TARGET_SSE_MATH"
9620   "#")
9621
9622 (define_split
9623   [(set (match_operand:SF 0 "register_operand" "")
9624         (unspec:SF
9625           [(match_operand:SF 2 "register_operand" "")
9626            (match_operand:SF 3 "register_operand" "")
9627            (match_operand:V4SF 4 "" "")
9628            (match_operand:V4SF 5 "" "")]
9629           UNSPEC_COPYSIGN))
9630    (clobber (match_scratch:V4SF 1 ""))]
9631   "TARGET_SSE_MATH && reload_completed"
9632   [(const_int 0)]
9633 {
9634   ix86_split_copysign_var (operands);
9635   DONE;
9636 })
9637
9638 (define_expand "negdf2"
9639   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9640         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9641   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9642   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9643
9644 (define_expand "absdf2"
9645   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9646         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9647   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9648   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9649
9650 (define_insn "*absnegdf2_mixed"
9651   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9652         (match_operator:DF 3 "absneg_operator"
9653           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9654    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9657    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9658   "#")
9659
9660 (define_insn "*absnegdf2_sse"
9661   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9662         (match_operator:DF 3 "absneg_operator"
9663           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9664    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "TARGET_SSE2 && TARGET_SSE_MATH
9667    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9668   "#")
9669
9670 (define_insn "*absnegdf2_i387"
9671   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9672         (match_operator:DF 3 "absneg_operator"
9673           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9674    (use (match_operand 2 "" ""))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9677    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9678   "#")
9679
9680 (define_expand "copysigndf3"
9681   [(match_operand:DF 0 "register_operand" "")
9682    (match_operand:DF 1 "nonmemory_operand" "")
9683    (match_operand:DF 2 "register_operand" "")]
9684   "TARGET_SSE2 && TARGET_SSE_MATH"
9685 {
9686   ix86_expand_copysign (operands);
9687   DONE;
9688 })
9689
9690 (define_insn_and_split "copysigndf3_const"
9691   [(set (match_operand:DF 0 "register_operand"          "=x")
9692         (unspec:DF
9693           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9694            (match_operand:DF 2 "register_operand"       "0")
9695            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9696           UNSPEC_COPYSIGN))]
9697   "TARGET_SSE2 && TARGET_SSE_MATH"
9698   "#"
9699   "&& reload_completed"
9700   [(const_int 0)]
9701 {
9702   ix86_split_copysign_const (operands);
9703   DONE;
9704 })
9705
9706 (define_insn "copysigndf3_var"
9707   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9708         (unspec:DF
9709           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9710            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9711            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9712            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9713           UNSPEC_COPYSIGN))
9714    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9715   "TARGET_SSE2 && TARGET_SSE_MATH"
9716   "#")
9717
9718 (define_split
9719   [(set (match_operand:DF 0 "register_operand" "")
9720         (unspec:DF
9721           [(match_operand:DF 2 "register_operand" "")
9722            (match_operand:DF 3 "register_operand" "")
9723            (match_operand:V2DF 4 "" "")
9724            (match_operand:V2DF 5 "" "")]
9725           UNSPEC_COPYSIGN))
9726    (clobber (match_scratch:V2DF 1 ""))]
9727   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9728   [(const_int 0)]
9729 {
9730   ix86_split_copysign_var (operands);
9731   DONE;
9732 })
9733
9734 (define_expand "negxf2"
9735   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9736         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737   "TARGET_80387"
9738   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9739
9740 (define_expand "absxf2"
9741   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9742         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9743   "TARGET_80387"
9744   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9745
9746 (define_insn "*absnegxf2_i387"
9747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9748         (match_operator:XF 3 "absneg_operator"
9749           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9750    (use (match_operand 2 "" ""))
9751    (clobber (reg:CC FLAGS_REG))]
9752   "TARGET_80387
9753    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9754   "#")
9755
9756 ;; Splitters for fp abs and neg.
9757
9758 (define_split
9759   [(set (match_operand 0 "fp_register_operand" "")
9760         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9761    (use (match_operand 2 "" ""))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "reload_completed"
9764   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9765
9766 (define_split
9767   [(set (match_operand 0 "register_operand" "")
9768         (match_operator 3 "absneg_operator"
9769           [(match_operand 1 "register_operand" "")]))
9770    (use (match_operand 2 "nonimmediate_operand" ""))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "reload_completed && SSE_REG_P (operands[0])"
9773   [(set (match_dup 0) (match_dup 3))]
9774 {
9775   enum machine_mode mode = GET_MODE (operands[0]);
9776   enum machine_mode vmode = GET_MODE (operands[2]);
9777   rtx tmp;
9778   
9779   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9780   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9781   if (operands_match_p (operands[0], operands[2]))
9782     {
9783       tmp = operands[1];
9784       operands[1] = operands[2];
9785       operands[2] = tmp;
9786     }
9787   if (GET_CODE (operands[3]) == ABS)
9788     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9789   else
9790     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9791   operands[3] = tmp;
9792 })
9793
9794 (define_split
9795   [(set (match_operand:SF 0 "register_operand" "")
9796         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9797    (use (match_operand:V4SF 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "reload_completed"
9800   [(parallel [(set (match_dup 0) (match_dup 1))
9801               (clobber (reg:CC FLAGS_REG))])]
9802
9803   rtx tmp;
9804   operands[0] = gen_lowpart (SImode, operands[0]);
9805   if (GET_CODE (operands[1]) == ABS)
9806     {
9807       tmp = gen_int_mode (0x7fffffff, SImode);
9808       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9809     }
9810   else
9811     {
9812       tmp = gen_int_mode (0x80000000, SImode);
9813       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9814     }
9815   operands[1] = tmp;
9816 })
9817
9818 (define_split
9819   [(set (match_operand:DF 0 "register_operand" "")
9820         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9821    (use (match_operand 2 "" ""))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "reload_completed"
9824   [(parallel [(set (match_dup 0) (match_dup 1))
9825               (clobber (reg:CC FLAGS_REG))])]
9826 {
9827   rtx tmp;
9828   if (TARGET_64BIT)
9829     {
9830       tmp = gen_lowpart (DImode, operands[0]);
9831       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9832       operands[0] = tmp;
9833
9834       if (GET_CODE (operands[1]) == ABS)
9835         tmp = const0_rtx;
9836       else
9837         tmp = gen_rtx_NOT (DImode, tmp);
9838     }
9839   else
9840     {
9841       operands[0] = gen_highpart (SImode, operands[0]);
9842       if (GET_CODE (operands[1]) == ABS)
9843         {
9844           tmp = gen_int_mode (0x7fffffff, SImode);
9845           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9846         }
9847       else
9848         {
9849           tmp = gen_int_mode (0x80000000, SImode);
9850           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9851         }
9852     }
9853   operands[1] = tmp;
9854 })
9855
9856 (define_split
9857   [(set (match_operand:XF 0 "register_operand" "")
9858         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9859    (use (match_operand 2 "" ""))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "reload_completed"
9862   [(parallel [(set (match_dup 0) (match_dup 1))
9863               (clobber (reg:CC FLAGS_REG))])]
9864 {
9865   rtx tmp;
9866   operands[0] = gen_rtx_REG (SImode,
9867                              true_regnum (operands[0])
9868                              + (TARGET_64BIT ? 1 : 2));
9869   if (GET_CODE (operands[1]) == ABS)
9870     {
9871       tmp = GEN_INT (0x7fff);
9872       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9873     }
9874   else
9875     {
9876       tmp = GEN_INT (0x8000);
9877       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9878     }
9879   operands[1] = tmp;
9880 })
9881
9882 (define_split
9883   [(set (match_operand 0 "memory_operand" "")
9884         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9885    (use (match_operand 2 "" ""))
9886    (clobber (reg:CC FLAGS_REG))]
9887   "reload_completed"
9888   [(parallel [(set (match_dup 0) (match_dup 1))
9889               (clobber (reg:CC FLAGS_REG))])]
9890 {
9891   enum machine_mode mode = GET_MODE (operands[0]);
9892   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9893   rtx tmp;
9894
9895   operands[0] = adjust_address (operands[0], QImode, size - 1);
9896   if (GET_CODE (operands[1]) == ABS)
9897     {
9898       tmp = gen_int_mode (0x7f, QImode);
9899       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9900     }
9901   else
9902     {
9903       tmp = gen_int_mode (0x80, QImode);
9904       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9905     }
9906   operands[1] = tmp;
9907 })
9908
9909 ;; Conditionalize these after reload. If they match before reload, we 
9910 ;; lose the clobber and ability to use integer instructions.
9911
9912 (define_insn "*negsf2_1"
9913   [(set (match_operand:SF 0 "register_operand" "=f")
9914         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9915   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9916   "fchs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "SF")])
9919
9920 (define_insn "*negdf2_1"
9921   [(set (match_operand:DF 0 "register_operand" "=f")
9922         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9923   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "DF")])
9927
9928 (define_insn "*negxf2_1"
9929   [(set (match_operand:XF 0 "register_operand" "=f")
9930         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "XF")])
9935
9936 (define_insn "*abssf2_1"
9937   [(set (match_operand:SF 0 "register_operand" "=f")
9938         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9939   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9940   "fabs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "SF")])
9943
9944 (define_insn "*absdf2_1"
9945   [(set (match_operand:DF 0 "register_operand" "=f")
9946         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9947   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "DF")])
9951
9952 (define_insn "*absxf2_1"
9953   [(set (match_operand:XF 0 "register_operand" "=f")
9954         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9955   "TARGET_80387"
9956   "fabs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9959
9960 (define_insn "*negextendsfdf2"
9961   [(set (match_operand:DF 0 "register_operand" "=f")
9962         (neg:DF (float_extend:DF
9963                   (match_operand:SF 1 "register_operand" "0"))))]
9964   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9965   "fchs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "DF")])
9968
9969 (define_insn "*negextenddfxf2"
9970   [(set (match_operand:XF 0 "register_operand" "=f")
9971         (neg:XF (float_extend:XF
9972                   (match_operand:DF 1 "register_operand" "0"))))]
9973   "TARGET_80387"
9974   "fchs"
9975   [(set_attr "type" "fsgn")
9976    (set_attr "mode" "XF")])
9977
9978 (define_insn "*negextendsfxf2"
9979   [(set (match_operand:XF 0 "register_operand" "=f")
9980         (neg:XF (float_extend:XF
9981                   (match_operand:SF 1 "register_operand" "0"))))]
9982   "TARGET_80387"
9983   "fchs"
9984   [(set_attr "type" "fsgn")
9985    (set_attr "mode" "XF")])
9986
9987 (define_insn "*absextendsfdf2"
9988   [(set (match_operand:DF 0 "register_operand" "=f")
9989         (abs:DF (float_extend:DF
9990                   (match_operand:SF 1 "register_operand" "0"))))]
9991   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9992   "fabs"
9993   [(set_attr "type" "fsgn")
9994    (set_attr "mode" "DF")])
9995
9996 (define_insn "*absextenddfxf2"
9997   [(set (match_operand:XF 0 "register_operand" "=f")
9998         (abs:XF (float_extend:XF
9999           (match_operand:DF 1 "register_operand" "0"))))]
10000   "TARGET_80387"
10001   "fabs"
10002   [(set_attr "type" "fsgn")
10003    (set_attr "mode" "XF")])
10004
10005 (define_insn "*absextendsfxf2"
10006   [(set (match_operand:XF 0 "register_operand" "=f")
10007         (abs:XF (float_extend:XF
10008           (match_operand:SF 1 "register_operand" "0"))))]
10009   "TARGET_80387"
10010   "fabs"
10011   [(set_attr "type" "fsgn")
10012    (set_attr "mode" "XF")])
10013 \f
10014 ;; One complement instructions
10015
10016 (define_expand "one_cmpldi2"
10017   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10018         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10019   "TARGET_64BIT"
10020   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10021
10022 (define_insn "*one_cmpldi2_1_rex64"
10023   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10024         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10025   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10026   "not{q}\t%0"
10027   [(set_attr "type" "negnot")
10028    (set_attr "mode" "DI")])
10029
10030 (define_insn "*one_cmpldi2_2_rex64"
10031   [(set (reg FLAGS_REG)
10032         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10033                  (const_int 0)))
10034    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10035         (not:DI (match_dup 1)))]
10036   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037    && ix86_unary_operator_ok (NOT, DImode, operands)"
10038   "#"
10039   [(set_attr "type" "alu1")
10040    (set_attr "mode" "DI")])
10041
10042 (define_split
10043   [(set (match_operand 0 "flags_reg_operand" "")
10044         (match_operator 2 "compare_operator"
10045           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10046            (const_int 0)]))
10047    (set (match_operand:DI 1 "nonimmediate_operand" "")
10048         (not:DI (match_dup 3)))]
10049   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10050   [(parallel [(set (match_dup 0)
10051                    (match_op_dup 2
10052                      [(xor:DI (match_dup 3) (const_int -1))
10053                       (const_int 0)]))
10054               (set (match_dup 1)
10055                    (xor:DI (match_dup 3) (const_int -1)))])]
10056   "")
10057
10058 (define_expand "one_cmplsi2"
10059   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10060         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10061   ""
10062   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10063
10064 (define_insn "*one_cmplsi2_1"
10065   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10066         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10067   "ix86_unary_operator_ok (NOT, SImode, operands)"
10068   "not{l}\t%0"
10069   [(set_attr "type" "negnot")
10070    (set_attr "mode" "SI")])
10071
10072 ;; ??? Currently never generated - xor is used instead.
10073 (define_insn "*one_cmplsi2_1_zext"
10074   [(set (match_operand:DI 0 "register_operand" "=r")
10075         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10076   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10077   "not{l}\t%k0"
10078   [(set_attr "type" "negnot")
10079    (set_attr "mode" "SI")])
10080
10081 (define_insn "*one_cmplsi2_2"
10082   [(set (reg FLAGS_REG)
10083         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10084                  (const_int 0)))
10085    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10086         (not:SI (match_dup 1)))]
10087   "ix86_match_ccmode (insn, CCNOmode)
10088    && ix86_unary_operator_ok (NOT, SImode, operands)"
10089   "#"
10090   [(set_attr "type" "alu1")
10091    (set_attr "mode" "SI")])
10092
10093 (define_split
10094   [(set (match_operand 0 "flags_reg_operand" "")
10095         (match_operator 2 "compare_operator"
10096           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10097            (const_int 0)]))
10098    (set (match_operand:SI 1 "nonimmediate_operand" "")
10099         (not:SI (match_dup 3)))]
10100   "ix86_match_ccmode (insn, CCNOmode)"
10101   [(parallel [(set (match_dup 0)
10102                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10103                                     (const_int 0)]))
10104               (set (match_dup 1)
10105                    (xor:SI (match_dup 3) (const_int -1)))])]
10106   "")
10107
10108 ;; ??? Currently never generated - xor is used instead.
10109 (define_insn "*one_cmplsi2_2_zext"
10110   [(set (reg FLAGS_REG)
10111         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10112                  (const_int 0)))
10113    (set (match_operand:DI 0 "register_operand" "=r")
10114         (zero_extend:DI (not:SI (match_dup 1))))]
10115   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10116    && ix86_unary_operator_ok (NOT, SImode, operands)"
10117   "#"
10118   [(set_attr "type" "alu1")
10119    (set_attr "mode" "SI")])
10120
10121 (define_split
10122   [(set (match_operand 0 "flags_reg_operand" "")
10123         (match_operator 2 "compare_operator"
10124           [(not:SI (match_operand:SI 3 "register_operand" ""))
10125            (const_int 0)]))
10126    (set (match_operand:DI 1 "register_operand" "")
10127         (zero_extend:DI (not:SI (match_dup 3))))]
10128   "ix86_match_ccmode (insn, CCNOmode)"
10129   [(parallel [(set (match_dup 0)
10130                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10131                                     (const_int 0)]))
10132               (set (match_dup 1)
10133                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10134   "")
10135
10136 (define_expand "one_cmplhi2"
10137   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10138         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10139   "TARGET_HIMODE_MATH"
10140   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10141
10142 (define_insn "*one_cmplhi2_1"
10143   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10144         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10145   "ix86_unary_operator_ok (NOT, HImode, operands)"
10146   "not{w}\t%0"
10147   [(set_attr "type" "negnot")
10148    (set_attr "mode" "HI")])
10149
10150 (define_insn "*one_cmplhi2_2"
10151   [(set (reg FLAGS_REG)
10152         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10153                  (const_int 0)))
10154    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10155         (not:HI (match_dup 1)))]
10156   "ix86_match_ccmode (insn, CCNOmode)
10157    && ix86_unary_operator_ok (NEG, HImode, operands)"
10158   "#"
10159   [(set_attr "type" "alu1")
10160    (set_attr "mode" "HI")])
10161
10162 (define_split
10163   [(set (match_operand 0 "flags_reg_operand" "")
10164         (match_operator 2 "compare_operator"
10165           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10166            (const_int 0)]))
10167    (set (match_operand:HI 1 "nonimmediate_operand" "")
10168         (not:HI (match_dup 3)))]
10169   "ix86_match_ccmode (insn, CCNOmode)"
10170   [(parallel [(set (match_dup 0)
10171                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10172                                     (const_int 0)]))
10173               (set (match_dup 1)
10174                    (xor:HI (match_dup 3) (const_int -1)))])]
10175   "")
10176
10177 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10178 (define_expand "one_cmplqi2"
10179   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10180         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10181   "TARGET_QIMODE_MATH"
10182   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10183
10184 (define_insn "*one_cmplqi2_1"
10185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10186         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10187   "ix86_unary_operator_ok (NOT, QImode, operands)"
10188   "@
10189    not{b}\t%0
10190    not{l}\t%k0"
10191   [(set_attr "type" "negnot")
10192    (set_attr "mode" "QI,SI")])
10193
10194 (define_insn "*one_cmplqi2_2"
10195   [(set (reg FLAGS_REG)
10196         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10197                  (const_int 0)))
10198    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10199         (not:QI (match_dup 1)))]
10200   "ix86_match_ccmode (insn, CCNOmode)
10201    && ix86_unary_operator_ok (NOT, QImode, operands)"
10202   "#"
10203   [(set_attr "type" "alu1")
10204    (set_attr "mode" "QI")])
10205
10206 (define_split
10207   [(set (match_operand 0 "flags_reg_operand" "")
10208         (match_operator 2 "compare_operator"
10209           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10210            (const_int 0)]))
10211    (set (match_operand:QI 1 "nonimmediate_operand" "")
10212         (not:QI (match_dup 3)))]
10213   "ix86_match_ccmode (insn, CCNOmode)"
10214   [(parallel [(set (match_dup 0)
10215                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10216                                     (const_int 0)]))
10217               (set (match_dup 1)
10218                    (xor:QI (match_dup 3) (const_int -1)))])]
10219   "")
10220 \f
10221 ;; Arithmetic shift instructions
10222
10223 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10224 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10225 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10226 ;; from the assembler input.
10227 ;;
10228 ;; This instruction shifts the target reg/mem as usual, but instead of
10229 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10230 ;; is a left shift double, bits are taken from the high order bits of
10231 ;; reg, else if the insn is a shift right double, bits are taken from the
10232 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10233 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10234 ;;
10235 ;; Since sh[lr]d does not change the `reg' operand, that is done
10236 ;; separately, making all shifts emit pairs of shift double and normal
10237 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10238 ;; support a 63 bit shift, each shift where the count is in a reg expands
10239 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10240 ;;
10241 ;; If the shift count is a constant, we need never emit more than one
10242 ;; shift pair, instead using moves and sign extension for counts greater
10243 ;; than 31.
10244
10245 (define_expand "ashlti3"
10246   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10247                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10248                               (match_operand:QI 2 "nonmemory_operand" "")))
10249               (clobber (reg:CC FLAGS_REG))])]
10250   "TARGET_64BIT"
10251 {
10252   if (! immediate_operand (operands[2], QImode))
10253     {
10254       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10255       DONE;
10256     }
10257   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10258   DONE;
10259 })
10260
10261 (define_insn "ashlti3_1"
10262   [(set (match_operand:TI 0 "register_operand" "=r")
10263         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10264                    (match_operand:QI 2 "register_operand" "c")))
10265    (clobber (match_scratch:DI 3 "=&r"))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "#"
10269   [(set_attr "type" "multi")])
10270
10271 (define_insn "*ashlti3_2"
10272   [(set (match_operand:TI 0 "register_operand" "=r")
10273         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10274                    (match_operand:QI 2 "immediate_operand" "O")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "TARGET_64BIT"
10277   "#"
10278   [(set_attr "type" "multi")])
10279
10280 (define_split
10281   [(set (match_operand:TI 0 "register_operand" "")
10282         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10283                    (match_operand:QI 2 "register_operand" "")))
10284    (clobber (match_scratch:DI 3 ""))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_64BIT && reload_completed"
10287   [(const_int 0)]
10288   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10289
10290 (define_split
10291   [(set (match_operand:TI 0 "register_operand" "")
10292         (ashift:TI (match_operand:TI 1 "register_operand" "")
10293                    (match_operand:QI 2 "immediate_operand" "")))
10294    (clobber (reg:CC FLAGS_REG))]
10295   "TARGET_64BIT && reload_completed"
10296   [(const_int 0)]
10297   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10298
10299 (define_insn "x86_64_shld"
10300   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10301         (ior:DI (ashift:DI (match_dup 0)
10302                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10303                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10304                   (minus:QI (const_int 64) (match_dup 2)))))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT"
10307   "@
10308    shld{q}\t{%2, %1, %0|%0, %1, %2}
10309    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10310   [(set_attr "type" "ishift")
10311    (set_attr "prefix_0f" "1")
10312    (set_attr "mode" "DI")
10313    (set_attr "athlon_decode" "vector")])
10314
10315 (define_expand "x86_64_shift_adj"
10316   [(set (reg:CCZ FLAGS_REG)
10317         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10318                              (const_int 64))
10319                      (const_int 0)))
10320    (set (match_operand:DI 0 "register_operand" "")
10321         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10322                          (match_operand:DI 1 "register_operand" "")
10323                          (match_dup 0)))
10324    (set (match_dup 1)
10325         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10326                          (match_operand:DI 3 "register_operand" "r")
10327                          (match_dup 1)))]
10328   "TARGET_64BIT"
10329   "")
10330
10331 (define_expand "ashldi3"
10332   [(set (match_operand:DI 0 "shiftdi_operand" "")
10333         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10334                    (match_operand:QI 2 "nonmemory_operand" "")))]
10335   ""
10336   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10337
10338 (define_insn "*ashldi3_1_rex64"
10339   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10340         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10341                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10344 {
10345   switch (get_attr_type (insn))
10346     {
10347     case TYPE_ALU:
10348       gcc_assert (operands[2] == const1_rtx);
10349       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10350       return "add{q}\t{%0, %0|%0, %0}";
10351
10352     case TYPE_LEA:
10353       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10354       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10355       operands[1] = gen_rtx_MULT (DImode, operands[1],
10356                                   GEN_INT (1 << INTVAL (operands[2])));
10357       return "lea{q}\t{%a1, %0|%0, %a1}";
10358
10359     default:
10360       if (REG_P (operands[2]))
10361         return "sal{q}\t{%b2, %0|%0, %b2}";
10362       else if (operands[2] == const1_rtx
10363                && (TARGET_SHIFT1 || optimize_size))
10364         return "sal{q}\t%0";
10365       else
10366         return "sal{q}\t{%2, %0|%0, %2}";
10367     }
10368 }
10369   [(set (attr "type")
10370      (cond [(eq_attr "alternative" "1")
10371               (const_string "lea")
10372             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10373                           (const_int 0))
10374                       (match_operand 0 "register_operand" ""))
10375                  (match_operand 2 "const1_operand" ""))
10376               (const_string "alu")
10377            ]
10378            (const_string "ishift")))
10379    (set_attr "mode" "DI")])
10380
10381 ;; Convert lea to the lea pattern to avoid flags dependency.
10382 (define_split
10383   [(set (match_operand:DI 0 "register_operand" "")
10384         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10385                    (match_operand:QI 2 "immediate_operand" "")))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_64BIT && reload_completed
10388    && true_regnum (operands[0]) != true_regnum (operands[1])"
10389   [(set (match_dup 0)
10390         (mult:DI (match_dup 1)
10391                  (match_dup 2)))]
10392   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10393
10394 ;; This pattern can't accept a variable shift count, since shifts by
10395 ;; zero don't affect the flags.  We assume that shifts by constant
10396 ;; zero are optimized away.
10397 (define_insn "*ashldi3_cmp_rex64"
10398   [(set (reg FLAGS_REG)
10399         (compare
10400           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10401                      (match_operand:QI 2 "immediate_operand" "e"))
10402           (const_int 0)))
10403    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10404         (ashift:DI (match_dup 1) (match_dup 2)))]
10405   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10406    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10407    && (optimize_size
10408        || !TARGET_PARTIAL_FLAG_REG_STALL
10409        || (operands[2] == const1_rtx
10410            && (TARGET_SHIFT1
10411                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10412 {
10413   switch (get_attr_type (insn))
10414     {
10415     case TYPE_ALU:
10416       gcc_assert (operands[2] == const1_rtx);
10417       return "add{q}\t{%0, %0|%0, %0}";
10418
10419     default:
10420       if (REG_P (operands[2]))
10421         return "sal{q}\t{%b2, %0|%0, %b2}";
10422       else if (operands[2] == const1_rtx
10423                && (TARGET_SHIFT1 || optimize_size))
10424         return "sal{q}\t%0";
10425       else
10426         return "sal{q}\t{%2, %0|%0, %2}";
10427     }
10428 }
10429   [(set (attr "type")
10430      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10431                           (const_int 0))
10432                       (match_operand 0 "register_operand" ""))
10433                  (match_operand 2 "const1_operand" ""))
10434               (const_string "alu")
10435            ]
10436            (const_string "ishift")))
10437    (set_attr "mode" "DI")])
10438
10439 (define_insn "*ashldi3_cconly_rex64"
10440   [(set (reg FLAGS_REG)
10441         (compare
10442           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10443                      (match_operand:QI 2 "immediate_operand" "e"))
10444           (const_int 0)))
10445    (clobber (match_scratch:DI 0 "=r"))]
10446   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10447    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10448    && (optimize_size
10449        || !TARGET_PARTIAL_FLAG_REG_STALL
10450        || (operands[2] == const1_rtx
10451            && (TARGET_SHIFT1
10452                || TARGET_DOUBLE_WITH_ADD)))"
10453 {
10454   switch (get_attr_type (insn))
10455     {
10456     case TYPE_ALU:
10457       gcc_assert (operands[2] == const1_rtx);
10458       return "add{q}\t{%0, %0|%0, %0}";
10459
10460     default:
10461       if (REG_P (operands[2]))
10462         return "sal{q}\t{%b2, %0|%0, %b2}";
10463       else if (operands[2] == const1_rtx
10464                && (TARGET_SHIFT1 || optimize_size))
10465         return "sal{q}\t%0";
10466       else
10467         return "sal{q}\t{%2, %0|%0, %2}";
10468     }
10469 }
10470   [(set (attr "type")
10471      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10472                           (const_int 0))
10473                       (match_operand 0 "register_operand" ""))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "DI")])
10479
10480 (define_insn "*ashldi3_1"
10481   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10482         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10483                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "!TARGET_64BIT"
10486   "#"
10487   [(set_attr "type" "multi")])
10488
10489 ;; By default we don't ask for a scratch register, because when DImode
10490 ;; values are manipulated, registers are already at a premium.  But if
10491 ;; we have one handy, we won't turn it away.
10492 (define_peephole2
10493   [(match_scratch:SI 3 "r")
10494    (parallel [(set (match_operand:DI 0 "register_operand" "")
10495                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10496                               (match_operand:QI 2 "nonmemory_operand" "")))
10497               (clobber (reg:CC FLAGS_REG))])
10498    (match_dup 3)]
10499   "!TARGET_64BIT && TARGET_CMOVE"
10500   [(const_int 0)]
10501   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10502
10503 (define_split
10504   [(set (match_operand:DI 0 "register_operand" "")
10505         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10506                    (match_operand:QI 2 "nonmemory_operand" "")))
10507    (clobber (reg:CC FLAGS_REG))]
10508   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10509                      ? flow2_completed : reload_completed)"
10510   [(const_int 0)]
10511   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10512
10513 (define_insn "x86_shld_1"
10514   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10515         (ior:SI (ashift:SI (match_dup 0)
10516                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10517                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10518                   (minus:QI (const_int 32) (match_dup 2)))))
10519    (clobber (reg:CC FLAGS_REG))]
10520   ""
10521   "@
10522    shld{l}\t{%2, %1, %0|%0, %1, %2}
10523    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10524   [(set_attr "type" "ishift")
10525    (set_attr "prefix_0f" "1")
10526    (set_attr "mode" "SI")
10527    (set_attr "pent_pair" "np")
10528    (set_attr "athlon_decode" "vector")])
10529
10530 (define_expand "x86_shift_adj_1"
10531   [(set (reg:CCZ FLAGS_REG)
10532         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10533                              (const_int 32))
10534                      (const_int 0)))
10535    (set (match_operand:SI 0 "register_operand" "")
10536         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10537                          (match_operand:SI 1 "register_operand" "")
10538                          (match_dup 0)))
10539    (set (match_dup 1)
10540         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10541                          (match_operand:SI 3 "register_operand" "r")
10542                          (match_dup 1)))]
10543   "TARGET_CMOVE"
10544   "")
10545
10546 (define_expand "x86_shift_adj_2"
10547   [(use (match_operand:SI 0 "register_operand" ""))
10548    (use (match_operand:SI 1 "register_operand" ""))
10549    (use (match_operand:QI 2 "register_operand" ""))]
10550   ""
10551 {
10552   rtx label = gen_label_rtx ();
10553   rtx tmp;
10554
10555   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10556
10557   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10558   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10559   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10560                               gen_rtx_LABEL_REF (VOIDmode, label),
10561                               pc_rtx);
10562   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10563   JUMP_LABEL (tmp) = label;
10564
10565   emit_move_insn (operands[0], operands[1]);
10566   ix86_expand_clear (operands[1]);
10567
10568   emit_label (label);
10569   LABEL_NUSES (label) = 1;
10570
10571   DONE;
10572 })
10573
10574 (define_expand "ashlsi3"
10575   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10576         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10577                    (match_operand:QI 2 "nonmemory_operand" "")))
10578    (clobber (reg:CC FLAGS_REG))]
10579   ""
10580   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10581
10582 (define_insn "*ashlsi3_1"
10583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10584         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10585                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10588 {
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       gcc_assert (operands[2] == const1_rtx);
10593       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10594       return "add{l}\t{%0, %0|%0, %0}";
10595
10596     case TYPE_LEA:
10597       return "#";
10598
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{l}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{l}\t%0";
10605       else
10606         return "sal{l}\t{%2, %0|%0, %2}";
10607     }
10608 }
10609   [(set (attr "type")
10610      (cond [(eq_attr "alternative" "1")
10611               (const_string "lea")
10612             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                           (const_int 0))
10614                       (match_operand 0 "register_operand" ""))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "SI")])
10620
10621 ;; Convert lea to the lea pattern to avoid flags dependency.
10622 (define_split
10623   [(set (match_operand 0 "register_operand" "")
10624         (ashift (match_operand 1 "index_register_operand" "")
10625                 (match_operand:QI 2 "const_int_operand" "")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "reload_completed
10628    && true_regnum (operands[0]) != true_regnum (operands[1])
10629    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10630   [(const_int 0)]
10631 {
10632   rtx pat;
10633   enum machine_mode mode = GET_MODE (operands[0]);
10634
10635   if (GET_MODE_SIZE (mode) < 4)
10636     operands[0] = gen_lowpart (SImode, operands[0]);
10637   if (mode != Pmode)
10638     operands[1] = gen_lowpart (Pmode, operands[1]);
10639   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10640
10641   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10642   if (Pmode != SImode)
10643     pat = gen_rtx_SUBREG (SImode, pat, 0);
10644   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10645   DONE;
10646 })
10647
10648 ;; Rare case of shifting RSP is handled by generating move and shift
10649 (define_split
10650   [(set (match_operand 0 "register_operand" "")
10651         (ashift (match_operand 1 "register_operand" "")
10652                 (match_operand:QI 2 "const_int_operand" "")))
10653    (clobber (reg:CC FLAGS_REG))]
10654   "reload_completed
10655    && true_regnum (operands[0]) != true_regnum (operands[1])"
10656   [(const_int 0)]
10657 {
10658   rtx pat, clob;
10659   emit_move_insn (operands[0], operands[1]);
10660   pat = gen_rtx_SET (VOIDmode, operands[0],
10661                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10662                                      operands[0], operands[2]));
10663   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10664   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10665   DONE;
10666 })
10667
10668 (define_insn "*ashlsi3_1_zext"
10669   [(set (match_operand:DI 0 "register_operand" "=r,r")
10670         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10671                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10672    (clobber (reg:CC FLAGS_REG))]
10673   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10674 {
10675   switch (get_attr_type (insn))
10676     {
10677     case TYPE_ALU:
10678       gcc_assert (operands[2] == const1_rtx);
10679       return "add{l}\t{%k0, %k0|%k0, %k0}";
10680
10681     case TYPE_LEA:
10682       return "#";
10683
10684     default:
10685       if (REG_P (operands[2]))
10686         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10687       else if (operands[2] == const1_rtx
10688                && (TARGET_SHIFT1 || optimize_size))
10689         return "sal{l}\t%k0";
10690       else
10691         return "sal{l}\t{%2, %k0|%k0, %2}";
10692     }
10693 }
10694   [(set (attr "type")
10695      (cond [(eq_attr "alternative" "1")
10696               (const_string "lea")
10697             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10698                      (const_int 0))
10699                  (match_operand 2 "const1_operand" ""))
10700               (const_string "alu")
10701            ]
10702            (const_string "ishift")))
10703    (set_attr "mode" "SI")])
10704
10705 ;; Convert lea to the lea pattern to avoid flags dependency.
10706 (define_split
10707   [(set (match_operand:DI 0 "register_operand" "")
10708         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10709                                 (match_operand:QI 2 "const_int_operand" ""))))
10710    (clobber (reg:CC FLAGS_REG))]
10711   "TARGET_64BIT && reload_completed
10712    && true_regnum (operands[0]) != true_regnum (operands[1])"
10713   [(set (match_dup 0) (zero_extend:DI
10714                         (subreg:SI (mult:SI (match_dup 1)
10715                                             (match_dup 2)) 0)))]
10716 {
10717   operands[1] = gen_lowpart (Pmode, operands[1]);
10718   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10719 })
10720
10721 ;; This pattern can't accept a variable shift count, since shifts by
10722 ;; zero don't affect the flags.  We assume that shifts by constant
10723 ;; zero are optimized away.
10724 (define_insn "*ashlsi3_cmp"
10725   [(set (reg FLAGS_REG)
10726         (compare
10727           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10728                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10729           (const_int 0)))
10730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10731         (ashift:SI (match_dup 1) (match_dup 2)))]
10732   "ix86_match_ccmode (insn, CCGOCmode)
10733    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10734    && (optimize_size
10735        || !TARGET_PARTIAL_FLAG_REG_STALL
10736        || (operands[2] == const1_rtx
10737            && (TARGET_SHIFT1
10738                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10739 {
10740   switch (get_attr_type (insn))
10741     {
10742     case TYPE_ALU:
10743       gcc_assert (operands[2] == const1_rtx);
10744       return "add{l}\t{%0, %0|%0, %0}";
10745
10746     default:
10747       if (REG_P (operands[2]))
10748         return "sal{l}\t{%b2, %0|%0, %b2}";
10749       else if (operands[2] == const1_rtx
10750                && (TARGET_SHIFT1 || optimize_size))
10751         return "sal{l}\t%0";
10752       else
10753         return "sal{l}\t{%2, %0|%0, %2}";
10754     }
10755 }
10756   [(set (attr "type")
10757      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10758                           (const_int 0))
10759                       (match_operand 0 "register_operand" ""))
10760                  (match_operand 2 "const1_operand" ""))
10761               (const_string "alu")
10762            ]
10763            (const_string "ishift")))
10764    (set_attr "mode" "SI")])
10765
10766 (define_insn "*ashlsi3_cconly"
10767   [(set (reg FLAGS_REG)
10768         (compare
10769           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10770                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10771           (const_int 0)))
10772    (clobber (match_scratch:SI 0 "=r"))]
10773   "ix86_match_ccmode (insn, CCGOCmode)
10774    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10775    && (optimize_size
10776        || !TARGET_PARTIAL_FLAG_REG_STALL
10777        || (operands[2] == const1_rtx
10778            && (TARGET_SHIFT1
10779                || TARGET_DOUBLE_WITH_ADD)))"
10780 {
10781   switch (get_attr_type (insn))
10782     {
10783     case TYPE_ALU:
10784       gcc_assert (operands[2] == const1_rtx);
10785       return "add{l}\t{%0, %0|%0, %0}";
10786
10787     default:
10788       if (REG_P (operands[2]))
10789         return "sal{l}\t{%b2, %0|%0, %b2}";
10790       else if (operands[2] == const1_rtx
10791                && (TARGET_SHIFT1 || optimize_size))
10792         return "sal{l}\t%0";
10793       else
10794         return "sal{l}\t{%2, %0|%0, %2}";
10795     }
10796 }
10797   [(set (attr "type")
10798      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10799                           (const_int 0))
10800                       (match_operand 0 "register_operand" ""))
10801                  (match_operand 2 "const1_operand" ""))
10802               (const_string "alu")
10803            ]
10804            (const_string "ishift")))
10805    (set_attr "mode" "SI")])
10806
10807 (define_insn "*ashlsi3_cmp_zext"
10808   [(set (reg FLAGS_REG)
10809         (compare
10810           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10811                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10812           (const_int 0)))
10813    (set (match_operand:DI 0 "register_operand" "=r")
10814         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10815   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10816    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10817    && (optimize_size
10818        || !TARGET_PARTIAL_FLAG_REG_STALL
10819        || (operands[2] == const1_rtx
10820            && (TARGET_SHIFT1
10821                || TARGET_DOUBLE_WITH_ADD)))"
10822 {
10823   switch (get_attr_type (insn))
10824     {
10825     case TYPE_ALU:
10826       gcc_assert (operands[2] == const1_rtx);
10827       return "add{l}\t{%k0, %k0|%k0, %k0}";
10828
10829     default:
10830       if (REG_P (operands[2]))
10831         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10832       else if (operands[2] == const1_rtx
10833                && (TARGET_SHIFT1 || optimize_size))
10834         return "sal{l}\t%k0";
10835       else
10836         return "sal{l}\t{%2, %k0|%k0, %2}";
10837     }
10838 }
10839   [(set (attr "type")
10840      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10841                      (const_int 0))
10842                  (match_operand 2 "const1_operand" ""))
10843               (const_string "alu")
10844            ]
10845            (const_string "ishift")))
10846    (set_attr "mode" "SI")])
10847
10848 (define_expand "ashlhi3"
10849   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10850         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10851                    (match_operand:QI 2 "nonmemory_operand" "")))
10852    (clobber (reg:CC FLAGS_REG))]
10853   "TARGET_HIMODE_MATH"
10854   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10855
10856 (define_insn "*ashlhi3_1_lea"
10857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10858         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10859                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "!TARGET_PARTIAL_REG_STALL
10862    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10863 {
10864   switch (get_attr_type (insn))
10865     {
10866     case TYPE_LEA:
10867       return "#";
10868     case TYPE_ALU:
10869       gcc_assert (operands[2] == const1_rtx);
10870       return "add{w}\t{%0, %0|%0, %0}";
10871
10872     default:
10873       if (REG_P (operands[2]))
10874         return "sal{w}\t{%b2, %0|%0, %b2}";
10875       else if (operands[2] == const1_rtx
10876                && (TARGET_SHIFT1 || optimize_size))
10877         return "sal{w}\t%0";
10878       else
10879         return "sal{w}\t{%2, %0|%0, %2}";
10880     }
10881 }
10882   [(set (attr "type")
10883      (cond [(eq_attr "alternative" "1")
10884               (const_string "lea")
10885             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886                           (const_int 0))
10887                       (match_operand 0 "register_operand" ""))
10888                  (match_operand 2 "const1_operand" ""))
10889               (const_string "alu")
10890            ]
10891            (const_string "ishift")))
10892    (set_attr "mode" "HI,SI")])
10893
10894 (define_insn "*ashlhi3_1"
10895   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10896         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10897                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_PARTIAL_REG_STALL
10900    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10901 {
10902   switch (get_attr_type (insn))
10903     {
10904     case TYPE_ALU:
10905       gcc_assert (operands[2] == const1_rtx);
10906       return "add{w}\t{%0, %0|%0, %0}";
10907
10908     default:
10909       if (REG_P (operands[2]))
10910         return "sal{w}\t{%b2, %0|%0, %b2}";
10911       else if (operands[2] == const1_rtx
10912                && (TARGET_SHIFT1 || optimize_size))
10913         return "sal{w}\t%0";
10914       else
10915         return "sal{w}\t{%2, %0|%0, %2}";
10916     }
10917 }
10918   [(set (attr "type")
10919      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10920                           (const_int 0))
10921                       (match_operand 0 "register_operand" ""))
10922                  (match_operand 2 "const1_operand" ""))
10923               (const_string "alu")
10924            ]
10925            (const_string "ishift")))
10926    (set_attr "mode" "HI")])
10927
10928 ;; This pattern can't accept a variable shift count, since shifts by
10929 ;; zero don't affect the flags.  We assume that shifts by constant
10930 ;; zero are optimized away.
10931 (define_insn "*ashlhi3_cmp"
10932   [(set (reg FLAGS_REG)
10933         (compare
10934           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10935                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10936           (const_int 0)))
10937    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10938         (ashift:HI (match_dup 1) (match_dup 2)))]
10939   "ix86_match_ccmode (insn, CCGOCmode)
10940    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10941    && (optimize_size
10942        || !TARGET_PARTIAL_FLAG_REG_STALL
10943        || (operands[2] == const1_rtx
10944            && (TARGET_SHIFT1
10945                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10946 {
10947   switch (get_attr_type (insn))
10948     {
10949     case TYPE_ALU:
10950       gcc_assert (operands[2] == const1_rtx);
10951       return "add{w}\t{%0, %0|%0, %0}";
10952
10953     default:
10954       if (REG_P (operands[2]))
10955         return "sal{w}\t{%b2, %0|%0, %b2}";
10956       else if (operands[2] == const1_rtx
10957                && (TARGET_SHIFT1 || optimize_size))
10958         return "sal{w}\t%0";
10959       else
10960         return "sal{w}\t{%2, %0|%0, %2}";
10961     }
10962 }
10963   [(set (attr "type")
10964      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10965                           (const_int 0))
10966                       (match_operand 0 "register_operand" ""))
10967                  (match_operand 2 "const1_operand" ""))
10968               (const_string "alu")
10969            ]
10970            (const_string "ishift")))
10971    (set_attr "mode" "HI")])
10972
10973 (define_insn "*ashlhi3_cconly"
10974   [(set (reg FLAGS_REG)
10975         (compare
10976           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10977                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10978           (const_int 0)))
10979    (clobber (match_scratch:HI 0 "=r"))]
10980   "ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10982    && (optimize_size
10983        || !TARGET_PARTIAL_FLAG_REG_STALL
10984        || (operands[2] == const1_rtx
10985            && (TARGET_SHIFT1
10986                || TARGET_DOUBLE_WITH_ADD)))"
10987 {
10988   switch (get_attr_type (insn))
10989     {
10990     case TYPE_ALU:
10991       gcc_assert (operands[2] == const1_rtx);
10992       return "add{w}\t{%0, %0|%0, %0}";
10993
10994     default:
10995       if (REG_P (operands[2]))
10996         return "sal{w}\t{%b2, %0|%0, %b2}";
10997       else if (operands[2] == const1_rtx
10998                && (TARGET_SHIFT1 || optimize_size))
10999         return "sal{w}\t%0";
11000       else
11001         return "sal{w}\t{%2, %0|%0, %2}";
11002     }
11003 }
11004   [(set (attr "type")
11005      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11006                           (const_int 0))
11007                       (match_operand 0 "register_operand" ""))
11008                  (match_operand 2 "const1_operand" ""))
11009               (const_string "alu")
11010            ]
11011            (const_string "ishift")))
11012    (set_attr "mode" "HI")])
11013
11014 (define_expand "ashlqi3"
11015   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11016         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11017                    (match_operand:QI 2 "nonmemory_operand" "")))
11018    (clobber (reg:CC FLAGS_REG))]
11019   "TARGET_QIMODE_MATH"
11020   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11021
11022 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11023
11024 (define_insn "*ashlqi3_1_lea"
11025   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11026         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11027                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "!TARGET_PARTIAL_REG_STALL
11030    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11031 {
11032   switch (get_attr_type (insn))
11033     {
11034     case TYPE_LEA:
11035       return "#";
11036     case TYPE_ALU:
11037       gcc_assert (operands[2] == const1_rtx);
11038       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11039         return "add{l}\t{%k0, %k0|%k0, %k0}";
11040       else
11041         return "add{b}\t{%0, %0|%0, %0}";
11042
11043     default:
11044       if (REG_P (operands[2]))
11045         {
11046           if (get_attr_mode (insn) == MODE_SI)
11047             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11048           else
11049             return "sal{b}\t{%b2, %0|%0, %b2}";
11050         }
11051       else if (operands[2] == const1_rtx
11052                && (TARGET_SHIFT1 || optimize_size))
11053         {
11054           if (get_attr_mode (insn) == MODE_SI)
11055             return "sal{l}\t%0";
11056           else
11057             return "sal{b}\t%0";
11058         }
11059       else
11060         {
11061           if (get_attr_mode (insn) == MODE_SI)
11062             return "sal{l}\t{%2, %k0|%k0, %2}";
11063           else
11064             return "sal{b}\t{%2, %0|%0, %2}";
11065         }
11066     }
11067 }
11068   [(set (attr "type")
11069      (cond [(eq_attr "alternative" "2")
11070               (const_string "lea")
11071             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11072                           (const_int 0))
11073                       (match_operand 0 "register_operand" ""))
11074                  (match_operand 2 "const1_operand" ""))
11075               (const_string "alu")
11076            ]
11077            (const_string "ishift")))
11078    (set_attr "mode" "QI,SI,SI")])
11079
11080 (define_insn "*ashlqi3_1"
11081   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11082         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11083                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11084    (clobber (reg:CC FLAGS_REG))]
11085   "TARGET_PARTIAL_REG_STALL
11086    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11087 {
11088   switch (get_attr_type (insn))
11089     {
11090     case TYPE_ALU:
11091       gcc_assert (operands[2] == const1_rtx);
11092       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11093         return "add{l}\t{%k0, %k0|%k0, %k0}";
11094       else
11095         return "add{b}\t{%0, %0|%0, %0}";
11096
11097     default:
11098       if (REG_P (operands[2]))
11099         {
11100           if (get_attr_mode (insn) == MODE_SI)
11101             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11102           else
11103             return "sal{b}\t{%b2, %0|%0, %b2}";
11104         }
11105       else if (operands[2] == const1_rtx
11106                && (TARGET_SHIFT1 || optimize_size))
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t%0";
11110           else
11111             return "sal{b}\t%0";
11112         }
11113       else
11114         {
11115           if (get_attr_mode (insn) == MODE_SI)
11116             return "sal{l}\t{%2, %k0|%k0, %2}";
11117           else
11118             return "sal{b}\t{%2, %0|%0, %2}";
11119         }
11120     }
11121 }
11122   [(set (attr "type")
11123      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                           (const_int 0))
11125                       (match_operand 0 "register_operand" ""))
11126                  (match_operand 2 "const1_operand" ""))
11127               (const_string "alu")
11128            ]
11129            (const_string "ishift")))
11130    (set_attr "mode" "QI,SI")])
11131
11132 ;; This pattern can't accept a variable shift count, since shifts by
11133 ;; zero don't affect the flags.  We assume that shifts by constant
11134 ;; zero are optimized away.
11135 (define_insn "*ashlqi3_cmp"
11136   [(set (reg FLAGS_REG)
11137         (compare
11138           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11139                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11140           (const_int 0)))
11141    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11142         (ashift:QI (match_dup 1) (match_dup 2)))]
11143   "ix86_match_ccmode (insn, CCGOCmode)
11144    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11145    && (optimize_size
11146        || !TARGET_PARTIAL_FLAG_REG_STALL
11147        || (operands[2] == const1_rtx
11148            && (TARGET_SHIFT1
11149                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11150 {
11151   switch (get_attr_type (insn))
11152     {
11153     case TYPE_ALU:
11154       gcc_assert (operands[2] == const1_rtx);
11155       return "add{b}\t{%0, %0|%0, %0}";
11156
11157     default:
11158       if (REG_P (operands[2]))
11159         return "sal{b}\t{%b2, %0|%0, %b2}";
11160       else if (operands[2] == const1_rtx
11161                && (TARGET_SHIFT1 || optimize_size))
11162         return "sal{b}\t%0";
11163       else
11164         return "sal{b}\t{%2, %0|%0, %2}";
11165     }
11166 }
11167   [(set (attr "type")
11168      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169                           (const_int 0))
11170                       (match_operand 0 "register_operand" ""))
11171                  (match_operand 2 "const1_operand" ""))
11172               (const_string "alu")
11173            ]
11174            (const_string "ishift")))
11175    (set_attr "mode" "QI")])
11176
11177 (define_insn "*ashlqi3_cconly"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11181                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11182           (const_int 0)))
11183    (clobber (match_scratch:QI 0 "=q"))]
11184   "ix86_match_ccmode (insn, CCGOCmode)
11185    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11186    && (optimize_size
11187        || !TARGET_PARTIAL_FLAG_REG_STALL
11188        || (operands[2] == const1_rtx
11189            && (TARGET_SHIFT1
11190                || TARGET_DOUBLE_WITH_ADD)))"
11191 {
11192   switch (get_attr_type (insn))
11193     {
11194     case TYPE_ALU:
11195       gcc_assert (operands[2] == const1_rtx);
11196       return "add{b}\t{%0, %0|%0, %0}";
11197
11198     default:
11199       if (REG_P (operands[2]))
11200         return "sal{b}\t{%b2, %0|%0, %b2}";
11201       else if (operands[2] == const1_rtx
11202                && (TARGET_SHIFT1 || optimize_size))
11203         return "sal{b}\t%0";
11204       else
11205         return "sal{b}\t{%2, %0|%0, %2}";
11206     }
11207 }
11208   [(set (attr "type")
11209      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11210                           (const_int 0))
11211                       (match_operand 0 "register_operand" ""))
11212                  (match_operand 2 "const1_operand" ""))
11213               (const_string "alu")
11214            ]
11215            (const_string "ishift")))
11216    (set_attr "mode" "QI")])
11217
11218 ;; See comment above `ashldi3' about how this works.
11219
11220 (define_expand "ashrti3"
11221   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11222                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11223                                 (match_operand:QI 2 "nonmemory_operand" "")))
11224               (clobber (reg:CC FLAGS_REG))])]
11225   "TARGET_64BIT"
11226 {
11227   if (! immediate_operand (operands[2], QImode))
11228     {
11229       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11230       DONE;
11231     }
11232   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11233   DONE;
11234 })
11235
11236 (define_insn "ashrti3_1"
11237   [(set (match_operand:TI 0 "register_operand" "=r")
11238         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11239                      (match_operand:QI 2 "register_operand" "c")))
11240    (clobber (match_scratch:DI 3 "=&r"))
11241    (clobber (reg:CC FLAGS_REG))]
11242   "TARGET_64BIT"
11243   "#"
11244   [(set_attr "type" "multi")])
11245
11246 (define_insn "*ashrti3_2"
11247   [(set (match_operand:TI 0 "register_operand" "=r")
11248         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11249                      (match_operand:QI 2 "immediate_operand" "O")))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "TARGET_64BIT"
11252   "#"
11253   [(set_attr "type" "multi")])
11254
11255 (define_split
11256   [(set (match_operand:TI 0 "register_operand" "")
11257         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11258                      (match_operand:QI 2 "register_operand" "")))
11259    (clobber (match_scratch:DI 3 ""))
11260    (clobber (reg:CC FLAGS_REG))]
11261   "TARGET_64BIT && reload_completed"
11262   [(const_int 0)]
11263   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11264
11265 (define_split
11266   [(set (match_operand:TI 0 "register_operand" "")
11267         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11268                      (match_operand:QI 2 "immediate_operand" "")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "TARGET_64BIT && reload_completed"
11271   [(const_int 0)]
11272   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11273
11274 (define_insn "x86_64_shrd"
11275   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11276         (ior:DI (ashiftrt:DI (match_dup 0)
11277                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11278                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11279                   (minus:QI (const_int 64) (match_dup 2)))))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "TARGET_64BIT"
11282   "@
11283    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11284    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11285   [(set_attr "type" "ishift")
11286    (set_attr "prefix_0f" "1")
11287    (set_attr "mode" "DI")
11288    (set_attr "athlon_decode" "vector")])
11289
11290 (define_expand "ashrdi3"
11291   [(set (match_operand:DI 0 "shiftdi_operand" "")
11292         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))]
11294   ""
11295   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11296
11297 (define_insn "*ashrdi3_63_rex64"
11298   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11299         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11300                      (match_operand:DI 2 "const_int_operand" "i,i")))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_64BIT && INTVAL (operands[2]) == 63
11303    && (TARGET_USE_CLTD || optimize_size)
11304    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11305   "@
11306    {cqto|cqo}
11307    sar{q}\t{%2, %0|%0, %2}"
11308   [(set_attr "type" "imovx,ishift")
11309    (set_attr "prefix_0f" "0,*")
11310    (set_attr "length_immediate" "0,*")
11311    (set_attr "modrm" "0,1")
11312    (set_attr "mode" "DI")])
11313
11314 (define_insn "*ashrdi3_1_one_bit_rex64"
11315   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11316         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const1_operand" "")))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{q}\t%0"
11322   [(set_attr "type" "ishift")
11323    (set (attr "length") 
11324      (if_then_else (match_operand:DI 0 "register_operand" "") 
11325         (const_string "2")
11326         (const_string "*")))])
11327
11328 (define_insn "*ashrdi3_1_rex64"
11329   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11330         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11331                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11334   "@
11335    sar{q}\t{%2, %0|%0, %2}
11336    sar{q}\t{%b2, %0|%0, %b2}"
11337   [(set_attr "type" "ishift")
11338    (set_attr "mode" "DI")])
11339
11340 ;; This pattern can't accept a variable shift count, since shifts by
11341 ;; zero don't affect the flags.  We assume that shifts by constant
11342 ;; zero are optimized away.
11343 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11344   [(set (reg FLAGS_REG)
11345         (compare
11346           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347                        (match_operand:QI 2 "const1_operand" ""))
11348           (const_int 0)))
11349    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11350         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11351   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11352    && (TARGET_SHIFT1 || optimize_size)
11353    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354   "sar{q}\t%0"
11355   [(set_attr "type" "ishift")
11356    (set (attr "length") 
11357      (if_then_else (match_operand:DI 0 "register_operand" "") 
11358         (const_string "2")
11359         (const_string "*")))])
11360
11361 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365                        (match_operand:QI 2 "const1_operand" ""))
11366           (const_int 0)))
11367    (clobber (match_scratch:DI 0 "=r"))]
11368   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11369    && (TARGET_SHIFT1 || optimize_size)
11370    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11371   "sar{q}\t%0"
11372   [(set_attr "type" "ishift")
11373    (set_attr "length" "2")])
11374
11375 ;; This pattern can't accept a variable shift count, since shifts by
11376 ;; zero don't affect the flags.  We assume that shifts by constant
11377 ;; zero are optimized away.
11378 (define_insn "*ashrdi3_cmp_rex64"
11379   [(set (reg FLAGS_REG)
11380         (compare
11381           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11382                        (match_operand:QI 2 "const_int_operand" "n"))
11383           (const_int 0)))
11384    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11386   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11387    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11388    && (optimize_size
11389        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11390   "sar{q}\t{%2, %0|%0, %2}"
11391   [(set_attr "type" "ishift")
11392    (set_attr "mode" "DI")])
11393
11394 (define_insn "*ashrdi3_cconly_rex64"
11395   [(set (reg FLAGS_REG)
11396         (compare
11397           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11398                        (match_operand:QI 2 "const_int_operand" "n"))
11399           (const_int 0)))
11400    (clobber (match_scratch:DI 0 "=r"))]
11401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11403    && (optimize_size
11404        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11405   "sar{q}\t{%2, %0|%0, %2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "DI")])
11408
11409 (define_insn "*ashrdi3_1"
11410   [(set (match_operand:DI 0 "register_operand" "=r")
11411         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11412                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "!TARGET_64BIT"
11415   "#"
11416   [(set_attr "type" "multi")])
11417
11418 ;; By default we don't ask for a scratch register, because when DImode
11419 ;; values are manipulated, registers are already at a premium.  But if
11420 ;; we have one handy, we won't turn it away.
11421 (define_peephole2
11422   [(match_scratch:SI 3 "r")
11423    (parallel [(set (match_operand:DI 0 "register_operand" "")
11424                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11425                                 (match_operand:QI 2 "nonmemory_operand" "")))
11426               (clobber (reg:CC FLAGS_REG))])
11427    (match_dup 3)]
11428   "!TARGET_64BIT && TARGET_CMOVE"
11429   [(const_int 0)]
11430   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11431
11432 (define_split
11433   [(set (match_operand:DI 0 "register_operand" "")
11434         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11435                      (match_operand:QI 2 "nonmemory_operand" "")))
11436    (clobber (reg:CC FLAGS_REG))]
11437   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11438                      ? flow2_completed : reload_completed)"
11439   [(const_int 0)]
11440   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11441
11442 (define_insn "x86_shrd_1"
11443   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11444         (ior:SI (ashiftrt:SI (match_dup 0)
11445                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11446                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11447                   (minus:QI (const_int 32) (match_dup 2)))))
11448    (clobber (reg:CC FLAGS_REG))]
11449   ""
11450   "@
11451    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11452    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11453   [(set_attr "type" "ishift")
11454    (set_attr "prefix_0f" "1")
11455    (set_attr "pent_pair" "np")
11456    (set_attr "mode" "SI")])
11457
11458 (define_expand "x86_shift_adj_3"
11459   [(use (match_operand:SI 0 "register_operand" ""))
11460    (use (match_operand:SI 1 "register_operand" ""))
11461    (use (match_operand:QI 2 "register_operand" ""))]
11462   ""
11463 {
11464   rtx label = gen_label_rtx ();
11465   rtx tmp;
11466
11467   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11468
11469   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11470   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11471   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11472                               gen_rtx_LABEL_REF (VOIDmode, label),
11473                               pc_rtx);
11474   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11475   JUMP_LABEL (tmp) = label;
11476
11477   emit_move_insn (operands[0], operands[1]);
11478   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11479
11480   emit_label (label);
11481   LABEL_NUSES (label) = 1;
11482
11483   DONE;
11484 })
11485
11486 (define_insn "ashrsi3_31"
11487   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11488         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11489                      (match_operand:SI 2 "const_int_operand" "i,i")))
11490    (clobber (reg:CC FLAGS_REG))]
11491   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11492    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11493   "@
11494    {cltd|cdq}
11495    sar{l}\t{%2, %0|%0, %2}"
11496   [(set_attr "type" "imovx,ishift")
11497    (set_attr "prefix_0f" "0,*")
11498    (set_attr "length_immediate" "0,*")
11499    (set_attr "modrm" "0,1")
11500    (set_attr "mode" "SI")])
11501
11502 (define_insn "*ashrsi3_31_zext"
11503   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11504         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11505                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11508    && INTVAL (operands[2]) == 31
11509    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11510   "@
11511    {cltd|cdq}
11512    sar{l}\t{%2, %k0|%k0, %2}"
11513   [(set_attr "type" "imovx,ishift")
11514    (set_attr "prefix_0f" "0,*")
11515    (set_attr "length_immediate" "0,*")
11516    (set_attr "modrm" "0,1")
11517    (set_attr "mode" "SI")])
11518
11519 (define_expand "ashrsi3"
11520   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11521         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11522                      (match_operand:QI 2 "nonmemory_operand" "")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   ""
11525   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11526
11527 (define_insn "*ashrsi3_1_one_bit"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11530                      (match_operand:QI 2 "const1_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11533    && (TARGET_SHIFT1 || optimize_size)"
11534   "sar{l}\t%0"
11535   [(set_attr "type" "ishift")
11536    (set (attr "length") 
11537      (if_then_else (match_operand:SI 0 "register_operand" "") 
11538         (const_string "2")
11539         (const_string "*")))])
11540
11541 (define_insn "*ashrsi3_1_one_bit_zext"
11542   [(set (match_operand:DI 0 "register_operand" "=r")
11543         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11544                                      (match_operand:QI 2 "const1_operand" ""))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11547    && (TARGET_SHIFT1 || optimize_size)"
11548   "sar{l}\t%k0"
11549   [(set_attr "type" "ishift")
11550    (set_attr "length" "2")])
11551
11552 (define_insn "*ashrsi3_1"
11553   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11554         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    sar{l}\t{%2, %0|%0, %2}
11560    sar{l}\t{%b2, %0|%0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "SI")])
11563
11564 (define_insn "*ashrsi3_1_zext"
11565   [(set (match_operand:DI 0 "register_operand" "=r,r")
11566         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11567                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570   "@
11571    sar{l}\t{%2, %k0|%k0, %2}
11572    sar{l}\t{%b2, %k0|%k0, %b2}"
11573   [(set_attr "type" "ishift")
11574    (set_attr "mode" "SI")])
11575
11576 ;; This pattern can't accept a variable shift count, since shifts by
11577 ;; zero don't affect the flags.  We assume that shifts by constant
11578 ;; zero are optimized away.
11579 (define_insn "*ashrsi3_one_bit_cmp"
11580   [(set (reg FLAGS_REG)
11581         (compare
11582           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11583                        (match_operand:QI 2 "const1_operand" ""))
11584           (const_int 0)))
11585    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11586         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11587   "ix86_match_ccmode (insn, CCGOCmode)
11588    && (TARGET_SHIFT1 || optimize_size)
11589    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11590   "sar{l}\t%0"
11591   [(set_attr "type" "ishift")
11592    (set (attr "length") 
11593      (if_then_else (match_operand:SI 0 "register_operand" "") 
11594         (const_string "2")
11595         (const_string "*")))])
11596
11597 (define_insn "*ashrsi3_one_bit_cconly"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601                        (match_operand:QI 2 "const1_operand" ""))
11602           (const_int 0)))
11603    (clobber (match_scratch:SI 0 "=r"))]
11604   "ix86_match_ccmode (insn, CCGOCmode)
11605    && (TARGET_SHIFT1 || optimize_size)
11606    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607   "sar{l}\t%0"
11608   [(set_attr "type" "ishift")
11609    (set_attr "length" "2")])
11610
11611 (define_insn "*ashrsi3_one_bit_cmp_zext"
11612   [(set (reg FLAGS_REG)
11613         (compare
11614           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11615                        (match_operand:QI 2 "const1_operand" ""))
11616           (const_int 0)))
11617    (set (match_operand:DI 0 "register_operand" "=r")
11618         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11619   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11620    && (TARGET_SHIFT1 || optimize_size)
11621    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11622   "sar{l}\t%k0"
11623   [(set_attr "type" "ishift")
11624    (set_attr "length" "2")])
11625
11626 ;; This pattern can't accept a variable shift count, since shifts by
11627 ;; zero don't affect the flags.  We assume that shifts by constant
11628 ;; zero are optimized away.
11629 (define_insn "*ashrsi3_cmp"
11630   [(set (reg FLAGS_REG)
11631         (compare
11632           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11633                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11634           (const_int 0)))
11635    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11636         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11637   "ix86_match_ccmode (insn, CCGOCmode)
11638    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11639    && (optimize_size
11640        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11641   "sar{l}\t{%2, %0|%0, %2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "SI")])
11644
11645 (define_insn "*ashrsi3_cconly"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11650           (const_int 0)))
11651    (clobber (match_scratch:SI 0 "=r"))]
11652   "ix86_match_ccmode (insn, CCGOCmode)
11653    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11654    && (optimize_size
11655        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11656   "sar{l}\t{%2, %0|%0, %2}"
11657   [(set_attr "type" "ishift")
11658    (set_attr "mode" "SI")])
11659
11660 (define_insn "*ashrsi3_cmp_zext"
11661   [(set (reg FLAGS_REG)
11662         (compare
11663           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11665           (const_int 0)))
11666    (set (match_operand:DI 0 "register_operand" "=r")
11667         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11669    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11670    && (optimize_size
11671        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11672   "sar{l}\t{%2, %k0|%k0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "SI")])
11675
11676 (define_expand "ashrhi3"
11677   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11678         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11679                      (match_operand:QI 2 "nonmemory_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "TARGET_HIMODE_MATH"
11682   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11683
11684 (define_insn "*ashrhi3_1_one_bit"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11687                      (match_operand:QI 2 "const1_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11690    && (TARGET_SHIFT1 || optimize_size)"
11691   "sar{w}\t%0"
11692   [(set_attr "type" "ishift")
11693    (set (attr "length") 
11694      (if_then_else (match_operand 0 "register_operand" "") 
11695         (const_string "2")
11696         (const_string "*")))])
11697
11698 (define_insn "*ashrhi3_1"
11699   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11700         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11701                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11704   "@
11705    sar{w}\t{%2, %0|%0, %2}
11706    sar{w}\t{%b2, %0|%0, %b2}"
11707   [(set_attr "type" "ishift")
11708    (set_attr "mode" "HI")])
11709
11710 ;; This pattern can't accept a variable shift count, since shifts by
11711 ;; zero don't affect the flags.  We assume that shifts by constant
11712 ;; zero are optimized away.
11713 (define_insn "*ashrhi3_one_bit_cmp"
11714   [(set (reg FLAGS_REG)
11715         (compare
11716           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717                        (match_operand:QI 2 "const1_operand" ""))
11718           (const_int 0)))
11719    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11721   "ix86_match_ccmode (insn, CCGOCmode)
11722    && (TARGET_SHIFT1 || optimize_size)
11723    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11724   "sar{w}\t%0"
11725   [(set_attr "type" "ishift")
11726    (set (attr "length") 
11727      (if_then_else (match_operand 0 "register_operand" "") 
11728         (const_string "2")
11729         (const_string "*")))])
11730
11731 (define_insn "*ashrhi3_one_bit_cconly"
11732   [(set (reg FLAGS_REG)
11733         (compare
11734           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735                        (match_operand:QI 2 "const1_operand" ""))
11736           (const_int 0)))
11737    (clobber (match_scratch:HI 0 "=r"))]
11738   "ix86_match_ccmode (insn, CCGOCmode)
11739    && (TARGET_SHIFT1 || optimize_size)
11740    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11741   "sar{w}\t%0"
11742   [(set_attr "type" "ishift")
11743    (set_attr "length" "2")])
11744
11745 ;; This pattern can't accept a variable shift count, since shifts by
11746 ;; zero don't affect the flags.  We assume that shifts by constant
11747 ;; zero are optimized away.
11748 (define_insn "*ashrhi3_cmp"
11749   [(set (reg FLAGS_REG)
11750         (compare
11751           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11752                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11753           (const_int 0)))
11754    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11755         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11756   "ix86_match_ccmode (insn, CCGOCmode)
11757    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11758    && (optimize_size
11759        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11760   "sar{w}\t{%2, %0|%0, %2}"
11761   [(set_attr "type" "ishift")
11762    (set_attr "mode" "HI")])
11763
11764 (define_insn "*ashrhi3_cconly"
11765   [(set (reg FLAGS_REG)
11766         (compare
11767           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11769           (const_int 0)))
11770    (clobber (match_scratch:HI 0 "=r"))]
11771   "ix86_match_ccmode (insn, CCGOCmode)
11772    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11773    && (optimize_size
11774        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11775   "sar{w}\t{%2, %0|%0, %2}"
11776   [(set_attr "type" "ishift")
11777    (set_attr "mode" "HI")])
11778
11779 (define_expand "ashrqi3"
11780   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11781         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11782                      (match_operand:QI 2 "nonmemory_operand" "")))
11783    (clobber (reg:CC FLAGS_REG))]
11784   "TARGET_QIMODE_MATH"
11785   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11786
11787 (define_insn "*ashrqi3_1_one_bit"
11788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11789         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11790                      (match_operand:QI 2 "const1_operand" "")))
11791    (clobber (reg:CC FLAGS_REG))]
11792   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11793    && (TARGET_SHIFT1 || optimize_size)"
11794   "sar{b}\t%0"
11795   [(set_attr "type" "ishift")
11796    (set (attr "length") 
11797      (if_then_else (match_operand 0 "register_operand" "") 
11798         (const_string "2")
11799         (const_string "*")))])
11800
11801 (define_insn "*ashrqi3_1_one_bit_slp"
11802   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11803         (ashiftrt:QI (match_dup 0)
11804                      (match_operand:QI 1 "const1_operand" "")))
11805    (clobber (reg:CC FLAGS_REG))]
11806   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11807    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11808    && (TARGET_SHIFT1 || optimize_size)"
11809   "sar{b}\t%0"
11810   [(set_attr "type" "ishift1")
11811    (set (attr "length") 
11812      (if_then_else (match_operand 0 "register_operand" "") 
11813         (const_string "2")
11814         (const_string "*")))])
11815
11816 (define_insn "*ashrqi3_1"
11817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11818         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11819                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11822   "@
11823    sar{b}\t{%2, %0|%0, %2}
11824    sar{b}\t{%b2, %0|%0, %b2}"
11825   [(set_attr "type" "ishift")
11826    (set_attr "mode" "QI")])
11827
11828 (define_insn "*ashrqi3_1_slp"
11829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11830         (ashiftrt:QI (match_dup 0)
11831                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11832    (clobber (reg:CC FLAGS_REG))]
11833   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11834    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11835   "@
11836    sar{b}\t{%1, %0|%0, %1}
11837    sar{b}\t{%b1, %0|%0, %b1}"
11838   [(set_attr "type" "ishift1")
11839    (set_attr "mode" "QI")])
11840
11841 ;; This pattern can't accept a variable shift count, since shifts by
11842 ;; zero don't affect the flags.  We assume that shifts by constant
11843 ;; zero are optimized away.
11844 (define_insn "*ashrqi3_one_bit_cmp"
11845   [(set (reg FLAGS_REG)
11846         (compare
11847           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11848                        (match_operand:QI 2 "const1_operand" "I"))
11849           (const_int 0)))
11850    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11851         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11852   "ix86_match_ccmode (insn, CCGOCmode)
11853    && (TARGET_SHIFT1 || optimize_size)
11854    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11855   "sar{b}\t%0"
11856   [(set_attr "type" "ishift")
11857    (set (attr "length") 
11858      (if_then_else (match_operand 0 "register_operand" "") 
11859         (const_string "2")
11860         (const_string "*")))])
11861
11862 (define_insn "*ashrqi3_one_bit_cconly"
11863   [(set (reg FLAGS_REG)
11864         (compare
11865           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11866                        (match_operand:QI 2 "const1_operand" "I"))
11867           (const_int 0)))
11868    (clobber (match_scratch:QI 0 "=q"))]
11869   "ix86_match_ccmode (insn, CCGOCmode)
11870    && (TARGET_SHIFT1 || optimize_size)
11871    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11872   "sar{b}\t%0"
11873   [(set_attr "type" "ishift")
11874    (set_attr "length" "2")])
11875
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags.  We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*ashrqi3_cmp"
11880   [(set (reg FLAGS_REG)
11881         (compare
11882           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11883                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11884           (const_int 0)))
11885    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11886         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11887   "ix86_match_ccmode (insn, CCGOCmode)
11888    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11889    && (optimize_size
11890        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11891   "sar{b}\t{%2, %0|%0, %2}"
11892   [(set_attr "type" "ishift")
11893    (set_attr "mode" "QI")])
11894
11895 (define_insn "*ashrqi3_cconly"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11899                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900           (const_int 0)))
11901    (clobber (match_scratch:QI 0 "=q"))]
11902   "ix86_match_ccmode (insn, CCGOCmode)
11903    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11904    && (optimize_size
11905        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11906   "sar{b}\t{%2, %0|%0, %2}"
11907   [(set_attr "type" "ishift")
11908    (set_attr "mode" "QI")])
11909
11910 \f
11911 ;; Logical shift instructions
11912
11913 ;; See comment above `ashldi3' about how this works.
11914
11915 (define_expand "lshrti3"
11916   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11917                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11918                                 (match_operand:QI 2 "nonmemory_operand" "")))
11919               (clobber (reg:CC FLAGS_REG))])]
11920   "TARGET_64BIT"
11921 {
11922   if (! immediate_operand (operands[2], QImode))
11923     {
11924       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11925       DONE;
11926     }
11927   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11928   DONE;
11929 })
11930
11931 (define_insn "lshrti3_1"
11932   [(set (match_operand:TI 0 "register_operand" "=r")
11933         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11934                      (match_operand:QI 2 "register_operand" "c")))
11935    (clobber (match_scratch:DI 3 "=&r"))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "TARGET_64BIT"
11938   "#"
11939   [(set_attr "type" "multi")])
11940
11941 (define_insn "*lshrti3_2"
11942   [(set (match_operand:TI 0 "register_operand" "=r")
11943         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11944                      (match_operand:QI 2 "immediate_operand" "O")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "TARGET_64BIT"
11947   "#"
11948   [(set_attr "type" "multi")])
11949
11950 (define_split 
11951   [(set (match_operand:TI 0 "register_operand" "")
11952         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11953                      (match_operand:QI 2 "register_operand" "")))
11954    (clobber (match_scratch:DI 3 ""))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "TARGET_64BIT && reload_completed"
11957   [(const_int 0)]
11958   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11959
11960 (define_split 
11961   [(set (match_operand:TI 0 "register_operand" "")
11962         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11963                      (match_operand:QI 2 "immediate_operand" "")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_64BIT && reload_completed"
11966   [(const_int 0)]
11967   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11968
11969 (define_expand "lshrdi3"
11970   [(set (match_operand:DI 0 "shiftdi_operand" "")
11971         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11972                      (match_operand:QI 2 "nonmemory_operand" "")))]
11973   ""
11974   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11975
11976 (define_insn "*lshrdi3_1_one_bit_rex64"
11977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11978         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11979                      (match_operand:QI 2 "const1_operand" "")))
11980    (clobber (reg:CC FLAGS_REG))]
11981   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11982    && (TARGET_SHIFT1 || optimize_size)"
11983   "shr{q}\t%0"
11984   [(set_attr "type" "ishift")
11985    (set (attr "length") 
11986      (if_then_else (match_operand:DI 0 "register_operand" "") 
11987         (const_string "2")
11988         (const_string "*")))])
11989
11990 (define_insn "*lshrdi3_1_rex64"
11991   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11992         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11993                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996   "@
11997    shr{q}\t{%2, %0|%0, %2}
11998    shr{q}\t{%b2, %0|%0, %b2}"
11999   [(set_attr "type" "ishift")
12000    (set_attr "mode" "DI")])
12001
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags.  We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12006   [(set (reg FLAGS_REG)
12007         (compare
12008           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009                        (match_operand:QI 2 "const1_operand" ""))
12010           (const_int 0)))
12011    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12012         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12013   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12014    && (TARGET_SHIFT1 || optimize_size)
12015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12016   "shr{q}\t%0"
12017   [(set_attr "type" "ishift")
12018    (set (attr "length") 
12019      (if_then_else (match_operand:DI 0 "register_operand" "") 
12020         (const_string "2")
12021         (const_string "*")))])
12022
12023 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12024   [(set (reg FLAGS_REG)
12025         (compare
12026           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027                        (match_operand:QI 2 "const1_operand" ""))
12028           (const_int 0)))
12029    (clobber (match_scratch:DI 0 "=r"))]
12030   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12031    && (TARGET_SHIFT1 || optimize_size)
12032    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12033   "shr{q}\t%0"
12034   [(set_attr "type" "ishift")
12035    (set_attr "length" "2")])
12036
12037 ;; This pattern can't accept a variable shift count, since shifts by
12038 ;; zero don't affect the flags.  We assume that shifts by constant
12039 ;; zero are optimized away.
12040 (define_insn "*lshrdi3_cmp_rex64"
12041   [(set (reg FLAGS_REG)
12042         (compare
12043           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044                        (match_operand:QI 2 "const_int_operand" "e"))
12045           (const_int 0)))
12046    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12048   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12049    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12050    && (optimize_size
12051        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12052   "shr{q}\t{%2, %0|%0, %2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "DI")])
12055
12056 (define_insn "*lshrdi3_cconly_rex64"
12057   [(set (reg FLAGS_REG)
12058         (compare
12059           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                        (match_operand:QI 2 "const_int_operand" "e"))
12061           (const_int 0)))
12062    (clobber (match_scratch:DI 0 "=r"))]
12063   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12064    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12065    && (optimize_size
12066        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12067   "shr{q}\t{%2, %0|%0, %2}"
12068   [(set_attr "type" "ishift")
12069    (set_attr "mode" "DI")])
12070
12071 (define_insn "*lshrdi3_1"
12072   [(set (match_operand:DI 0 "register_operand" "=r")
12073         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12074                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "!TARGET_64BIT"
12077   "#"
12078   [(set_attr "type" "multi")])
12079
12080 ;; By default we don't ask for a scratch register, because when DImode
12081 ;; values are manipulated, registers are already at a premium.  But if
12082 ;; we have one handy, we won't turn it away.
12083 (define_peephole2
12084   [(match_scratch:SI 3 "r")
12085    (parallel [(set (match_operand:DI 0 "register_operand" "")
12086                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12087                                 (match_operand:QI 2 "nonmemory_operand" "")))
12088               (clobber (reg:CC FLAGS_REG))])
12089    (match_dup 3)]
12090   "!TARGET_64BIT && TARGET_CMOVE"
12091   [(const_int 0)]
12092   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12093
12094 (define_split 
12095   [(set (match_operand:DI 0 "register_operand" "")
12096         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12097                      (match_operand:QI 2 "nonmemory_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100                      ? flow2_completed : reload_completed)"
12101   [(const_int 0)]
12102   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12103
12104 (define_expand "lshrsi3"
12105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12106         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12107                      (match_operand:QI 2 "nonmemory_operand" "")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   ""
12110   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12111
12112 (define_insn "*lshrsi3_1_one_bit"
12113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12114         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12115                      (match_operand:QI 2 "const1_operand" "")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12118    && (TARGET_SHIFT1 || optimize_size)"
12119   "shr{l}\t%0"
12120   [(set_attr "type" "ishift")
12121    (set (attr "length") 
12122      (if_then_else (match_operand:SI 0 "register_operand" "") 
12123         (const_string "2")
12124         (const_string "*")))])
12125
12126 (define_insn "*lshrsi3_1_one_bit_zext"
12127   [(set (match_operand:DI 0 "register_operand" "=r")
12128         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12129                      (match_operand:QI 2 "const1_operand" "")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12132    && (TARGET_SHIFT1 || optimize_size)"
12133   "shr{l}\t%k0"
12134   [(set_attr "type" "ishift")
12135    (set_attr "length" "2")])
12136
12137 (define_insn "*lshrsi3_1"
12138   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12139         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12140                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12143   "@
12144    shr{l}\t{%2, %0|%0, %2}
12145    shr{l}\t{%b2, %0|%0, %b2}"
12146   [(set_attr "type" "ishift")
12147    (set_attr "mode" "SI")])
12148
12149 (define_insn "*lshrsi3_1_zext"
12150   [(set (match_operand:DI 0 "register_operand" "=r,r")
12151         (zero_extend:DI
12152           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12153                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12156   "@
12157    shr{l}\t{%2, %k0|%k0, %2}
12158    shr{l}\t{%b2, %k0|%k0, %b2}"
12159   [(set_attr "type" "ishift")
12160    (set_attr "mode" "SI")])
12161
12162 ;; This pattern can't accept a variable shift count, since shifts by
12163 ;; zero don't affect the flags.  We assume that shifts by constant
12164 ;; zero are optimized away.
12165 (define_insn "*lshrsi3_one_bit_cmp"
12166   [(set (reg FLAGS_REG)
12167         (compare
12168           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12169                        (match_operand:QI 2 "const1_operand" ""))
12170           (const_int 0)))
12171    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12172         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12173   "ix86_match_ccmode (insn, CCGOCmode)
12174    && (TARGET_SHIFT1 || optimize_size)
12175    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12176   "shr{l}\t%0"
12177   [(set_attr "type" "ishift")
12178    (set (attr "length") 
12179      (if_then_else (match_operand:SI 0 "register_operand" "") 
12180         (const_string "2")
12181         (const_string "*")))])
12182
12183 (define_insn "*lshrsi3_one_bit_cconly"
12184   [(set (reg FLAGS_REG)
12185         (compare
12186           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12187                        (match_operand:QI 2 "const1_operand" ""))
12188           (const_int 0)))
12189    (clobber (match_scratch:SI 0 "=r"))]
12190   "ix86_match_ccmode (insn, CCGOCmode)
12191    && (TARGET_SHIFT1 || optimize_size)
12192    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193   "shr{l}\t%0"
12194   [(set_attr "type" "ishift")
12195    (set_attr "length" "2")])
12196
12197 (define_insn "*lshrsi3_cmp_one_bit_zext"
12198   [(set (reg FLAGS_REG)
12199         (compare
12200           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12201                        (match_operand:QI 2 "const1_operand" ""))
12202           (const_int 0)))
12203    (set (match_operand:DI 0 "register_operand" "=r")
12204         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12205   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12206    && (TARGET_SHIFT1 || optimize_size)
12207    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12208   "shr{l}\t%k0"
12209   [(set_attr "type" "ishift")
12210    (set_attr "length" "2")])
12211
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags.  We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*lshrsi3_cmp"
12216   [(set (reg FLAGS_REG)
12217         (compare
12218           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12219                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12220           (const_int 0)))
12221    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12222         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12225    && (optimize_size
12226        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12227   "shr{l}\t{%2, %0|%0, %2}"
12228   [(set_attr "type" "ishift")
12229    (set_attr "mode" "SI")])
12230
12231 (define_insn "*lshrsi3_cconly"
12232   [(set (reg FLAGS_REG)
12233       (compare
12234         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12236         (const_int 0)))
12237    (clobber (match_scratch:SI 0 "=r"))]
12238   "ix86_match_ccmode (insn, CCGOCmode)
12239    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12240    && (optimize_size
12241        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12242   "shr{l}\t{%2, %0|%0, %2}"
12243   [(set_attr "type" "ishift")
12244    (set_attr "mode" "SI")])
12245
12246 (define_insn "*lshrsi3_cmp_zext"
12247   [(set (reg FLAGS_REG)
12248         (compare
12249           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12250                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12251           (const_int 0)))
12252    (set (match_operand:DI 0 "register_operand" "=r")
12253         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12254   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12256    && (optimize_size
12257        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12258   "shr{l}\t{%2, %k0|%k0, %2}"
12259   [(set_attr "type" "ishift")
12260    (set_attr "mode" "SI")])
12261
12262 (define_expand "lshrhi3"
12263   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12264         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12265                      (match_operand:QI 2 "nonmemory_operand" "")))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "TARGET_HIMODE_MATH"
12268   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12269
12270 (define_insn "*lshrhi3_1_one_bit"
12271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12272         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12273                      (match_operand:QI 2 "const1_operand" "")))
12274    (clobber (reg:CC FLAGS_REG))]
12275   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12276    && (TARGET_SHIFT1 || optimize_size)"
12277   "shr{w}\t%0"
12278   [(set_attr "type" "ishift")
12279    (set (attr "length") 
12280      (if_then_else (match_operand 0 "register_operand" "") 
12281         (const_string "2")
12282         (const_string "*")))])
12283
12284 (define_insn "*lshrhi3_1"
12285   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12286         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12288    (clobber (reg:CC FLAGS_REG))]
12289   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12290   "@
12291    shr{w}\t{%2, %0|%0, %2}
12292    shr{w}\t{%b2, %0|%0, %b2}"
12293   [(set_attr "type" "ishift")
12294    (set_attr "mode" "HI")])
12295
12296 ;; This pattern can't accept a variable shift count, since shifts by
12297 ;; zero don't affect the flags.  We assume that shifts by constant
12298 ;; zero are optimized away.
12299 (define_insn "*lshrhi3_one_bit_cmp"
12300   [(set (reg FLAGS_REG)
12301         (compare
12302           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12303                        (match_operand:QI 2 "const1_operand" ""))
12304           (const_int 0)))
12305    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12306         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12307   "ix86_match_ccmode (insn, CCGOCmode)
12308    && (TARGET_SHIFT1 || optimize_size)
12309    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12310   "shr{w}\t%0"
12311   [(set_attr "type" "ishift")
12312    (set (attr "length") 
12313      (if_then_else (match_operand:SI 0 "register_operand" "") 
12314         (const_string "2")
12315         (const_string "*")))])
12316
12317 (define_insn "*lshrhi3_one_bit_cconly"
12318   [(set (reg FLAGS_REG)
12319         (compare
12320           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321                        (match_operand:QI 2 "const1_operand" ""))
12322           (const_int 0)))
12323    (clobber (match_scratch:HI 0 "=r"))]
12324   "ix86_match_ccmode (insn, CCGOCmode)
12325    && (TARGET_SHIFT1 || optimize_size)
12326    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12327   "shr{w}\t%0"
12328   [(set_attr "type" "ishift")
12329    (set_attr "length" "2")])
12330
12331 ;; This pattern can't accept a variable shift count, since shifts by
12332 ;; zero don't affect the flags.  We assume that shifts by constant
12333 ;; zero are optimized away.
12334 (define_insn "*lshrhi3_cmp"
12335   [(set (reg FLAGS_REG)
12336         (compare
12337           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12339           (const_int 0)))
12340    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12341         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12342   "ix86_match_ccmode (insn, CCGOCmode)
12343    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12344    && (optimize_size
12345        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12346   "shr{w}\t{%2, %0|%0, %2}"
12347   [(set_attr "type" "ishift")
12348    (set_attr "mode" "HI")])
12349
12350 (define_insn "*lshrhi3_cconly"
12351   [(set (reg FLAGS_REG)
12352         (compare
12353           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12355           (const_int 0)))
12356    (clobber (match_scratch:HI 0 "=r"))]
12357   "ix86_match_ccmode (insn, CCGOCmode)
12358    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12359    && (optimize_size
12360        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12361   "shr{w}\t{%2, %0|%0, %2}"
12362   [(set_attr "type" "ishift")
12363    (set_attr "mode" "HI")])
12364
12365 (define_expand "lshrqi3"
12366   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12367         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12368                      (match_operand:QI 2 "nonmemory_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_QIMODE_MATH"
12371   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12372
12373 (define_insn "*lshrqi3_1_one_bit"
12374   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12375         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12376                      (match_operand:QI 2 "const1_operand" "")))
12377    (clobber (reg:CC FLAGS_REG))]
12378   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12379    && (TARGET_SHIFT1 || optimize_size)"
12380   "shr{b}\t%0"
12381   [(set_attr "type" "ishift")
12382    (set (attr "length") 
12383      (if_then_else (match_operand 0 "register_operand" "") 
12384         (const_string "2")
12385         (const_string "*")))])
12386
12387 (define_insn "*lshrqi3_1_one_bit_slp"
12388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389         (lshiftrt:QI (match_dup 0)
12390                      (match_operand:QI 1 "const1_operand" "")))
12391    (clobber (reg:CC FLAGS_REG))]
12392   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12393    && (TARGET_SHIFT1 || optimize_size)"
12394   "shr{b}\t%0"
12395   [(set_attr "type" "ishift1")
12396    (set (attr "length") 
12397      (if_then_else (match_operand 0 "register_operand" "") 
12398         (const_string "2")
12399         (const_string "*")))])
12400
12401 (define_insn "*lshrqi3_1"
12402   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12403         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12404                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12407   "@
12408    shr{b}\t{%2, %0|%0, %2}
12409    shr{b}\t{%b2, %0|%0, %b2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "QI")])
12412
12413 (define_insn "*lshrqi3_1_slp"
12414   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12415         (lshiftrt:QI (match_dup 0)
12416                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12419    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12420   "@
12421    shr{b}\t{%1, %0|%0, %1}
12422    shr{b}\t{%b1, %0|%0, %b1}"
12423   [(set_attr "type" "ishift1")
12424    (set_attr "mode" "QI")])
12425
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags.  We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrqi2_one_bit_cmp"
12430   [(set (reg FLAGS_REG)
12431         (compare
12432           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12433                        (match_operand:QI 2 "const1_operand" ""))
12434           (const_int 0)))
12435    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12436         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12437   "ix86_match_ccmode (insn, CCGOCmode)
12438    && (TARGET_SHIFT1 || optimize_size)
12439    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12440   "shr{b}\t%0"
12441   [(set_attr "type" "ishift")
12442    (set (attr "length") 
12443      (if_then_else (match_operand:SI 0 "register_operand" "") 
12444         (const_string "2")
12445         (const_string "*")))])
12446
12447 (define_insn "*lshrqi2_one_bit_cconly"
12448   [(set (reg FLAGS_REG)
12449         (compare
12450           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12451                        (match_operand:QI 2 "const1_operand" ""))
12452           (const_int 0)))
12453    (clobber (match_scratch:QI 0 "=q"))]
12454   "ix86_match_ccmode (insn, CCGOCmode)
12455    && (TARGET_SHIFT1 || optimize_size)
12456    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12457   "shr{b}\t%0"
12458   [(set_attr "type" "ishift")
12459    (set_attr "length" "2")])
12460
12461 ;; This pattern can't accept a variable shift count, since shifts by
12462 ;; zero don't affect the flags.  We assume that shifts by constant
12463 ;; zero are optimized away.
12464 (define_insn "*lshrqi2_cmp"
12465   [(set (reg FLAGS_REG)
12466         (compare
12467           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12468                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469           (const_int 0)))
12470    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12471         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12472   "ix86_match_ccmode (insn, CCGOCmode)
12473    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474    && (optimize_size
12475        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12476   "shr{b}\t{%2, %0|%0, %2}"
12477   [(set_attr "type" "ishift")
12478    (set_attr "mode" "QI")])
12479
12480 (define_insn "*lshrqi2_cconly"
12481   [(set (reg FLAGS_REG)
12482         (compare
12483           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12484                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12485           (const_int 0)))
12486    (clobber (match_scratch:QI 0 "=q"))]
12487   "ix86_match_ccmode (insn, CCGOCmode)
12488    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12489    && (optimize_size
12490        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12491   "shr{b}\t{%2, %0|%0, %2}"
12492   [(set_attr "type" "ishift")
12493    (set_attr "mode" "QI")])
12494 \f
12495 ;; Rotate instructions
12496
12497 (define_expand "rotldi3"
12498   [(set (match_operand:DI 0 "shiftdi_operand" "")
12499         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12500                    (match_operand:QI 2 "nonmemory_operand" "")))
12501    (clobber (reg:CC FLAGS_REG))]
12502  ""
12503 {
12504   if (TARGET_64BIT)
12505     {
12506       ix86_expand_binary_operator (ROTATE, DImode, operands);
12507       DONE;
12508     }
12509   if (!const_1_to_31_operand (operands[2], VOIDmode))
12510     FAIL;
12511   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12512   DONE;
12513 })
12514
12515 ;; Implement rotation using two double-precision shift instructions
12516 ;; and a scratch register.   
12517 (define_insn_and_split "ix86_rotldi3"
12518  [(set (match_operand:DI 0 "register_operand" "=r")
12519        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12520                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12521   (clobber (reg:CC FLAGS_REG))
12522   (clobber (match_scratch:SI 3 "=&r"))]
12523  "!TARGET_64BIT"
12524  "" 
12525  "&& reload_completed"
12526  [(set (match_dup 3) (match_dup 4))
12527   (parallel
12528    [(set (match_dup 4)
12529          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12530                  (lshiftrt:SI (match_dup 5)
12531                               (minus:QI (const_int 32) (match_dup 2)))))
12532     (clobber (reg:CC FLAGS_REG))])
12533   (parallel
12534    [(set (match_dup 5)
12535          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12536                  (lshiftrt:SI (match_dup 3)
12537                               (minus:QI (const_int 32) (match_dup 2)))))
12538     (clobber (reg:CC FLAGS_REG))])]
12539  "split_di (operands, 1, operands + 4, operands + 5);")
12540  
12541 (define_insn "*rotlsi3_1_one_bit_rex64"
12542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12543         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12544                    (match_operand:QI 2 "const1_operand" "")))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12547    && (TARGET_SHIFT1 || optimize_size)"
12548   "rol{q}\t%0"
12549   [(set_attr "type" "rotate")
12550    (set (attr "length") 
12551      (if_then_else (match_operand:DI 0 "register_operand" "") 
12552         (const_string "2")
12553         (const_string "*")))])
12554
12555 (define_insn "*rotldi3_1_rex64"
12556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12557         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12558                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12559    (clobber (reg:CC FLAGS_REG))]
12560   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12561   "@
12562    rol{q}\t{%2, %0|%0, %2}
12563    rol{q}\t{%b2, %0|%0, %b2}"
12564   [(set_attr "type" "rotate")
12565    (set_attr "mode" "DI")])
12566
12567 (define_expand "rotlsi3"
12568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12569         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12570                    (match_operand:QI 2 "nonmemory_operand" "")))
12571    (clobber (reg:CC FLAGS_REG))]
12572   ""
12573   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12574
12575 (define_insn "*rotlsi3_1_one_bit"
12576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12577         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12578                    (match_operand:QI 2 "const1_operand" "")))
12579    (clobber (reg:CC FLAGS_REG))]
12580   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12581    && (TARGET_SHIFT1 || optimize_size)"
12582   "rol{l}\t%0"
12583   [(set_attr "type" "rotate")
12584    (set (attr "length") 
12585      (if_then_else (match_operand:SI 0 "register_operand" "") 
12586         (const_string "2")
12587         (const_string "*")))])
12588
12589 (define_insn "*rotlsi3_1_one_bit_zext"
12590   [(set (match_operand:DI 0 "register_operand" "=r")
12591         (zero_extend:DI
12592           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12593                      (match_operand:QI 2 "const1_operand" ""))))
12594    (clobber (reg:CC FLAGS_REG))]
12595   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12596    && (TARGET_SHIFT1 || optimize_size)"
12597   "rol{l}\t%k0"
12598   [(set_attr "type" "rotate")
12599    (set_attr "length" "2")])
12600
12601 (define_insn "*rotlsi3_1"
12602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12603         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12604                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12605    (clobber (reg:CC FLAGS_REG))]
12606   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12607   "@
12608    rol{l}\t{%2, %0|%0, %2}
12609    rol{l}\t{%b2, %0|%0, %b2}"
12610   [(set_attr "type" "rotate")
12611    (set_attr "mode" "SI")])
12612
12613 (define_insn "*rotlsi3_1_zext"
12614   [(set (match_operand:DI 0 "register_operand" "=r,r")
12615         (zero_extend:DI
12616           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12617                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12618    (clobber (reg:CC FLAGS_REG))]
12619   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12620   "@
12621    rol{l}\t{%2, %k0|%k0, %2}
12622    rol{l}\t{%b2, %k0|%k0, %b2}"
12623   [(set_attr "type" "rotate")
12624    (set_attr "mode" "SI")])
12625
12626 (define_expand "rotlhi3"
12627   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12628         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12629                    (match_operand:QI 2 "nonmemory_operand" "")))
12630    (clobber (reg:CC FLAGS_REG))]
12631   "TARGET_HIMODE_MATH"
12632   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12633
12634 (define_insn "*rotlhi3_1_one_bit"
12635   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12636         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12637                    (match_operand:QI 2 "const1_operand" "")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12640    && (TARGET_SHIFT1 || optimize_size)"
12641   "rol{w}\t%0"
12642   [(set_attr "type" "rotate")
12643    (set (attr "length") 
12644      (if_then_else (match_operand 0 "register_operand" "") 
12645         (const_string "2")
12646         (const_string "*")))])
12647
12648 (define_insn "*rotlhi3_1"
12649   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12650         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12651                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12652    (clobber (reg:CC FLAGS_REG))]
12653   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12654   "@
12655    rol{w}\t{%2, %0|%0, %2}
12656    rol{w}\t{%b2, %0|%0, %b2}"
12657   [(set_attr "type" "rotate")
12658    (set_attr "mode" "HI")])
12659
12660 (define_expand "rotlqi3"
12661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12662         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12663                    (match_operand:QI 2 "nonmemory_operand" "")))
12664    (clobber (reg:CC FLAGS_REG))]
12665   "TARGET_QIMODE_MATH"
12666   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12667
12668 (define_insn "*rotlqi3_1_one_bit_slp"
12669   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12670         (rotate:QI (match_dup 0)
12671                    (match_operand:QI 1 "const1_operand" "")))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12674    && (TARGET_SHIFT1 || optimize_size)"
12675   "rol{b}\t%0"
12676   [(set_attr "type" "rotate1")
12677    (set (attr "length") 
12678      (if_then_else (match_operand 0 "register_operand" "") 
12679         (const_string "2")
12680         (const_string "*")))])
12681
12682 (define_insn "*rotlqi3_1_one_bit"
12683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12684         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12685                    (match_operand:QI 2 "const1_operand" "")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12688    && (TARGET_SHIFT1 || optimize_size)"
12689   "rol{b}\t%0"
12690   [(set_attr "type" "rotate")
12691    (set (attr "length") 
12692      (if_then_else (match_operand 0 "register_operand" "") 
12693         (const_string "2")
12694         (const_string "*")))])
12695
12696 (define_insn "*rotlqi3_1_slp"
12697   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12698         (rotate:QI (match_dup 0)
12699                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12703   "@
12704    rol{b}\t{%1, %0|%0, %1}
12705    rol{b}\t{%b1, %0|%0, %b1}"
12706   [(set_attr "type" "rotate1")
12707    (set_attr "mode" "QI")])
12708
12709 (define_insn "*rotlqi3_1"
12710   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12711         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12712                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12713    (clobber (reg:CC FLAGS_REG))]
12714   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12715   "@
12716    rol{b}\t{%2, %0|%0, %2}
12717    rol{b}\t{%b2, %0|%0, %b2}"
12718   [(set_attr "type" "rotate")
12719    (set_attr "mode" "QI")])
12720
12721 (define_expand "rotrdi3"
12722   [(set (match_operand:DI 0 "shiftdi_operand" "")
12723         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12724                    (match_operand:QI 2 "nonmemory_operand" "")))
12725    (clobber (reg:CC FLAGS_REG))]
12726  ""
12727 {
12728   if (TARGET_64BIT)
12729     {
12730       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12731       DONE;
12732     }
12733   if (!const_1_to_31_operand (operands[2], VOIDmode))
12734     FAIL;
12735   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12736   DONE;
12737 })
12738   
12739 ;; Implement rotation using two double-precision shift instructions
12740 ;; and a scratch register.   
12741 (define_insn_and_split "ix86_rotrdi3"
12742  [(set (match_operand:DI 0 "register_operand" "=r")
12743        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12744                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12745   (clobber (reg:CC FLAGS_REG))
12746   (clobber (match_scratch:SI 3 "=&r"))]
12747  "!TARGET_64BIT"
12748  ""
12749  "&& reload_completed"
12750  [(set (match_dup 3) (match_dup 4))
12751   (parallel
12752    [(set (match_dup 4)
12753          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12754                  (ashift:SI (match_dup 5)
12755                             (minus:QI (const_int 32) (match_dup 2)))))
12756     (clobber (reg:CC FLAGS_REG))])
12757   (parallel
12758    [(set (match_dup 5)
12759          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12760                  (ashift:SI (match_dup 3)
12761                             (minus:QI (const_int 32) (match_dup 2)))))
12762     (clobber (reg:CC FLAGS_REG))])]
12763  "split_di (operands, 1, operands + 4, operands + 5);")
12764
12765 (define_insn "*rotrdi3_1_one_bit_rex64"
12766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12767         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12768                      (match_operand:QI 2 "const1_operand" "")))
12769    (clobber (reg:CC FLAGS_REG))]
12770   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12771    && (TARGET_SHIFT1 || optimize_size)"
12772   "ror{q}\t%0"
12773   [(set_attr "type" "rotate")
12774    (set (attr "length") 
12775      (if_then_else (match_operand:DI 0 "register_operand" "") 
12776         (const_string "2")
12777         (const_string "*")))])
12778
12779 (define_insn "*rotrdi3_1_rex64"
12780   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12781         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12782                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12785   "@
12786    ror{q}\t{%2, %0|%0, %2}
12787    ror{q}\t{%b2, %0|%0, %b2}"
12788   [(set_attr "type" "rotate")
12789    (set_attr "mode" "DI")])
12790
12791 (define_expand "rotrsi3"
12792   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12793         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12794                      (match_operand:QI 2 "nonmemory_operand" "")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   ""
12797   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12798
12799 (define_insn "*rotrsi3_1_one_bit"
12800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12801         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12802                      (match_operand:QI 2 "const1_operand" "")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12805    && (TARGET_SHIFT1 || optimize_size)"
12806   "ror{l}\t%0"
12807   [(set_attr "type" "rotate")
12808    (set (attr "length") 
12809      (if_then_else (match_operand:SI 0 "register_operand" "") 
12810         (const_string "2")
12811         (const_string "*")))])
12812
12813 (define_insn "*rotrsi3_1_one_bit_zext"
12814   [(set (match_operand:DI 0 "register_operand" "=r")
12815         (zero_extend:DI
12816           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12817                        (match_operand:QI 2 "const1_operand" ""))))
12818    (clobber (reg:CC FLAGS_REG))]
12819   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12820    && (TARGET_SHIFT1 || optimize_size)"
12821   "ror{l}\t%k0"
12822   [(set_attr "type" "rotate")
12823    (set (attr "length") 
12824      (if_then_else (match_operand:SI 0 "register_operand" "") 
12825         (const_string "2")
12826         (const_string "*")))])
12827
12828 (define_insn "*rotrsi3_1"
12829   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12830         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12831                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12832    (clobber (reg:CC FLAGS_REG))]
12833   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12834   "@
12835    ror{l}\t{%2, %0|%0, %2}
12836    ror{l}\t{%b2, %0|%0, %b2}"
12837   [(set_attr "type" "rotate")
12838    (set_attr "mode" "SI")])
12839
12840 (define_insn "*rotrsi3_1_zext"
12841   [(set (match_operand:DI 0 "register_operand" "=r,r")
12842         (zero_extend:DI
12843           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12844                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12845    (clobber (reg:CC FLAGS_REG))]
12846   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12847   "@
12848    ror{l}\t{%2, %k0|%k0, %2}
12849    ror{l}\t{%b2, %k0|%k0, %b2}"
12850   [(set_attr "type" "rotate")
12851    (set_attr "mode" "SI")])
12852
12853 (define_expand "rotrhi3"
12854   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12855         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12856                      (match_operand:QI 2 "nonmemory_operand" "")))
12857    (clobber (reg:CC FLAGS_REG))]
12858   "TARGET_HIMODE_MATH"
12859   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12860
12861 (define_insn "*rotrhi3_one_bit"
12862   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12863         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12864                      (match_operand:QI 2 "const1_operand" "")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12867    && (TARGET_SHIFT1 || optimize_size)"
12868   "ror{w}\t%0"
12869   [(set_attr "type" "rotate")
12870    (set (attr "length") 
12871      (if_then_else (match_operand 0 "register_operand" "") 
12872         (const_string "2")
12873         (const_string "*")))])
12874
12875 (define_insn "*rotrhi3"
12876   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12877         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12878                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12881   "@
12882    ror{w}\t{%2, %0|%0, %2}
12883    ror{w}\t{%b2, %0|%0, %b2}"
12884   [(set_attr "type" "rotate")
12885    (set_attr "mode" "HI")])
12886
12887 (define_expand "rotrqi3"
12888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12889         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12890                      (match_operand:QI 2 "nonmemory_operand" "")))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "TARGET_QIMODE_MATH"
12893   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12894
12895 (define_insn "*rotrqi3_1_one_bit"
12896   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12897         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12898                      (match_operand:QI 2 "const1_operand" "")))
12899    (clobber (reg:CC FLAGS_REG))]
12900   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12901    && (TARGET_SHIFT1 || optimize_size)"
12902   "ror{b}\t%0"
12903   [(set_attr "type" "rotate")
12904    (set (attr "length") 
12905      (if_then_else (match_operand 0 "register_operand" "") 
12906         (const_string "2")
12907         (const_string "*")))])
12908
12909 (define_insn "*rotrqi3_1_one_bit_slp"
12910   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12911         (rotatert:QI (match_dup 0)
12912                      (match_operand:QI 1 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{b}\t%0"
12917   [(set_attr "type" "rotate1")
12918    (set (attr "length") 
12919      (if_then_else (match_operand 0 "register_operand" "") 
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotrqi3_1"
12924   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12925         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12929   "@
12930    ror{b}\t{%2, %0|%0, %2}
12931    ror{b}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "QI")])
12934
12935 (define_insn "*rotrqi3_1_slp"
12936   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12937         (rotatert:QI (match_dup 0)
12938                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12941    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12942   "@
12943    ror{b}\t{%1, %0|%0, %1}
12944    ror{b}\t{%b1, %0|%0, %b1}"
12945   [(set_attr "type" "rotate1")
12946    (set_attr "mode" "QI")])
12947 \f
12948 ;; Bit set / bit test instructions
12949
12950 (define_expand "extv"
12951   [(set (match_operand:SI 0 "register_operand" "")
12952         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12953                          (match_operand:SI 2 "const8_operand" "")
12954                          (match_operand:SI 3 "const8_operand" "")))]
12955   ""
12956 {
12957   /* Handle extractions from %ah et al.  */
12958   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12959     FAIL;
12960
12961   /* From mips.md: extract_bit_field doesn't verify that our source
12962      matches the predicate, so check it again here.  */
12963   if (! ext_register_operand (operands[1], VOIDmode))
12964     FAIL;
12965 })
12966
12967 (define_expand "extzv"
12968   [(set (match_operand:SI 0 "register_operand" "")
12969         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12970                          (match_operand:SI 2 "const8_operand" "")
12971                          (match_operand:SI 3 "const8_operand" "")))]
12972   ""
12973 {
12974   /* Handle extractions from %ah et al.  */
12975   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12976     FAIL;
12977
12978   /* From mips.md: extract_bit_field doesn't verify that our source
12979      matches the predicate, so check it again here.  */
12980   if (! ext_register_operand (operands[1], VOIDmode))
12981     FAIL;
12982 })
12983
12984 (define_expand "insv"
12985   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12986                       (match_operand 1 "const8_operand" "")
12987                       (match_operand 2 "const8_operand" ""))
12988         (match_operand 3 "register_operand" ""))]
12989   ""
12990 {
12991   /* Handle insertions to %ah et al.  */
12992   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12993     FAIL;
12994
12995   /* From mips.md: insert_bit_field doesn't verify that our source
12996      matches the predicate, so check it again here.  */
12997   if (! ext_register_operand (operands[0], VOIDmode))
12998     FAIL;
12999
13000   if (TARGET_64BIT)
13001     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13002   else
13003     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13004
13005   DONE;
13006 })
13007
13008 ;; %%% bts, btr, btc, bt.
13009 ;; In general these instructions are *slow* when applied to memory,
13010 ;; since they enforce atomic operation.  When applied to registers,
13011 ;; it depends on the cpu implementation.  They're never faster than
13012 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13013 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13014 ;; within the instruction itself, so operating on bits in the high
13015 ;; 32-bits of a register becomes easier.
13016 ;;
13017 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13018 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13019 ;; negdf respectively, so they can never be disabled entirely.
13020
13021 (define_insn "*btsq"
13022   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13023                          (const_int 1)
13024                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13025         (const_int 1))
13026    (clobber (reg:CC FLAGS_REG))]
13027   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13028   "bts{q} %1,%0"
13029   [(set_attr "type" "alu1")])
13030
13031 (define_insn "*btrq"
13032   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13033                          (const_int 1)
13034                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13035         (const_int 0))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13038   "btr{q} %1,%0"
13039   [(set_attr "type" "alu1")])
13040
13041 (define_insn "*btcq"
13042   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13043                          (const_int 1)
13044                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13045         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13046    (clobber (reg:CC FLAGS_REG))]
13047   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13048   "btc{q} %1,%0"
13049   [(set_attr "type" "alu1")])
13050
13051 ;; Allow Nocona to avoid these instructions if a register is available.
13052
13053 (define_peephole2
13054   [(match_scratch:DI 2 "r")
13055    (parallel [(set (zero_extract:DI
13056                      (match_operand:DI 0 "register_operand" "")
13057                      (const_int 1)
13058                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13059                    (const_int 1))
13060               (clobber (reg:CC FLAGS_REG))])]
13061   "TARGET_64BIT && !TARGET_USE_BT"
13062   [(const_int 0)]
13063 {
13064   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13065   rtx op1;
13066
13067   if (HOST_BITS_PER_WIDE_INT >= 64)
13068     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13069   else if (i < HOST_BITS_PER_WIDE_INT)
13070     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13071   else
13072     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13073
13074   op1 = immed_double_const (lo, hi, DImode);
13075   if (i >= 31)
13076     {
13077       emit_move_insn (operands[2], op1);
13078       op1 = operands[2];
13079     }
13080
13081   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13082   DONE;
13083 })
13084
13085 (define_peephole2
13086   [(match_scratch:DI 2 "r")
13087    (parallel [(set (zero_extract:DI
13088                      (match_operand:DI 0 "register_operand" "")
13089                      (const_int 1)
13090                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13091                    (const_int 0))
13092               (clobber (reg:CC FLAGS_REG))])]
13093   "TARGET_64BIT && !TARGET_USE_BT"
13094   [(const_int 0)]
13095 {
13096   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13097   rtx op1;
13098
13099   if (HOST_BITS_PER_WIDE_INT >= 64)
13100     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13101   else if (i < HOST_BITS_PER_WIDE_INT)
13102     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13103   else
13104     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13105
13106   op1 = immed_double_const (~lo, ~hi, DImode);
13107   if (i >= 32)
13108     {
13109       emit_move_insn (operands[2], op1);
13110       op1 = operands[2];
13111     }
13112
13113   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13114   DONE;
13115 })
13116
13117 (define_peephole2
13118   [(match_scratch:DI 2 "r")
13119    (parallel [(set (zero_extract:DI
13120                      (match_operand:DI 0 "register_operand" "")
13121                      (const_int 1)
13122                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13123               (not:DI (zero_extract:DI
13124                         (match_dup 0) (const_int 1) (match_dup 1))))
13125               (clobber (reg:CC FLAGS_REG))])]
13126   "TARGET_64BIT && !TARGET_USE_BT"
13127   [(const_int 0)]
13128 {
13129   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13130   rtx op1;
13131
13132   if (HOST_BITS_PER_WIDE_INT >= 64)
13133     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134   else if (i < HOST_BITS_PER_WIDE_INT)
13135     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13136   else
13137     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13138
13139   op1 = immed_double_const (lo, hi, DImode);
13140   if (i >= 31)
13141     {
13142       emit_move_insn (operands[2], op1);
13143       op1 = operands[2];
13144     }
13145
13146   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13147   DONE;
13148 })
13149 \f
13150 ;; Store-flag instructions.
13151
13152 ;; For all sCOND expanders, also expand the compare or test insn that
13153 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13154
13155 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13156 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13157 ;; way, which can later delete the movzx if only QImode is needed.
13158
13159 (define_expand "seq"
13160   [(set (match_operand:QI 0 "register_operand" "")
13161         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13162   ""
13163   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13164
13165 (define_expand "sne"
13166   [(set (match_operand:QI 0 "register_operand" "")
13167         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13168   ""
13169   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13170
13171 (define_expand "sgt"
13172   [(set (match_operand:QI 0 "register_operand" "")
13173         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13174   ""
13175   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13176
13177 (define_expand "sgtu"
13178   [(set (match_operand:QI 0 "register_operand" "")
13179         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13180   ""
13181   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13182
13183 (define_expand "slt"
13184   [(set (match_operand:QI 0 "register_operand" "")
13185         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13186   ""
13187   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13188
13189 (define_expand "sltu"
13190   [(set (match_operand:QI 0 "register_operand" "")
13191         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192   ""
13193   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13194
13195 (define_expand "sge"
13196   [(set (match_operand:QI 0 "register_operand" "")
13197         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198   ""
13199   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13200
13201 (define_expand "sgeu"
13202   [(set (match_operand:QI 0 "register_operand" "")
13203         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204   ""
13205   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13206
13207 (define_expand "sle"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13212
13213 (define_expand "sleu"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13218
13219 (define_expand "sunordered"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   "TARGET_80387 || TARGET_SSE"
13223   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13224
13225 (define_expand "sordered"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   "TARGET_80387"
13229   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13230
13231 (define_expand "suneq"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   "TARGET_80387 || TARGET_SSE"
13235   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13236
13237 (define_expand "sunge"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   "TARGET_80387 || TARGET_SSE"
13241   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13242
13243 (define_expand "sungt"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   "TARGET_80387 || TARGET_SSE"
13247   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13248
13249 (define_expand "sunle"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   "TARGET_80387 || TARGET_SSE"
13253   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13254
13255 (define_expand "sunlt"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   "TARGET_80387 || TARGET_SSE"
13259   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13260
13261 (define_expand "sltgt"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   "TARGET_80387 || TARGET_SSE"
13265   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13266
13267 (define_insn "*setcc_1"
13268   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13269         (match_operator:QI 1 "ix86_comparison_operator"
13270           [(reg FLAGS_REG) (const_int 0)]))]
13271   ""
13272   "set%C1\t%0"
13273   [(set_attr "type" "setcc")
13274    (set_attr "mode" "QI")])
13275
13276 (define_insn "*setcc_2"
13277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13278         (match_operator:QI 1 "ix86_comparison_operator"
13279           [(reg FLAGS_REG) (const_int 0)]))]
13280   ""
13281   "set%C1\t%0"
13282   [(set_attr "type" "setcc")
13283    (set_attr "mode" "QI")])
13284
13285 ;; In general it is not safe to assume too much about CCmode registers,
13286 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13287 ;; conditions this is safe on x86, so help combine not create
13288 ;;
13289 ;;      seta    %al
13290 ;;      testb   %al, %al
13291 ;;      sete    %al
13292
13293 (define_split 
13294   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13295         (ne:QI (match_operator 1 "ix86_comparison_operator"
13296                  [(reg FLAGS_REG) (const_int 0)])
13297             (const_int 0)))]
13298   ""
13299   [(set (match_dup 0) (match_dup 1))]
13300 {
13301   PUT_MODE (operands[1], QImode);
13302 })
13303
13304 (define_split 
13305   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13306         (ne:QI (match_operator 1 "ix86_comparison_operator"
13307                  [(reg FLAGS_REG) (const_int 0)])
13308             (const_int 0)))]
13309   ""
13310   [(set (match_dup 0) (match_dup 1))]
13311 {
13312   PUT_MODE (operands[1], QImode);
13313 })
13314
13315 (define_split 
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13317         (eq:QI (match_operator 1 "ix86_comparison_operator"
13318                  [(reg FLAGS_REG) (const_int 0)])
13319             (const_int 0)))]
13320   ""
13321   [(set (match_dup 0) (match_dup 1))]
13322 {
13323   rtx new_op1 = copy_rtx (operands[1]);
13324   operands[1] = new_op1;
13325   PUT_MODE (new_op1, QImode);
13326   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13327                                              GET_MODE (XEXP (new_op1, 0))));
13328
13329   /* Make sure that (a) the CCmode we have for the flags is strong
13330      enough for the reversed compare or (b) we have a valid FP compare.  */
13331   if (! ix86_comparison_operator (new_op1, VOIDmode))
13332     FAIL;
13333 })
13334
13335 (define_split 
13336   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13337         (eq:QI (match_operator 1 "ix86_comparison_operator"
13338                  [(reg FLAGS_REG) (const_int 0)])
13339             (const_int 0)))]
13340   ""
13341   [(set (match_dup 0) (match_dup 1))]
13342 {
13343   rtx new_op1 = copy_rtx (operands[1]);
13344   operands[1] = new_op1;
13345   PUT_MODE (new_op1, QImode);
13346   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13347                                              GET_MODE (XEXP (new_op1, 0))));
13348
13349   /* Make sure that (a) the CCmode we have for the flags is strong
13350      enough for the reversed compare or (b) we have a valid FP compare.  */
13351   if (! ix86_comparison_operator (new_op1, VOIDmode))
13352     FAIL;
13353 })
13354
13355 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13356 ;; subsequent logical operations are used to imitate conditional moves.
13357 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13358 ;; it directly.
13359
13360 (define_insn "*sse_setccsf"
13361   [(set (match_operand:SF 0 "register_operand" "=x")
13362         (match_operator:SF 1 "sse_comparison_operator"
13363           [(match_operand:SF 2 "register_operand" "0")
13364            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13365   "TARGET_SSE"
13366   "cmp%D1ss\t{%3, %0|%0, %3}"
13367   [(set_attr "type" "ssecmp")
13368    (set_attr "mode" "SF")])
13369
13370 (define_insn "*sse_setccdf"
13371   [(set (match_operand:DF 0 "register_operand" "=Y")
13372         (match_operator:DF 1 "sse_comparison_operator"
13373           [(match_operand:DF 2 "register_operand" "0")
13374            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13375   "TARGET_SSE2"
13376   "cmp%D1sd\t{%3, %0|%0, %3}"
13377   [(set_attr "type" "ssecmp")
13378    (set_attr "mode" "DF")])
13379 \f
13380 ;; Basic conditional jump instructions.
13381 ;; We ignore the overflow flag for signed branch instructions.
13382
13383 ;; For all bCOND expanders, also expand the compare or test insn that
13384 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13385
13386 (define_expand "beq"
13387   [(set (pc)
13388         (if_then_else (match_dup 1)
13389                       (label_ref (match_operand 0 "" ""))
13390                       (pc)))]
13391   ""
13392   "ix86_expand_branch (EQ, operands[0]); DONE;")
13393
13394 (define_expand "bne"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   ""
13400   "ix86_expand_branch (NE, operands[0]); DONE;")
13401
13402 (define_expand "bgt"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   ""
13408   "ix86_expand_branch (GT, operands[0]); DONE;")
13409
13410 (define_expand "bgtu"
13411   [(set (pc)
13412         (if_then_else (match_dup 1)
13413                       (label_ref (match_operand 0 "" ""))
13414                       (pc)))]
13415   ""
13416   "ix86_expand_branch (GTU, operands[0]); DONE;")
13417
13418 (define_expand "blt"
13419   [(set (pc)
13420         (if_then_else (match_dup 1)
13421                       (label_ref (match_operand 0 "" ""))
13422                       (pc)))]
13423   ""
13424   "ix86_expand_branch (LT, operands[0]); DONE;")
13425
13426 (define_expand "bltu"
13427   [(set (pc)
13428         (if_then_else (match_dup 1)
13429                       (label_ref (match_operand 0 "" ""))
13430                       (pc)))]
13431   ""
13432   "ix86_expand_branch (LTU, operands[0]); DONE;")
13433
13434 (define_expand "bge"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (GE, operands[0]); DONE;")
13441
13442 (define_expand "bgeu"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (GEU, operands[0]); DONE;")
13449
13450 (define_expand "ble"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (LE, operands[0]); DONE;")
13457
13458 (define_expand "bleu"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (LEU, operands[0]); DONE;")
13465
13466 (define_expand "bunordered"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   "TARGET_80387 || TARGET_SSE_MATH"
13472   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13473
13474 (define_expand "bordered"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   "TARGET_80387 || TARGET_SSE_MATH"
13480   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13481
13482 (define_expand "buneq"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   "TARGET_80387 || TARGET_SSE_MATH"
13488   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13489
13490 (define_expand "bunge"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   "TARGET_80387 || TARGET_SSE_MATH"
13496   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13497
13498 (define_expand "bungt"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   "TARGET_80387 || TARGET_SSE_MATH"
13504   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13505
13506 (define_expand "bunle"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   "TARGET_80387 || TARGET_SSE_MATH"
13512   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13513
13514 (define_expand "bunlt"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13521
13522 (define_expand "bltgt"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13529
13530 (define_insn "*jcc_1"
13531   [(set (pc)
13532         (if_then_else (match_operator 1 "ix86_comparison_operator"
13533                                       [(reg FLAGS_REG) (const_int 0)])
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   ""
13537   "%+j%C1\t%l0"
13538   [(set_attr "type" "ibr")
13539    (set_attr "modrm" "0")
13540    (set (attr "length")
13541            (if_then_else (and (ge (minus (match_dup 0) (pc))
13542                                   (const_int -126))
13543                               (lt (minus (match_dup 0) (pc))
13544                                   (const_int 128)))
13545              (const_int 2)
13546              (const_int 6)))])
13547
13548 (define_insn "*jcc_2"
13549   [(set (pc)
13550         (if_then_else (match_operator 1 "ix86_comparison_operator"
13551                                       [(reg FLAGS_REG) (const_int 0)])
13552                       (pc)
13553                       (label_ref (match_operand 0 "" ""))))]
13554   ""
13555   "%+j%c1\t%l0"
13556   [(set_attr "type" "ibr")
13557    (set_attr "modrm" "0")
13558    (set (attr "length")
13559            (if_then_else (and (ge (minus (match_dup 0) (pc))
13560                                   (const_int -126))
13561                               (lt (minus (match_dup 0) (pc))
13562                                   (const_int 128)))
13563              (const_int 2)
13564              (const_int 6)))])
13565
13566 ;; In general it is not safe to assume too much about CCmode registers,
13567 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13568 ;; conditions this is safe on x86, so help combine not create
13569 ;;
13570 ;;      seta    %al
13571 ;;      testb   %al, %al
13572 ;;      je      Lfoo
13573
13574 (define_split 
13575   [(set (pc)
13576         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13577                                       [(reg FLAGS_REG) (const_int 0)])
13578                           (const_int 0))
13579                       (label_ref (match_operand 1 "" ""))
13580                       (pc)))]
13581   ""
13582   [(set (pc)
13583         (if_then_else (match_dup 0)
13584                       (label_ref (match_dup 1))
13585                       (pc)))]
13586 {
13587   PUT_MODE (operands[0], VOIDmode);
13588 })
13589   
13590 (define_split 
13591   [(set (pc)
13592         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13593                                       [(reg FLAGS_REG) (const_int 0)])
13594                           (const_int 0))
13595                       (label_ref (match_operand 1 "" ""))
13596                       (pc)))]
13597   ""
13598   [(set (pc)
13599         (if_then_else (match_dup 0)
13600                       (label_ref (match_dup 1))
13601                       (pc)))]
13602 {
13603   rtx new_op0 = copy_rtx (operands[0]);
13604   operands[0] = new_op0;
13605   PUT_MODE (new_op0, VOIDmode);
13606   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13607                                              GET_MODE (XEXP (new_op0, 0))));
13608
13609   /* Make sure that (a) the CCmode we have for the flags is strong
13610      enough for the reversed compare or (b) we have a valid FP compare.  */
13611   if (! ix86_comparison_operator (new_op0, VOIDmode))
13612     FAIL;
13613 })
13614
13615 ;; Define combination compare-and-branch fp compare instructions to use
13616 ;; during early optimization.  Splitting the operation apart early makes
13617 ;; for bad code when we want to reverse the operation.
13618
13619 (define_insn "*fp_jcc_1_mixed"
13620   [(set (pc)
13621         (if_then_else (match_operator 0 "comparison_operator"
13622                         [(match_operand 1 "register_operand" "f,x")
13623                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13624           (label_ref (match_operand 3 "" ""))
13625           (pc)))
13626    (clobber (reg:CCFP FPSR_REG))
13627    (clobber (reg:CCFP FLAGS_REG))]
13628   "TARGET_MIX_SSE_I387
13629    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13630    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13631    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13632   "#")
13633
13634 (define_insn "*fp_jcc_1_sse"
13635   [(set (pc)
13636         (if_then_else (match_operator 0 "comparison_operator"
13637                         [(match_operand 1 "register_operand" "x")
13638                          (match_operand 2 "nonimmediate_operand" "xm")])
13639           (label_ref (match_operand 3 "" ""))
13640           (pc)))
13641    (clobber (reg:CCFP FPSR_REG))
13642    (clobber (reg:CCFP FLAGS_REG))]
13643   "TARGET_SSE_MATH
13644    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13645    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13646    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13647   "#")
13648
13649 (define_insn "*fp_jcc_1_387"
13650   [(set (pc)
13651         (if_then_else (match_operator 0 "comparison_operator"
13652                         [(match_operand 1 "register_operand" "f")
13653                          (match_operand 2 "register_operand" "f")])
13654           (label_ref (match_operand 3 "" ""))
13655           (pc)))
13656    (clobber (reg:CCFP FPSR_REG))
13657    (clobber (reg:CCFP FLAGS_REG))]
13658   "TARGET_CMOVE && TARGET_80387
13659    && FLOAT_MODE_P (GET_MODE (operands[1]))
13660    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13661    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13662   "#")
13663
13664 (define_insn "*fp_jcc_2_mixed"
13665   [(set (pc)
13666         (if_then_else (match_operator 0 "comparison_operator"
13667                         [(match_operand 1 "register_operand" "f,x")
13668                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13669           (pc)
13670           (label_ref (match_operand 3 "" ""))))
13671    (clobber (reg:CCFP FPSR_REG))
13672    (clobber (reg:CCFP FLAGS_REG))]
13673   "TARGET_MIX_SSE_I387
13674    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13675    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13676    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13677   "#")
13678
13679 (define_insn "*fp_jcc_2_sse"
13680   [(set (pc)
13681         (if_then_else (match_operator 0 "comparison_operator"
13682                         [(match_operand 1 "register_operand" "x")
13683                          (match_operand 2 "nonimmediate_operand" "xm")])
13684           (pc)
13685           (label_ref (match_operand 3 "" ""))))
13686    (clobber (reg:CCFP FPSR_REG))
13687    (clobber (reg:CCFP FLAGS_REG))]
13688   "TARGET_SSE_MATH
13689    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13690    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13691    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13692   "#")
13693
13694 (define_insn "*fp_jcc_2_387"
13695   [(set (pc)
13696         (if_then_else (match_operator 0 "comparison_operator"
13697                         [(match_operand 1 "register_operand" "f")
13698                          (match_operand 2 "register_operand" "f")])
13699           (pc)
13700           (label_ref (match_operand 3 "" ""))))
13701    (clobber (reg:CCFP FPSR_REG))
13702    (clobber (reg:CCFP FLAGS_REG))]
13703   "TARGET_CMOVE && TARGET_80387
13704    && FLOAT_MODE_P (GET_MODE (operands[1]))
13705    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13706    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13707   "#")
13708
13709 (define_insn "*fp_jcc_3_387"
13710   [(set (pc)
13711         (if_then_else (match_operator 0 "comparison_operator"
13712                         [(match_operand 1 "register_operand" "f")
13713                          (match_operand 2 "nonimmediate_operand" "fm")])
13714           (label_ref (match_operand 3 "" ""))
13715           (pc)))
13716    (clobber (reg:CCFP FPSR_REG))
13717    (clobber (reg:CCFP FLAGS_REG))
13718    (clobber (match_scratch:HI 4 "=a"))]
13719   "TARGET_80387
13720    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13721    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13722    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13723    && SELECT_CC_MODE (GET_CODE (operands[0]),
13724                       operands[1], operands[2]) == CCFPmode
13725    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726   "#")
13727
13728 (define_insn "*fp_jcc_4_387"
13729   [(set (pc)
13730         (if_then_else (match_operator 0 "comparison_operator"
13731                         [(match_operand 1 "register_operand" "f")
13732                          (match_operand 2 "nonimmediate_operand" "fm")])
13733           (pc)
13734           (label_ref (match_operand 3 "" ""))))
13735    (clobber (reg:CCFP FPSR_REG))
13736    (clobber (reg:CCFP FLAGS_REG))
13737    (clobber (match_scratch:HI 4 "=a"))]
13738   "TARGET_80387
13739    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13742    && SELECT_CC_MODE (GET_CODE (operands[0]),
13743                       operands[1], operands[2]) == CCFPmode
13744    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13745   "#")
13746
13747 (define_insn "*fp_jcc_5_387"
13748   [(set (pc)
13749         (if_then_else (match_operator 0 "comparison_operator"
13750                         [(match_operand 1 "register_operand" "f")
13751                          (match_operand 2 "register_operand" "f")])
13752           (label_ref (match_operand 3 "" ""))
13753           (pc)))
13754    (clobber (reg:CCFP FPSR_REG))
13755    (clobber (reg:CCFP FLAGS_REG))
13756    (clobber (match_scratch:HI 4 "=a"))]
13757   "TARGET_80387
13758    && FLOAT_MODE_P (GET_MODE (operands[1]))
13759    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13760    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13761   "#")
13762
13763 (define_insn "*fp_jcc_6_387"
13764   [(set (pc)
13765         (if_then_else (match_operator 0 "comparison_operator"
13766                         [(match_operand 1 "register_operand" "f")
13767                          (match_operand 2 "register_operand" "f")])
13768           (pc)
13769           (label_ref (match_operand 3 "" ""))))
13770    (clobber (reg:CCFP FPSR_REG))
13771    (clobber (reg:CCFP FLAGS_REG))
13772    (clobber (match_scratch:HI 4 "=a"))]
13773   "TARGET_80387
13774    && FLOAT_MODE_P (GET_MODE (operands[1]))
13775    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13776    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777   "#")
13778
13779 (define_insn "*fp_jcc_7_387"
13780   [(set (pc)
13781         (if_then_else (match_operator 0 "comparison_operator"
13782                         [(match_operand 1 "register_operand" "f")
13783                          (match_operand 2 "const0_operand" "X")])
13784           (label_ref (match_operand 3 "" ""))
13785           (pc)))
13786    (clobber (reg:CCFP FPSR_REG))
13787    (clobber (reg:CCFP FLAGS_REG))
13788    (clobber (match_scratch:HI 4 "=a"))]
13789   "TARGET_80387
13790    && FLOAT_MODE_P (GET_MODE (operands[1]))
13791    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13792    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13793    && SELECT_CC_MODE (GET_CODE (operands[0]),
13794                       operands[1], operands[2]) == CCFPmode
13795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13796   "#")
13797
13798 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13799 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13800 ;; with a precedence over other operators and is always put in the first
13801 ;; place. Swap condition and operands to match ficom instruction.
13802
13803 (define_insn "*fp_jcc_8<mode>_387"
13804   [(set (pc)
13805         (if_then_else (match_operator 0 "comparison_operator"
13806                         [(match_operator 1 "float_operator"
13807                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13808                            (match_operand 3 "register_operand" "f,f")])
13809           (label_ref (match_operand 4 "" ""))
13810           (pc)))
13811    (clobber (reg:CCFP FPSR_REG))
13812    (clobber (reg:CCFP FLAGS_REG))
13813    (clobber (match_scratch:HI 5 "=a,a"))]
13814   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13815    && FLOAT_MODE_P (GET_MODE (operands[3]))
13816    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13817    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13818    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13819    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13820   "#")
13821
13822 (define_split
13823   [(set (pc)
13824         (if_then_else (match_operator 0 "comparison_operator"
13825                         [(match_operand 1 "register_operand" "")
13826                          (match_operand 2 "nonimmediate_operand" "")])
13827           (match_operand 3 "" "")
13828           (match_operand 4 "" "")))
13829    (clobber (reg:CCFP FPSR_REG))
13830    (clobber (reg:CCFP FLAGS_REG))]
13831   "reload_completed"
13832   [(const_int 0)]
13833 {
13834   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13835                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13836   DONE;
13837 })
13838
13839 (define_split
13840   [(set (pc)
13841         (if_then_else (match_operator 0 "comparison_operator"
13842                         [(match_operand 1 "register_operand" "")
13843                          (match_operand 2 "general_operand" "")])
13844           (match_operand 3 "" "")
13845           (match_operand 4 "" "")))
13846    (clobber (reg:CCFP FPSR_REG))
13847    (clobber (reg:CCFP FLAGS_REG))
13848    (clobber (match_scratch:HI 5 "=a"))]
13849   "reload_completed"
13850   [(const_int 0)]
13851 {
13852   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13853                         operands[3], operands[4], operands[5], NULL_RTX);
13854   DONE;
13855 })
13856
13857 (define_split
13858   [(set (pc)
13859         (if_then_else (match_operator 0 "comparison_operator"
13860                         [(match_operator 1 "float_operator"
13861                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13862                            (match_operand 3 "register_operand" "")])
13863           (match_operand 4 "" "")
13864           (match_operand 5 "" "")))
13865    (clobber (reg:CCFP FPSR_REG))
13866    (clobber (reg:CCFP FLAGS_REG))
13867    (clobber (match_scratch:HI 6 "=a"))]
13868   "reload_completed"
13869   [(const_int 0)]
13870 {
13871   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13872   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13873                         operands[3], operands[7],
13874                         operands[4], operands[5], operands[6], NULL_RTX);
13875   DONE;
13876 })
13877
13878 ;; %%% Kill this when reload knows how to do it.
13879 (define_split
13880   [(set (pc)
13881         (if_then_else (match_operator 0 "comparison_operator"
13882                         [(match_operator 1 "float_operator"
13883                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13884                            (match_operand 3 "register_operand" "")])
13885           (match_operand 4 "" "")
13886           (match_operand 5 "" "")))
13887    (clobber (reg:CCFP FPSR_REG))
13888    (clobber (reg:CCFP FLAGS_REG))
13889    (clobber (match_scratch:HI 6 "=a"))]
13890   "reload_completed"
13891   [(const_int 0)]
13892 {
13893   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13894   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13895   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13896                         operands[3], operands[7],
13897                         operands[4], operands[5], operands[6], operands[2]);
13898   DONE;
13899 })
13900 \f
13901 ;; Unconditional and other jump instructions
13902
13903 (define_insn "jump"
13904   [(set (pc)
13905         (label_ref (match_operand 0 "" "")))]
13906   ""
13907   "jmp\t%l0"
13908   [(set_attr "type" "ibr")
13909    (set (attr "length")
13910            (if_then_else (and (ge (minus (match_dup 0) (pc))
13911                                   (const_int -126))
13912                               (lt (minus (match_dup 0) (pc))
13913                                   (const_int 128)))
13914              (const_int 2)
13915              (const_int 5)))
13916    (set_attr "modrm" "0")])
13917
13918 (define_expand "indirect_jump"
13919   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13920   ""
13921   "")
13922
13923 (define_insn "*indirect_jump"
13924   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13925   "!TARGET_64BIT"
13926   "jmp\t%A0"
13927   [(set_attr "type" "ibr")
13928    (set_attr "length_immediate" "0")])
13929
13930 (define_insn "*indirect_jump_rtx64"
13931   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13932   "TARGET_64BIT"
13933   "jmp\t%A0"
13934   [(set_attr "type" "ibr")
13935    (set_attr "length_immediate" "0")])
13936
13937 (define_expand "tablejump"
13938   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13939               (use (label_ref (match_operand 1 "" "")))])]
13940   ""
13941 {
13942   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13943      relative.  Convert the relative address to an absolute address.  */
13944   if (flag_pic)
13945     {
13946       rtx op0, op1;
13947       enum rtx_code code;
13948
13949       if (TARGET_64BIT)
13950         {
13951           code = PLUS;
13952           op0 = operands[0];
13953           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13954         }
13955       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13956         {
13957           code = PLUS;
13958           op0 = operands[0];
13959           op1 = pic_offset_table_rtx;
13960         }
13961       else
13962         {
13963           code = MINUS;
13964           op0 = pic_offset_table_rtx;
13965           op1 = operands[0];
13966         }
13967
13968       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13969                                          OPTAB_DIRECT);
13970     }
13971 })
13972
13973 (define_insn "*tablejump_1"
13974   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13975    (use (label_ref (match_operand 1 "" "")))]
13976   "!TARGET_64BIT"
13977   "jmp\t%A0"
13978   [(set_attr "type" "ibr")
13979    (set_attr "length_immediate" "0")])
13980
13981 (define_insn "*tablejump_1_rtx64"
13982   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13983    (use (label_ref (match_operand 1 "" "")))]
13984   "TARGET_64BIT"
13985   "jmp\t%A0"
13986   [(set_attr "type" "ibr")
13987    (set_attr "length_immediate" "0")])
13988 \f
13989 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13990
13991 (define_peephole2
13992   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13993    (set (match_operand:QI 1 "register_operand" "")
13994         (match_operator:QI 2 "ix86_comparison_operator"
13995           [(reg FLAGS_REG) (const_int 0)]))
13996    (set (match_operand 3 "q_regs_operand" "")
13997         (zero_extend (match_dup 1)))]
13998   "(peep2_reg_dead_p (3, operands[1])
13999     || operands_match_p (operands[1], operands[3]))
14000    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14001   [(set (match_dup 4) (match_dup 0))
14002    (set (strict_low_part (match_dup 5))
14003         (match_dup 2))]
14004 {
14005   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14006   operands[5] = gen_lowpart (QImode, operands[3]);
14007   ix86_expand_clear (operands[3]);
14008 })
14009
14010 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14011
14012 (define_peephole2
14013   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14014    (set (match_operand:QI 1 "register_operand" "")
14015         (match_operator:QI 2 "ix86_comparison_operator"
14016           [(reg FLAGS_REG) (const_int 0)]))
14017    (parallel [(set (match_operand 3 "q_regs_operand" "")
14018                    (zero_extend (match_dup 1)))
14019               (clobber (reg:CC FLAGS_REG))])]
14020   "(peep2_reg_dead_p (3, operands[1])
14021     || operands_match_p (operands[1], operands[3]))
14022    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14023   [(set (match_dup 4) (match_dup 0))
14024    (set (strict_low_part (match_dup 5))
14025         (match_dup 2))]
14026 {
14027   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14028   operands[5] = gen_lowpart (QImode, operands[3]);
14029   ix86_expand_clear (operands[3]);
14030 })
14031 \f
14032 ;; Call instructions.
14033
14034 ;; The predicates normally associated with named expanders are not properly
14035 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14036 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14037
14038 ;; Call subroutine returning no value.
14039
14040 (define_expand "call_pop"
14041   [(parallel [(call (match_operand:QI 0 "" "")
14042                     (match_operand:SI 1 "" ""))
14043               (set (reg:SI SP_REG)
14044                    (plus:SI (reg:SI SP_REG)
14045                             (match_operand:SI 3 "" "")))])]
14046   "!TARGET_64BIT"
14047 {
14048   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14049   DONE;
14050 })
14051
14052 (define_insn "*call_pop_0"
14053   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14054          (match_operand:SI 1 "" ""))
14055    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14056                             (match_operand:SI 2 "immediate_operand" "")))]
14057   "!TARGET_64BIT"
14058 {
14059   if (SIBLING_CALL_P (insn))
14060     return "jmp\t%P0";
14061   else
14062     return "call\t%P0";
14063 }
14064   [(set_attr "type" "call")])
14065   
14066 (define_insn "*call_pop_1"
14067   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14068          (match_operand:SI 1 "" ""))
14069    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14070                             (match_operand:SI 2 "immediate_operand" "i")))]
14071   "!TARGET_64BIT"
14072 {
14073   if (constant_call_address_operand (operands[0], Pmode))
14074     {
14075       if (SIBLING_CALL_P (insn))
14076         return "jmp\t%P0";
14077       else
14078         return "call\t%P0";
14079     }
14080   if (SIBLING_CALL_P (insn))
14081     return "jmp\t%A0";
14082   else
14083     return "call\t%A0";
14084 }
14085   [(set_attr "type" "call")])
14086
14087 (define_expand "call"
14088   [(call (match_operand:QI 0 "" "")
14089          (match_operand 1 "" ""))
14090    (use (match_operand 2 "" ""))]
14091   ""
14092 {
14093   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14094   DONE;
14095 })
14096
14097 (define_expand "sibcall"
14098   [(call (match_operand:QI 0 "" "")
14099          (match_operand 1 "" ""))
14100    (use (match_operand 2 "" ""))]
14101   ""
14102 {
14103   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14104   DONE;
14105 })
14106
14107 (define_insn "*call_0"
14108   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14109          (match_operand 1 "" ""))]
14110   ""
14111 {
14112   if (SIBLING_CALL_P (insn))
14113     return "jmp\t%P0";
14114   else
14115     return "call\t%P0";
14116 }
14117   [(set_attr "type" "call")])
14118
14119 (define_insn "*call_1"
14120   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14121          (match_operand 1 "" ""))]
14122   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14123 {
14124   if (constant_call_address_operand (operands[0], Pmode))
14125     return "call\t%P0";
14126   return "call\t%A0";
14127 }
14128   [(set_attr "type" "call")])
14129
14130 (define_insn "*sibcall_1"
14131   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14132          (match_operand 1 "" ""))]
14133   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14134 {
14135   if (constant_call_address_operand (operands[0], Pmode))
14136     return "jmp\t%P0";
14137   return "jmp\t%A0";
14138 }
14139   [(set_attr "type" "call")])
14140
14141 (define_insn "*call_1_rex64"
14142   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14143          (match_operand 1 "" ""))]
14144   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14145 {
14146   if (constant_call_address_operand (operands[0], Pmode))
14147     return "call\t%P0";
14148   return "call\t%A0";
14149 }
14150   [(set_attr "type" "call")])
14151
14152 (define_insn "*sibcall_1_rex64"
14153   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14154          (match_operand 1 "" ""))]
14155   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14156   "jmp\t%P0"
14157   [(set_attr "type" "call")])
14158
14159 (define_insn "*sibcall_1_rex64_v"
14160   [(call (mem:QI (reg:DI 40))
14161          (match_operand 0 "" ""))]
14162   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14163   "jmp\t*%%r11"
14164   [(set_attr "type" "call")])
14165
14166
14167 ;; Call subroutine, returning value in operand 0
14168
14169 (define_expand "call_value_pop"
14170   [(parallel [(set (match_operand 0 "" "")
14171                    (call (match_operand:QI 1 "" "")
14172                          (match_operand:SI 2 "" "")))
14173               (set (reg:SI SP_REG)
14174                    (plus:SI (reg:SI SP_REG)
14175                             (match_operand:SI 4 "" "")))])]
14176   "!TARGET_64BIT"
14177 {
14178   ix86_expand_call (operands[0], operands[1], operands[2],
14179                     operands[3], operands[4], 0);
14180   DONE;
14181 })
14182
14183 (define_expand "call_value"
14184   [(set (match_operand 0 "" "")
14185         (call (match_operand:QI 1 "" "")
14186               (match_operand:SI 2 "" "")))
14187    (use (match_operand:SI 3 "" ""))]
14188   ;; Operand 2 not used on the i386.
14189   ""
14190 {
14191   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14192   DONE;
14193 })
14194
14195 (define_expand "sibcall_value"
14196   [(set (match_operand 0 "" "")
14197         (call (match_operand:QI 1 "" "")
14198               (match_operand:SI 2 "" "")))
14199    (use (match_operand:SI 3 "" ""))]
14200   ;; Operand 2 not used on the i386.
14201   ""
14202 {
14203   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14204   DONE;
14205 })
14206
14207 ;; Call subroutine returning any type.
14208
14209 (define_expand "untyped_call"
14210   [(parallel [(call (match_operand 0 "" "")
14211                     (const_int 0))
14212               (match_operand 1 "" "")
14213               (match_operand 2 "" "")])]
14214   ""
14215 {
14216   int i;
14217
14218   /* In order to give reg-stack an easier job in validating two
14219      coprocessor registers as containing a possible return value,
14220      simply pretend the untyped call returns a complex long double
14221      value.  */
14222
14223   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14224                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14225                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14226                     NULL, 0);
14227
14228   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14229     {
14230       rtx set = XVECEXP (operands[2], 0, i);
14231       emit_move_insn (SET_DEST (set), SET_SRC (set));
14232     }
14233
14234   /* The optimizer does not know that the call sets the function value
14235      registers we stored in the result block.  We avoid problems by
14236      claiming that all hard registers are used and clobbered at this
14237      point.  */
14238   emit_insn (gen_blockage (const0_rtx));
14239
14240   DONE;
14241 })
14242 \f
14243 ;; Prologue and epilogue instructions
14244
14245 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14246 ;; all of memory.  This blocks insns from being moved across this point.
14247
14248 (define_insn "blockage"
14249   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14250   ""
14251   ""
14252   [(set_attr "length" "0")])
14253
14254 ;; Insn emitted into the body of a function to return from a function.
14255 ;; This is only done if the function's epilogue is known to be simple.
14256 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14257
14258 (define_expand "return"
14259   [(return)]
14260   "ix86_can_use_return_insn_p ()"
14261 {
14262   if (current_function_pops_args)
14263     {
14264       rtx popc = GEN_INT (current_function_pops_args);
14265       emit_jump_insn (gen_return_pop_internal (popc));
14266       DONE;
14267     }
14268 })
14269
14270 (define_insn "return_internal"
14271   [(return)]
14272   "reload_completed"
14273   "ret"
14274   [(set_attr "length" "1")
14275    (set_attr "length_immediate" "0")
14276    (set_attr "modrm" "0")])
14277
14278 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14279 ;; instruction Athlon and K8 have.
14280
14281 (define_insn "return_internal_long"
14282   [(return)
14283    (unspec [(const_int 0)] UNSPEC_REP)]
14284   "reload_completed"
14285   "rep {;} ret"
14286   [(set_attr "length" "1")
14287    (set_attr "length_immediate" "0")
14288    (set_attr "prefix_rep" "1")
14289    (set_attr "modrm" "0")])
14290
14291 (define_insn "return_pop_internal"
14292   [(return)
14293    (use (match_operand:SI 0 "const_int_operand" ""))]
14294   "reload_completed"
14295   "ret\t%0"
14296   [(set_attr "length" "3")
14297    (set_attr "length_immediate" "2")
14298    (set_attr "modrm" "0")])
14299
14300 (define_insn "return_indirect_internal"
14301   [(return)
14302    (use (match_operand:SI 0 "register_operand" "r"))]
14303   "reload_completed"
14304   "jmp\t%A0"
14305   [(set_attr "type" "ibr")
14306    (set_attr "length_immediate" "0")])
14307
14308 (define_insn "nop"
14309   [(const_int 0)]
14310   ""
14311   "nop"
14312   [(set_attr "length" "1")
14313    (set_attr "length_immediate" "0")
14314    (set_attr "modrm" "0")])
14315
14316 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14317 ;; branch prediction penalty for the third jump in a 16-byte
14318 ;; block on K8.
14319
14320 (define_insn "align"
14321   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14322   ""
14323 {
14324 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14325   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14326 #else
14327   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14328      The align insn is used to avoid 3 jump instructions in the row to improve
14329      branch prediction and the benefits hardly outweigh the cost of extra 8
14330      nops on the average inserted by full alignment pseudo operation.  */
14331 #endif
14332   return "";
14333 }
14334   [(set_attr "length" "16")])
14335
14336 (define_expand "prologue"
14337   [(const_int 1)]
14338   ""
14339   "ix86_expand_prologue (); DONE;")
14340
14341 (define_insn "set_got"
14342   [(set (match_operand:SI 0 "register_operand" "=r")
14343         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14344    (clobber (reg:CC FLAGS_REG))]
14345   "!TARGET_64BIT"
14346   { return output_set_got (operands[0], NULL_RTX); }
14347   [(set_attr "type" "multi")
14348    (set_attr "length" "12")])
14349
14350 (define_insn "set_got_labelled"
14351   [(set (match_operand:SI 0 "register_operand" "=r")
14352         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14353          UNSPEC_SET_GOT))
14354    (clobber (reg:CC FLAGS_REG))]
14355   "!TARGET_64BIT"
14356   { return output_set_got (operands[0], operands[1]); }
14357   [(set_attr "type" "multi")
14358    (set_attr "length" "12")])
14359
14360 (define_insn "set_got_rex64"
14361   [(set (match_operand:DI 0 "register_operand" "=r")
14362         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14363   "TARGET_64BIT"
14364   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14365   [(set_attr "type" "lea")
14366    (set_attr "length" "6")])
14367
14368 (define_expand "epilogue"
14369   [(const_int 1)]
14370   ""
14371   "ix86_expand_epilogue (1); DONE;")
14372
14373 (define_expand "sibcall_epilogue"
14374   [(const_int 1)]
14375   ""
14376   "ix86_expand_epilogue (0); DONE;")
14377
14378 (define_expand "eh_return"
14379   [(use (match_operand 0 "register_operand" ""))]
14380   ""
14381 {
14382   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14383
14384   /* Tricky bit: we write the address of the handler to which we will
14385      be returning into someone else's stack frame, one word below the
14386      stack address we wish to restore.  */
14387   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14388   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14389   tmp = gen_rtx_MEM (Pmode, tmp);
14390   emit_move_insn (tmp, ra);
14391
14392   if (Pmode == SImode)
14393     emit_jump_insn (gen_eh_return_si (sa));
14394   else
14395     emit_jump_insn (gen_eh_return_di (sa));
14396   emit_barrier ();
14397   DONE;
14398 })
14399
14400 (define_insn_and_split "eh_return_si"
14401   [(set (pc) 
14402         (unspec [(match_operand:SI 0 "register_operand" "c")]
14403                  UNSPEC_EH_RETURN))]
14404   "!TARGET_64BIT"
14405   "#"
14406   "reload_completed"
14407   [(const_int 1)]
14408   "ix86_expand_epilogue (2); DONE;")
14409
14410 (define_insn_and_split "eh_return_di"
14411   [(set (pc) 
14412         (unspec [(match_operand:DI 0 "register_operand" "c")]
14413                  UNSPEC_EH_RETURN))]
14414   "TARGET_64BIT"
14415   "#"
14416   "reload_completed"
14417   [(const_int 1)]
14418   "ix86_expand_epilogue (2); DONE;")
14419
14420 (define_insn "leave"
14421   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14422    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14423    (clobber (mem:BLK (scratch)))]
14424   "!TARGET_64BIT"
14425   "leave"
14426   [(set_attr "type" "leave")])
14427
14428 (define_insn "leave_rex64"
14429   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14430    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14431    (clobber (mem:BLK (scratch)))]
14432   "TARGET_64BIT"
14433   "leave"
14434   [(set_attr "type" "leave")])
14435 \f
14436 (define_expand "ffssi2"
14437   [(parallel
14438      [(set (match_operand:SI 0 "register_operand" "") 
14439            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14440       (clobber (match_scratch:SI 2 ""))
14441       (clobber (reg:CC FLAGS_REG))])]
14442   ""
14443   "")
14444
14445 (define_insn_and_split "*ffs_cmove"
14446   [(set (match_operand:SI 0 "register_operand" "=r") 
14447         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14448    (clobber (match_scratch:SI 2 "=&r"))
14449    (clobber (reg:CC FLAGS_REG))]
14450   "TARGET_CMOVE"
14451   "#"
14452   "&& reload_completed"
14453   [(set (match_dup 2) (const_int -1))
14454    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14455               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14456    (set (match_dup 0) (if_then_else:SI
14457                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14458                         (match_dup 2)
14459                         (match_dup 0)))
14460    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14461               (clobber (reg:CC FLAGS_REG))])]
14462   "")
14463
14464 (define_insn_and_split "*ffs_no_cmove"
14465   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14466         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14467    (clobber (match_scratch:SI 2 "=&q"))
14468    (clobber (reg:CC FLAGS_REG))]
14469   ""
14470   "#"
14471   "reload_completed"
14472   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14473               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14474    (set (strict_low_part (match_dup 3))
14475         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14476    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14477               (clobber (reg:CC FLAGS_REG))])
14478    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14479               (clobber (reg:CC FLAGS_REG))])
14480    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14481               (clobber (reg:CC FLAGS_REG))])]
14482 {
14483   operands[3] = gen_lowpart (QImode, operands[2]);
14484   ix86_expand_clear (operands[2]);
14485 })
14486
14487 (define_insn "*ffssi_1"
14488   [(set (reg:CCZ FLAGS_REG)
14489         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14490                      (const_int 0)))
14491    (set (match_operand:SI 0 "register_operand" "=r")
14492         (ctz:SI (match_dup 1)))]
14493   ""
14494   "bsf{l}\t{%1, %0|%0, %1}"
14495   [(set_attr "prefix_0f" "1")])
14496
14497 (define_expand "ffsdi2"
14498   [(parallel
14499      [(set (match_operand:DI 0 "register_operand" "") 
14500            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14501       (clobber (match_scratch:DI 2 ""))
14502       (clobber (reg:CC FLAGS_REG))])]
14503   "TARGET_64BIT && TARGET_CMOVE"
14504   "")
14505
14506 (define_insn_and_split "*ffs_rex64"
14507   [(set (match_operand:DI 0 "register_operand" "=r") 
14508         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14509    (clobber (match_scratch:DI 2 "=&r"))
14510    (clobber (reg:CC FLAGS_REG))]
14511   "TARGET_64BIT && TARGET_CMOVE"
14512   "#"
14513   "&& reload_completed"
14514   [(set (match_dup 2) (const_int -1))
14515    (parallel [(set (reg:CCZ FLAGS_REG)
14516                    (compare:CCZ (match_dup 1) (const_int 0)))
14517               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14518    (set (match_dup 0) (if_then_else:DI
14519                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14520                         (match_dup 2)
14521                         (match_dup 0)))
14522    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14523               (clobber (reg:CC FLAGS_REG))])]
14524   "")
14525
14526 (define_insn "*ffsdi_1"
14527   [(set (reg:CCZ FLAGS_REG)
14528         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14529                      (const_int 0)))
14530    (set (match_operand:DI 0 "register_operand" "=r")
14531         (ctz:DI (match_dup 1)))]
14532   "TARGET_64BIT"
14533   "bsf{q}\t{%1, %0|%0, %1}"
14534   [(set_attr "prefix_0f" "1")])
14535
14536 (define_insn "ctzsi2"
14537   [(set (match_operand:SI 0 "register_operand" "=r")
14538         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14539    (clobber (reg:CC FLAGS_REG))]
14540   ""
14541   "bsf{l}\t{%1, %0|%0, %1}"
14542   [(set_attr "prefix_0f" "1")])
14543
14544 (define_insn "ctzdi2"
14545   [(set (match_operand:DI 0 "register_operand" "=r")
14546         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14547    (clobber (reg:CC FLAGS_REG))]
14548   "TARGET_64BIT"
14549   "bsf{q}\t{%1, %0|%0, %1}"
14550   [(set_attr "prefix_0f" "1")])
14551
14552 (define_expand "clzsi2"
14553   [(parallel
14554      [(set (match_operand:SI 0 "register_operand" "")
14555            (minus:SI (const_int 31)
14556                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14557       (clobber (reg:CC FLAGS_REG))])
14558    (parallel
14559      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14560       (clobber (reg:CC FLAGS_REG))])]
14561   ""
14562   "")
14563
14564 (define_insn "*bsr"
14565   [(set (match_operand:SI 0 "register_operand" "=r")
14566         (minus:SI (const_int 31)
14567                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14568    (clobber (reg:CC FLAGS_REG))]
14569   ""
14570   "bsr{l}\t{%1, %0|%0, %1}"
14571   [(set_attr "prefix_0f" "1")])
14572
14573 (define_expand "clzdi2"
14574   [(parallel
14575      [(set (match_operand:DI 0 "register_operand" "")
14576            (minus:DI (const_int 63)
14577                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14578       (clobber (reg:CC FLAGS_REG))])
14579    (parallel
14580      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14581       (clobber (reg:CC FLAGS_REG))])]
14582   "TARGET_64BIT"
14583   "")
14584
14585 (define_insn "*bsr_rex64"
14586   [(set (match_operand:DI 0 "register_operand" "=r")
14587         (minus:DI (const_int 63)
14588                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14589    (clobber (reg:CC FLAGS_REG))]
14590   "TARGET_64BIT"
14591   "bsr{q}\t{%1, %0|%0, %1}"
14592   [(set_attr "prefix_0f" "1")])
14593 \f
14594 ;; Thread-local storage patterns for ELF.
14595 ;;
14596 ;; Note that these code sequences must appear exactly as shown
14597 ;; in order to allow linker relaxation.
14598
14599 (define_insn "*tls_global_dynamic_32_gnu"
14600   [(set (match_operand:SI 0 "register_operand" "=a")
14601         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14602                     (match_operand:SI 2 "tls_symbolic_operand" "")
14603                     (match_operand:SI 3 "call_insn_operand" "")]
14604                     UNSPEC_TLS_GD))
14605    (clobber (match_scratch:SI 4 "=d"))
14606    (clobber (match_scratch:SI 5 "=c"))
14607    (clobber (reg:CC FLAGS_REG))]
14608   "!TARGET_64BIT && TARGET_GNU_TLS"
14609   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14610   [(set_attr "type" "multi")
14611    (set_attr "length" "12")])
14612
14613 (define_insn "*tls_global_dynamic_32_sun"
14614   [(set (match_operand:SI 0 "register_operand" "=a")
14615         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14616                     (match_operand:SI 2 "tls_symbolic_operand" "")
14617                     (match_operand:SI 3 "call_insn_operand" "")]
14618                     UNSPEC_TLS_GD))
14619    (clobber (match_scratch:SI 4 "=d"))
14620    (clobber (match_scratch:SI 5 "=c"))
14621    (clobber (reg:CC FLAGS_REG))]
14622   "!TARGET_64BIT && TARGET_SUN_TLS"
14623   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14624         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14625   [(set_attr "type" "multi")
14626    (set_attr "length" "14")])
14627
14628 (define_expand "tls_global_dynamic_32"
14629   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14630                    (unspec:SI
14631                     [(match_dup 2)
14632                      (match_operand:SI 1 "tls_symbolic_operand" "")
14633                      (match_dup 3)]
14634                     UNSPEC_TLS_GD))
14635               (clobber (match_scratch:SI 4 ""))
14636               (clobber (match_scratch:SI 5 ""))
14637               (clobber (reg:CC FLAGS_REG))])]
14638   ""
14639 {
14640   if (flag_pic)
14641     operands[2] = pic_offset_table_rtx;
14642   else
14643     {
14644       operands[2] = gen_reg_rtx (Pmode);
14645       emit_insn (gen_set_got (operands[2]));
14646     }
14647   if (TARGET_GNU2_TLS)
14648     {
14649        emit_insn (gen_tls_dynamic_gnu2_32
14650                   (operands[0], operands[1], operands[2]));
14651        DONE;
14652     }
14653   operands[3] = ix86_tls_get_addr ();
14654 })
14655
14656 (define_insn "*tls_global_dynamic_64"
14657   [(set (match_operand:DI 0 "register_operand" "=a")
14658         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14659                  (match_operand:DI 3 "" "")))
14660    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14661               UNSPEC_TLS_GD)]
14662   "TARGET_64BIT"
14663   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14664   [(set_attr "type" "multi")
14665    (set_attr "length" "16")])
14666
14667 (define_expand "tls_global_dynamic_64"
14668   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14669                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14670               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14671                          UNSPEC_TLS_GD)])]
14672   ""
14673 {
14674   if (TARGET_GNU2_TLS)
14675     {
14676        emit_insn (gen_tls_dynamic_gnu2_64
14677                   (operands[0], operands[1]));
14678        DONE;
14679     }
14680   operands[2] = ix86_tls_get_addr ();
14681 })
14682
14683 (define_insn "*tls_local_dynamic_base_32_gnu"
14684   [(set (match_operand:SI 0 "register_operand" "=a")
14685         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14686                     (match_operand:SI 2 "call_insn_operand" "")]
14687                    UNSPEC_TLS_LD_BASE))
14688    (clobber (match_scratch:SI 3 "=d"))
14689    (clobber (match_scratch:SI 4 "=c"))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "!TARGET_64BIT && TARGET_GNU_TLS"
14692   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14693   [(set_attr "type" "multi")
14694    (set_attr "length" "11")])
14695
14696 (define_insn "*tls_local_dynamic_base_32_sun"
14697   [(set (match_operand:SI 0 "register_operand" "=a")
14698         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14699                     (match_operand:SI 2 "call_insn_operand" "")]
14700                    UNSPEC_TLS_LD_BASE))
14701    (clobber (match_scratch:SI 3 "=d"))
14702    (clobber (match_scratch:SI 4 "=c"))
14703    (clobber (reg:CC FLAGS_REG))]
14704   "!TARGET_64BIT && TARGET_SUN_TLS"
14705   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14706         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14707   [(set_attr "type" "multi")
14708    (set_attr "length" "13")])
14709
14710 (define_expand "tls_local_dynamic_base_32"
14711   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14712                    (unspec:SI [(match_dup 1) (match_dup 2)]
14713                               UNSPEC_TLS_LD_BASE))
14714               (clobber (match_scratch:SI 3 ""))
14715               (clobber (match_scratch:SI 4 ""))
14716               (clobber (reg:CC FLAGS_REG))])]
14717   ""
14718 {
14719   if (flag_pic)
14720     operands[1] = pic_offset_table_rtx;
14721   else
14722     {
14723       operands[1] = gen_reg_rtx (Pmode);
14724       emit_insn (gen_set_got (operands[1]));
14725     }
14726   if (TARGET_GNU2_TLS)
14727     {
14728        emit_insn (gen_tls_dynamic_gnu2_32
14729                   (operands[0], ix86_tls_module_base (), operands[1]));
14730        DONE;
14731     }
14732   operands[2] = ix86_tls_get_addr ();
14733 })
14734
14735 (define_insn "*tls_local_dynamic_base_64"
14736   [(set (match_operand:DI 0 "register_operand" "=a")
14737         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14738                  (match_operand:DI 2 "" "")))
14739    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14740   "TARGET_64BIT"
14741   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14742   [(set_attr "type" "multi")
14743    (set_attr "length" "12")])
14744
14745 (define_expand "tls_local_dynamic_base_64"
14746   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14747                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14748               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14749   ""
14750 {
14751   if (TARGET_GNU2_TLS)
14752     {
14753        emit_insn (gen_tls_dynamic_gnu2_64
14754                   (operands[0], ix86_tls_module_base ()));
14755        DONE;
14756     }
14757   operands[1] = ix86_tls_get_addr ();
14758 })
14759
14760 ;; Local dynamic of a single variable is a lose.  Show combine how
14761 ;; to convert that back to global dynamic.
14762
14763 (define_insn_and_split "*tls_local_dynamic_32_once"
14764   [(set (match_operand:SI 0 "register_operand" "=a")
14765         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14766                              (match_operand:SI 2 "call_insn_operand" "")]
14767                             UNSPEC_TLS_LD_BASE)
14768                  (const:SI (unspec:SI
14769                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14770                             UNSPEC_DTPOFF))))
14771    (clobber (match_scratch:SI 4 "=d"))
14772    (clobber (match_scratch:SI 5 "=c"))
14773    (clobber (reg:CC FLAGS_REG))]
14774   ""
14775   "#"
14776   ""
14777   [(parallel [(set (match_dup 0)
14778                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14779                               UNSPEC_TLS_GD))
14780               (clobber (match_dup 4))
14781               (clobber (match_dup 5))
14782               (clobber (reg:CC FLAGS_REG))])]
14783   "")
14784
14785 ;; Load and add the thread base pointer from %gs:0.
14786
14787 (define_insn "*load_tp_si"
14788   [(set (match_operand:SI 0 "register_operand" "=r")
14789         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14790   "!TARGET_64BIT"
14791   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14792   [(set_attr "type" "imov")
14793    (set_attr "modrm" "0")
14794    (set_attr "length" "7")
14795    (set_attr "memory" "load")
14796    (set_attr "imm_disp" "false")])
14797
14798 (define_insn "*add_tp_si"
14799   [(set (match_operand:SI 0 "register_operand" "=r")
14800         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14801                  (match_operand:SI 1 "register_operand" "0")))
14802    (clobber (reg:CC FLAGS_REG))]
14803   "!TARGET_64BIT"
14804   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14805   [(set_attr "type" "alu")
14806    (set_attr "modrm" "0")
14807    (set_attr "length" "7")
14808    (set_attr "memory" "load")
14809    (set_attr "imm_disp" "false")])
14810
14811 (define_insn "*load_tp_di"
14812   [(set (match_operand:DI 0 "register_operand" "=r")
14813         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14814   "TARGET_64BIT"
14815   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14816   [(set_attr "type" "imov")
14817    (set_attr "modrm" "0")
14818    (set_attr "length" "7")
14819    (set_attr "memory" "load")
14820    (set_attr "imm_disp" "false")])
14821
14822 (define_insn "*add_tp_di"
14823   [(set (match_operand:DI 0 "register_operand" "=r")
14824         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14825                  (match_operand:DI 1 "register_operand" "0")))
14826    (clobber (reg:CC FLAGS_REG))]
14827   "TARGET_64BIT"
14828   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14829   [(set_attr "type" "alu")
14830    (set_attr "modrm" "0")
14831    (set_attr "length" "7")
14832    (set_attr "memory" "load")
14833    (set_attr "imm_disp" "false")])
14834
14835 ;; GNU2 TLS patterns can be split.
14836
14837 (define_expand "tls_dynamic_gnu2_32"
14838   [(set (match_dup 3)
14839         (plus:SI (match_operand:SI 2 "register_operand" "")
14840                  (const:SI
14841                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14842                              UNSPEC_TLSDESC))))
14843    (parallel
14844     [(set (match_operand:SI 0 "register_operand" "")
14845           (unspec:SI [(match_dup 1) (match_dup 3)
14846                       (match_dup 2) (reg:SI SP_REG)]
14847                       UNSPEC_TLSDESC))
14848      (clobber (reg:CC FLAGS_REG))])]
14849   "!TARGET_64BIT && TARGET_GNU2_TLS"
14850 {
14851   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14852   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14853 })
14854
14855 (define_insn "*tls_dynamic_lea_32"
14856   [(set (match_operand:SI 0 "register_operand" "=r")
14857         (plus:SI (match_operand:SI 1 "register_operand" "b")
14858                  (const:SI
14859                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14860                               UNSPEC_TLSDESC))))]
14861   "!TARGET_64BIT && TARGET_GNU2_TLS"
14862   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14863   [(set_attr "type" "lea")
14864    (set_attr "mode" "SI")
14865    (set_attr "length" "6")
14866    (set_attr "length_address" "4")])
14867
14868 (define_insn "*tls_dynamic_call_32"
14869   [(set (match_operand:SI 0 "register_operand" "=a")
14870         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14871                     (match_operand:SI 2 "register_operand" "0")
14872                     ;; we have to make sure %ebx still points to the GOT
14873                     (match_operand:SI 3 "register_operand" "b")
14874                     (reg:SI SP_REG)]
14875                    UNSPEC_TLSDESC))
14876    (clobber (reg:CC FLAGS_REG))]
14877   "!TARGET_64BIT && TARGET_GNU2_TLS"
14878   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14879   [(set_attr "type" "call")
14880    (set_attr "length" "2")
14881    (set_attr "length_address" "0")])
14882
14883 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14884   [(set (match_operand:SI 0 "register_operand" "=&a")
14885         (plus:SI
14886          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14887                      (match_operand:SI 4 "" "")
14888                      (match_operand:SI 2 "register_operand" "b")
14889                      (reg:SI SP_REG)]
14890                     UNSPEC_TLSDESC)
14891          (const:SI (unspec:SI
14892                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14893                     UNSPEC_DTPOFF))))
14894    (clobber (reg:CC FLAGS_REG))]
14895   "!TARGET_64BIT && TARGET_GNU2_TLS"
14896   "#"
14897   ""
14898   [(set (match_dup 0) (match_dup 5))]
14899 {
14900   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14901   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14902 })
14903
14904 (define_expand "tls_dynamic_gnu2_64"
14905   [(set (match_dup 2)
14906         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14907                    UNSPEC_TLSDESC))
14908    (parallel
14909     [(set (match_operand:DI 0 "register_operand" "")
14910           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14911                      UNSPEC_TLSDESC))
14912      (clobber (reg:CC FLAGS_REG))])]
14913   "TARGET_64BIT && TARGET_GNU2_TLS"
14914 {
14915   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14916   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14917 })
14918
14919 (define_insn "*tls_dynamic_lea_64"
14920   [(set (match_operand:DI 0 "register_operand" "=r")
14921         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14922                    UNSPEC_TLSDESC))]
14923   "TARGET_64BIT && TARGET_GNU2_TLS"
14924   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14925   [(set_attr "type" "lea")
14926    (set_attr "mode" "DI")
14927    (set_attr "length" "7")
14928    (set_attr "length_address" "4")])
14929
14930 (define_insn "*tls_dynamic_call_64"
14931   [(set (match_operand:DI 0 "register_operand" "=a")
14932         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14933                     (match_operand:DI 2 "register_operand" "0")
14934                     (reg:DI SP_REG)]
14935                    UNSPEC_TLSDESC))
14936    (clobber (reg:CC FLAGS_REG))]
14937   "TARGET_64BIT && TARGET_GNU2_TLS"
14938   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14939   [(set_attr "type" "call")
14940    (set_attr "length" "2")
14941    (set_attr "length_address" "0")])
14942
14943 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14944   [(set (match_operand:DI 0 "register_operand" "=&a")
14945         (plus:DI
14946          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14947                      (match_operand:DI 3 "" "")
14948                      (reg:DI SP_REG)]
14949                     UNSPEC_TLSDESC)
14950          (const:DI (unspec:DI
14951                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14952                     UNSPEC_DTPOFF))))
14953    (clobber (reg:CC FLAGS_REG))]
14954   "TARGET_64BIT && TARGET_GNU2_TLS"
14955   "#"
14956   ""
14957   [(set (match_dup 0) (match_dup 4))]
14958 {
14959   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14960   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14961 })
14962
14963 ;;
14964 \f
14965 ;; These patterns match the binary 387 instructions for addM3, subM3,
14966 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14967 ;; SFmode.  The first is the normal insn, the second the same insn but
14968 ;; with one operand a conversion, and the third the same insn but with
14969 ;; the other operand a conversion.  The conversion may be SFmode or
14970 ;; SImode if the target mode DFmode, but only SImode if the target mode
14971 ;; is SFmode.
14972
14973 ;; Gcc is slightly more smart about handling normal two address instructions
14974 ;; so use special patterns for add and mull.
14975
14976 (define_insn "*fop_sf_comm_mixed"
14977   [(set (match_operand:SF 0 "register_operand" "=f,x")
14978         (match_operator:SF 3 "binary_fp_operator"
14979                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14980                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14981   "TARGET_MIX_SSE_I387
14982    && COMMUTATIVE_ARITH_P (operands[3])
14983    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14984   "* return output_387_binary_op (insn, operands);"
14985   [(set (attr "type") 
14986         (if_then_else (eq_attr "alternative" "1")
14987            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14988               (const_string "ssemul")
14989               (const_string "sseadd"))
14990            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14991               (const_string "fmul")
14992               (const_string "fop"))))
14993    (set_attr "mode" "SF")])
14994
14995 (define_insn "*fop_sf_comm_sse"
14996   [(set (match_operand:SF 0 "register_operand" "=x")
14997         (match_operator:SF 3 "binary_fp_operator"
14998                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14999                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15000   "TARGET_SSE_MATH
15001    && COMMUTATIVE_ARITH_P (operands[3])
15002    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15003   "* return output_387_binary_op (insn, operands);"
15004   [(set (attr "type") 
15005         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15006            (const_string "ssemul")
15007            (const_string "sseadd")))
15008    (set_attr "mode" "SF")])
15009
15010 (define_insn "*fop_sf_comm_i387"
15011   [(set (match_operand:SF 0 "register_operand" "=f")
15012         (match_operator:SF 3 "binary_fp_operator"
15013                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15014                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15015   "TARGET_80387
15016    && COMMUTATIVE_ARITH_P (operands[3])
15017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15018   "* return output_387_binary_op (insn, operands);"
15019   [(set (attr "type") 
15020         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15021            (const_string "fmul")
15022            (const_string "fop")))
15023    (set_attr "mode" "SF")])
15024
15025 (define_insn "*fop_sf_1_mixed"
15026   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15027         (match_operator:SF 3 "binary_fp_operator"
15028                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15029                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15030   "TARGET_MIX_SSE_I387
15031    && !COMMUTATIVE_ARITH_P (operands[3])
15032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15033   "* return output_387_binary_op (insn, operands);"
15034   [(set (attr "type") 
15035         (cond [(and (eq_attr "alternative" "2")
15036                     (match_operand:SF 3 "mult_operator" ""))
15037                  (const_string "ssemul")
15038                (and (eq_attr "alternative" "2")
15039                     (match_operand:SF 3 "div_operator" ""))
15040                  (const_string "ssediv")
15041                (eq_attr "alternative" "2")
15042                  (const_string "sseadd")
15043                (match_operand:SF 3 "mult_operator" "") 
15044                  (const_string "fmul")
15045                (match_operand:SF 3 "div_operator" "") 
15046                  (const_string "fdiv")
15047               ]
15048               (const_string "fop")))
15049    (set_attr "mode" "SF")])
15050
15051 (define_insn "*fop_sf_1_sse"
15052   [(set (match_operand:SF 0 "register_operand" "=x")
15053         (match_operator:SF 3 "binary_fp_operator"
15054                         [(match_operand:SF 1 "register_operand" "0")
15055                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15056   "TARGET_SSE_MATH
15057    && !COMMUTATIVE_ARITH_P (operands[3])"
15058   "* return output_387_binary_op (insn, operands);"
15059   [(set (attr "type") 
15060         (cond [(match_operand:SF 3 "mult_operator" "")
15061                  (const_string "ssemul")
15062                (match_operand:SF 3 "div_operator" "")
15063                  (const_string "ssediv")
15064               ]
15065               (const_string "sseadd")))
15066    (set_attr "mode" "SF")])
15067
15068 ;; This pattern is not fully shadowed by the pattern above.
15069 (define_insn "*fop_sf_1_i387"
15070   [(set (match_operand:SF 0 "register_operand" "=f,f")
15071         (match_operator:SF 3 "binary_fp_operator"
15072                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15073                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15074   "TARGET_80387 && !TARGET_SSE_MATH
15075    && !COMMUTATIVE_ARITH_P (operands[3])
15076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15077   "* return output_387_binary_op (insn, operands);"
15078   [(set (attr "type") 
15079         (cond [(match_operand:SF 3 "mult_operator" "") 
15080                  (const_string "fmul")
15081                (match_operand:SF 3 "div_operator" "") 
15082                  (const_string "fdiv")
15083               ]
15084               (const_string "fop")))
15085    (set_attr "mode" "SF")])
15086
15087 ;; ??? Add SSE splitters for these!
15088 (define_insn "*fop_sf_2<mode>_i387"
15089   [(set (match_operand:SF 0 "register_operand" "=f,f")
15090         (match_operator:SF 3 "binary_fp_operator"
15091           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15092            (match_operand:SF 2 "register_operand" "0,0")]))]
15093   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15094   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15095   [(set (attr "type") 
15096         (cond [(match_operand:SF 3 "mult_operator" "") 
15097                  (const_string "fmul")
15098                (match_operand:SF 3 "div_operator" "") 
15099                  (const_string "fdiv")
15100               ]
15101               (const_string "fop")))
15102    (set_attr "fp_int_src" "true")
15103    (set_attr "mode" "<MODE>")])
15104
15105 (define_insn "*fop_sf_3<mode>_i387"
15106   [(set (match_operand:SF 0 "register_operand" "=f,f")
15107         (match_operator:SF 3 "binary_fp_operator"
15108           [(match_operand:SF 1 "register_operand" "0,0")
15109            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15110   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15111   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15112   [(set (attr "type") 
15113         (cond [(match_operand:SF 3 "mult_operator" "") 
15114                  (const_string "fmul")
15115                (match_operand:SF 3 "div_operator" "") 
15116                  (const_string "fdiv")
15117               ]
15118               (const_string "fop")))
15119    (set_attr "fp_int_src" "true")
15120    (set_attr "mode" "<MODE>")])
15121
15122 (define_insn "*fop_df_comm_mixed"
15123   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15124         (match_operator:DF 3 "binary_fp_operator"
15125                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15126                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15127   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15128    && COMMUTATIVE_ARITH_P (operands[3])
15129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15130   "* return output_387_binary_op (insn, operands);"
15131   [(set (attr "type") 
15132         (if_then_else (eq_attr "alternative" "1")
15133            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15134               (const_string "ssemul")
15135               (const_string "sseadd"))
15136            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15137               (const_string "fmul")
15138               (const_string "fop"))))
15139    (set_attr "mode" "DF")])
15140
15141 (define_insn "*fop_df_comm_sse"
15142   [(set (match_operand:DF 0 "register_operand" "=Y")
15143         (match_operator:DF 3 "binary_fp_operator"
15144                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15145                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15146   "TARGET_SSE2 && TARGET_SSE_MATH
15147    && COMMUTATIVE_ARITH_P (operands[3])
15148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15149   "* return output_387_binary_op (insn, operands);"
15150   [(set (attr "type") 
15151         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15152            (const_string "ssemul")
15153            (const_string "sseadd")))
15154    (set_attr "mode" "DF")])
15155
15156 (define_insn "*fop_df_comm_i387"
15157   [(set (match_operand:DF 0 "register_operand" "=f")
15158         (match_operator:DF 3 "binary_fp_operator"
15159                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15160                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15161   "TARGET_80387
15162    && COMMUTATIVE_ARITH_P (operands[3])
15163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15164   "* return output_387_binary_op (insn, operands);"
15165   [(set (attr "type") 
15166         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15167            (const_string "fmul")
15168            (const_string "fop")))
15169    (set_attr "mode" "DF")])
15170
15171 (define_insn "*fop_df_1_mixed"
15172   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15173         (match_operator:DF 3 "binary_fp_operator"
15174                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15175                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15176   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15177    && !COMMUTATIVE_ARITH_P (operands[3])
15178    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15179   "* return output_387_binary_op (insn, operands);"
15180   [(set (attr "type") 
15181         (cond [(and (eq_attr "alternative" "2")
15182                     (match_operand:DF 3 "mult_operator" ""))
15183                  (const_string "ssemul")
15184                (and (eq_attr "alternative" "2")
15185                     (match_operand:DF 3 "div_operator" ""))
15186                  (const_string "ssediv")
15187                (eq_attr "alternative" "2")
15188                  (const_string "sseadd")
15189                (match_operand:DF 3 "mult_operator" "") 
15190                  (const_string "fmul")
15191                (match_operand:DF 3 "div_operator" "") 
15192                  (const_string "fdiv")
15193               ]
15194               (const_string "fop")))
15195    (set_attr "mode" "DF")])
15196
15197 (define_insn "*fop_df_1_sse"
15198   [(set (match_operand:DF 0 "register_operand" "=Y")
15199         (match_operator:DF 3 "binary_fp_operator"
15200                         [(match_operand:DF 1 "register_operand" "0")
15201                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15202   "TARGET_SSE2 && TARGET_SSE_MATH
15203    && !COMMUTATIVE_ARITH_P (operands[3])"
15204   "* return output_387_binary_op (insn, operands);"
15205   [(set_attr "mode" "DF")
15206    (set (attr "type") 
15207         (cond [(match_operand:DF 3 "mult_operator" "")
15208                  (const_string "ssemul")
15209                (match_operand:DF 3 "div_operator" "")
15210                  (const_string "ssediv")
15211               ]
15212               (const_string "sseadd")))])
15213
15214 ;; This pattern is not fully shadowed by the pattern above.
15215 (define_insn "*fop_df_1_i387"
15216   [(set (match_operand:DF 0 "register_operand" "=f,f")
15217         (match_operator:DF 3 "binary_fp_operator"
15218                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15219                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15220   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15221    && !COMMUTATIVE_ARITH_P (operands[3])
15222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15223   "* return output_387_binary_op (insn, operands);"
15224   [(set (attr "type") 
15225         (cond [(match_operand:DF 3 "mult_operator" "") 
15226                  (const_string "fmul")
15227                (match_operand:DF 3 "div_operator" "")
15228                  (const_string "fdiv")
15229               ]
15230               (const_string "fop")))
15231    (set_attr "mode" "DF")])
15232
15233 ;; ??? Add SSE splitters for these!
15234 (define_insn "*fop_df_2<mode>_i387"
15235   [(set (match_operand:DF 0 "register_operand" "=f,f")
15236         (match_operator:DF 3 "binary_fp_operator"
15237            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15238             (match_operand:DF 2 "register_operand" "0,0")]))]
15239   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15240    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15241   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15242   [(set (attr "type") 
15243         (cond [(match_operand:DF 3 "mult_operator" "") 
15244                  (const_string "fmul")
15245                (match_operand:DF 3 "div_operator" "") 
15246                  (const_string "fdiv")
15247               ]
15248               (const_string "fop")))
15249    (set_attr "fp_int_src" "true")
15250    (set_attr "mode" "<MODE>")])
15251
15252 (define_insn "*fop_df_3<mode>_i387"
15253   [(set (match_operand:DF 0 "register_operand" "=f,f")
15254         (match_operator:DF 3 "binary_fp_operator"
15255            [(match_operand:DF 1 "register_operand" "0,0")
15256             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15257   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15258    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15259   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15260   [(set (attr "type") 
15261         (cond [(match_operand:DF 3 "mult_operator" "") 
15262                  (const_string "fmul")
15263                (match_operand:DF 3 "div_operator" "") 
15264                  (const_string "fdiv")
15265               ]
15266               (const_string "fop")))
15267    (set_attr "fp_int_src" "true")
15268    (set_attr "mode" "<MODE>")])
15269
15270 (define_insn "*fop_df_4_i387"
15271   [(set (match_operand:DF 0 "register_operand" "=f,f")
15272         (match_operator:DF 3 "binary_fp_operator"
15273            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15274             (match_operand:DF 2 "register_operand" "0,f")]))]
15275   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15276    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15277   "* return output_387_binary_op (insn, operands);"
15278   [(set (attr "type") 
15279         (cond [(match_operand:DF 3 "mult_operator" "") 
15280                  (const_string "fmul")
15281                (match_operand:DF 3 "div_operator" "") 
15282                  (const_string "fdiv")
15283               ]
15284               (const_string "fop")))
15285    (set_attr "mode" "SF")])
15286
15287 (define_insn "*fop_df_5_i387"
15288   [(set (match_operand:DF 0 "register_operand" "=f,f")
15289         (match_operator:DF 3 "binary_fp_operator"
15290           [(match_operand:DF 1 "register_operand" "0,f")
15291            (float_extend:DF
15292             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15293   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15294   "* return output_387_binary_op (insn, operands);"
15295   [(set (attr "type") 
15296         (cond [(match_operand:DF 3 "mult_operator" "") 
15297                  (const_string "fmul")
15298                (match_operand:DF 3 "div_operator" "") 
15299                  (const_string "fdiv")
15300               ]
15301               (const_string "fop")))
15302    (set_attr "mode" "SF")])
15303
15304 (define_insn "*fop_df_6_i387"
15305   [(set (match_operand:DF 0 "register_operand" "=f,f")
15306         (match_operator:DF 3 "binary_fp_operator"
15307           [(float_extend:DF
15308             (match_operand:SF 1 "register_operand" "0,f"))
15309            (float_extend:DF
15310             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15311   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15312   "* return output_387_binary_op (insn, operands);"
15313   [(set (attr "type") 
15314         (cond [(match_operand:DF 3 "mult_operator" "") 
15315                  (const_string "fmul")
15316                (match_operand:DF 3 "div_operator" "") 
15317                  (const_string "fdiv")
15318               ]
15319               (const_string "fop")))
15320    (set_attr "mode" "SF")])
15321
15322 (define_insn "*fop_xf_comm_i387"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (match_operator:XF 3 "binary_fp_operator"
15325                         [(match_operand:XF 1 "register_operand" "%0")
15326                          (match_operand:XF 2 "register_operand" "f")]))]
15327   "TARGET_80387
15328    && COMMUTATIVE_ARITH_P (operands[3])"
15329   "* return output_387_binary_op (insn, operands);"
15330   [(set (attr "type") 
15331         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15332            (const_string "fmul")
15333            (const_string "fop")))
15334    (set_attr "mode" "XF")])
15335
15336 (define_insn "*fop_xf_1_i387"
15337   [(set (match_operand:XF 0 "register_operand" "=f,f")
15338         (match_operator:XF 3 "binary_fp_operator"
15339                         [(match_operand:XF 1 "register_operand" "0,f")
15340                          (match_operand:XF 2 "register_operand" "f,0")]))]
15341   "TARGET_80387
15342    && !COMMUTATIVE_ARITH_P (operands[3])"
15343   "* return output_387_binary_op (insn, operands);"
15344   [(set (attr "type") 
15345         (cond [(match_operand:XF 3 "mult_operator" "") 
15346                  (const_string "fmul")
15347                (match_operand:XF 3 "div_operator" "") 
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "mode" "XF")])
15352
15353 (define_insn "*fop_xf_2<mode>_i387"
15354   [(set (match_operand:XF 0 "register_operand" "=f,f")
15355         (match_operator:XF 3 "binary_fp_operator"
15356            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15357             (match_operand:XF 2 "register_operand" "0,0")]))]
15358   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15359   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15360   [(set (attr "type") 
15361         (cond [(match_operand:XF 3 "mult_operator" "") 
15362                  (const_string "fmul")
15363                (match_operand:XF 3 "div_operator" "") 
15364                  (const_string "fdiv")
15365               ]
15366               (const_string "fop")))
15367    (set_attr "fp_int_src" "true")
15368    (set_attr "mode" "<MODE>")])
15369
15370 (define_insn "*fop_xf_3<mode>_i387"
15371   [(set (match_operand:XF 0 "register_operand" "=f,f")
15372         (match_operator:XF 3 "binary_fp_operator"
15373           [(match_operand:XF 1 "register_operand" "0,0")
15374            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15375   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15376   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15377   [(set (attr "type") 
15378         (cond [(match_operand:XF 3 "mult_operator" "") 
15379                  (const_string "fmul")
15380                (match_operand:XF 3 "div_operator" "") 
15381                  (const_string "fdiv")
15382               ]
15383               (const_string "fop")))
15384    (set_attr "fp_int_src" "true")
15385    (set_attr "mode" "<MODE>")])
15386
15387 (define_insn "*fop_xf_4_i387"
15388   [(set (match_operand:XF 0 "register_operand" "=f,f")
15389         (match_operator:XF 3 "binary_fp_operator"
15390            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15391             (match_operand:XF 2 "register_operand" "0,f")]))]
15392   "TARGET_80387"
15393   "* return output_387_binary_op (insn, operands);"
15394   [(set (attr "type") 
15395         (cond [(match_operand:XF 3 "mult_operator" "") 
15396                  (const_string "fmul")
15397                (match_operand:XF 3 "div_operator" "") 
15398                  (const_string "fdiv")
15399               ]
15400               (const_string "fop")))
15401    (set_attr "mode" "SF")])
15402
15403 (define_insn "*fop_xf_5_i387"
15404   [(set (match_operand:XF 0 "register_operand" "=f,f")
15405         (match_operator:XF 3 "binary_fp_operator"
15406           [(match_operand:XF 1 "register_operand" "0,f")
15407            (float_extend:XF
15408             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15409   "TARGET_80387"
15410   "* return output_387_binary_op (insn, operands);"
15411   [(set (attr "type") 
15412         (cond [(match_operand:XF 3 "mult_operator" "") 
15413                  (const_string "fmul")
15414                (match_operand:XF 3 "div_operator" "") 
15415                  (const_string "fdiv")
15416               ]
15417               (const_string "fop")))
15418    (set_attr "mode" "SF")])
15419
15420 (define_insn "*fop_xf_6_i387"
15421   [(set (match_operand:XF 0 "register_operand" "=f,f")
15422         (match_operator:XF 3 "binary_fp_operator"
15423           [(float_extend:XF
15424             (match_operand 1 "register_operand" "0,f"))
15425            (float_extend:XF
15426             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15427   "TARGET_80387"
15428   "* return output_387_binary_op (insn, operands);"
15429   [(set (attr "type") 
15430         (cond [(match_operand:XF 3 "mult_operator" "") 
15431                  (const_string "fmul")
15432                (match_operand:XF 3 "div_operator" "") 
15433                  (const_string "fdiv")
15434               ]
15435               (const_string "fop")))
15436    (set_attr "mode" "SF")])
15437
15438 (define_split
15439   [(set (match_operand 0 "register_operand" "")
15440         (match_operator 3 "binary_fp_operator"
15441            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15442             (match_operand 2 "register_operand" "")]))]
15443   "TARGET_80387 && reload_completed
15444    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15445   [(const_int 0)]
15446
15447   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15448   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15449   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15450                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15451                                           GET_MODE (operands[3]),
15452                                           operands[4],
15453                                           operands[2])));
15454   ix86_free_from_memory (GET_MODE (operands[1]));
15455   DONE;
15456 })
15457
15458 (define_split
15459   [(set (match_operand 0 "register_operand" "")
15460         (match_operator 3 "binary_fp_operator"
15461            [(match_operand 1 "register_operand" "")
15462             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15463   "TARGET_80387 && reload_completed
15464    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15465   [(const_int 0)]
15466 {
15467   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15468   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15469   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15470                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15471                                           GET_MODE (operands[3]),
15472                                           operands[1],
15473                                           operands[4])));
15474   ix86_free_from_memory (GET_MODE (operands[2]));
15475   DONE;
15476 })
15477 \f
15478 ;; FPU special functions.
15479
15480 (define_expand "sqrtsf2"
15481   [(set (match_operand:SF 0 "register_operand" "")
15482         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15483   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15484 {
15485   if (!TARGET_SSE_MATH)
15486     operands[1] = force_reg (SFmode, operands[1]);
15487 })
15488
15489 (define_insn "*sqrtsf2_mixed"
15490   [(set (match_operand:SF 0 "register_operand" "=f,x")
15491         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15492   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15493   "@
15494    fsqrt
15495    sqrtss\t{%1, %0|%0, %1}"
15496   [(set_attr "type" "fpspc,sse")
15497    (set_attr "mode" "SF,SF")
15498    (set_attr "athlon_decode" "direct,*")])
15499
15500 (define_insn "*sqrtsf2_sse"
15501   [(set (match_operand:SF 0 "register_operand" "=x")
15502         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15503   "TARGET_SSE_MATH"
15504   "sqrtss\t{%1, %0|%0, %1}"
15505   [(set_attr "type" "sse")
15506    (set_attr "mode" "SF")
15507    (set_attr "athlon_decode" "*")])
15508
15509 (define_insn "*sqrtsf2_i387"
15510   [(set (match_operand:SF 0 "register_operand" "=f")
15511         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15512   "TARGET_USE_FANCY_MATH_387"
15513   "fsqrt"
15514   [(set_attr "type" "fpspc")
15515    (set_attr "mode" "SF")
15516    (set_attr "athlon_decode" "direct")])
15517
15518 (define_expand "sqrtdf2"
15519   [(set (match_operand:DF 0 "register_operand" "")
15520         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15521   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15522 {
15523   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15524     operands[1] = force_reg (DFmode, operands[1]);
15525 })
15526
15527 (define_insn "*sqrtdf2_mixed"
15528   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15529         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15530   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15531   "@
15532    fsqrt
15533    sqrtsd\t{%1, %0|%0, %1}"
15534   [(set_attr "type" "fpspc,sse")
15535    (set_attr "mode" "DF,DF")
15536    (set_attr "athlon_decode" "direct,*")])
15537
15538 (define_insn "*sqrtdf2_sse"
15539   [(set (match_operand:DF 0 "register_operand" "=Y")
15540         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15541   "TARGET_SSE2 && TARGET_SSE_MATH"
15542   "sqrtsd\t{%1, %0|%0, %1}"
15543   [(set_attr "type" "sse")
15544    (set_attr "mode" "DF")
15545    (set_attr "athlon_decode" "*")])
15546
15547 (define_insn "*sqrtdf2_i387"
15548   [(set (match_operand:DF 0 "register_operand" "=f")
15549         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15550   "TARGET_USE_FANCY_MATH_387"
15551   "fsqrt"
15552   [(set_attr "type" "fpspc")
15553    (set_attr "mode" "DF")
15554    (set_attr "athlon_decode" "direct")])
15555
15556 (define_insn "*sqrtextendsfdf2_i387"
15557   [(set (match_operand:DF 0 "register_operand" "=f")
15558         (sqrt:DF (float_extend:DF
15559                   (match_operand:SF 1 "register_operand" "0"))))]
15560   "TARGET_USE_FANCY_MATH_387
15561    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15562   "fsqrt"
15563   [(set_attr "type" "fpspc")
15564    (set_attr "mode" "DF")
15565    (set_attr "athlon_decode" "direct")])
15566
15567 (define_insn "sqrtxf2"
15568   [(set (match_operand:XF 0 "register_operand" "=f")
15569         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15570   "TARGET_USE_FANCY_MATH_387"
15571   "fsqrt"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "mode" "XF")
15574    (set_attr "athlon_decode" "direct")])
15575
15576 (define_insn "*sqrtextendsfxf2_i387"
15577   [(set (match_operand:XF 0 "register_operand" "=f")
15578         (sqrt:XF (float_extend:XF
15579                   (match_operand:SF 1 "register_operand" "0"))))]
15580   "TARGET_USE_FANCY_MATH_387"
15581   "fsqrt"
15582   [(set_attr "type" "fpspc")
15583    (set_attr "mode" "XF")
15584    (set_attr "athlon_decode" "direct")])
15585
15586 (define_insn "*sqrtextenddfxf2_i387"
15587   [(set (match_operand:XF 0 "register_operand" "=f")
15588         (sqrt:XF (float_extend:XF
15589                   (match_operand:DF 1 "register_operand" "0"))))]
15590   "TARGET_USE_FANCY_MATH_387"
15591   "fsqrt"
15592   [(set_attr "type" "fpspc")
15593    (set_attr "mode" "XF")
15594    (set_attr "athlon_decode" "direct")])
15595
15596 (define_insn "fpremxf4"
15597   [(set (match_operand:XF 0 "register_operand" "=f")
15598         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15599                     (match_operand:XF 3 "register_operand" "1")]
15600                    UNSPEC_FPREM_F))
15601    (set (match_operand:XF 1 "register_operand" "=u")
15602         (unspec:XF [(match_dup 2) (match_dup 3)]
15603                    UNSPEC_FPREM_U))
15604    (set (reg:CCFP FPSR_REG)
15605         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && flag_unsafe_math_optimizations"
15608   "fprem"
15609   [(set_attr "type" "fpspc")
15610    (set_attr "mode" "XF")])
15611
15612 (define_expand "fmodsf3"
15613   [(use (match_operand:SF 0 "register_operand" ""))
15614    (use (match_operand:SF 1 "register_operand" ""))
15615    (use (match_operand:SF 2 "register_operand" ""))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15618    && flag_unsafe_math_optimizations"
15619 {
15620   rtx label = gen_label_rtx ();
15621
15622   rtx op1 = gen_reg_rtx (XFmode);
15623   rtx op2 = gen_reg_rtx (XFmode);
15624
15625   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15626   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15627
15628   emit_label (label);
15629
15630   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15631   ix86_emit_fp_unordered_jump (label);
15632
15633   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15634   DONE;
15635 })
15636
15637 (define_expand "fmoddf3"
15638   [(use (match_operand:DF 0 "register_operand" ""))
15639    (use (match_operand:DF 1 "register_operand" ""))
15640    (use (match_operand:DF 2 "register_operand" ""))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15643    && flag_unsafe_math_optimizations"
15644 {
15645   rtx label = gen_label_rtx ();
15646
15647   rtx op1 = gen_reg_rtx (XFmode);
15648   rtx op2 = gen_reg_rtx (XFmode);
15649
15650   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15651   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15652
15653   emit_label (label);
15654
15655   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15656   ix86_emit_fp_unordered_jump (label);
15657
15658   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15659   DONE;
15660 })
15661
15662 (define_expand "fmodxf3"
15663   [(use (match_operand:XF 0 "register_operand" ""))
15664    (use (match_operand:XF 1 "register_operand" ""))
15665    (use (match_operand:XF 2 "register_operand" ""))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && flag_unsafe_math_optimizations"
15668 {
15669   rtx label = gen_label_rtx ();
15670
15671   emit_label (label);
15672
15673   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15674                            operands[1], operands[2]));
15675   ix86_emit_fp_unordered_jump (label);
15676
15677   emit_move_insn (operands[0], operands[1]);
15678   DONE;
15679 })
15680
15681 (define_insn "fprem1xf4"
15682   [(set (match_operand:XF 0 "register_operand" "=f")
15683         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15684                     (match_operand:XF 3 "register_operand" "1")]
15685                    UNSPEC_FPREM1_F))
15686    (set (match_operand:XF 1 "register_operand" "=u")
15687         (unspec:XF [(match_dup 2) (match_dup 3)]
15688                    UNSPEC_FPREM1_U))
15689    (set (reg:CCFP FPSR_REG)
15690         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && flag_unsafe_math_optimizations"
15693   "fprem1"
15694   [(set_attr "type" "fpspc")
15695    (set_attr "mode" "XF")])
15696
15697 (define_expand "dremsf3"
15698   [(use (match_operand:SF 0 "register_operand" ""))
15699    (use (match_operand:SF 1 "register_operand" ""))
15700    (use (match_operand:SF 2 "register_operand" ""))]
15701   "TARGET_USE_FANCY_MATH_387
15702    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15703    && flag_unsafe_math_optimizations"
15704 {
15705   rtx label = gen_label_rtx ();
15706
15707   rtx op1 = gen_reg_rtx (XFmode);
15708   rtx op2 = gen_reg_rtx (XFmode);
15709
15710   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15711   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15712
15713   emit_label (label);
15714
15715   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15716   ix86_emit_fp_unordered_jump (label);
15717
15718   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15719   DONE;
15720 })
15721
15722 (define_expand "dremdf3"
15723   [(use (match_operand:DF 0 "register_operand" ""))
15724    (use (match_operand:DF 1 "register_operand" ""))
15725    (use (match_operand:DF 2 "register_operand" ""))]
15726   "TARGET_USE_FANCY_MATH_387
15727    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728    && flag_unsafe_math_optimizations"
15729 {
15730   rtx label = gen_label_rtx ();
15731
15732   rtx op1 = gen_reg_rtx (XFmode);
15733   rtx op2 = gen_reg_rtx (XFmode);
15734
15735   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15736   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15737
15738   emit_label (label);
15739
15740   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15741   ix86_emit_fp_unordered_jump (label);
15742
15743   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15744   DONE;
15745 })
15746
15747 (define_expand "dremxf3"
15748   [(use (match_operand:XF 0 "register_operand" ""))
15749    (use (match_operand:XF 1 "register_operand" ""))
15750    (use (match_operand:XF 2 "register_operand" ""))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && flag_unsafe_math_optimizations"
15753 {
15754   rtx label = gen_label_rtx ();
15755
15756   emit_label (label);
15757
15758   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759                             operands[1], operands[2]));
15760   ix86_emit_fp_unordered_jump (label);
15761
15762   emit_move_insn (operands[0], operands[1]);
15763   DONE;
15764 })
15765
15766 (define_insn "*sindf2"
15767   [(set (match_operand:DF 0 "register_operand" "=f")
15768         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771    && flag_unsafe_math_optimizations"
15772   "fsin"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "DF")])
15775
15776 (define_insn "*sinsf2"
15777   [(set (match_operand:SF 0 "register_operand" "=f")
15778         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782   "fsin"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "SF")])
15785
15786 (define_insn "*sinextendsfdf2"
15787   [(set (match_operand:DF 0 "register_operand" "=f")
15788         (unspec:DF [(float_extend:DF
15789                      (match_operand:SF 1 "register_operand" "0"))]
15790                    UNSPEC_SIN))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15794   "fsin"
15795   [(set_attr "type" "fpspc")
15796    (set_attr "mode" "DF")])
15797
15798 (define_insn "*sinxf2"
15799   [(set (match_operand:XF 0 "register_operand" "=f")
15800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && flag_unsafe_math_optimizations"
15803   "fsin"
15804   [(set_attr "type" "fpspc")
15805    (set_attr "mode" "XF")])
15806
15807 (define_insn "*cosdf2"
15808   [(set (match_operand:DF 0 "register_operand" "=f")
15809         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813   "fcos"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "DF")])
15816
15817 (define_insn "*cossf2"
15818   [(set (match_operand:SF 0 "register_operand" "=f")
15819         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820   "TARGET_USE_FANCY_MATH_387
15821    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822    && flag_unsafe_math_optimizations"
15823   "fcos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "SF")])
15826
15827 (define_insn "*cosextendsfdf2"
15828   [(set (match_operand:DF 0 "register_operand" "=f")
15829         (unspec:DF [(float_extend:DF
15830                      (match_operand:SF 1 "register_operand" "0"))]
15831                    UNSPEC_COS))]
15832   "TARGET_USE_FANCY_MATH_387
15833    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15835   "fcos"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")])
15838
15839 (define_insn "*cosxf2"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15844   "fcos"
15845   [(set_attr "type" "fpspc")
15846    (set_attr "mode" "XF")])
15847
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused. 
15850 ;; Cse pass  will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15853
15854 (define_insn "sincosdf3"
15855   [(set (match_operand:DF 0 "register_operand" "=f")
15856         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857                    UNSPEC_SINCOS_COS))
15858    (set (match_operand:DF 1 "register_operand" "=u")
15859         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862    && flag_unsafe_math_optimizations"
15863   "fsincos"
15864   [(set_attr "type" "fpspc")
15865    (set_attr "mode" "DF")])
15866
15867 (define_split
15868   [(set (match_operand:DF 0 "register_operand" "")
15869         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870                    UNSPEC_SINCOS_COS))
15871    (set (match_operand:DF 1 "register_operand" "")
15872         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874    && !reload_completed && !reload_in_progress"
15875   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15876   "")
15877
15878 (define_split
15879   [(set (match_operand:DF 0 "register_operand" "")
15880         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881                    UNSPEC_SINCOS_COS))
15882    (set (match_operand:DF 1 "register_operand" "")
15883         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885    && !reload_completed && !reload_in_progress"
15886   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15887   "")
15888
15889 (define_insn "sincossf3"
15890   [(set (match_operand:SF 0 "register_operand" "=f")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:SF 1 "register_operand" "=u")
15894         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fsincos"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "SF")])
15901
15902 (define_split
15903   [(set (match_operand:SF 0 "register_operand" "")
15904         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905                    UNSPEC_SINCOS_COS))
15906    (set (match_operand:SF 1 "register_operand" "")
15907         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909    && !reload_completed && !reload_in_progress"
15910   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15911   "")
15912
15913 (define_split
15914   [(set (match_operand:SF 0 "register_operand" "")
15915         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916                    UNSPEC_SINCOS_COS))
15917    (set (match_operand:SF 1 "register_operand" "")
15918         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920    && !reload_completed && !reload_in_progress"
15921   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15922   "")
15923
15924 (define_insn "*sincosextendsfdf3"
15925   [(set (match_operand:DF 0 "register_operand" "=f")
15926         (unspec:DF [(float_extend:DF
15927                      (match_operand:SF 2 "register_operand" "0"))]
15928                    UNSPEC_SINCOS_COS))
15929    (set (match_operand:DF 1 "register_operand" "=u")
15930         (unspec:DF [(float_extend:DF
15931                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15935   "fsincos"
15936   [(set_attr "type" "fpspc")
15937    (set_attr "mode" "DF")])
15938
15939 (define_split
15940   [(set (match_operand:DF 0 "register_operand" "")
15941         (unspec:DF [(float_extend:DF
15942                      (match_operand:SF 2 "register_operand" ""))]
15943                    UNSPEC_SINCOS_COS))
15944    (set (match_operand:DF 1 "register_operand" "")
15945         (unspec:DF [(float_extend:DF
15946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948    && !reload_completed && !reload_in_progress"
15949   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950                                    (match_dup 2))] UNSPEC_SIN))]
15951   "")
15952
15953 (define_split
15954   [(set (match_operand:DF 0 "register_operand" "")
15955         (unspec:DF [(float_extend:DF
15956                      (match_operand:SF 2 "register_operand" ""))]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:DF 1 "register_operand" "")
15959         (unspec:DF [(float_extend:DF
15960                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962    && !reload_completed && !reload_in_progress"
15963   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964                                    (match_dup 2))] UNSPEC_COS))]
15965   "")
15966
15967 (define_insn "sincosxf3"
15968   [(set (match_operand:XF 0 "register_operand" "=f")
15969         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970                    UNSPEC_SINCOS_COS))
15971    (set (match_operand:XF 1 "register_operand" "=u")
15972         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973   "TARGET_USE_FANCY_MATH_387
15974    && flag_unsafe_math_optimizations"
15975   "fsincos"
15976   [(set_attr "type" "fpspc")
15977    (set_attr "mode" "XF")])
15978
15979 (define_split
15980   [(set (match_operand:XF 0 "register_operand" "")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982                    UNSPEC_SINCOS_COS))
15983    (set (match_operand:XF 1 "register_operand" "")
15984         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986    && !reload_completed && !reload_in_progress"
15987   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15988   "")
15989
15990 (define_split
15991   [(set (match_operand:XF 0 "register_operand" "")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993                    UNSPEC_SINCOS_COS))
15994    (set (match_operand:XF 1 "register_operand" "")
15995         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997    && !reload_completed && !reload_in_progress"
15998   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15999   "")
16000
16001 (define_insn "*tandf3_1"
16002   [(set (match_operand:DF 0 "register_operand" "=f")
16003         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004                    UNSPEC_TAN_ONE))
16005    (set (match_operand:DF 1 "register_operand" "=u")
16006         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007   "TARGET_USE_FANCY_MATH_387
16008    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009    && flag_unsafe_math_optimizations"
16010   "fptan"
16011   [(set_attr "type" "fpspc")
16012    (set_attr "mode" "DF")])
16013
16014 ;; optimize sequence: fptan
16015 ;;                    fstp    %st(0)
16016 ;;                    fld1
16017 ;; into fptan insn.
16018
16019 (define_peephole2
16020   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022                              UNSPEC_TAN_ONE))
16023              (set (match_operand:DF 1 "register_operand" "")
16024                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025    (set (match_dup 0)
16026         (match_operand:DF 3 "immediate_operand" ""))]
16027   "standard_80387_constant_p (operands[3]) == 2"
16028   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16030   "")
16031
16032 (define_expand "tandf2"
16033   [(parallel [(set (match_dup 2)
16034                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035                               UNSPEC_TAN_ONE))
16036               (set (match_operand:DF 0 "register_operand" "")
16037                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16041 {
16042   operands[2] = gen_reg_rtx (DFmode);
16043 })
16044
16045 (define_insn "*tansf3_1"
16046   [(set (match_operand:SF 0 "register_operand" "=f")
16047         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048                    UNSPEC_TAN_ONE))
16049    (set (match_operand:SF 1 "register_operand" "=u")
16050         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054   "fptan"
16055   [(set_attr "type" "fpspc")
16056    (set_attr "mode" "SF")])
16057
16058 ;; optimize sequence: fptan
16059 ;;                    fstp    %st(0)
16060 ;;                    fld1
16061 ;; into fptan insn.
16062
16063 (define_peephole2
16064   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066                              UNSPEC_TAN_ONE))
16067              (set (match_operand:SF 1 "register_operand" "")
16068                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069    (set (match_dup 0)
16070         (match_operand:SF 3 "immediate_operand" ""))]
16071   "standard_80387_constant_p (operands[3]) == 2"
16072   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16074   "")
16075
16076 (define_expand "tansf2"
16077   [(parallel [(set (match_dup 2)
16078                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079                               UNSPEC_TAN_ONE))
16080               (set (match_operand:SF 0 "register_operand" "")
16081                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082   "TARGET_USE_FANCY_MATH_387
16083    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084    && flag_unsafe_math_optimizations"
16085 {
16086   operands[2] = gen_reg_rtx (SFmode);
16087 })
16088
16089 (define_insn "*tanxf3_1"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092                    UNSPEC_TAN_ONE))
16093    (set (match_operand:XF 1 "register_operand" "=u")
16094         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16097   "fptan"
16098   [(set_attr "type" "fpspc")
16099    (set_attr "mode" "XF")])
16100
16101 ;; optimize sequence: fptan
16102 ;;                    fstp    %st(0)
16103 ;;                    fld1
16104 ;; into fptan insn.
16105
16106 (define_peephole2
16107   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109                              UNSPEC_TAN_ONE))
16110              (set (match_operand:XF 1 "register_operand" "")
16111                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112    (set (match_dup 0)
16113         (match_operand:XF 3 "immediate_operand" ""))]
16114   "standard_80387_constant_p (operands[3]) == 2"
16115   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16117   "")
16118
16119 (define_expand "tanxf2"
16120   [(parallel [(set (match_dup 2)
16121                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122                               UNSPEC_TAN_ONE))
16123               (set (match_operand:XF 0 "register_operand" "")
16124                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16127 {
16128   operands[2] = gen_reg_rtx (XFmode);
16129 })
16130
16131 (define_insn "atan2df3_1"
16132   [(set (match_operand:DF 0 "register_operand" "=f")
16133         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134                     (match_operand:DF 1 "register_operand" "u")]
16135                    UNSPEC_FPATAN))
16136    (clobber (match_scratch:DF 3 "=1"))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139    && flag_unsafe_math_optimizations"
16140   "fpatan"
16141   [(set_attr "type" "fpspc")
16142    (set_attr "mode" "DF")])
16143
16144 (define_expand "atan2df3"
16145   [(use (match_operand:DF 0 "register_operand" ""))
16146    (use (match_operand:DF 2 "register_operand" ""))
16147    (use (match_operand:DF 1 "register_operand" ""))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16151 {
16152   rtx copy = gen_reg_rtx (DFmode);
16153   emit_move_insn (copy, operands[1]);
16154   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16155   DONE;
16156 })
16157
16158 (define_expand "atandf2"
16159   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160                    (unspec:DF [(match_dup 2)
16161                                (match_operand:DF 1 "register_operand" "")]
16162                     UNSPEC_FPATAN))
16163               (clobber (match_scratch:DF 3 ""))])]
16164   "TARGET_USE_FANCY_MATH_387
16165    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166    && flag_unsafe_math_optimizations"
16167 {
16168   operands[2] = gen_reg_rtx (DFmode);
16169   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16170 })
16171
16172 (define_insn "atan2sf3_1"
16173   [(set (match_operand:SF 0 "register_operand" "=f")
16174         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175                     (match_operand:SF 1 "register_operand" "u")]
16176                    UNSPEC_FPATAN))
16177    (clobber (match_scratch:SF 3 "=1"))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16181   "fpatan"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "SF")])
16184
16185 (define_expand "atan2sf3"
16186   [(use (match_operand:SF 0 "register_operand" ""))
16187    (use (match_operand:SF 2 "register_operand" ""))
16188    (use (match_operand:SF 1 "register_operand" ""))]
16189   "TARGET_USE_FANCY_MATH_387
16190    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx copy = gen_reg_rtx (SFmode);
16194   emit_move_insn (copy, operands[1]);
16195   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16196   DONE;
16197 })
16198
16199 (define_expand "atansf2"
16200   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201                    (unspec:SF [(match_dup 2)
16202                                (match_operand:SF 1 "register_operand" "")]
16203                     UNSPEC_FPATAN))
16204               (clobber (match_scratch:SF 3 ""))])]
16205   "TARGET_USE_FANCY_MATH_387
16206    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207    && flag_unsafe_math_optimizations"
16208 {
16209   operands[2] = gen_reg_rtx (SFmode);
16210   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16211 })
16212
16213 (define_insn "atan2xf3_1"
16214   [(set (match_operand:XF 0 "register_operand" "=f")
16215         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216                     (match_operand:XF 1 "register_operand" "u")]
16217                    UNSPEC_FPATAN))
16218    (clobber (match_scratch:XF 3 "=1"))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221   "fpatan"
16222   [(set_attr "type" "fpspc")
16223    (set_attr "mode" "XF")])
16224
16225 (define_expand "atan2xf3"
16226   [(use (match_operand:XF 0 "register_operand" ""))
16227    (use (match_operand:XF 2 "register_operand" ""))
16228    (use (match_operand:XF 1 "register_operand" ""))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && flag_unsafe_math_optimizations"
16231 {
16232   rtx copy = gen_reg_rtx (XFmode);
16233   emit_move_insn (copy, operands[1]);
16234   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16235   DONE;
16236 })
16237
16238 (define_expand "atanxf2"
16239   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240                    (unspec:XF [(match_dup 2)
16241                                (match_operand:XF 1 "register_operand" "")]
16242                     UNSPEC_FPATAN))
16243               (clobber (match_scratch:XF 3 ""))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   operands[2] = gen_reg_rtx (XFmode);
16248   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16249 })
16250
16251 (define_expand "asindf2"
16252   [(set (match_dup 2)
16253         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257    (parallel [(set (match_dup 7)
16258                    (unspec:XF [(match_dup 6) (match_dup 2)]
16259                               UNSPEC_FPATAN))
16260               (clobber (match_scratch:XF 8 ""))])
16261    (set (match_operand:DF 0 "register_operand" "")
16262         (float_truncate:DF (match_dup 7)))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16266 {
16267   int i;
16268
16269   for (i=2; i<8; i++)
16270     operands[i] = gen_reg_rtx (XFmode);
16271
16272   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16273 })
16274
16275 (define_expand "asinsf2"
16276   [(set (match_dup 2)
16277         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281    (parallel [(set (match_dup 7)
16282                    (unspec:XF [(match_dup 6) (match_dup 2)]
16283                               UNSPEC_FPATAN))
16284               (clobber (match_scratch:XF 8 ""))])
16285    (set (match_operand:SF 0 "register_operand" "")
16286         (float_truncate:SF (match_dup 7)))]
16287   "TARGET_USE_FANCY_MATH_387
16288    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289    && flag_unsafe_math_optimizations"
16290 {
16291   int i;
16292
16293   for (i=2; i<8; i++)
16294     operands[i] = gen_reg_rtx (XFmode);
16295
16296   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16297 })
16298
16299 (define_expand "asinxf2"
16300   [(set (match_dup 2)
16301         (mult:XF (match_operand:XF 1 "register_operand" "")
16302                  (match_dup 1)))
16303    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305    (parallel [(set (match_operand:XF 0 "register_operand" "")
16306                    (unspec:XF [(match_dup 5) (match_dup 1)]
16307                               UNSPEC_FPATAN))
16308               (clobber (match_scratch:XF 6 ""))])]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16311 {
16312   int i;
16313
16314   for (i=2; i<6; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16316
16317   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16318 })
16319
16320 (define_expand "acosdf2"
16321   [(set (match_dup 2)
16322         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326    (parallel [(set (match_dup 7)
16327                    (unspec:XF [(match_dup 2) (match_dup 6)]
16328                               UNSPEC_FPATAN))
16329               (clobber (match_scratch:XF 8 ""))])
16330    (set (match_operand:DF 0 "register_operand" "")
16331         (float_truncate:DF (match_dup 7)))]
16332   "TARGET_USE_FANCY_MATH_387
16333    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334    && flag_unsafe_math_optimizations"
16335 {
16336   int i;
16337
16338   for (i=2; i<8; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16340
16341   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16342 })
16343
16344 (define_expand "acossf2"
16345   [(set (match_dup 2)
16346         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350    (parallel [(set (match_dup 7)
16351                    (unspec:XF [(match_dup 2) (match_dup 6)]
16352                               UNSPEC_FPATAN))
16353               (clobber (match_scratch:XF 8 ""))])
16354    (set (match_operand:SF 0 "register_operand" "")
16355         (float_truncate:SF (match_dup 7)))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358    && flag_unsafe_math_optimizations"
16359 {
16360   int i;
16361
16362   for (i=2; i<8; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16364
16365   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16366 })
16367
16368 (define_expand "acosxf2"
16369   [(set (match_dup 2)
16370         (mult:XF (match_operand:XF 1 "register_operand" "")
16371                  (match_dup 1)))
16372    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374    (parallel [(set (match_operand:XF 0 "register_operand" "")
16375                    (unspec:XF [(match_dup 1) (match_dup 5)]
16376                               UNSPEC_FPATAN))
16377               (clobber (match_scratch:XF 6 ""))])]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16380 {
16381   int i;
16382
16383   for (i=2; i<6; i++)
16384     operands[i] = gen_reg_rtx (XFmode);
16385
16386   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16387 })
16388
16389 (define_insn "fyl2x_xf3"
16390   [(set (match_operand:XF 0 "register_operand" "=f")
16391         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392                     (match_operand:XF 1 "register_operand" "u")]
16393                    UNSPEC_FYL2X))
16394    (clobber (match_scratch:XF 3 "=1"))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && flag_unsafe_math_optimizations"
16397   "fyl2x"
16398   [(set_attr "type" "fpspc")
16399    (set_attr "mode" "XF")])
16400
16401 (define_expand "logsf2"
16402   [(set (match_dup 2)
16403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404    (parallel [(set (match_dup 4)
16405                    (unspec:XF [(match_dup 2)
16406                                (match_dup 3)] UNSPEC_FYL2X))
16407               (clobber (match_scratch:XF 5 ""))])
16408    (set (match_operand:SF 0 "register_operand" "")
16409         (float_truncate:SF (match_dup 4)))]
16410   "TARGET_USE_FANCY_MATH_387
16411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412    && flag_unsafe_math_optimizations"
16413 {
16414   rtx temp;
16415
16416   operands[2] = gen_reg_rtx (XFmode);
16417   operands[3] = gen_reg_rtx (XFmode);
16418   operands[4] = gen_reg_rtx (XFmode);
16419
16420   temp = standard_80387_constant_rtx (4); /* fldln2 */
16421   emit_move_insn (operands[3], temp);
16422 })
16423
16424 (define_expand "logdf2"
16425   [(set (match_dup 2)
16426         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427    (parallel [(set (match_dup 4)
16428                    (unspec:XF [(match_dup 2)
16429                                (match_dup 3)] UNSPEC_FYL2X))
16430               (clobber (match_scratch:XF 5 ""))])
16431    (set (match_operand:DF 0 "register_operand" "")
16432         (float_truncate:DF (match_dup 4)))]
16433   "TARGET_USE_FANCY_MATH_387
16434    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations"
16436 {
16437   rtx temp;
16438
16439   operands[2] = gen_reg_rtx (XFmode);
16440   operands[3] = gen_reg_rtx (XFmode);
16441   operands[4] = gen_reg_rtx (XFmode);
16442
16443   temp = standard_80387_constant_rtx (4); /* fldln2 */
16444   emit_move_insn (operands[3], temp);
16445 })
16446
16447 (define_expand "logxf2"
16448   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450                                (match_dup 2)] UNSPEC_FYL2X))
16451               (clobber (match_scratch:XF 3 ""))])]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16454 {
16455   rtx temp;
16456
16457   operands[2] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (4); /* fldln2 */
16459   emit_move_insn (operands[2], temp);
16460 })
16461
16462 (define_expand "log10sf2"
16463   [(set (match_dup 2)
16464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465    (parallel [(set (match_dup 4)
16466                    (unspec:XF [(match_dup 2)
16467                                (match_dup 3)] UNSPEC_FYL2X))
16468               (clobber (match_scratch:XF 5 ""))])
16469    (set (match_operand:SF 0 "register_operand" "")
16470         (float_truncate:SF (match_dup 4)))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473    && flag_unsafe_math_optimizations"
16474 {
16475   rtx temp;
16476
16477   operands[2] = gen_reg_rtx (XFmode);
16478   operands[3] = gen_reg_rtx (XFmode);
16479   operands[4] = gen_reg_rtx (XFmode);
16480
16481   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482   emit_move_insn (operands[3], temp);
16483 })
16484
16485 (define_expand "log10df2"
16486   [(set (match_dup 2)
16487         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488    (parallel [(set (match_dup 4)
16489                    (unspec:XF [(match_dup 2)
16490                                (match_dup 3)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 5 ""))])
16492    (set (match_operand:DF 0 "register_operand" "")
16493         (float_truncate:DF (match_dup 4)))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496    && flag_unsafe_math_optimizations"
16497 {
16498   rtx temp;
16499
16500   operands[2] = gen_reg_rtx (XFmode);
16501   operands[3] = gen_reg_rtx (XFmode);
16502   operands[4] = gen_reg_rtx (XFmode);
16503
16504   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505   emit_move_insn (operands[3], temp);
16506 })
16507
16508 (define_expand "log10xf2"
16509   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511                                (match_dup 2)] UNSPEC_FYL2X))
16512               (clobber (match_scratch:XF 3 ""))])]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16515 {
16516   rtx temp;
16517
16518   operands[2] = gen_reg_rtx (XFmode);
16519   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520   emit_move_insn (operands[2], temp);
16521 })
16522
16523 (define_expand "log2sf2"
16524   [(set (match_dup 2)
16525         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526    (parallel [(set (match_dup 4)
16527                    (unspec:XF [(match_dup 2)
16528                                (match_dup 3)] UNSPEC_FYL2X))
16529               (clobber (match_scratch:XF 5 ""))])
16530    (set (match_operand:SF 0 "register_operand" "")
16531         (float_truncate:SF (match_dup 4)))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534    && flag_unsafe_math_optimizations"
16535 {
16536   operands[2] = gen_reg_rtx (XFmode);
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16539
16540   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16541 })
16542
16543 (define_expand "log2df2"
16544   [(set (match_dup 2)
16545         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546    (parallel [(set (match_dup 4)
16547                    (unspec:XF [(match_dup 2)
16548                                (match_dup 3)] UNSPEC_FYL2X))
16549               (clobber (match_scratch:XF 5 ""))])
16550    (set (match_operand:DF 0 "register_operand" "")
16551         (float_truncate:DF (match_dup 4)))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations"
16555 {
16556   operands[2] = gen_reg_rtx (XFmode);
16557   operands[3] = gen_reg_rtx (XFmode);
16558   operands[4] = gen_reg_rtx (XFmode);
16559
16560   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16561 })
16562
16563 (define_expand "log2xf2"
16564   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566                                (match_dup 2)] UNSPEC_FYL2X))
16567               (clobber (match_scratch:XF 3 ""))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570 {
16571   operands[2] = gen_reg_rtx (XFmode);
16572   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16573 })
16574
16575 (define_insn "fyl2xp1_xf3"
16576   [(set (match_operand:XF 0 "register_operand" "=f")
16577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578                     (match_operand:XF 1 "register_operand" "u")]
16579                    UNSPEC_FYL2XP1))
16580    (clobber (match_scratch:XF 3 "=1"))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && flag_unsafe_math_optimizations"
16583   "fyl2xp1"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16586
16587 (define_expand "log1psf2"
16588   [(use (match_operand:SF 0 "register_operand" ""))
16589    (use (match_operand:SF 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592    && flag_unsafe_math_optimizations"
16593 {
16594   rtx op0 = gen_reg_rtx (XFmode);
16595   rtx op1 = gen_reg_rtx (XFmode);
16596
16597   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598   ix86_emit_i387_log1p (op0, op1);
16599   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16600   DONE;
16601 })
16602
16603 (define_expand "log1pdf2"
16604   [(use (match_operand:DF 0 "register_operand" ""))
16605    (use (match_operand:DF 1 "register_operand" ""))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608    && flag_unsafe_math_optimizations"
16609 {
16610   rtx op0 = gen_reg_rtx (XFmode);
16611   rtx op1 = gen_reg_rtx (XFmode);
16612
16613   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614   ix86_emit_i387_log1p (op0, op1);
16615   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16616   DONE;
16617 })
16618
16619 (define_expand "log1pxf2"
16620   [(use (match_operand:XF 0 "register_operand" ""))
16621    (use (match_operand:XF 1 "register_operand" ""))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624 {
16625   ix86_emit_i387_log1p (operands[0], operands[1]);
16626   DONE;
16627 })
16628
16629 (define_insn "*fxtractxf3"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632                    UNSPEC_XTRACT_FRACT))
16633    (set (match_operand:XF 1 "register_operand" "=u")
16634         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations"
16637   "fxtract"
16638   [(set_attr "type" "fpspc")
16639    (set_attr "mode" "XF")])
16640
16641 (define_expand "logbsf2"
16642   [(set (match_dup 2)
16643         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644    (parallel [(set (match_dup 3)
16645                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646               (set (match_dup 4)
16647                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648    (set (match_operand:SF 0 "register_operand" "")
16649         (float_truncate:SF (match_dup 4)))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652    && flag_unsafe_math_optimizations"
16653 {
16654   operands[2] = gen_reg_rtx (XFmode);
16655   operands[3] = gen_reg_rtx (XFmode);
16656   operands[4] = gen_reg_rtx (XFmode);
16657 })
16658
16659 (define_expand "logbdf2"
16660   [(set (match_dup 2)
16661         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662    (parallel [(set (match_dup 3)
16663                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664               (set (match_dup 4)
16665                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666    (set (match_operand:DF 0 "register_operand" "")
16667         (float_truncate:DF (match_dup 4)))]
16668   "TARGET_USE_FANCY_MATH_387
16669    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations"
16671 {
16672   operands[2] = gen_reg_rtx (XFmode);
16673   operands[3] = gen_reg_rtx (XFmode);
16674   operands[4] = gen_reg_rtx (XFmode);
16675 })
16676
16677 (define_expand "logbxf2"
16678   [(parallel [(set (match_dup 2)
16679                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680                               UNSPEC_XTRACT_FRACT))
16681               (set (match_operand:XF 0 "register_operand" "")
16682                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16685 {
16686   operands[2] = gen_reg_rtx (XFmode);
16687 })
16688
16689 (define_expand "ilogbsi2"
16690   [(parallel [(set (match_dup 2)
16691                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692                               UNSPEC_XTRACT_FRACT))
16693               (set (match_operand:XF 3 "register_operand" "")
16694                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695    (parallel [(set (match_operand:SI 0 "register_operand" "")
16696                    (fix:SI (match_dup 3)))
16697               (clobber (reg:CC FLAGS_REG))])]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16701 {
16702   operands[2] = gen_reg_rtx (XFmode);
16703   operands[3] = gen_reg_rtx (XFmode);
16704 })
16705
16706 (define_insn "*f2xm1xf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709          UNSPEC_F2XM1))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations"
16712   "f2xm1"
16713   [(set_attr "type" "fpspc")
16714    (set_attr "mode" "XF")])
16715
16716 (define_insn "*fscalexf4"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719                     (match_operand:XF 3 "register_operand" "1")]
16720                    UNSPEC_FSCALE_FRACT))
16721    (set (match_operand:XF 1 "register_operand" "=u")
16722         (unspec:XF [(match_dup 2) (match_dup 3)]
16723                    UNSPEC_FSCALE_EXP))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && flag_unsafe_math_optimizations"
16726   "fscale"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")])
16729
16730 (define_expand "expsf2"
16731   [(set (match_dup 2)
16732         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738    (parallel [(set (match_dup 10)
16739                    (unspec:XF [(match_dup 9) (match_dup 5)]
16740                               UNSPEC_FSCALE_FRACT))
16741               (set (match_dup 11)
16742                    (unspec:XF [(match_dup 9) (match_dup 5)]
16743                               UNSPEC_FSCALE_EXP))])
16744    (set (match_operand:SF 0 "register_operand" "")
16745         (float_truncate:SF (match_dup 10)))]
16746   "TARGET_USE_FANCY_MATH_387
16747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748    && flag_unsafe_math_optimizations"
16749 {
16750   rtx temp;
16751   int i;
16752
16753   for (i=2; i<12; i++)
16754     operands[i] = gen_reg_rtx (XFmode);
16755   temp = standard_80387_constant_rtx (5); /* fldl2e */
16756   emit_move_insn (operands[3], temp);
16757   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16758 })
16759
16760 (define_expand "expdf2"
16761   [(set (match_dup 2)
16762         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768    (parallel [(set (match_dup 10)
16769                    (unspec:XF [(match_dup 9) (match_dup 5)]
16770                               UNSPEC_FSCALE_FRACT))
16771               (set (match_dup 11)
16772                    (unspec:XF [(match_dup 9) (match_dup 5)]
16773                               UNSPEC_FSCALE_EXP))])
16774    (set (match_operand:DF 0 "register_operand" "")
16775         (float_truncate:DF (match_dup 10)))]
16776   "TARGET_USE_FANCY_MATH_387
16777    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations"
16779 {
16780   rtx temp;
16781   int i;
16782
16783   for (i=2; i<12; i++)
16784     operands[i] = gen_reg_rtx (XFmode);
16785   temp = standard_80387_constant_rtx (5); /* fldl2e */
16786   emit_move_insn (operands[3], temp);
16787   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16788 })
16789
16790 (define_expand "expxf2"
16791   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792                                (match_dup 2)))
16793    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797    (parallel [(set (match_operand:XF 0 "register_operand" "")
16798                    (unspec:XF [(match_dup 8) (match_dup 4)]
16799                               UNSPEC_FSCALE_FRACT))
16800               (set (match_dup 9)
16801                    (unspec:XF [(match_dup 8) (match_dup 4)]
16802                               UNSPEC_FSCALE_EXP))])]
16803   "TARGET_USE_FANCY_MATH_387
16804    && flag_unsafe_math_optimizations"
16805 {
16806   rtx temp;
16807   int i;
16808
16809   for (i=2; i<10; i++)
16810     operands[i] = gen_reg_rtx (XFmode);
16811   temp = standard_80387_constant_rtx (5); /* fldl2e */
16812   emit_move_insn (operands[2], temp);
16813   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16814 })
16815
16816 (define_expand "exp10sf2"
16817   [(set (match_dup 2)
16818         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824    (parallel [(set (match_dup 10)
16825                    (unspec:XF [(match_dup 9) (match_dup 5)]
16826                               UNSPEC_FSCALE_FRACT))
16827               (set (match_dup 11)
16828                    (unspec:XF [(match_dup 9) (match_dup 5)]
16829                               UNSPEC_FSCALE_EXP))])
16830    (set (match_operand:SF 0 "register_operand" "")
16831         (float_truncate:SF (match_dup 10)))]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16835 {
16836   rtx temp;
16837   int i;
16838
16839   for (i=2; i<12; i++)
16840     operands[i] = gen_reg_rtx (XFmode);
16841   temp = standard_80387_constant_rtx (6); /* fldl2t */
16842   emit_move_insn (operands[3], temp);
16843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16844 })
16845
16846 (define_expand "exp10df2"
16847   [(set (match_dup 2)
16848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854    (parallel [(set (match_dup 10)
16855                    (unspec:XF [(match_dup 9) (match_dup 5)]
16856                               UNSPEC_FSCALE_FRACT))
16857               (set (match_dup 11)
16858                    (unspec:XF [(match_dup 9) (match_dup 5)]
16859                               UNSPEC_FSCALE_EXP))])
16860    (set (match_operand:DF 0 "register_operand" "")
16861         (float_truncate:DF (match_dup 10)))]
16862   "TARGET_USE_FANCY_MATH_387
16863    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864    && flag_unsafe_math_optimizations"
16865 {
16866   rtx temp;
16867   int i;
16868
16869   for (i=2; i<12; i++)
16870     operands[i] = gen_reg_rtx (XFmode);
16871   temp = standard_80387_constant_rtx (6); /* fldl2t */
16872   emit_move_insn (operands[3], temp);
16873   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16874 })
16875
16876 (define_expand "exp10xf2"
16877   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878                                (match_dup 2)))
16879    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883    (parallel [(set (match_operand:XF 0 "register_operand" "")
16884                    (unspec:XF [(match_dup 8) (match_dup 4)]
16885                               UNSPEC_FSCALE_FRACT))
16886               (set (match_dup 9)
16887                    (unspec:XF [(match_dup 8) (match_dup 4)]
16888                               UNSPEC_FSCALE_EXP))])]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16891 {
16892   rtx temp;
16893   int i;
16894
16895   for (i=2; i<10; i++)
16896     operands[i] = gen_reg_rtx (XFmode);
16897   temp = standard_80387_constant_rtx (6); /* fldl2t */
16898   emit_move_insn (operands[2], temp);
16899   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16900 })
16901
16902 (define_expand "exp2sf2"
16903   [(set (match_dup 2)
16904         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909    (parallel [(set (match_dup 8)
16910                    (unspec:XF [(match_dup 7) (match_dup 3)]
16911                               UNSPEC_FSCALE_FRACT))
16912               (set (match_dup 9)
16913                    (unspec:XF [(match_dup 7) (match_dup 3)]
16914                               UNSPEC_FSCALE_EXP))])
16915    (set (match_operand:SF 0 "register_operand" "")
16916         (float_truncate:SF (match_dup 8)))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations"
16920 {
16921   int i;
16922
16923   for (i=2; i<10; i++)
16924     operands[i] = gen_reg_rtx (XFmode);
16925   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16926 })
16927
16928 (define_expand "exp2df2"
16929   [(set (match_dup 2)
16930         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935    (parallel [(set (match_dup 8)
16936                    (unspec:XF [(match_dup 7) (match_dup 3)]
16937                               UNSPEC_FSCALE_FRACT))
16938               (set (match_dup 9)
16939                    (unspec:XF [(match_dup 7) (match_dup 3)]
16940                               UNSPEC_FSCALE_EXP))])
16941    (set (match_operand:DF 0 "register_operand" "")
16942         (float_truncate:DF (match_dup 8)))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16946 {
16947   int i;
16948
16949   for (i=2; i<10; i++)
16950     operands[i] = gen_reg_rtx (XFmode);
16951   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16952 })
16953
16954 (define_expand "exp2xf2"
16955   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960    (parallel [(set (match_operand:XF 0 "register_operand" "")
16961                    (unspec:XF [(match_dup 7) (match_dup 3)]
16962                               UNSPEC_FSCALE_FRACT))
16963               (set (match_dup 8)
16964                    (unspec:XF [(match_dup 7) (match_dup 3)]
16965                               UNSPEC_FSCALE_EXP))])]
16966   "TARGET_USE_FANCY_MATH_387
16967    && flag_unsafe_math_optimizations"
16968 {
16969   int i;
16970
16971   for (i=2; i<9; i++)
16972     operands[i] = gen_reg_rtx (XFmode);
16973   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16974 })
16975
16976 (define_expand "expm1df2"
16977   [(set (match_dup 2)
16978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983    (parallel [(set (match_dup 8)
16984                    (unspec:XF [(match_dup 7) (match_dup 5)]
16985                               UNSPEC_FSCALE_FRACT))
16986                    (set (match_dup 9)
16987                    (unspec:XF [(match_dup 7) (match_dup 5)]
16988                               UNSPEC_FSCALE_EXP))])
16989    (parallel [(set (match_dup 11)
16990                    (unspec:XF [(match_dup 10) (match_dup 9)]
16991                               UNSPEC_FSCALE_FRACT))
16992               (set (match_dup 12)
16993                    (unspec:XF [(match_dup 10) (match_dup 9)]
16994                               UNSPEC_FSCALE_EXP))])
16995    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997    (set (match_operand:DF 0 "register_operand" "")
16998         (float_truncate:DF (match_dup 14)))]
16999   "TARGET_USE_FANCY_MATH_387
17000    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17002 {
17003   rtx temp;
17004   int i;
17005
17006   for (i=2; i<15; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008   temp = standard_80387_constant_rtx (5); /* fldl2e */
17009   emit_move_insn (operands[3], temp);
17010   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17011 })
17012
17013 (define_expand "expm1sf2"
17014   [(set (match_dup 2)
17015         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020    (parallel [(set (match_dup 8)
17021                    (unspec:XF [(match_dup 7) (match_dup 5)]
17022                               UNSPEC_FSCALE_FRACT))
17023                    (set (match_dup 9)
17024                    (unspec:XF [(match_dup 7) (match_dup 5)]
17025                               UNSPEC_FSCALE_EXP))])
17026    (parallel [(set (match_dup 11)
17027                    (unspec:XF [(match_dup 10) (match_dup 9)]
17028                               UNSPEC_FSCALE_FRACT))
17029               (set (match_dup 12)
17030                    (unspec:XF [(match_dup 10) (match_dup 9)]
17031                               UNSPEC_FSCALE_EXP))])
17032    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034    (set (match_operand:SF 0 "register_operand" "")
17035         (float_truncate:SF (match_dup 14)))]
17036   "TARGET_USE_FANCY_MATH_387
17037    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038    && flag_unsafe_math_optimizations"
17039 {
17040   rtx temp;
17041   int i;
17042
17043   for (i=2; i<15; i++)
17044     operands[i] = gen_reg_rtx (XFmode);
17045   temp = standard_80387_constant_rtx (5); /* fldl2e */
17046   emit_move_insn (operands[3], temp);
17047   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17048 })
17049
17050 (define_expand "expm1xf2"
17051   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052                                (match_dup 2)))
17053    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056    (parallel [(set (match_dup 7)
17057                    (unspec:XF [(match_dup 6) (match_dup 4)]
17058                               UNSPEC_FSCALE_FRACT))
17059                    (set (match_dup 8)
17060                    (unspec:XF [(match_dup 6) (match_dup 4)]
17061                               UNSPEC_FSCALE_EXP))])
17062    (parallel [(set (match_dup 10)
17063                    (unspec:XF [(match_dup 9) (match_dup 8)]
17064                               UNSPEC_FSCALE_FRACT))
17065               (set (match_dup 11)
17066                    (unspec:XF [(match_dup 9) (match_dup 8)]
17067                               UNSPEC_FSCALE_EXP))])
17068    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069    (set (match_operand:XF 0 "register_operand" "")
17070         (plus:XF (match_dup 12) (match_dup 7)))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073 {
17074   rtx temp;
17075   int i;
17076
17077   for (i=2; i<13; i++)
17078     operands[i] = gen_reg_rtx (XFmode);
17079   temp = standard_80387_constant_rtx (5); /* fldl2e */
17080   emit_move_insn (operands[2], temp);
17081   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17082 })
17083
17084 (define_expand "ldexpdf3"
17085   [(set (match_dup 3)
17086         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087    (set (match_dup 4)
17088         (float:XF (match_operand:SI 2 "register_operand" "")))
17089    (parallel [(set (match_dup 5)
17090                    (unspec:XF [(match_dup 3) (match_dup 4)]
17091                               UNSPEC_FSCALE_FRACT))
17092               (set (match_dup 6)
17093                    (unspec:XF [(match_dup 3) (match_dup 4)]
17094                               UNSPEC_FSCALE_EXP))])
17095    (set (match_operand:DF 0 "register_operand" "")
17096         (float_truncate:DF (match_dup 5)))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17100 {
17101   int i;
17102
17103   for (i=3; i<7; i++)
17104     operands[i] = gen_reg_rtx (XFmode);
17105 })
17106
17107 (define_expand "ldexpsf3"
17108   [(set (match_dup 3)
17109         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110    (set (match_dup 4)
17111         (float:XF (match_operand:SI 2 "register_operand" "")))
17112    (parallel [(set (match_dup 5)
17113                    (unspec:XF [(match_dup 3) (match_dup 4)]
17114                               UNSPEC_FSCALE_FRACT))
17115               (set (match_dup 6)
17116                    (unspec:XF [(match_dup 3) (match_dup 4)]
17117                               UNSPEC_FSCALE_EXP))])
17118    (set (match_operand:SF 0 "register_operand" "")
17119         (float_truncate:SF (match_dup 5)))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122    && flag_unsafe_math_optimizations"
17123 {
17124   int i;
17125
17126   for (i=3; i<7; i++)
17127     operands[i] = gen_reg_rtx (XFmode);
17128 })
17129
17130 (define_expand "ldexpxf3"
17131   [(set (match_dup 3)
17132         (float:XF (match_operand:SI 2 "register_operand" "")))
17133    (parallel [(set (match_operand:XF 0 " register_operand" "")
17134                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135                                (match_dup 3)]
17136                               UNSPEC_FSCALE_FRACT))
17137               (set (match_dup 4)
17138                    (unspec:XF [(match_dup 1) (match_dup 3)]
17139                               UNSPEC_FSCALE_EXP))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && flag_unsafe_math_optimizations"
17142 {
17143   int i;
17144
17145   for (i=3; i<5; i++)
17146     operands[i] = gen_reg_rtx (XFmode);
17147 })
17148 \f
17149
17150 (define_insn "frndintxf2"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153          UNSPEC_FRNDINT))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "frndint"
17157   [(set_attr "type" "fpspc")
17158    (set_attr "mode" "XF")])
17159
17160 (define_expand "rintdf2"
17161   [(use (match_operand:DF 0 "register_operand" ""))
17162    (use (match_operand:DF 1 "register_operand" ""))]
17163   "TARGET_USE_FANCY_MATH_387
17164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165    && flag_unsafe_math_optimizations"
17166 {
17167   rtx op0 = gen_reg_rtx (XFmode);
17168   rtx op1 = gen_reg_rtx (XFmode);
17169
17170   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17171   emit_insn (gen_frndintxf2 (op0, op1));
17172
17173   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17174   DONE;
17175 })
17176
17177 (define_expand "rintsf2"
17178   [(use (match_operand:SF 0 "register_operand" ""))
17179    (use (match_operand:SF 1 "register_operand" ""))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182    && flag_unsafe_math_optimizations"
17183 {
17184   rtx op0 = gen_reg_rtx (XFmode);
17185   rtx op1 = gen_reg_rtx (XFmode);
17186
17187   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17188   emit_insn (gen_frndintxf2 (op0, op1));
17189
17190   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17191   DONE;
17192 })
17193
17194 (define_expand "rintxf2"
17195   [(use (match_operand:XF 0 "register_operand" ""))
17196    (use (match_operand:XF 1 "register_operand" ""))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && flag_unsafe_math_optimizations"
17199 {
17200   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17201   DONE;
17202 })
17203
17204 (define_insn_and_split "*fistdi2_1"
17205   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17206         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17207          UNSPEC_FIST))]
17208   "TARGET_USE_FANCY_MATH_387
17209    && flag_unsafe_math_optimizations
17210    && !(reload_completed || reload_in_progress)"
17211   "#"
17212   "&& 1"
17213   [(const_int 0)]
17214 {
17215   if (memory_operand (operands[0], VOIDmode))
17216     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17217   else
17218     {
17219       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17220       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17221                                          operands[2]));
17222     }
17223   DONE;
17224 }
17225   [(set_attr "type" "fpspc")
17226    (set_attr "mode" "DI")])
17227
17228 (define_insn "fistdi2"
17229   [(set (match_operand:DI 0 "memory_operand" "=m")
17230         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17231          UNSPEC_FIST))
17232    (clobber (match_scratch:XF 2 "=&1f"))]
17233   "TARGET_USE_FANCY_MATH_387
17234    && flag_unsafe_math_optimizations"
17235   "* return output_fix_trunc (insn, operands, 0);"
17236   [(set_attr "type" "fpspc")
17237    (set_attr "mode" "DI")])
17238
17239 (define_insn "fistdi2_with_temp"
17240   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17241         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17242          UNSPEC_FIST))
17243    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17244    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17245   "TARGET_USE_FANCY_MATH_387
17246    && flag_unsafe_math_optimizations"
17247   "#"
17248   [(set_attr "type" "fpspc")
17249    (set_attr "mode" "DI")])
17250
17251 (define_split 
17252   [(set (match_operand:DI 0 "register_operand" "")
17253         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17254          UNSPEC_FIST))
17255    (clobber (match_operand:DI 2 "memory_operand" ""))
17256    (clobber (match_scratch 3 ""))]
17257   "reload_completed"
17258   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17259               (clobber (match_dup 3))])
17260    (set (match_dup 0) (match_dup 2))]
17261   "")
17262
17263 (define_split 
17264   [(set (match_operand:DI 0 "memory_operand" "")
17265         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17266          UNSPEC_FIST))
17267    (clobber (match_operand:DI 2 "memory_operand" ""))
17268    (clobber (match_scratch 3 ""))]
17269   "reload_completed"
17270   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17271               (clobber (match_dup 3))])]
17272   "")
17273
17274 (define_insn_and_split "*fist<mode>2_1"
17275   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17276         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17277          UNSPEC_FIST))]
17278   "TARGET_USE_FANCY_MATH_387
17279    && flag_unsafe_math_optimizations
17280    && !(reload_completed || reload_in_progress)"
17281   "#"
17282   "&& 1"
17283   [(const_int 0)]
17284 {
17285   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17286   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17287                                         operands[2]));
17288   DONE;
17289 }
17290   [(set_attr "type" "fpspc")
17291    (set_attr "mode" "<MODE>")])
17292
17293 (define_insn "fist<mode>2"
17294   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17295         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17296          UNSPEC_FIST))]
17297   "TARGET_USE_FANCY_MATH_387
17298    && flag_unsafe_math_optimizations"
17299   "* return output_fix_trunc (insn, operands, 0);"
17300   [(set_attr "type" "fpspc")
17301    (set_attr "mode" "<MODE>")])
17302
17303 (define_insn "fist<mode>2_with_temp"
17304   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17305         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17306          UNSPEC_FIST))
17307    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && flag_unsafe_math_optimizations"
17310   "#"
17311   [(set_attr "type" "fpspc")
17312    (set_attr "mode" "<MODE>")])
17313
17314 (define_split 
17315   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17316         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17317          UNSPEC_FIST))
17318    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17319   "reload_completed"
17320   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17321                        UNSPEC_FIST))
17322    (set (match_dup 0) (match_dup 2))]
17323   "")
17324
17325 (define_split 
17326   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17328          UNSPEC_FIST))
17329    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17330   "reload_completed"
17331   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17332                        UNSPEC_FIST))]
17333   "")
17334
17335 (define_expand "lrint<mode>2"
17336   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17337         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17338          UNSPEC_FIST))]
17339   "TARGET_USE_FANCY_MATH_387
17340    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17341    && flag_unsafe_math_optimizations"
17342   "")
17343
17344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17345 (define_insn_and_split "frndintxf2_floor"
17346   [(set (match_operand:XF 0 "register_operand" "=f")
17347         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17348          UNSPEC_FRNDINT_FLOOR))
17349    (clobber (reg:CC FLAGS_REG))]
17350   "TARGET_USE_FANCY_MATH_387
17351    && flag_unsafe_math_optimizations
17352    && !(reload_completed || reload_in_progress)"
17353   "#"
17354   "&& 1"
17355   [(const_int 0)]
17356 {
17357   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17358
17359   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17360   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17361
17362   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17363                                         operands[2], operands[3]));
17364   DONE;
17365 }
17366   [(set_attr "type" "frndint")
17367    (set_attr "i387_cw" "floor")
17368    (set_attr "mode" "XF")])
17369
17370 (define_insn "frndintxf2_floor_i387"
17371   [(set (match_operand:XF 0 "register_operand" "=f")
17372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17373          UNSPEC_FRNDINT_FLOOR))
17374    (use (match_operand:HI 2 "memory_operand" "m"))
17375    (use (match_operand:HI 3 "memory_operand" "m"))]
17376   "TARGET_USE_FANCY_MATH_387
17377    && flag_unsafe_math_optimizations"
17378   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17379   [(set_attr "type" "frndint")
17380    (set_attr "i387_cw" "floor")
17381    (set_attr "mode" "XF")])
17382
17383 (define_expand "floorxf2"
17384   [(use (match_operand:XF 0 "register_operand" ""))
17385    (use (match_operand:XF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && flag_unsafe_math_optimizations"
17388 {
17389   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17390   DONE;
17391 })
17392
17393 (define_expand "floordf2"
17394   [(use (match_operand:DF 0 "register_operand" ""))
17395    (use (match_operand:DF 1 "register_operand" ""))]
17396   "TARGET_USE_FANCY_MATH_387
17397    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17398    && flag_unsafe_math_optimizations"
17399 {
17400   rtx op0 = gen_reg_rtx (XFmode);
17401   rtx op1 = gen_reg_rtx (XFmode);
17402
17403   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17404   emit_insn (gen_frndintxf2_floor (op0, op1));
17405
17406   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17407   DONE;
17408 })
17409
17410 (define_expand "floorsf2"
17411   [(use (match_operand:SF 0 "register_operand" ""))
17412    (use (match_operand:SF 1 "register_operand" ""))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17415    && flag_unsafe_math_optimizations"
17416 {
17417   rtx op0 = gen_reg_rtx (XFmode);
17418   rtx op1 = gen_reg_rtx (XFmode);
17419
17420   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17421   emit_insn (gen_frndintxf2_floor (op0, op1));
17422
17423   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17424   DONE;
17425 })
17426
17427 (define_insn_and_split "*fist<mode>2_floor_1"
17428   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17429         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17430          UNSPEC_FIST_FLOOR))
17431    (clobber (reg:CC FLAGS_REG))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && flag_unsafe_math_optimizations
17434    && !(reload_completed || reload_in_progress)"
17435   "#"
17436   "&& 1"
17437   [(const_int 0)]
17438 {
17439   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17440
17441   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17442   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17443   if (memory_operand (operands[0], VOIDmode))
17444     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17445                                       operands[2], operands[3]));
17446   else
17447     {
17448       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17449       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17450                                                   operands[2], operands[3],
17451                                                   operands[4]));
17452     }
17453   DONE;
17454 }
17455   [(set_attr "type" "fistp")
17456    (set_attr "i387_cw" "floor")
17457    (set_attr "mode" "<MODE>")])
17458
17459 (define_insn "fistdi2_floor"
17460   [(set (match_operand:DI 0 "memory_operand" "=m")
17461         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17462          UNSPEC_FIST_FLOOR))
17463    (use (match_operand:HI 2 "memory_operand" "m"))
17464    (use (match_operand:HI 3 "memory_operand" "m"))
17465    (clobber (match_scratch:XF 4 "=&1f"))]
17466   "TARGET_USE_FANCY_MATH_387
17467    && flag_unsafe_math_optimizations"
17468   "* return output_fix_trunc (insn, operands, 0);"
17469   [(set_attr "type" "fistp")
17470    (set_attr "i387_cw" "floor")
17471    (set_attr "mode" "DI")])
17472
17473 (define_insn "fistdi2_floor_with_temp"
17474   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17475         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17476          UNSPEC_FIST_FLOOR))
17477    (use (match_operand:HI 2 "memory_operand" "m,m"))
17478    (use (match_operand:HI 3 "memory_operand" "m,m"))
17479    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17480    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17481   "TARGET_USE_FANCY_MATH_387
17482    && flag_unsafe_math_optimizations"
17483   "#"
17484   [(set_attr "type" "fistp")
17485    (set_attr "i387_cw" "floor")
17486    (set_attr "mode" "DI")])
17487
17488 (define_split 
17489   [(set (match_operand:DI 0 "register_operand" "")
17490         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17491          UNSPEC_FIST_FLOOR))
17492    (use (match_operand:HI 2 "memory_operand" ""))
17493    (use (match_operand:HI 3 "memory_operand" ""))
17494    (clobber (match_operand:DI 4 "memory_operand" ""))
17495    (clobber (match_scratch 5 ""))]
17496   "reload_completed"
17497   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17498               (use (match_dup 2))
17499               (use (match_dup 3))
17500               (clobber (match_dup 5))])
17501    (set (match_dup 0) (match_dup 4))]
17502   "")
17503
17504 (define_split 
17505   [(set (match_operand:DI 0 "memory_operand" "")
17506         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17507          UNSPEC_FIST_FLOOR))
17508    (use (match_operand:HI 2 "memory_operand" ""))
17509    (use (match_operand:HI 3 "memory_operand" ""))
17510    (clobber (match_operand:DI 4 "memory_operand" ""))
17511    (clobber (match_scratch 5 ""))]
17512   "reload_completed"
17513   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17514               (use (match_dup 2))
17515               (use (match_dup 3))
17516               (clobber (match_dup 5))])]
17517   "")
17518
17519 (define_insn "fist<mode>2_floor"
17520   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17521         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17522          UNSPEC_FIST_FLOOR))
17523    (use (match_operand:HI 2 "memory_operand" "m"))
17524    (use (match_operand:HI 3 "memory_operand" "m"))]
17525   "TARGET_USE_FANCY_MATH_387
17526    && flag_unsafe_math_optimizations"
17527   "* return output_fix_trunc (insn, operands, 0);"
17528   [(set_attr "type" "fistp")
17529    (set_attr "i387_cw" "floor")
17530    (set_attr "mode" "<MODE>")])
17531
17532 (define_insn "fist<mode>2_floor_with_temp"
17533   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17534         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17535          UNSPEC_FIST_FLOOR))
17536    (use (match_operand:HI 2 "memory_operand" "m,m"))
17537    (use (match_operand:HI 3 "memory_operand" "m,m"))
17538    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17539   "TARGET_USE_FANCY_MATH_387
17540    && flag_unsafe_math_optimizations"
17541   "#"
17542   [(set_attr "type" "fistp")
17543    (set_attr "i387_cw" "floor")
17544    (set_attr "mode" "<MODE>")])
17545
17546 (define_split 
17547   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17548         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17549          UNSPEC_FIST_FLOOR))
17550    (use (match_operand:HI 2 "memory_operand" ""))
17551    (use (match_operand:HI 3 "memory_operand" ""))
17552    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17553   "reload_completed"
17554   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17555                                   UNSPEC_FIST_FLOOR))
17556               (use (match_dup 2))
17557               (use (match_dup 3))])
17558    (set (match_dup 0) (match_dup 4))]
17559   "")
17560
17561 (define_split 
17562   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17563         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17564          UNSPEC_FIST_FLOOR))
17565    (use (match_operand:HI 2 "memory_operand" ""))
17566    (use (match_operand:HI 3 "memory_operand" ""))
17567    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17568   "reload_completed"
17569   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17570                                   UNSPEC_FIST_FLOOR))
17571               (use (match_dup 2))
17572               (use (match_dup 3))])]
17573   "")
17574
17575 (define_expand "lfloor<mode>2"
17576   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17577                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17578                     UNSPEC_FIST_FLOOR))
17579               (clobber (reg:CC FLAGS_REG))])]
17580   "TARGET_USE_FANCY_MATH_387
17581    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17582    && flag_unsafe_math_optimizations"
17583   "")
17584
17585 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17586 (define_insn_and_split "frndintxf2_ceil"
17587   [(set (match_operand:XF 0 "register_operand" "=f")
17588         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17589          UNSPEC_FRNDINT_CEIL))
17590    (clobber (reg:CC FLAGS_REG))]
17591   "TARGET_USE_FANCY_MATH_387
17592    && flag_unsafe_math_optimizations
17593    && !(reload_completed || reload_in_progress)"
17594   "#"
17595   "&& 1"
17596   [(const_int 0)]
17597 {
17598   ix86_optimize_mode_switching[I387_CEIL] = 1;
17599
17600   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17601   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17602
17603   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17604                                        operands[2], operands[3]));
17605   DONE;
17606 }
17607   [(set_attr "type" "frndint")
17608    (set_attr "i387_cw" "ceil")
17609    (set_attr "mode" "XF")])
17610
17611 (define_insn "frndintxf2_ceil_i387"
17612   [(set (match_operand:XF 0 "register_operand" "=f")
17613         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17614          UNSPEC_FRNDINT_CEIL))
17615    (use (match_operand:HI 2 "memory_operand" "m"))
17616    (use (match_operand:HI 3 "memory_operand" "m"))]
17617   "TARGET_USE_FANCY_MATH_387
17618    && flag_unsafe_math_optimizations"
17619   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17620   [(set_attr "type" "frndint")
17621    (set_attr "i387_cw" "ceil")
17622    (set_attr "mode" "XF")])
17623
17624 (define_expand "ceilxf2"
17625   [(use (match_operand:XF 0 "register_operand" ""))
17626    (use (match_operand:XF 1 "register_operand" ""))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17629 {
17630   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17631   DONE;
17632 })
17633
17634 (define_expand "ceildf2"
17635   [(use (match_operand:DF 0 "register_operand" ""))
17636    (use (match_operand:DF 1 "register_operand" ""))]
17637   "TARGET_USE_FANCY_MATH_387
17638    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17639    && flag_unsafe_math_optimizations"
17640 {
17641   rtx op0 = gen_reg_rtx (XFmode);
17642   rtx op1 = gen_reg_rtx (XFmode);
17643
17644   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17645   emit_insn (gen_frndintxf2_ceil (op0, op1));
17646
17647   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17648   DONE;
17649 })
17650
17651 (define_expand "ceilsf2"
17652   [(use (match_operand:SF 0 "register_operand" ""))
17653    (use (match_operand:SF 1 "register_operand" ""))]
17654   "TARGET_USE_FANCY_MATH_387
17655    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17656    && flag_unsafe_math_optimizations"
17657 {
17658   rtx op0 = gen_reg_rtx (XFmode);
17659   rtx op1 = gen_reg_rtx (XFmode);
17660
17661   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17662   emit_insn (gen_frndintxf2_ceil (op0, op1));
17663
17664   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17665   DONE;
17666 })
17667
17668 (define_insn_and_split "*fist<mode>2_ceil_1"
17669   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17670         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17671          UNSPEC_FIST_CEIL))
17672    (clobber (reg:CC FLAGS_REG))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && flag_unsafe_math_optimizations
17675    && !(reload_completed || reload_in_progress)"
17676   "#"
17677   "&& 1"
17678   [(const_int 0)]
17679 {
17680   ix86_optimize_mode_switching[I387_CEIL] = 1;
17681
17682   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17683   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17684   if (memory_operand (operands[0], VOIDmode))
17685     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17686                                      operands[2], operands[3]));
17687   else
17688     {
17689       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17690       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17691                                                  operands[2], operands[3],
17692                                                  operands[4]));
17693     }
17694   DONE;
17695 }
17696   [(set_attr "type" "fistp")
17697    (set_attr "i387_cw" "ceil")
17698    (set_attr "mode" "<MODE>")])
17699
17700 (define_insn "fistdi2_ceil"
17701   [(set (match_operand:DI 0 "memory_operand" "=m")
17702         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17703          UNSPEC_FIST_CEIL))
17704    (use (match_operand:HI 2 "memory_operand" "m"))
17705    (use (match_operand:HI 3 "memory_operand" "m"))
17706    (clobber (match_scratch:XF 4 "=&1f"))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17709   "* return output_fix_trunc (insn, operands, 0);"
17710   [(set_attr "type" "fistp")
17711    (set_attr "i387_cw" "ceil")
17712    (set_attr "mode" "DI")])
17713
17714 (define_insn "fistdi2_ceil_with_temp"
17715   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17716         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17717          UNSPEC_FIST_CEIL))
17718    (use (match_operand:HI 2 "memory_operand" "m,m"))
17719    (use (match_operand:HI 3 "memory_operand" "m,m"))
17720    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17721    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17722   "TARGET_USE_FANCY_MATH_387
17723    && flag_unsafe_math_optimizations"
17724   "#"
17725   [(set_attr "type" "fistp")
17726    (set_attr "i387_cw" "ceil")
17727    (set_attr "mode" "DI")])
17728
17729 (define_split 
17730   [(set (match_operand:DI 0 "register_operand" "")
17731         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17732          UNSPEC_FIST_CEIL))
17733    (use (match_operand:HI 2 "memory_operand" ""))
17734    (use (match_operand:HI 3 "memory_operand" ""))
17735    (clobber (match_operand:DI 4 "memory_operand" ""))
17736    (clobber (match_scratch 5 ""))]
17737   "reload_completed"
17738   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17739               (use (match_dup 2))
17740               (use (match_dup 3))
17741               (clobber (match_dup 5))])
17742    (set (match_dup 0) (match_dup 4))]
17743   "")
17744
17745 (define_split 
17746   [(set (match_operand:DI 0 "memory_operand" "")
17747         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17748          UNSPEC_FIST_CEIL))
17749    (use (match_operand:HI 2 "memory_operand" ""))
17750    (use (match_operand:HI 3 "memory_operand" ""))
17751    (clobber (match_operand:DI 4 "memory_operand" ""))
17752    (clobber (match_scratch 5 ""))]
17753   "reload_completed"
17754   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17755               (use (match_dup 2))
17756               (use (match_dup 3))
17757               (clobber (match_dup 5))])]
17758   "")
17759
17760 (define_insn "fist<mode>2_ceil"
17761   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17762         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17763          UNSPEC_FIST_CEIL))
17764    (use (match_operand:HI 2 "memory_operand" "m"))
17765    (use (match_operand:HI 3 "memory_operand" "m"))]
17766   "TARGET_USE_FANCY_MATH_387
17767    && flag_unsafe_math_optimizations"
17768   "* return output_fix_trunc (insn, operands, 0);"
17769   [(set_attr "type" "fistp")
17770    (set_attr "i387_cw" "ceil")
17771    (set_attr "mode" "<MODE>")])
17772
17773 (define_insn "fist<mode>2_ceil_with_temp"
17774   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17775         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17776          UNSPEC_FIST_CEIL))
17777    (use (match_operand:HI 2 "memory_operand" "m,m"))
17778    (use (match_operand:HI 3 "memory_operand" "m,m"))
17779    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17780   "TARGET_USE_FANCY_MATH_387
17781    && flag_unsafe_math_optimizations"
17782   "#"
17783   [(set_attr "type" "fistp")
17784    (set_attr "i387_cw" "ceil")
17785    (set_attr "mode" "<MODE>")])
17786
17787 (define_split 
17788   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17789         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17790          UNSPEC_FIST_CEIL))
17791    (use (match_operand:HI 2 "memory_operand" ""))
17792    (use (match_operand:HI 3 "memory_operand" ""))
17793    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17794   "reload_completed"
17795   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17796                                   UNSPEC_FIST_CEIL))
17797               (use (match_dup 2))
17798               (use (match_dup 3))])
17799    (set (match_dup 0) (match_dup 4))]
17800   "")
17801
17802 (define_split 
17803   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17804         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17805          UNSPEC_FIST_CEIL))
17806    (use (match_operand:HI 2 "memory_operand" ""))
17807    (use (match_operand:HI 3 "memory_operand" ""))
17808    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17809   "reload_completed"
17810   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17811                                   UNSPEC_FIST_CEIL))
17812               (use (match_dup 2))
17813               (use (match_dup 3))])]
17814   "")
17815
17816 (define_expand "lceil<mode>2"
17817   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17818                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17819                     UNSPEC_FIST_CEIL))
17820               (clobber (reg:CC FLAGS_REG))])]
17821   "TARGET_USE_FANCY_MATH_387
17822    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17823    && flag_unsafe_math_optimizations"
17824   "")
17825
17826 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17827 (define_insn_and_split "frndintxf2_trunc"
17828   [(set (match_operand:XF 0 "register_operand" "=f")
17829         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17830          UNSPEC_FRNDINT_TRUNC))
17831    (clobber (reg:CC FLAGS_REG))]
17832   "TARGET_USE_FANCY_MATH_387
17833    && flag_unsafe_math_optimizations
17834    && !(reload_completed || reload_in_progress)"
17835   "#"
17836   "&& 1"
17837   [(const_int 0)]
17838 {
17839   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17840
17841   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17842   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17843
17844   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17845                                         operands[2], operands[3]));
17846   DONE;
17847 }
17848   [(set_attr "type" "frndint")
17849    (set_attr "i387_cw" "trunc")
17850    (set_attr "mode" "XF")])
17851
17852 (define_insn "frndintxf2_trunc_i387"
17853   [(set (match_operand:XF 0 "register_operand" "=f")
17854         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17855          UNSPEC_FRNDINT_TRUNC))
17856    (use (match_operand:HI 2 "memory_operand" "m"))
17857    (use (match_operand:HI 3 "memory_operand" "m"))]
17858   "TARGET_USE_FANCY_MATH_387
17859    && flag_unsafe_math_optimizations"
17860   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17861   [(set_attr "type" "frndint")
17862    (set_attr "i387_cw" "trunc")
17863    (set_attr "mode" "XF")])
17864
17865 (define_expand "btruncxf2"
17866   [(use (match_operand:XF 0 "register_operand" ""))
17867    (use (match_operand:XF 1 "register_operand" ""))]
17868   "TARGET_USE_FANCY_MATH_387
17869    && flag_unsafe_math_optimizations"
17870 {
17871   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17872   DONE;
17873 })
17874
17875 (define_expand "btruncdf2"
17876   [(use (match_operand:DF 0 "register_operand" ""))
17877    (use (match_operand:DF 1 "register_operand" ""))]
17878   "TARGET_USE_FANCY_MATH_387
17879    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17880    && flag_unsafe_math_optimizations"
17881 {
17882   rtx op0 = gen_reg_rtx (XFmode);
17883   rtx op1 = gen_reg_rtx (XFmode);
17884
17885   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17886   emit_insn (gen_frndintxf2_trunc (op0, op1));
17887
17888   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17889   DONE;
17890 })
17891
17892 (define_expand "btruncsf2"
17893   [(use (match_operand:SF 0 "register_operand" ""))
17894    (use (match_operand:SF 1 "register_operand" ""))]
17895   "TARGET_USE_FANCY_MATH_387
17896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17897    && flag_unsafe_math_optimizations"
17898 {
17899   rtx op0 = gen_reg_rtx (XFmode);
17900   rtx op1 = gen_reg_rtx (XFmode);
17901
17902   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17903   emit_insn (gen_frndintxf2_trunc (op0, op1));
17904
17905   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17906   DONE;
17907 })
17908
17909 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17910 (define_insn_and_split "frndintxf2_mask_pm"
17911   [(set (match_operand:XF 0 "register_operand" "=f")
17912         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17913          UNSPEC_FRNDINT_MASK_PM))
17914    (clobber (reg:CC FLAGS_REG))]
17915   "TARGET_USE_FANCY_MATH_387
17916    && flag_unsafe_math_optimizations
17917    && !(reload_completed || reload_in_progress)"
17918   "#"
17919   "&& 1"
17920   [(const_int 0)]
17921 {
17922   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17923
17924   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17925   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17926
17927   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17928                                           operands[2], operands[3]));
17929   DONE;
17930 }
17931   [(set_attr "type" "frndint")
17932    (set_attr "i387_cw" "mask_pm")
17933    (set_attr "mode" "XF")])
17934
17935 (define_insn "frndintxf2_mask_pm_i387"
17936   [(set (match_operand:XF 0 "register_operand" "=f")
17937         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17938          UNSPEC_FRNDINT_MASK_PM))
17939    (use (match_operand:HI 2 "memory_operand" "m"))
17940    (use (match_operand:HI 3 "memory_operand" "m"))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && flag_unsafe_math_optimizations"
17943   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17944   [(set_attr "type" "frndint")
17945    (set_attr "i387_cw" "mask_pm")
17946    (set_attr "mode" "XF")])
17947
17948 (define_expand "nearbyintxf2"
17949   [(use (match_operand:XF 0 "register_operand" ""))
17950    (use (match_operand:XF 1 "register_operand" ""))]
17951   "TARGET_USE_FANCY_MATH_387
17952    && flag_unsafe_math_optimizations"
17953 {
17954   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17955
17956   DONE;
17957 })
17958
17959 (define_expand "nearbyintdf2"
17960   [(use (match_operand:DF 0 "register_operand" ""))
17961    (use (match_operand:DF 1 "register_operand" ""))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17964    && flag_unsafe_math_optimizations"
17965 {
17966   rtx op0 = gen_reg_rtx (XFmode);
17967   rtx op1 = gen_reg_rtx (XFmode);
17968
17969   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17970   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17971
17972   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17973   DONE;
17974 })
17975
17976 (define_expand "nearbyintsf2"
17977   [(use (match_operand:SF 0 "register_operand" ""))
17978    (use (match_operand:SF 1 "register_operand" ""))]
17979   "TARGET_USE_FANCY_MATH_387
17980    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17981    && flag_unsafe_math_optimizations"
17982 {
17983   rtx op0 = gen_reg_rtx (XFmode);
17984   rtx op1 = gen_reg_rtx (XFmode);
17985
17986   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17987   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17988
17989   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17990   DONE;
17991 })
17992
17993 \f
17994 ;; Block operation instructions
17995
17996 (define_insn "cld"
17997  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17998  ""
17999  "cld"
18000   [(set_attr "type" "cld")])
18001
18002 (define_expand "movmemsi"
18003   [(use (match_operand:BLK 0 "memory_operand" ""))
18004    (use (match_operand:BLK 1 "memory_operand" ""))
18005    (use (match_operand:SI 2 "nonmemory_operand" ""))
18006    (use (match_operand:SI 3 "const_int_operand" ""))]
18007   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18008 {
18009  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18010    DONE;
18011  else
18012    FAIL;
18013 })
18014
18015 (define_expand "movmemdi"
18016   [(use (match_operand:BLK 0 "memory_operand" ""))
18017    (use (match_operand:BLK 1 "memory_operand" ""))
18018    (use (match_operand:DI 2 "nonmemory_operand" ""))
18019    (use (match_operand:DI 3 "const_int_operand" ""))]
18020   "TARGET_64BIT"
18021 {
18022  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18023    DONE;
18024  else
18025    FAIL;
18026 })
18027
18028 ;; Most CPUs don't like single string operations
18029 ;; Handle this case here to simplify previous expander.
18030
18031 (define_expand "strmov"
18032   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18033    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18034    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18035               (clobber (reg:CC FLAGS_REG))])
18036    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18037               (clobber (reg:CC FLAGS_REG))])]
18038   ""
18039 {
18040   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18041
18042   /* If .md ever supports :P for Pmode, these can be directly
18043      in the pattern above.  */
18044   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18045   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18046
18047   if (TARGET_SINGLE_STRINGOP || optimize_size)
18048     {
18049       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18050                                       operands[2], operands[3],
18051                                       operands[5], operands[6]));
18052       DONE;
18053     }
18054
18055   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18056 })
18057
18058 (define_expand "strmov_singleop"
18059   [(parallel [(set (match_operand 1 "memory_operand" "")
18060                    (match_operand 3 "memory_operand" ""))
18061               (set (match_operand 0 "register_operand" "")
18062                    (match_operand 4 "" ""))
18063               (set (match_operand 2 "register_operand" "")
18064                    (match_operand 5 "" ""))
18065               (use (reg:SI DIRFLAG_REG))])]
18066   "TARGET_SINGLE_STRINGOP || optimize_size"
18067   "")
18068
18069 (define_insn "*strmovdi_rex_1"
18070   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18071         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18072    (set (match_operand:DI 0 "register_operand" "=D")
18073         (plus:DI (match_dup 2)
18074                  (const_int 8)))
18075    (set (match_operand:DI 1 "register_operand" "=S")
18076         (plus:DI (match_dup 3)
18077                  (const_int 8)))
18078    (use (reg:SI DIRFLAG_REG))]
18079   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18080   "movsq"
18081   [(set_attr "type" "str")
18082    (set_attr "mode" "DI")
18083    (set_attr "memory" "both")])
18084
18085 (define_insn "*strmovsi_1"
18086   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18087         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18088    (set (match_operand:SI 0 "register_operand" "=D")
18089         (plus:SI (match_dup 2)
18090                  (const_int 4)))
18091    (set (match_operand:SI 1 "register_operand" "=S")
18092         (plus:SI (match_dup 3)
18093                  (const_int 4)))
18094    (use (reg:SI DIRFLAG_REG))]
18095   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18096   "{movsl|movsd}"
18097   [(set_attr "type" "str")
18098    (set_attr "mode" "SI")
18099    (set_attr "memory" "both")])
18100
18101 (define_insn "*strmovsi_rex_1"
18102   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18103         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18104    (set (match_operand:DI 0 "register_operand" "=D")
18105         (plus:DI (match_dup 2)
18106                  (const_int 4)))
18107    (set (match_operand:DI 1 "register_operand" "=S")
18108         (plus:DI (match_dup 3)
18109                  (const_int 4)))
18110    (use (reg:SI DIRFLAG_REG))]
18111   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18112   "{movsl|movsd}"
18113   [(set_attr "type" "str")
18114    (set_attr "mode" "SI")
18115    (set_attr "memory" "both")])
18116
18117 (define_insn "*strmovhi_1"
18118   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18119         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18120    (set (match_operand:SI 0 "register_operand" "=D")
18121         (plus:SI (match_dup 2)
18122                  (const_int 2)))
18123    (set (match_operand:SI 1 "register_operand" "=S")
18124         (plus:SI (match_dup 3)
18125                  (const_int 2)))
18126    (use (reg:SI DIRFLAG_REG))]
18127   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18128   "movsw"
18129   [(set_attr "type" "str")
18130    (set_attr "memory" "both")
18131    (set_attr "mode" "HI")])
18132
18133 (define_insn "*strmovhi_rex_1"
18134   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18135         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18136    (set (match_operand:DI 0 "register_operand" "=D")
18137         (plus:DI (match_dup 2)
18138                  (const_int 2)))
18139    (set (match_operand:DI 1 "register_operand" "=S")
18140         (plus:DI (match_dup 3)
18141                  (const_int 2)))
18142    (use (reg:SI DIRFLAG_REG))]
18143   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18144   "movsw"
18145   [(set_attr "type" "str")
18146    (set_attr "memory" "both")
18147    (set_attr "mode" "HI")])
18148
18149 (define_insn "*strmovqi_1"
18150   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18151         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18152    (set (match_operand:SI 0 "register_operand" "=D")
18153         (plus:SI (match_dup 2)
18154                  (const_int 1)))
18155    (set (match_operand:SI 1 "register_operand" "=S")
18156         (plus:SI (match_dup 3)
18157                  (const_int 1)))
18158    (use (reg:SI DIRFLAG_REG))]
18159   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18160   "movsb"
18161   [(set_attr "type" "str")
18162    (set_attr "memory" "both")
18163    (set_attr "mode" "QI")])
18164
18165 (define_insn "*strmovqi_rex_1"
18166   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18167         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18168    (set (match_operand:DI 0 "register_operand" "=D")
18169         (plus:DI (match_dup 2)
18170                  (const_int 1)))
18171    (set (match_operand:DI 1 "register_operand" "=S")
18172         (plus:DI (match_dup 3)
18173                  (const_int 1)))
18174    (use (reg:SI DIRFLAG_REG))]
18175   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18176   "movsb"
18177   [(set_attr "type" "str")
18178    (set_attr "memory" "both")
18179    (set_attr "mode" "QI")])
18180
18181 (define_expand "rep_mov"
18182   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18183               (set (match_operand 0 "register_operand" "")
18184                    (match_operand 5 "" ""))
18185               (set (match_operand 2 "register_operand" "")
18186                    (match_operand 6 "" ""))
18187               (set (match_operand 1 "memory_operand" "")
18188                    (match_operand 3 "memory_operand" ""))
18189               (use (match_dup 4))
18190               (use (reg:SI DIRFLAG_REG))])]
18191   ""
18192   "")
18193
18194 (define_insn "*rep_movdi_rex64"
18195   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18196    (set (match_operand:DI 0 "register_operand" "=D") 
18197         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18198                             (const_int 3))
18199                  (match_operand:DI 3 "register_operand" "0")))
18200    (set (match_operand:DI 1 "register_operand" "=S") 
18201         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18202                  (match_operand:DI 4 "register_operand" "1")))
18203    (set (mem:BLK (match_dup 3))
18204         (mem:BLK (match_dup 4)))
18205    (use (match_dup 5))
18206    (use (reg:SI DIRFLAG_REG))]
18207   "TARGET_64BIT"
18208   "{rep\;movsq|rep movsq}"
18209   [(set_attr "type" "str")
18210    (set_attr "prefix_rep" "1")
18211    (set_attr "memory" "both")
18212    (set_attr "mode" "DI")])
18213
18214 (define_insn "*rep_movsi"
18215   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18216    (set (match_operand:SI 0 "register_operand" "=D") 
18217         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18218                             (const_int 2))
18219                  (match_operand:SI 3 "register_operand" "0")))
18220    (set (match_operand:SI 1 "register_operand" "=S") 
18221         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18222                  (match_operand:SI 4 "register_operand" "1")))
18223    (set (mem:BLK (match_dup 3))
18224         (mem:BLK (match_dup 4)))
18225    (use (match_dup 5))
18226    (use (reg:SI DIRFLAG_REG))]
18227   "!TARGET_64BIT"
18228   "{rep\;movsl|rep movsd}"
18229   [(set_attr "type" "str")
18230    (set_attr "prefix_rep" "1")
18231    (set_attr "memory" "both")
18232    (set_attr "mode" "SI")])
18233
18234 (define_insn "*rep_movsi_rex64"
18235   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18236    (set (match_operand:DI 0 "register_operand" "=D") 
18237         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18238                             (const_int 2))
18239                  (match_operand:DI 3 "register_operand" "0")))
18240    (set (match_operand:DI 1 "register_operand" "=S") 
18241         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18242                  (match_operand:DI 4 "register_operand" "1")))
18243    (set (mem:BLK (match_dup 3))
18244         (mem:BLK (match_dup 4)))
18245    (use (match_dup 5))
18246    (use (reg:SI DIRFLAG_REG))]
18247   "TARGET_64BIT"
18248   "{rep\;movsl|rep movsd}"
18249   [(set_attr "type" "str")
18250    (set_attr "prefix_rep" "1")
18251    (set_attr "memory" "both")
18252    (set_attr "mode" "SI")])
18253
18254 (define_insn "*rep_movqi"
18255   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18256    (set (match_operand:SI 0 "register_operand" "=D") 
18257         (plus:SI (match_operand:SI 3 "register_operand" "0")
18258                  (match_operand:SI 5 "register_operand" "2")))
18259    (set (match_operand:SI 1 "register_operand" "=S") 
18260         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18261    (set (mem:BLK (match_dup 3))
18262         (mem:BLK (match_dup 4)))
18263    (use (match_dup 5))
18264    (use (reg:SI DIRFLAG_REG))]
18265   "!TARGET_64BIT"
18266   "{rep\;movsb|rep movsb}"
18267   [(set_attr "type" "str")
18268    (set_attr "prefix_rep" "1")
18269    (set_attr "memory" "both")
18270    (set_attr "mode" "SI")])
18271
18272 (define_insn "*rep_movqi_rex64"
18273   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18274    (set (match_operand:DI 0 "register_operand" "=D") 
18275         (plus:DI (match_operand:DI 3 "register_operand" "0")
18276                  (match_operand:DI 5 "register_operand" "2")))
18277    (set (match_operand:DI 1 "register_operand" "=S") 
18278         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18279    (set (mem:BLK (match_dup 3))
18280         (mem:BLK (match_dup 4)))
18281    (use (match_dup 5))
18282    (use (reg:SI DIRFLAG_REG))]
18283   "TARGET_64BIT"
18284   "{rep\;movsb|rep movsb}"
18285   [(set_attr "type" "str")
18286    (set_attr "prefix_rep" "1")
18287    (set_attr "memory" "both")
18288    (set_attr "mode" "SI")])
18289
18290 (define_expand "setmemsi"
18291    [(use (match_operand:BLK 0 "memory_operand" ""))
18292     (use (match_operand:SI 1 "nonmemory_operand" ""))
18293     (use (match_operand 2 "const_int_operand" ""))
18294     (use (match_operand 3 "const_int_operand" ""))]
18295   ""
18296 {
18297  /* If value to set is not zero, use the library routine.  */
18298  if (operands[2] != const0_rtx)
18299    FAIL;
18300
18301  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18302    DONE;
18303  else
18304    FAIL;
18305 })
18306
18307 (define_expand "setmemdi"
18308    [(use (match_operand:BLK 0 "memory_operand" ""))
18309     (use (match_operand:DI 1 "nonmemory_operand" ""))
18310     (use (match_operand 2 "const_int_operand" ""))
18311     (use (match_operand 3 "const_int_operand" ""))]
18312   "TARGET_64BIT"
18313 {
18314  /* If value to set is not zero, use the library routine.  */
18315  if (operands[2] != const0_rtx)
18316    FAIL;
18317
18318  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18319    DONE;
18320  else
18321    FAIL;
18322 })
18323
18324 ;; Most CPUs don't like single string operations
18325 ;; Handle this case here to simplify previous expander.
18326
18327 (define_expand "strset"
18328   [(set (match_operand 1 "memory_operand" "")
18329         (match_operand 2 "register_operand" ""))
18330    (parallel [(set (match_operand 0 "register_operand" "")
18331                    (match_dup 3))
18332               (clobber (reg:CC FLAGS_REG))])]
18333   ""
18334 {
18335   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18336     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18337
18338   /* If .md ever supports :P for Pmode, this can be directly
18339      in the pattern above.  */
18340   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18341                               GEN_INT (GET_MODE_SIZE (GET_MODE
18342                                                       (operands[2]))));
18343   if (TARGET_SINGLE_STRINGOP || optimize_size)
18344     {
18345       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18346                                       operands[3]));
18347       DONE;
18348     }
18349 })
18350
18351 (define_expand "strset_singleop"
18352   [(parallel [(set (match_operand 1 "memory_operand" "")
18353                    (match_operand 2 "register_operand" ""))
18354               (set (match_operand 0 "register_operand" "")
18355                    (match_operand 3 "" ""))
18356               (use (reg:SI DIRFLAG_REG))])]
18357   "TARGET_SINGLE_STRINGOP || optimize_size"
18358   "")
18359
18360 (define_insn "*strsetdi_rex_1"
18361   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18362         (match_operand:DI 2 "register_operand" "a"))
18363    (set (match_operand:DI 0 "register_operand" "=D")
18364         (plus:DI (match_dup 1)
18365                  (const_int 8)))
18366    (use (reg:SI DIRFLAG_REG))]
18367   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368   "stosq"
18369   [(set_attr "type" "str")
18370    (set_attr "memory" "store")
18371    (set_attr "mode" "DI")])
18372
18373 (define_insn "*strsetsi_1"
18374   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18375         (match_operand:SI 2 "register_operand" "a"))
18376    (set (match_operand:SI 0 "register_operand" "=D")
18377         (plus:SI (match_dup 1)
18378                  (const_int 4)))
18379    (use (reg:SI DIRFLAG_REG))]
18380   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18381   "{stosl|stosd}"
18382   [(set_attr "type" "str")
18383    (set_attr "memory" "store")
18384    (set_attr "mode" "SI")])
18385
18386 (define_insn "*strsetsi_rex_1"
18387   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18388         (match_operand:SI 2 "register_operand" "a"))
18389    (set (match_operand:DI 0 "register_operand" "=D")
18390         (plus:DI (match_dup 1)
18391                  (const_int 4)))
18392    (use (reg:SI DIRFLAG_REG))]
18393   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18394   "{stosl|stosd}"
18395   [(set_attr "type" "str")
18396    (set_attr "memory" "store")
18397    (set_attr "mode" "SI")])
18398
18399 (define_insn "*strsethi_1"
18400   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18401         (match_operand:HI 2 "register_operand" "a"))
18402    (set (match_operand:SI 0 "register_operand" "=D")
18403         (plus:SI (match_dup 1)
18404                  (const_int 2)))
18405    (use (reg:SI DIRFLAG_REG))]
18406   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18407   "stosw"
18408   [(set_attr "type" "str")
18409    (set_attr "memory" "store")
18410    (set_attr "mode" "HI")])
18411
18412 (define_insn "*strsethi_rex_1"
18413   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18414         (match_operand:HI 2 "register_operand" "a"))
18415    (set (match_operand:DI 0 "register_operand" "=D")
18416         (plus:DI (match_dup 1)
18417                  (const_int 2)))
18418    (use (reg:SI DIRFLAG_REG))]
18419   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18420   "stosw"
18421   [(set_attr "type" "str")
18422    (set_attr "memory" "store")
18423    (set_attr "mode" "HI")])
18424
18425 (define_insn "*strsetqi_1"
18426   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18427         (match_operand:QI 2 "register_operand" "a"))
18428    (set (match_operand:SI 0 "register_operand" "=D")
18429         (plus:SI (match_dup 1)
18430                  (const_int 1)))
18431    (use (reg:SI DIRFLAG_REG))]
18432   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18433   "stosb"
18434   [(set_attr "type" "str")
18435    (set_attr "memory" "store")
18436    (set_attr "mode" "QI")])
18437
18438 (define_insn "*strsetqi_rex_1"
18439   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18440         (match_operand:QI 2 "register_operand" "a"))
18441    (set (match_operand:DI 0 "register_operand" "=D")
18442         (plus:DI (match_dup 1)
18443                  (const_int 1)))
18444    (use (reg:SI DIRFLAG_REG))]
18445   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18446   "stosb"
18447   [(set_attr "type" "str")
18448    (set_attr "memory" "store")
18449    (set_attr "mode" "QI")])
18450
18451 (define_expand "rep_stos"
18452   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18453               (set (match_operand 0 "register_operand" "")
18454                    (match_operand 4 "" ""))
18455               (set (match_operand 2 "memory_operand" "") (const_int 0))
18456               (use (match_operand 3 "register_operand" ""))
18457               (use (match_dup 1))
18458               (use (reg:SI DIRFLAG_REG))])]
18459   ""
18460   "")
18461
18462 (define_insn "*rep_stosdi_rex64"
18463   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18464    (set (match_operand:DI 0 "register_operand" "=D") 
18465         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18466                             (const_int 3))
18467                  (match_operand:DI 3 "register_operand" "0")))
18468    (set (mem:BLK (match_dup 3))
18469         (const_int 0))
18470    (use (match_operand:DI 2 "register_operand" "a"))
18471    (use (match_dup 4))
18472    (use (reg:SI DIRFLAG_REG))]
18473   "TARGET_64BIT"
18474   "{rep\;stosq|rep stosq}"
18475   [(set_attr "type" "str")
18476    (set_attr "prefix_rep" "1")
18477    (set_attr "memory" "store")
18478    (set_attr "mode" "DI")])
18479
18480 (define_insn "*rep_stossi"
18481   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18482    (set (match_operand:SI 0 "register_operand" "=D") 
18483         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18484                             (const_int 2))
18485                  (match_operand:SI 3 "register_operand" "0")))
18486    (set (mem:BLK (match_dup 3))
18487         (const_int 0))
18488    (use (match_operand:SI 2 "register_operand" "a"))
18489    (use (match_dup 4))
18490    (use (reg:SI DIRFLAG_REG))]
18491   "!TARGET_64BIT"
18492   "{rep\;stosl|rep stosd}"
18493   [(set_attr "type" "str")
18494    (set_attr "prefix_rep" "1")
18495    (set_attr "memory" "store")
18496    (set_attr "mode" "SI")])
18497
18498 (define_insn "*rep_stossi_rex64"
18499   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18500    (set (match_operand:DI 0 "register_operand" "=D") 
18501         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18502                             (const_int 2))
18503                  (match_operand:DI 3 "register_operand" "0")))
18504    (set (mem:BLK (match_dup 3))
18505         (const_int 0))
18506    (use (match_operand:SI 2 "register_operand" "a"))
18507    (use (match_dup 4))
18508    (use (reg:SI DIRFLAG_REG))]
18509   "TARGET_64BIT"
18510   "{rep\;stosl|rep stosd}"
18511   [(set_attr "type" "str")
18512    (set_attr "prefix_rep" "1")
18513    (set_attr "memory" "store")
18514    (set_attr "mode" "SI")])
18515
18516 (define_insn "*rep_stosqi"
18517   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18518    (set (match_operand:SI 0 "register_operand" "=D") 
18519         (plus:SI (match_operand:SI 3 "register_operand" "0")
18520                  (match_operand:SI 4 "register_operand" "1")))
18521    (set (mem:BLK (match_dup 3))
18522         (const_int 0))
18523    (use (match_operand:QI 2 "register_operand" "a"))
18524    (use (match_dup 4))
18525    (use (reg:SI DIRFLAG_REG))]
18526   "!TARGET_64BIT"
18527   "{rep\;stosb|rep stosb}"
18528   [(set_attr "type" "str")
18529    (set_attr "prefix_rep" "1")
18530    (set_attr "memory" "store")
18531    (set_attr "mode" "QI")])
18532
18533 (define_insn "*rep_stosqi_rex64"
18534   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18535    (set (match_operand:DI 0 "register_operand" "=D") 
18536         (plus:DI (match_operand:DI 3 "register_operand" "0")
18537                  (match_operand:DI 4 "register_operand" "1")))
18538    (set (mem:BLK (match_dup 3))
18539         (const_int 0))
18540    (use (match_operand:QI 2 "register_operand" "a"))
18541    (use (match_dup 4))
18542    (use (reg:SI DIRFLAG_REG))]
18543   "TARGET_64BIT"
18544   "{rep\;stosb|rep stosb}"
18545   [(set_attr "type" "str")
18546    (set_attr "prefix_rep" "1")
18547    (set_attr "memory" "store")
18548    (set_attr "mode" "QI")])
18549
18550 (define_expand "cmpstrnsi"
18551   [(set (match_operand:SI 0 "register_operand" "")
18552         (compare:SI (match_operand:BLK 1 "general_operand" "")
18553                     (match_operand:BLK 2 "general_operand" "")))
18554    (use (match_operand 3 "general_operand" ""))
18555    (use (match_operand 4 "immediate_operand" ""))]
18556   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18557 {
18558   rtx addr1, addr2, out, outlow, count, countreg, align;
18559
18560   /* Can't use this if the user has appropriated esi or edi.  */
18561   if (global_regs[4] || global_regs[5])
18562     FAIL;
18563
18564   out = operands[0];
18565   if (GET_CODE (out) != REG)
18566     out = gen_reg_rtx (SImode);
18567
18568   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18569   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18570   if (addr1 != XEXP (operands[1], 0))
18571     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18572   if (addr2 != XEXP (operands[2], 0))
18573     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18574
18575   count = operands[3];
18576   countreg = ix86_zero_extend_to_Pmode (count);
18577
18578   /* %%% Iff we are testing strict equality, we can use known alignment
18579      to good advantage.  This may be possible with combine, particularly
18580      once cc0 is dead.  */
18581   align = operands[4];
18582
18583   emit_insn (gen_cld ());
18584   if (GET_CODE (count) == CONST_INT)
18585     {
18586       if (INTVAL (count) == 0)
18587         {
18588           emit_move_insn (operands[0], const0_rtx);
18589           DONE;
18590         }
18591       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18592                                      operands[1], operands[2]));
18593     }
18594   else
18595     {
18596       if (TARGET_64BIT)
18597         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18598       else
18599         emit_insn (gen_cmpsi_1 (countreg, countreg));
18600       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18601                                   operands[1], operands[2]));
18602     }
18603
18604   outlow = gen_lowpart (QImode, out);
18605   emit_insn (gen_cmpintqi (outlow));
18606   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18607
18608   if (operands[0] != out)
18609     emit_move_insn (operands[0], out);
18610
18611   DONE;
18612 })
18613
18614 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18615
18616 (define_expand "cmpintqi"
18617   [(set (match_dup 1)
18618         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18619    (set (match_dup 2)
18620         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18621    (parallel [(set (match_operand:QI 0 "register_operand" "")
18622                    (minus:QI (match_dup 1)
18623                              (match_dup 2)))
18624               (clobber (reg:CC FLAGS_REG))])]
18625   ""
18626   "operands[1] = gen_reg_rtx (QImode);
18627    operands[2] = gen_reg_rtx (QImode);")
18628
18629 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18630 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18631
18632 (define_expand "cmpstrnqi_nz_1"
18633   [(parallel [(set (reg:CC FLAGS_REG)
18634                    (compare:CC (match_operand 4 "memory_operand" "")
18635                                (match_operand 5 "memory_operand" "")))
18636               (use (match_operand 2 "register_operand" ""))
18637               (use (match_operand:SI 3 "immediate_operand" ""))
18638               (use (reg:SI DIRFLAG_REG))
18639               (clobber (match_operand 0 "register_operand" ""))
18640               (clobber (match_operand 1 "register_operand" ""))
18641               (clobber (match_dup 2))])]
18642   ""
18643   "")
18644
18645 (define_insn "*cmpstrnqi_nz_1"
18646   [(set (reg:CC FLAGS_REG)
18647         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18648                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18649    (use (match_operand:SI 6 "register_operand" "2"))
18650    (use (match_operand:SI 3 "immediate_operand" "i"))
18651    (use (reg:SI DIRFLAG_REG))
18652    (clobber (match_operand:SI 0 "register_operand" "=S"))
18653    (clobber (match_operand:SI 1 "register_operand" "=D"))
18654    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18655   "!TARGET_64BIT"
18656   "repz{\;| }cmpsb"
18657   [(set_attr "type" "str")
18658    (set_attr "mode" "QI")
18659    (set_attr "prefix_rep" "1")])
18660
18661 (define_insn "*cmpstrnqi_nz_rex_1"
18662   [(set (reg:CC FLAGS_REG)
18663         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18664                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18665    (use (match_operand:DI 6 "register_operand" "2"))
18666    (use (match_operand:SI 3 "immediate_operand" "i"))
18667    (use (reg:SI DIRFLAG_REG))
18668    (clobber (match_operand:DI 0 "register_operand" "=S"))
18669    (clobber (match_operand:DI 1 "register_operand" "=D"))
18670    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18671   "TARGET_64BIT"
18672   "repz{\;| }cmpsb"
18673   [(set_attr "type" "str")
18674    (set_attr "mode" "QI")
18675    (set_attr "prefix_rep" "1")])
18676
18677 ;; The same, but the count is not known to not be zero.
18678
18679 (define_expand "cmpstrnqi_1"
18680   [(parallel [(set (reg:CC FLAGS_REG)
18681                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18682                                      (const_int 0))
18683                   (compare:CC (match_operand 4 "memory_operand" "")
18684                               (match_operand 5 "memory_operand" ""))
18685                   (const_int 0)))
18686               (use (match_operand:SI 3 "immediate_operand" ""))
18687               (use (reg:CC FLAGS_REG))
18688               (use (reg:SI DIRFLAG_REG))
18689               (clobber (match_operand 0 "register_operand" ""))
18690               (clobber (match_operand 1 "register_operand" ""))
18691               (clobber (match_dup 2))])]
18692   ""
18693   "")
18694
18695 (define_insn "*cmpstrnqi_1"
18696   [(set (reg:CC FLAGS_REG)
18697         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18698                              (const_int 0))
18699           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18700                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18701           (const_int 0)))
18702    (use (match_operand:SI 3 "immediate_operand" "i"))
18703    (use (reg:CC FLAGS_REG))
18704    (use (reg:SI DIRFLAG_REG))
18705    (clobber (match_operand:SI 0 "register_operand" "=S"))
18706    (clobber (match_operand:SI 1 "register_operand" "=D"))
18707    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18708   "!TARGET_64BIT"
18709   "repz{\;| }cmpsb"
18710   [(set_attr "type" "str")
18711    (set_attr "mode" "QI")
18712    (set_attr "prefix_rep" "1")])
18713
18714 (define_insn "*cmpstrnqi_rex_1"
18715   [(set (reg:CC FLAGS_REG)
18716         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18717                              (const_int 0))
18718           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18719                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18720           (const_int 0)))
18721    (use (match_operand:SI 3 "immediate_operand" "i"))
18722    (use (reg:CC FLAGS_REG))
18723    (use (reg:SI DIRFLAG_REG))
18724    (clobber (match_operand:DI 0 "register_operand" "=S"))
18725    (clobber (match_operand:DI 1 "register_operand" "=D"))
18726    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18727   "TARGET_64BIT"
18728   "repz{\;| }cmpsb"
18729   [(set_attr "type" "str")
18730    (set_attr "mode" "QI")
18731    (set_attr "prefix_rep" "1")])
18732
18733 (define_expand "strlensi"
18734   [(set (match_operand:SI 0 "register_operand" "")
18735         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18736                     (match_operand:QI 2 "immediate_operand" "")
18737                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18738   ""
18739 {
18740  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18741    DONE;
18742  else
18743    FAIL;
18744 })
18745
18746 (define_expand "strlendi"
18747   [(set (match_operand:DI 0 "register_operand" "")
18748         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18749                     (match_operand:QI 2 "immediate_operand" "")
18750                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18751   ""
18752 {
18753  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18754    DONE;
18755  else
18756    FAIL;
18757 })
18758
18759 (define_expand "strlenqi_1"
18760   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18761               (use (reg:SI DIRFLAG_REG))
18762               (clobber (match_operand 1 "register_operand" ""))
18763               (clobber (reg:CC FLAGS_REG))])]
18764   ""
18765   "")
18766
18767 (define_insn "*strlenqi_1"
18768   [(set (match_operand:SI 0 "register_operand" "=&c")
18769         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18770                     (match_operand:QI 2 "register_operand" "a")
18771                     (match_operand:SI 3 "immediate_operand" "i")
18772                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18773    (use (reg:SI DIRFLAG_REG))
18774    (clobber (match_operand:SI 1 "register_operand" "=D"))
18775    (clobber (reg:CC FLAGS_REG))]
18776   "!TARGET_64BIT"
18777   "repnz{\;| }scasb"
18778   [(set_attr "type" "str")
18779    (set_attr "mode" "QI")
18780    (set_attr "prefix_rep" "1")])
18781
18782 (define_insn "*strlenqi_rex_1"
18783   [(set (match_operand:DI 0 "register_operand" "=&c")
18784         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18785                     (match_operand:QI 2 "register_operand" "a")
18786                     (match_operand:DI 3 "immediate_operand" "i")
18787                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18788    (use (reg:SI DIRFLAG_REG))
18789    (clobber (match_operand:DI 1 "register_operand" "=D"))
18790    (clobber (reg:CC FLAGS_REG))]
18791   "TARGET_64BIT"
18792   "repnz{\;| }scasb"
18793   [(set_attr "type" "str")
18794    (set_attr "mode" "QI")
18795    (set_attr "prefix_rep" "1")])
18796
18797 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18798 ;; handled in combine, but it is not currently up to the task.
18799 ;; When used for their truth value, the cmpstrn* expanders generate
18800 ;; code like this:
18801 ;;
18802 ;;   repz cmpsb
18803 ;;   seta       %al
18804 ;;   setb       %dl
18805 ;;   cmpb       %al, %dl
18806 ;;   jcc        label
18807 ;;
18808 ;; The intermediate three instructions are unnecessary.
18809
18810 ;; This one handles cmpstrn*_nz_1...
18811 (define_peephole2
18812   [(parallel[
18813      (set (reg:CC FLAGS_REG)
18814           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18815                       (mem:BLK (match_operand 5 "register_operand" ""))))
18816      (use (match_operand 6 "register_operand" ""))
18817      (use (match_operand:SI 3 "immediate_operand" ""))
18818      (use (reg:SI DIRFLAG_REG))
18819      (clobber (match_operand 0 "register_operand" ""))
18820      (clobber (match_operand 1 "register_operand" ""))
18821      (clobber (match_operand 2 "register_operand" ""))])
18822    (set (match_operand:QI 7 "register_operand" "")
18823         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824    (set (match_operand:QI 8 "register_operand" "")
18825         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18826    (set (reg FLAGS_REG)
18827         (compare (match_dup 7) (match_dup 8)))
18828   ]
18829   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18830   [(parallel[
18831      (set (reg:CC FLAGS_REG)
18832           (compare:CC (mem:BLK (match_dup 4))
18833                       (mem:BLK (match_dup 5))))
18834      (use (match_dup 6))
18835      (use (match_dup 3))
18836      (use (reg:SI DIRFLAG_REG))
18837      (clobber (match_dup 0))
18838      (clobber (match_dup 1))
18839      (clobber (match_dup 2))])]
18840   "")
18841
18842 ;; ...and this one handles cmpstrn*_1.
18843 (define_peephole2
18844   [(parallel[
18845      (set (reg:CC FLAGS_REG)
18846           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18847                                (const_int 0))
18848             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18849                         (mem:BLK (match_operand 5 "register_operand" "")))
18850             (const_int 0)))
18851      (use (match_operand:SI 3 "immediate_operand" ""))
18852      (use (reg:CC FLAGS_REG))
18853      (use (reg:SI DIRFLAG_REG))
18854      (clobber (match_operand 0 "register_operand" ""))
18855      (clobber (match_operand 1 "register_operand" ""))
18856      (clobber (match_operand 2 "register_operand" ""))])
18857    (set (match_operand:QI 7 "register_operand" "")
18858         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18859    (set (match_operand:QI 8 "register_operand" "")
18860         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18861    (set (reg FLAGS_REG)
18862         (compare (match_dup 7) (match_dup 8)))
18863   ]
18864   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18865   [(parallel[
18866      (set (reg:CC FLAGS_REG)
18867           (if_then_else:CC (ne (match_dup 6)
18868                                (const_int 0))
18869             (compare:CC (mem:BLK (match_dup 4))
18870                         (mem:BLK (match_dup 5)))
18871             (const_int 0)))
18872      (use (match_dup 3))
18873      (use (reg:CC FLAGS_REG))
18874      (use (reg:SI DIRFLAG_REG))
18875      (clobber (match_dup 0))
18876      (clobber (match_dup 1))
18877      (clobber (match_dup 2))])]
18878   "")
18879
18880
18881 \f
18882 ;; Conditional move instructions.
18883
18884 (define_expand "movdicc"
18885   [(set (match_operand:DI 0 "register_operand" "")
18886         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18887                          (match_operand:DI 2 "general_operand" "")
18888                          (match_operand:DI 3 "general_operand" "")))]
18889   "TARGET_64BIT"
18890   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18891
18892 (define_insn "x86_movdicc_0_m1_rex64"
18893   [(set (match_operand:DI 0 "register_operand" "=r")
18894         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18895           (const_int -1)
18896           (const_int 0)))
18897    (clobber (reg:CC FLAGS_REG))]
18898   "TARGET_64BIT"
18899   "sbb{q}\t%0, %0"
18900   ; Since we don't have the proper number of operands for an alu insn,
18901   ; fill in all the blanks.
18902   [(set_attr "type" "alu")
18903    (set_attr "pent_pair" "pu")
18904    (set_attr "memory" "none")
18905    (set_attr "imm_disp" "false")
18906    (set_attr "mode" "DI")
18907    (set_attr "length_immediate" "0")])
18908
18909 (define_insn "*movdicc_c_rex64"
18910   [(set (match_operand:DI 0 "register_operand" "=r,r")
18911         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18912                                 [(reg FLAGS_REG) (const_int 0)])
18913                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18914                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18915   "TARGET_64BIT && TARGET_CMOVE
18916    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18917   "@
18918    cmov%O2%C1\t{%2, %0|%0, %2}
18919    cmov%O2%c1\t{%3, %0|%0, %3}"
18920   [(set_attr "type" "icmov")
18921    (set_attr "mode" "DI")])
18922
18923 (define_expand "movsicc"
18924   [(set (match_operand:SI 0 "register_operand" "")
18925         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18926                          (match_operand:SI 2 "general_operand" "")
18927                          (match_operand:SI 3 "general_operand" "")))]
18928   ""
18929   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18930
18931 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18932 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18933 ;; So just document what we're doing explicitly.
18934
18935 (define_insn "x86_movsicc_0_m1"
18936   [(set (match_operand:SI 0 "register_operand" "=r")
18937         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18938           (const_int -1)
18939           (const_int 0)))
18940    (clobber (reg:CC FLAGS_REG))]
18941   ""
18942   "sbb{l}\t%0, %0"
18943   ; Since we don't have the proper number of operands for an alu insn,
18944   ; fill in all the blanks.
18945   [(set_attr "type" "alu")
18946    (set_attr "pent_pair" "pu")
18947    (set_attr "memory" "none")
18948    (set_attr "imm_disp" "false")
18949    (set_attr "mode" "SI")
18950    (set_attr "length_immediate" "0")])
18951
18952 (define_insn "*movsicc_noc"
18953   [(set (match_operand:SI 0 "register_operand" "=r,r")
18954         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18955                                 [(reg FLAGS_REG) (const_int 0)])
18956                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18957                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18958   "TARGET_CMOVE
18959    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18960   "@
18961    cmov%O2%C1\t{%2, %0|%0, %2}
18962    cmov%O2%c1\t{%3, %0|%0, %3}"
18963   [(set_attr "type" "icmov")
18964    (set_attr "mode" "SI")])
18965
18966 (define_expand "movhicc"
18967   [(set (match_operand:HI 0 "register_operand" "")
18968         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18969                          (match_operand:HI 2 "general_operand" "")
18970                          (match_operand:HI 3 "general_operand" "")))]
18971   "TARGET_HIMODE_MATH"
18972   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18973
18974 (define_insn "*movhicc_noc"
18975   [(set (match_operand:HI 0 "register_operand" "=r,r")
18976         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18977                                 [(reg FLAGS_REG) (const_int 0)])
18978                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18979                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18980   "TARGET_CMOVE
18981    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18982   "@
18983    cmov%O2%C1\t{%2, %0|%0, %2}
18984    cmov%O2%c1\t{%3, %0|%0, %3}"
18985   [(set_attr "type" "icmov")
18986    (set_attr "mode" "HI")])
18987
18988 (define_expand "movqicc"
18989   [(set (match_operand:QI 0 "register_operand" "")
18990         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18991                          (match_operand:QI 2 "general_operand" "")
18992                          (match_operand:QI 3 "general_operand" "")))]
18993   "TARGET_QIMODE_MATH"
18994   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18995
18996 (define_insn_and_split "*movqicc_noc"
18997   [(set (match_operand:QI 0 "register_operand" "=r,r")
18998         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18999                                 [(match_operand 4 "flags_reg_operand" "")
19000                                  (const_int 0)])
19001                       (match_operand:QI 2 "register_operand" "r,0")
19002                       (match_operand:QI 3 "register_operand" "0,r")))]
19003   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19004   "#"
19005   "&& reload_completed"
19006   [(set (match_dup 0)
19007         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19008                       (match_dup 2)
19009                       (match_dup 3)))]
19010   "operands[0] = gen_lowpart (SImode, operands[0]);
19011    operands[2] = gen_lowpart (SImode, operands[2]);
19012    operands[3] = gen_lowpart (SImode, operands[3]);"
19013   [(set_attr "type" "icmov")
19014    (set_attr "mode" "SI")])
19015
19016 (define_expand "movsfcc"
19017   [(set (match_operand:SF 0 "register_operand" "")
19018         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19019                          (match_operand:SF 2 "register_operand" "")
19020                          (match_operand:SF 3 "register_operand" "")))]
19021   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19022   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19023
19024 (define_insn "*movsfcc_1_387"
19025   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19026         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19027                                 [(reg FLAGS_REG) (const_int 0)])
19028                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19029                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19030   "TARGET_80387 && TARGET_CMOVE
19031    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19032   "@
19033    fcmov%F1\t{%2, %0|%0, %2}
19034    fcmov%f1\t{%3, %0|%0, %3}
19035    cmov%O2%C1\t{%2, %0|%0, %2}
19036    cmov%O2%c1\t{%3, %0|%0, %3}"
19037   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19038    (set_attr "mode" "SF,SF,SI,SI")])
19039
19040 (define_expand "movdfcc"
19041   [(set (match_operand:DF 0 "register_operand" "")
19042         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19043                          (match_operand:DF 2 "register_operand" "")
19044                          (match_operand:DF 3 "register_operand" "")))]
19045   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19046   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19047
19048 (define_insn "*movdfcc_1"
19049   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19050         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19051                                 [(reg FLAGS_REG) (const_int 0)])
19052                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19053                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19054   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19055    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19056   "@
19057    fcmov%F1\t{%2, %0|%0, %2}
19058    fcmov%f1\t{%3, %0|%0, %3}
19059    #
19060    #"
19061   [(set_attr "type" "fcmov,fcmov,multi,multi")
19062    (set_attr "mode" "DF")])
19063
19064 (define_insn "*movdfcc_1_rex64"
19065   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19066         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19067                                 [(reg FLAGS_REG) (const_int 0)])
19068                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19069                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19070   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19071    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19072   "@
19073    fcmov%F1\t{%2, %0|%0, %2}
19074    fcmov%f1\t{%3, %0|%0, %3}
19075    cmov%O2%C1\t{%2, %0|%0, %2}
19076    cmov%O2%c1\t{%3, %0|%0, %3}"
19077   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19078    (set_attr "mode" "DF")])
19079
19080 (define_split
19081   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19082         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19083                                 [(match_operand 4 "flags_reg_operand" "")
19084                                  (const_int 0)])
19085                       (match_operand:DF 2 "nonimmediate_operand" "")
19086                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19087   "!TARGET_64BIT && reload_completed"
19088   [(set (match_dup 2)
19089         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19090                       (match_dup 5)
19091                       (match_dup 7)))
19092    (set (match_dup 3)
19093         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19094                       (match_dup 6)
19095                       (match_dup 8)))]
19096   "split_di (operands+2, 1, operands+5, operands+6);
19097    split_di (operands+3, 1, operands+7, operands+8);
19098    split_di (operands, 1, operands+2, operands+3);")
19099
19100 (define_expand "movxfcc"
19101   [(set (match_operand:XF 0 "register_operand" "")
19102         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19103                          (match_operand:XF 2 "register_operand" "")
19104                          (match_operand:XF 3 "register_operand" "")))]
19105   "TARGET_80387 && TARGET_CMOVE"
19106   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19107
19108 (define_insn "*movxfcc_1"
19109   [(set (match_operand:XF 0 "register_operand" "=f,f")
19110         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19111                                 [(reg FLAGS_REG) (const_int 0)])
19112                       (match_operand:XF 2 "register_operand" "f,0")
19113                       (match_operand:XF 3 "register_operand" "0,f")))]
19114   "TARGET_80387 && TARGET_CMOVE"
19115   "@
19116    fcmov%F1\t{%2, %0|%0, %2}
19117    fcmov%f1\t{%3, %0|%0, %3}"
19118   [(set_attr "type" "fcmov")
19119    (set_attr "mode" "XF")])
19120
19121 ;; These versions of the min/max patterns are intentionally ignorant of
19122 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19123 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19124 ;; are undefined in this condition, we're certain this is correct.
19125
19126 (define_insn "sminsf3"
19127   [(set (match_operand:SF 0 "register_operand" "=x")
19128         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19129                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19130   "TARGET_SSE_MATH"
19131   "minss\t{%2, %0|%0, %2}"
19132   [(set_attr "type" "sseadd")
19133    (set_attr "mode" "SF")])
19134
19135 (define_insn "smaxsf3"
19136   [(set (match_operand:SF 0 "register_operand" "=x")
19137         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19138                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19139   "TARGET_SSE_MATH"
19140   "maxss\t{%2, %0|%0, %2}"
19141   [(set_attr "type" "sseadd")
19142    (set_attr "mode" "SF")])
19143
19144 (define_insn "smindf3"
19145   [(set (match_operand:DF 0 "register_operand" "=x")
19146         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19147                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19148   "TARGET_SSE2 && TARGET_SSE_MATH"
19149   "minsd\t{%2, %0|%0, %2}"
19150   [(set_attr "type" "sseadd")
19151    (set_attr "mode" "DF")])
19152
19153 (define_insn "smaxdf3"
19154   [(set (match_operand:DF 0 "register_operand" "=x")
19155         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19156                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19157   "TARGET_SSE2 && TARGET_SSE_MATH"
19158   "maxsd\t{%2, %0|%0, %2}"
19159   [(set_attr "type" "sseadd")
19160    (set_attr "mode" "DF")])
19161
19162 ;; These versions of the min/max patterns implement exactly the operations
19163 ;;   min = (op1 < op2 ? op1 : op2)
19164 ;;   max = (!(op1 < op2) ? op1 : op2)
19165 ;; Their operands are not commutative, and thus they may be used in the
19166 ;; presence of -0.0 and NaN.
19167
19168 (define_insn "*ieee_sminsf3"
19169   [(set (match_operand:SF 0 "register_operand" "=x")
19170         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19171                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19172                    UNSPEC_IEEE_MIN))]
19173   "TARGET_SSE_MATH"
19174   "minss\t{%2, %0|%0, %2}"
19175   [(set_attr "type" "sseadd")
19176    (set_attr "mode" "SF")])
19177
19178 (define_insn "*ieee_smaxsf3"
19179   [(set (match_operand:SF 0 "register_operand" "=x")
19180         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19181                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19182                    UNSPEC_IEEE_MAX))]
19183   "TARGET_SSE_MATH"
19184   "maxss\t{%2, %0|%0, %2}"
19185   [(set_attr "type" "sseadd")
19186    (set_attr "mode" "SF")])
19187
19188 (define_insn "*ieee_smindf3"
19189   [(set (match_operand:DF 0 "register_operand" "=x")
19190         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19191                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19192                    UNSPEC_IEEE_MIN))]
19193   "TARGET_SSE2 && TARGET_SSE_MATH"
19194   "minsd\t{%2, %0|%0, %2}"
19195   [(set_attr "type" "sseadd")
19196    (set_attr "mode" "DF")])
19197
19198 (define_insn "*ieee_smaxdf3"
19199   [(set (match_operand:DF 0 "register_operand" "=x")
19200         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19201                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19202                    UNSPEC_IEEE_MAX))]
19203   "TARGET_SSE2 && TARGET_SSE_MATH"
19204   "maxsd\t{%2, %0|%0, %2}"
19205   [(set_attr "type" "sseadd")
19206    (set_attr "mode" "DF")])
19207
19208 ;; Make two stack loads independent:
19209 ;;   fld aa              fld aa
19210 ;;   fld %st(0)     ->   fld bb
19211 ;;   fmul bb             fmul %st(1), %st
19212 ;;
19213 ;; Actually we only match the last two instructions for simplicity.
19214 (define_peephole2
19215   [(set (match_operand 0 "fp_register_operand" "")
19216         (match_operand 1 "fp_register_operand" ""))
19217    (set (match_dup 0)
19218         (match_operator 2 "binary_fp_operator"
19219            [(match_dup 0)
19220             (match_operand 3 "memory_operand" "")]))]
19221   "REGNO (operands[0]) != REGNO (operands[1])"
19222   [(set (match_dup 0) (match_dup 3))
19223    (set (match_dup 0) (match_dup 4))]
19224
19225   ;; The % modifier is not operational anymore in peephole2's, so we have to
19226   ;; swap the operands manually in the case of addition and multiplication.
19227   "if (COMMUTATIVE_ARITH_P (operands[2]))
19228      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19229                                  operands[0], operands[1]);
19230    else
19231      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19232                                  operands[1], operands[0]);")
19233
19234 ;; Conditional addition patterns
19235 (define_expand "addqicc"
19236   [(match_operand:QI 0 "register_operand" "")
19237    (match_operand 1 "comparison_operator" "")
19238    (match_operand:QI 2 "register_operand" "")
19239    (match_operand:QI 3 "const_int_operand" "")]
19240   ""
19241   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19242
19243 (define_expand "addhicc"
19244   [(match_operand:HI 0 "register_operand" "")
19245    (match_operand 1 "comparison_operator" "")
19246    (match_operand:HI 2 "register_operand" "")
19247    (match_operand:HI 3 "const_int_operand" "")]
19248   ""
19249   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19250
19251 (define_expand "addsicc"
19252   [(match_operand:SI 0 "register_operand" "")
19253    (match_operand 1 "comparison_operator" "")
19254    (match_operand:SI 2 "register_operand" "")
19255    (match_operand:SI 3 "const_int_operand" "")]
19256   ""
19257   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19258
19259 (define_expand "adddicc"
19260   [(match_operand:DI 0 "register_operand" "")
19261    (match_operand 1 "comparison_operator" "")
19262    (match_operand:DI 2 "register_operand" "")
19263    (match_operand:DI 3 "const_int_operand" "")]
19264   "TARGET_64BIT"
19265   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19266
19267 \f
19268 ;; Misc patterns (?)
19269
19270 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19271 ;; Otherwise there will be nothing to keep
19272 ;; 
19273 ;; [(set (reg ebp) (reg esp))]
19274 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19275 ;;  (clobber (eflags)]
19276 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19277 ;;
19278 ;; in proper program order.
19279 (define_insn "pro_epilogue_adjust_stack_1"
19280   [(set (match_operand:SI 0 "register_operand" "=r,r")
19281         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19282                  (match_operand:SI 2 "immediate_operand" "i,i")))
19283    (clobber (reg:CC FLAGS_REG))
19284    (clobber (mem:BLK (scratch)))]
19285   "!TARGET_64BIT"
19286 {
19287   switch (get_attr_type (insn))
19288     {
19289     case TYPE_IMOV:
19290       return "mov{l}\t{%1, %0|%0, %1}";
19291
19292     case TYPE_ALU:
19293       if (GET_CODE (operands[2]) == CONST_INT
19294           && (INTVAL (operands[2]) == 128
19295               || (INTVAL (operands[2]) < 0
19296                   && INTVAL (operands[2]) != -128)))
19297         {
19298           operands[2] = GEN_INT (-INTVAL (operands[2]));
19299           return "sub{l}\t{%2, %0|%0, %2}";
19300         }
19301       return "add{l}\t{%2, %0|%0, %2}";
19302
19303     case TYPE_LEA:
19304       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19305       return "lea{l}\t{%a2, %0|%0, %a2}";
19306
19307     default:
19308       gcc_unreachable ();
19309     }
19310 }
19311   [(set (attr "type")
19312         (cond [(eq_attr "alternative" "0")
19313                  (const_string "alu")
19314                (match_operand:SI 2 "const0_operand" "")
19315                  (const_string "imov")
19316               ]
19317               (const_string "lea")))
19318    (set_attr "mode" "SI")])
19319
19320 (define_insn "pro_epilogue_adjust_stack_rex64"
19321   [(set (match_operand:DI 0 "register_operand" "=r,r")
19322         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19323                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19324    (clobber (reg:CC FLAGS_REG))
19325    (clobber (mem:BLK (scratch)))]
19326   "TARGET_64BIT"
19327 {
19328   switch (get_attr_type (insn))
19329     {
19330     case TYPE_IMOV:
19331       return "mov{q}\t{%1, %0|%0, %1}";
19332
19333     case TYPE_ALU:
19334       if (GET_CODE (operands[2]) == CONST_INT
19335           /* Avoid overflows.  */
19336           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19337           && (INTVAL (operands[2]) == 128
19338               || (INTVAL (operands[2]) < 0
19339                   && INTVAL (operands[2]) != -128)))
19340         {
19341           operands[2] = GEN_INT (-INTVAL (operands[2]));
19342           return "sub{q}\t{%2, %0|%0, %2}";
19343         }
19344       return "add{q}\t{%2, %0|%0, %2}";
19345
19346     case TYPE_LEA:
19347       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19348       return "lea{q}\t{%a2, %0|%0, %a2}";
19349
19350     default:
19351       gcc_unreachable ();
19352     }
19353 }
19354   [(set (attr "type")
19355         (cond [(eq_attr "alternative" "0")
19356                  (const_string "alu")
19357                (match_operand:DI 2 "const0_operand" "")
19358                  (const_string "imov")
19359               ]
19360               (const_string "lea")))
19361    (set_attr "mode" "DI")])
19362
19363 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19364   [(set (match_operand:DI 0 "register_operand" "=r,r")
19365         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19366                  (match_operand:DI 3 "immediate_operand" "i,i")))
19367    (use (match_operand:DI 2 "register_operand" "r,r"))
19368    (clobber (reg:CC FLAGS_REG))
19369    (clobber (mem:BLK (scratch)))]
19370   "TARGET_64BIT"
19371 {
19372   switch (get_attr_type (insn))
19373     {
19374     case TYPE_ALU:
19375       return "add{q}\t{%2, %0|%0, %2}";
19376
19377     case TYPE_LEA:
19378       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19379       return "lea{q}\t{%a2, %0|%0, %a2}";
19380
19381     default:
19382       gcc_unreachable ();
19383     }
19384 }
19385   [(set_attr "type" "alu,lea")
19386    (set_attr "mode" "DI")])
19387
19388 (define_expand "allocate_stack_worker"
19389   [(match_operand:SI 0 "register_operand" "")]
19390   "TARGET_STACK_PROBE"
19391 {
19392   if (reload_completed)
19393     {
19394       if (TARGET_64BIT)
19395         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19396       else
19397         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19398     }
19399   else
19400     {
19401       if (TARGET_64BIT)
19402         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19403       else
19404         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19405     }
19406   DONE;
19407 })
19408
19409 (define_insn "allocate_stack_worker_1"
19410   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19411     UNSPECV_STACK_PROBE)
19412    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19413    (clobber (match_scratch:SI 1 "=0"))
19414    (clobber (reg:CC FLAGS_REG))]
19415   "!TARGET_64BIT && TARGET_STACK_PROBE"
19416   "call\t__alloca"
19417   [(set_attr "type" "multi")
19418    (set_attr "length" "5")])
19419
19420 (define_expand "allocate_stack_worker_postreload"
19421   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19422                                     UNSPECV_STACK_PROBE)
19423               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19424               (clobber (match_dup 0))
19425               (clobber (reg:CC FLAGS_REG))])]
19426   ""
19427   "")
19428
19429 (define_insn "allocate_stack_worker_rex64"
19430   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19431     UNSPECV_STACK_PROBE)
19432    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19433    (clobber (match_scratch:DI 1 "=0"))
19434    (clobber (reg:CC FLAGS_REG))]
19435   "TARGET_64BIT && TARGET_STACK_PROBE"
19436   "call\t__alloca"
19437   [(set_attr "type" "multi")
19438    (set_attr "length" "5")])
19439
19440 (define_expand "allocate_stack_worker_rex64_postreload"
19441   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19442                                     UNSPECV_STACK_PROBE)
19443               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19444               (clobber (match_dup 0))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   ""
19447   "")
19448
19449 (define_expand "allocate_stack"
19450   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19451                    (minus:SI (reg:SI SP_REG)
19452                              (match_operand:SI 1 "general_operand" "")))
19453               (clobber (reg:CC FLAGS_REG))])
19454    (parallel [(set (reg:SI SP_REG)
19455                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19456               (clobber (reg:CC FLAGS_REG))])]
19457   "TARGET_STACK_PROBE"
19458 {
19459 #ifdef CHECK_STACK_LIMIT
19460   if (GET_CODE (operands[1]) == CONST_INT
19461       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19462     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19463                            operands[1]));
19464   else 
19465 #endif
19466     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19467                                                             operands[1])));
19468
19469   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19470   DONE;
19471 })
19472
19473 (define_expand "builtin_setjmp_receiver"
19474   [(label_ref (match_operand 0 "" ""))]
19475   "!TARGET_64BIT && flag_pic"
19476 {
19477   if (TARGET_MACHO)
19478     {
19479       rtx xops[3];
19480       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19481       rtx label_rtx = gen_label_rtx ();
19482       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19483       xops[0] = xops[1] = picreg;
19484       xops[2] = gen_rtx_CONST (SImode,
19485                   gen_rtx_MINUS (SImode,
19486                     gen_rtx_LABEL_REF (SImode, label_rtx),
19487                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19488       ix86_expand_binary_operator (MINUS, SImode, xops);
19489     }
19490   else
19491     emit_insn (gen_set_got (pic_offset_table_rtx));
19492   DONE;
19493 })
19494 \f
19495 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19496
19497 (define_split
19498   [(set (match_operand 0 "register_operand" "")
19499         (match_operator 3 "promotable_binary_operator"
19500            [(match_operand 1 "register_operand" "")
19501             (match_operand 2 "aligned_operand" "")]))
19502    (clobber (reg:CC FLAGS_REG))]
19503   "! TARGET_PARTIAL_REG_STALL && reload_completed
19504    && ((GET_MODE (operands[0]) == HImode 
19505         && ((!optimize_size && !TARGET_FAST_PREFIX)
19506             /* ??? next two lines just !satisfies_constraint_K (...) */
19507             || GET_CODE (operands[2]) != CONST_INT
19508             || satisfies_constraint_K (operands[2])))
19509        || (GET_MODE (operands[0]) == QImode 
19510            && (TARGET_PROMOTE_QImode || optimize_size)))"
19511   [(parallel [(set (match_dup 0)
19512                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19513               (clobber (reg:CC FLAGS_REG))])]
19514   "operands[0] = gen_lowpart (SImode, operands[0]);
19515    operands[1] = gen_lowpart (SImode, operands[1]);
19516    if (GET_CODE (operands[3]) != ASHIFT)
19517      operands[2] = gen_lowpart (SImode, operands[2]);
19518    PUT_MODE (operands[3], SImode);")
19519
19520 ; Promote the QImode tests, as i386 has encoding of the AND
19521 ; instruction with 32-bit sign-extended immediate and thus the
19522 ; instruction size is unchanged, except in the %eax case for
19523 ; which it is increased by one byte, hence the ! optimize_size.
19524 (define_split
19525   [(set (match_operand 0 "flags_reg_operand" "")
19526         (match_operator 2 "compare_operator"
19527           [(and (match_operand 3 "aligned_operand" "")
19528                 (match_operand 4 "const_int_operand" ""))
19529            (const_int 0)]))
19530    (set (match_operand 1 "register_operand" "")
19531         (and (match_dup 3) (match_dup 4)))]
19532   "! TARGET_PARTIAL_REG_STALL && reload_completed
19533    /* Ensure that the operand will remain sign-extended immediate.  */
19534    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19535    && ! optimize_size
19536    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19537        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19538   [(parallel [(set (match_dup 0)
19539                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19540                                     (const_int 0)]))
19541               (set (match_dup 1)
19542                    (and:SI (match_dup 3) (match_dup 4)))])]
19543 {
19544   operands[4]
19545     = gen_int_mode (INTVAL (operands[4])
19546                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19547   operands[1] = gen_lowpart (SImode, operands[1]);
19548   operands[3] = gen_lowpart (SImode, operands[3]);
19549 })
19550
19551 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19552 ; the TEST instruction with 32-bit sign-extended immediate and thus
19553 ; the instruction size would at least double, which is not what we
19554 ; want even with ! optimize_size.
19555 (define_split
19556   [(set (match_operand 0 "flags_reg_operand" "")
19557         (match_operator 1 "compare_operator"
19558           [(and (match_operand:HI 2 "aligned_operand" "")
19559                 (match_operand:HI 3 "const_int_operand" ""))
19560            (const_int 0)]))]
19561   "! TARGET_PARTIAL_REG_STALL && reload_completed
19562    /* Ensure that the operand will remain sign-extended immediate.  */
19563    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19564    && ! TARGET_FAST_PREFIX
19565    && ! optimize_size"
19566   [(set (match_dup 0)
19567         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19568                          (const_int 0)]))]
19569 {
19570   operands[3]
19571     = gen_int_mode (INTVAL (operands[3])
19572                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19573   operands[2] = gen_lowpart (SImode, operands[2]);
19574 })
19575
19576 (define_split
19577   [(set (match_operand 0 "register_operand" "")
19578         (neg (match_operand 1 "register_operand" "")))
19579    (clobber (reg:CC FLAGS_REG))]
19580   "! TARGET_PARTIAL_REG_STALL && reload_completed
19581    && (GET_MODE (operands[0]) == HImode
19582        || (GET_MODE (operands[0]) == QImode 
19583            && (TARGET_PROMOTE_QImode || optimize_size)))"
19584   [(parallel [(set (match_dup 0)
19585                    (neg:SI (match_dup 1)))
19586               (clobber (reg:CC FLAGS_REG))])]
19587   "operands[0] = gen_lowpart (SImode, operands[0]);
19588    operands[1] = gen_lowpart (SImode, operands[1]);")
19589
19590 (define_split
19591   [(set (match_operand 0 "register_operand" "")
19592         (not (match_operand 1 "register_operand" "")))]
19593   "! TARGET_PARTIAL_REG_STALL && reload_completed
19594    && (GET_MODE (operands[0]) == HImode
19595        || (GET_MODE (operands[0]) == QImode 
19596            && (TARGET_PROMOTE_QImode || optimize_size)))"
19597   [(set (match_dup 0)
19598         (not:SI (match_dup 1)))]
19599   "operands[0] = gen_lowpart (SImode, operands[0]);
19600    operands[1] = gen_lowpart (SImode, operands[1]);")
19601
19602 (define_split 
19603   [(set (match_operand 0 "register_operand" "")
19604         (if_then_else (match_operator 1 "comparison_operator" 
19605                                 [(reg FLAGS_REG) (const_int 0)])
19606                       (match_operand 2 "register_operand" "")
19607                       (match_operand 3 "register_operand" "")))]
19608   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19609    && (GET_MODE (operands[0]) == HImode
19610        || (GET_MODE (operands[0]) == QImode 
19611            && (TARGET_PROMOTE_QImode || optimize_size)))"
19612   [(set (match_dup 0)
19613         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19614   "operands[0] = gen_lowpart (SImode, operands[0]);
19615    operands[2] = gen_lowpart (SImode, operands[2]);
19616    operands[3] = gen_lowpart (SImode, operands[3]);")
19617                         
19618 \f
19619 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19620 ;; transform a complex memory operation into two memory to register operations.
19621
19622 ;; Don't push memory operands
19623 (define_peephole2
19624   [(set (match_operand:SI 0 "push_operand" "")
19625         (match_operand:SI 1 "memory_operand" ""))
19626    (match_scratch:SI 2 "r")]
19627   "!optimize_size && !TARGET_PUSH_MEMORY
19628    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19629   [(set (match_dup 2) (match_dup 1))
19630    (set (match_dup 0) (match_dup 2))]
19631   "")
19632
19633 (define_peephole2
19634   [(set (match_operand:DI 0 "push_operand" "")
19635         (match_operand:DI 1 "memory_operand" ""))
19636    (match_scratch:DI 2 "r")]
19637   "!optimize_size && !TARGET_PUSH_MEMORY
19638    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19639   [(set (match_dup 2) (match_dup 1))
19640    (set (match_dup 0) (match_dup 2))]
19641   "")
19642
19643 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19644 ;; SImode pushes.
19645 (define_peephole2
19646   [(set (match_operand:SF 0 "push_operand" "")
19647         (match_operand:SF 1 "memory_operand" ""))
19648    (match_scratch:SF 2 "r")]
19649   "!optimize_size && !TARGET_PUSH_MEMORY
19650    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19651   [(set (match_dup 2) (match_dup 1))
19652    (set (match_dup 0) (match_dup 2))]
19653   "")
19654
19655 (define_peephole2
19656   [(set (match_operand:HI 0 "push_operand" "")
19657         (match_operand:HI 1 "memory_operand" ""))
19658    (match_scratch:HI 2 "r")]
19659   "!optimize_size && !TARGET_PUSH_MEMORY
19660    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19661   [(set (match_dup 2) (match_dup 1))
19662    (set (match_dup 0) (match_dup 2))]
19663   "")
19664
19665 (define_peephole2
19666   [(set (match_operand:QI 0 "push_operand" "")
19667         (match_operand:QI 1 "memory_operand" ""))
19668    (match_scratch:QI 2 "q")]
19669   "!optimize_size && !TARGET_PUSH_MEMORY
19670    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19671   [(set (match_dup 2) (match_dup 1))
19672    (set (match_dup 0) (match_dup 2))]
19673   "")
19674
19675 ;; Don't move an immediate directly to memory when the instruction
19676 ;; gets too big.
19677 (define_peephole2
19678   [(match_scratch:SI 1 "r")
19679    (set (match_operand:SI 0 "memory_operand" "")
19680         (const_int 0))]
19681   "! optimize_size
19682    && ! TARGET_USE_MOV0
19683    && TARGET_SPLIT_LONG_MOVES
19684    && get_attr_length (insn) >= ix86_cost->large_insn
19685    && peep2_regno_dead_p (0, FLAGS_REG)"
19686   [(parallel [(set (match_dup 1) (const_int 0))
19687               (clobber (reg:CC FLAGS_REG))])
19688    (set (match_dup 0) (match_dup 1))]
19689   "")
19690
19691 (define_peephole2
19692   [(match_scratch:HI 1 "r")
19693    (set (match_operand:HI 0 "memory_operand" "")
19694         (const_int 0))]
19695   "! optimize_size
19696    && ! TARGET_USE_MOV0
19697    && TARGET_SPLIT_LONG_MOVES
19698    && get_attr_length (insn) >= ix86_cost->large_insn
19699    && peep2_regno_dead_p (0, FLAGS_REG)"
19700   [(parallel [(set (match_dup 2) (const_int 0))
19701               (clobber (reg:CC FLAGS_REG))])
19702    (set (match_dup 0) (match_dup 1))]
19703   "operands[2] = gen_lowpart (SImode, operands[1]);")
19704
19705 (define_peephole2
19706   [(match_scratch:QI 1 "q")
19707    (set (match_operand:QI 0 "memory_operand" "")
19708         (const_int 0))]
19709   "! optimize_size
19710    && ! TARGET_USE_MOV0
19711    && TARGET_SPLIT_LONG_MOVES
19712    && get_attr_length (insn) >= ix86_cost->large_insn
19713    && peep2_regno_dead_p (0, FLAGS_REG)"
19714   [(parallel [(set (match_dup 2) (const_int 0))
19715               (clobber (reg:CC FLAGS_REG))])
19716    (set (match_dup 0) (match_dup 1))]
19717   "operands[2] = gen_lowpart (SImode, operands[1]);")
19718
19719 (define_peephole2
19720   [(match_scratch:SI 2 "r")
19721    (set (match_operand:SI 0 "memory_operand" "")
19722         (match_operand:SI 1 "immediate_operand" ""))]
19723   "! optimize_size
19724    && get_attr_length (insn) >= ix86_cost->large_insn
19725    && TARGET_SPLIT_LONG_MOVES"
19726   [(set (match_dup 2) (match_dup 1))
19727    (set (match_dup 0) (match_dup 2))]
19728   "")
19729
19730 (define_peephole2
19731   [(match_scratch:HI 2 "r")
19732    (set (match_operand:HI 0 "memory_operand" "")
19733         (match_operand:HI 1 "immediate_operand" ""))]
19734   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19735   && TARGET_SPLIT_LONG_MOVES"
19736   [(set (match_dup 2) (match_dup 1))
19737    (set (match_dup 0) (match_dup 2))]
19738   "")
19739
19740 (define_peephole2
19741   [(match_scratch:QI 2 "q")
19742    (set (match_operand:QI 0 "memory_operand" "")
19743         (match_operand:QI 1 "immediate_operand" ""))]
19744   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19745   && TARGET_SPLIT_LONG_MOVES"
19746   [(set (match_dup 2) (match_dup 1))
19747    (set (match_dup 0) (match_dup 2))]
19748   "")
19749
19750 ;; Don't compare memory with zero, load and use a test instead.
19751 (define_peephole2
19752   [(set (match_operand 0 "flags_reg_operand" "")
19753         (match_operator 1 "compare_operator"
19754           [(match_operand:SI 2 "memory_operand" "")
19755            (const_int 0)]))
19756    (match_scratch:SI 3 "r")]
19757   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19758   [(set (match_dup 3) (match_dup 2))
19759    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19760   "")
19761
19762 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19763 ;; Don't split NOTs with a displacement operand, because resulting XOR
19764 ;; will not be pairable anyway.
19765 ;;
19766 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19767 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19768 ;; so this split helps here as well.
19769 ;;
19770 ;; Note: Can't do this as a regular split because we can't get proper
19771 ;; lifetime information then.
19772
19773 (define_peephole2
19774   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19775         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19776   "!optimize_size
19777    && peep2_regno_dead_p (0, FLAGS_REG)
19778    && ((TARGET_PENTIUM 
19779         && (GET_CODE (operands[0]) != MEM
19780             || !memory_displacement_operand (operands[0], SImode)))
19781        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19782   [(parallel [(set (match_dup 0)
19783                    (xor:SI (match_dup 1) (const_int -1)))
19784               (clobber (reg:CC FLAGS_REG))])]
19785   "")
19786
19787 (define_peephole2
19788   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19789         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19790   "!optimize_size
19791    && peep2_regno_dead_p (0, FLAGS_REG)
19792    && ((TARGET_PENTIUM 
19793         && (GET_CODE (operands[0]) != MEM
19794             || !memory_displacement_operand (operands[0], HImode)))
19795        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19796   [(parallel [(set (match_dup 0)
19797                    (xor:HI (match_dup 1) (const_int -1)))
19798               (clobber (reg:CC FLAGS_REG))])]
19799   "")
19800
19801 (define_peephole2
19802   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19803         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19804   "!optimize_size
19805    && peep2_regno_dead_p (0, FLAGS_REG)
19806    && ((TARGET_PENTIUM 
19807         && (GET_CODE (operands[0]) != MEM
19808             || !memory_displacement_operand (operands[0], QImode)))
19809        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19810   [(parallel [(set (match_dup 0)
19811                    (xor:QI (match_dup 1) (const_int -1)))
19812               (clobber (reg:CC FLAGS_REG))])]
19813   "")
19814
19815 ;; Non pairable "test imm, reg" instructions can be translated to
19816 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19817 ;; byte opcode instead of two, have a short form for byte operands),
19818 ;; so do it for other CPUs as well.  Given that the value was dead,
19819 ;; this should not create any new dependencies.  Pass on the sub-word
19820 ;; versions if we're concerned about partial register stalls.
19821
19822 (define_peephole2
19823   [(set (match_operand 0 "flags_reg_operand" "")
19824         (match_operator 1 "compare_operator"
19825           [(and:SI (match_operand:SI 2 "register_operand" "")
19826                    (match_operand:SI 3 "immediate_operand" ""))
19827            (const_int 0)]))]
19828   "ix86_match_ccmode (insn, CCNOmode)
19829    && (true_regnum (operands[2]) != 0
19830        || satisfies_constraint_K (operands[3]))
19831    && peep2_reg_dead_p (1, operands[2])"
19832   [(parallel
19833      [(set (match_dup 0)
19834            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19835                             (const_int 0)]))
19836       (set (match_dup 2)
19837            (and:SI (match_dup 2) (match_dup 3)))])]
19838   "")
19839
19840 ;; We don't need to handle HImode case, because it will be promoted to SImode
19841 ;; on ! TARGET_PARTIAL_REG_STALL
19842
19843 (define_peephole2
19844   [(set (match_operand 0 "flags_reg_operand" "")
19845         (match_operator 1 "compare_operator"
19846           [(and:QI (match_operand:QI 2 "register_operand" "")
19847                    (match_operand:QI 3 "immediate_operand" ""))
19848            (const_int 0)]))]
19849   "! TARGET_PARTIAL_REG_STALL
19850    && ix86_match_ccmode (insn, CCNOmode)
19851    && true_regnum (operands[2]) != 0
19852    && peep2_reg_dead_p (1, operands[2])"
19853   [(parallel
19854      [(set (match_dup 0)
19855            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19856                             (const_int 0)]))
19857       (set (match_dup 2)
19858            (and:QI (match_dup 2) (match_dup 3)))])]
19859   "")
19860
19861 (define_peephole2
19862   [(set (match_operand 0 "flags_reg_operand" "")
19863         (match_operator 1 "compare_operator"
19864           [(and:SI
19865              (zero_extract:SI
19866                (match_operand 2 "ext_register_operand" "")
19867                (const_int 8)
19868                (const_int 8))
19869              (match_operand 3 "const_int_operand" ""))
19870            (const_int 0)]))]
19871   "! TARGET_PARTIAL_REG_STALL
19872    && ix86_match_ccmode (insn, CCNOmode)
19873    && true_regnum (operands[2]) != 0
19874    && peep2_reg_dead_p (1, operands[2])"
19875   [(parallel [(set (match_dup 0)
19876                    (match_op_dup 1
19877                      [(and:SI
19878                         (zero_extract:SI
19879                           (match_dup 2)
19880                           (const_int 8)
19881                           (const_int 8))
19882                         (match_dup 3))
19883                       (const_int 0)]))
19884               (set (zero_extract:SI (match_dup 2)
19885                                     (const_int 8)
19886                                     (const_int 8))
19887                    (and:SI 
19888                      (zero_extract:SI
19889                        (match_dup 2)
19890                        (const_int 8)
19891                        (const_int 8))
19892                      (match_dup 3)))])]
19893   "")
19894
19895 ;; Don't do logical operations with memory inputs.
19896 (define_peephole2
19897   [(match_scratch:SI 2 "r")
19898    (parallel [(set (match_operand:SI 0 "register_operand" "")
19899                    (match_operator:SI 3 "arith_or_logical_operator"
19900                      [(match_dup 0)
19901                       (match_operand:SI 1 "memory_operand" "")]))
19902               (clobber (reg:CC FLAGS_REG))])]
19903   "! optimize_size && ! TARGET_READ_MODIFY"
19904   [(set (match_dup 2) (match_dup 1))
19905    (parallel [(set (match_dup 0)
19906                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19907               (clobber (reg:CC FLAGS_REG))])]
19908   "")
19909
19910 (define_peephole2
19911   [(match_scratch:SI 2 "r")
19912    (parallel [(set (match_operand:SI 0 "register_operand" "")
19913                    (match_operator:SI 3 "arith_or_logical_operator"
19914                      [(match_operand:SI 1 "memory_operand" "")
19915                       (match_dup 0)]))
19916               (clobber (reg:CC FLAGS_REG))])]
19917   "! optimize_size && ! TARGET_READ_MODIFY"
19918   [(set (match_dup 2) (match_dup 1))
19919    (parallel [(set (match_dup 0)
19920                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19921               (clobber (reg:CC FLAGS_REG))])]
19922   "")
19923
19924 ; Don't do logical operations with memory outputs
19925 ;
19926 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19927 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19928 ; the same decoder scheduling characteristics as the original.
19929
19930 (define_peephole2
19931   [(match_scratch:SI 2 "r")
19932    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19933                    (match_operator:SI 3 "arith_or_logical_operator"
19934                      [(match_dup 0)
19935                       (match_operand:SI 1 "nonmemory_operand" "")]))
19936               (clobber (reg:CC FLAGS_REG))])]
19937   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19938   [(set (match_dup 2) (match_dup 0))
19939    (parallel [(set (match_dup 2)
19940                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19941               (clobber (reg:CC FLAGS_REG))])
19942    (set (match_dup 0) (match_dup 2))]
19943   "")
19944
19945 (define_peephole2
19946   [(match_scratch:SI 2 "r")
19947    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19948                    (match_operator:SI 3 "arith_or_logical_operator"
19949                      [(match_operand:SI 1 "nonmemory_operand" "")
19950                       (match_dup 0)]))
19951               (clobber (reg:CC FLAGS_REG))])]
19952   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19953   [(set (match_dup 2) (match_dup 0))
19954    (parallel [(set (match_dup 2)
19955                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19956               (clobber (reg:CC FLAGS_REG))])
19957    (set (match_dup 0) (match_dup 2))]
19958   "")
19959
19960 ;; Attempt to always use XOR for zeroing registers.
19961 (define_peephole2
19962   [(set (match_operand 0 "register_operand" "")
19963         (match_operand 1 "const0_operand" ""))]
19964   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19965    && (! TARGET_USE_MOV0 || optimize_size)
19966    && GENERAL_REG_P (operands[0])
19967    && peep2_regno_dead_p (0, FLAGS_REG)"
19968   [(parallel [(set (match_dup 0) (const_int 0))
19969               (clobber (reg:CC FLAGS_REG))])]
19970 {
19971   operands[0] = gen_lowpart (word_mode, operands[0]);
19972 })
19973
19974 (define_peephole2
19975   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19976         (const_int 0))]
19977   "(GET_MODE (operands[0]) == QImode
19978     || GET_MODE (operands[0]) == HImode)
19979    && (! TARGET_USE_MOV0 || optimize_size)
19980    && peep2_regno_dead_p (0, FLAGS_REG)"
19981   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19982               (clobber (reg:CC FLAGS_REG))])])
19983
19984 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19985 (define_peephole2
19986   [(set (match_operand 0 "register_operand" "")
19987         (const_int -1))]
19988   "(GET_MODE (operands[0]) == HImode
19989     || GET_MODE (operands[0]) == SImode 
19990     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19991    && (optimize_size || TARGET_PENTIUM)
19992    && peep2_regno_dead_p (0, FLAGS_REG)"
19993   [(parallel [(set (match_dup 0) (const_int -1))
19994               (clobber (reg:CC FLAGS_REG))])]
19995   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19996                               operands[0]);")
19997
19998 ;; Attempt to convert simple leas to adds. These can be created by
19999 ;; move expanders.
20000 (define_peephole2
20001   [(set (match_operand:SI 0 "register_operand" "")
20002         (plus:SI (match_dup 0)
20003                  (match_operand:SI 1 "nonmemory_operand" "")))]
20004   "peep2_regno_dead_p (0, FLAGS_REG)"
20005   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20006               (clobber (reg:CC FLAGS_REG))])]
20007   "")
20008
20009 (define_peephole2
20010   [(set (match_operand:SI 0 "register_operand" "")
20011         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20012                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20013   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20014   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20015               (clobber (reg:CC FLAGS_REG))])]
20016   "operands[2] = gen_lowpart (SImode, operands[2]);")
20017
20018 (define_peephole2
20019   [(set (match_operand:DI 0 "register_operand" "")
20020         (plus:DI (match_dup 0)
20021                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20022   "peep2_regno_dead_p (0, FLAGS_REG)"
20023   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20024               (clobber (reg:CC FLAGS_REG))])]
20025   "")
20026
20027 (define_peephole2
20028   [(set (match_operand:SI 0 "register_operand" "")
20029         (mult:SI (match_dup 0)
20030                  (match_operand:SI 1 "const_int_operand" "")))]
20031   "exact_log2 (INTVAL (operands[1])) >= 0
20032    && peep2_regno_dead_p (0, FLAGS_REG)"
20033   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20034               (clobber (reg:CC FLAGS_REG))])]
20035   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20036
20037 (define_peephole2
20038   [(set (match_operand:DI 0 "register_operand" "")
20039         (mult:DI (match_dup 0)
20040                  (match_operand:DI 1 "const_int_operand" "")))]
20041   "exact_log2 (INTVAL (operands[1])) >= 0
20042    && peep2_regno_dead_p (0, FLAGS_REG)"
20043   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20044               (clobber (reg:CC FLAGS_REG))])]
20045   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20046
20047 (define_peephole2
20048   [(set (match_operand:SI 0 "register_operand" "")
20049         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20050                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20051   "exact_log2 (INTVAL (operands[2])) >= 0
20052    && REGNO (operands[0]) == REGNO (operands[1])
20053    && peep2_regno_dead_p (0, FLAGS_REG)"
20054   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20055               (clobber (reg:CC FLAGS_REG))])]
20056   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20057
20058 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20059 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20060 ;; many CPUs it is also faster, since special hardware to avoid esp
20061 ;; dependencies is present.
20062
20063 ;; While some of these conversions may be done using splitters, we use peepholes
20064 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20065
20066 ;; Convert prologue esp subtractions to push.
20067 ;; We need register to push.  In order to keep verify_flow_info happy we have
20068 ;; two choices
20069 ;; - use scratch and clobber it in order to avoid dependencies
20070 ;; - use already live register
20071 ;; We can't use the second way right now, since there is no reliable way how to
20072 ;; verify that given register is live.  First choice will also most likely in
20073 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20074 ;; call clobbered registers are dead.  We may want to use base pointer as an
20075 ;; alternative when no register is available later.
20076
20077 (define_peephole2
20078   [(match_scratch:SI 0 "r")
20079    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20080               (clobber (reg:CC FLAGS_REG))
20081               (clobber (mem:BLK (scratch)))])]
20082   "optimize_size || !TARGET_SUB_ESP_4"
20083   [(clobber (match_dup 0))
20084    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20085               (clobber (mem:BLK (scratch)))])])
20086
20087 (define_peephole2
20088   [(match_scratch:SI 0 "r")
20089    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20090               (clobber (reg:CC FLAGS_REG))
20091               (clobber (mem:BLK (scratch)))])]
20092   "optimize_size || !TARGET_SUB_ESP_8"
20093   [(clobber (match_dup 0))
20094    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20096               (clobber (mem:BLK (scratch)))])])
20097
20098 ;; Convert esp subtractions to push.
20099 (define_peephole2
20100   [(match_scratch:SI 0 "r")
20101    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20102               (clobber (reg:CC FLAGS_REG))])]
20103   "optimize_size || !TARGET_SUB_ESP_4"
20104   [(clobber (match_dup 0))
20105    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20106
20107 (define_peephole2
20108   [(match_scratch:SI 0 "r")
20109    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20110               (clobber (reg:CC FLAGS_REG))])]
20111   "optimize_size || !TARGET_SUB_ESP_8"
20112   [(clobber (match_dup 0))
20113    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20114    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20115
20116 ;; Convert epilogue deallocator to pop.
20117 (define_peephole2
20118   [(match_scratch:SI 0 "r")
20119    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20120               (clobber (reg:CC FLAGS_REG))
20121               (clobber (mem:BLK (scratch)))])]
20122   "optimize_size || !TARGET_ADD_ESP_4"
20123   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20124               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20125               (clobber (mem:BLK (scratch)))])]
20126   "")
20127
20128 ;; Two pops case is tricky, since pop causes dependency on destination register.
20129 ;; We use two registers if available.
20130 (define_peephole2
20131   [(match_scratch:SI 0 "r")
20132    (match_scratch:SI 1 "r")
20133    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20134               (clobber (reg:CC FLAGS_REG))
20135               (clobber (mem:BLK (scratch)))])]
20136   "optimize_size || !TARGET_ADD_ESP_8"
20137   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20138               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20139               (clobber (mem:BLK (scratch)))])
20140    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20141               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20142   "")
20143
20144 (define_peephole2
20145   [(match_scratch:SI 0 "r")
20146    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20147               (clobber (reg:CC FLAGS_REG))
20148               (clobber (mem:BLK (scratch)))])]
20149   "optimize_size"
20150   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20151               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20152               (clobber (mem:BLK (scratch)))])
20153    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20154               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20155   "")
20156
20157 ;; Convert esp additions to pop.
20158 (define_peephole2
20159   [(match_scratch:SI 0 "r")
20160    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   ""
20163   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20164               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20165   "")
20166
20167 ;; Two pops case is tricky, since pop causes dependency on destination register.
20168 ;; We use two registers if available.
20169 (define_peephole2
20170   [(match_scratch:SI 0 "r")
20171    (match_scratch:SI 1 "r")
20172    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20173               (clobber (reg:CC FLAGS_REG))])]
20174   ""
20175   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20176               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20177    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20178               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20179   "")
20180
20181 (define_peephole2
20182   [(match_scratch:SI 0 "r")
20183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20184               (clobber (reg:CC FLAGS_REG))])]
20185   "optimize_size"
20186   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20187               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20188    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20189               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20190   "")
20191 \f
20192 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20193 ;; required and register dies.  Similarly for 128 to plus -128.
20194 (define_peephole2
20195   [(set (match_operand 0 "flags_reg_operand" "")
20196         (match_operator 1 "compare_operator"
20197           [(match_operand 2 "register_operand" "")
20198            (match_operand 3 "const_int_operand" "")]))]
20199   "(INTVAL (operands[3]) == -1
20200     || INTVAL (operands[3]) == 1
20201     || INTVAL (operands[3]) == 128)
20202    && ix86_match_ccmode (insn, CCGCmode)
20203    && peep2_reg_dead_p (1, operands[2])"
20204   [(parallel [(set (match_dup 0)
20205                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20206               (clobber (match_dup 2))])]
20207   "")
20208 \f
20209 (define_peephole2
20210   [(match_scratch:DI 0 "r")
20211    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20212               (clobber (reg:CC FLAGS_REG))
20213               (clobber (mem:BLK (scratch)))])]
20214   "optimize_size || !TARGET_SUB_ESP_4"
20215   [(clobber (match_dup 0))
20216    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20217               (clobber (mem:BLK (scratch)))])])
20218
20219 (define_peephole2
20220   [(match_scratch:DI 0 "r")
20221    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20222               (clobber (reg:CC FLAGS_REG))
20223               (clobber (mem:BLK (scratch)))])]
20224   "optimize_size || !TARGET_SUB_ESP_8"
20225   [(clobber (match_dup 0))
20226    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20228               (clobber (mem:BLK (scratch)))])])
20229
20230 ;; Convert esp subtractions to push.
20231 (define_peephole2
20232   [(match_scratch:DI 0 "r")
20233    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20234               (clobber (reg:CC FLAGS_REG))])]
20235   "optimize_size || !TARGET_SUB_ESP_4"
20236   [(clobber (match_dup 0))
20237    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20238
20239 (define_peephole2
20240   [(match_scratch:DI 0 "r")
20241    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20242               (clobber (reg:CC FLAGS_REG))])]
20243   "optimize_size || !TARGET_SUB_ESP_8"
20244   [(clobber (match_dup 0))
20245    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20246    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20247
20248 ;; Convert epilogue deallocator to pop.
20249 (define_peephole2
20250   [(match_scratch:DI 0 "r")
20251    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20252               (clobber (reg:CC FLAGS_REG))
20253               (clobber (mem:BLK (scratch)))])]
20254   "optimize_size || !TARGET_ADD_ESP_4"
20255   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20256               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20257               (clobber (mem:BLK (scratch)))])]
20258   "")
20259
20260 ;; Two pops case is tricky, since pop causes dependency on destination register.
20261 ;; We use two registers if available.
20262 (define_peephole2
20263   [(match_scratch:DI 0 "r")
20264    (match_scratch:DI 1 "r")
20265    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20266               (clobber (reg:CC FLAGS_REG))
20267               (clobber (mem:BLK (scratch)))])]
20268   "optimize_size || !TARGET_ADD_ESP_8"
20269   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20270               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20271               (clobber (mem:BLK (scratch)))])
20272    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20273               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20274   "")
20275
20276 (define_peephole2
20277   [(match_scratch:DI 0 "r")
20278    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20279               (clobber (reg:CC FLAGS_REG))
20280               (clobber (mem:BLK (scratch)))])]
20281   "optimize_size"
20282   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20283               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20284               (clobber (mem:BLK (scratch)))])
20285    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20286               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20287   "")
20288
20289 ;; Convert esp additions to pop.
20290 (define_peephole2
20291   [(match_scratch:DI 0 "r")
20292    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20293               (clobber (reg:CC FLAGS_REG))])]
20294   ""
20295   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20296               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20297   "")
20298
20299 ;; Two pops case is tricky, since pop causes dependency on destination register.
20300 ;; We use two registers if available.
20301 (define_peephole2
20302   [(match_scratch:DI 0 "r")
20303    (match_scratch:DI 1 "r")
20304    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20305               (clobber (reg:CC FLAGS_REG))])]
20306   ""
20307   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20309    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20310               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20311   "")
20312
20313 (define_peephole2
20314   [(match_scratch:DI 0 "r")
20315    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20316               (clobber (reg:CC FLAGS_REG))])]
20317   "optimize_size"
20318   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20319               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20320    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20321               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20322   "")
20323 \f
20324 ;; Convert imul by three, five and nine into lea
20325 (define_peephole2
20326   [(parallel
20327     [(set (match_operand:SI 0 "register_operand" "")
20328           (mult:SI (match_operand:SI 1 "register_operand" "")
20329                    (match_operand:SI 2 "const_int_operand" "")))
20330      (clobber (reg:CC FLAGS_REG))])]
20331   "INTVAL (operands[2]) == 3
20332    || INTVAL (operands[2]) == 5
20333    || INTVAL (operands[2]) == 9"
20334   [(set (match_dup 0)
20335         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20336                  (match_dup 1)))]
20337   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20338
20339 (define_peephole2
20340   [(parallel
20341     [(set (match_operand:SI 0 "register_operand" "")
20342           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20343                    (match_operand:SI 2 "const_int_operand" "")))
20344      (clobber (reg:CC FLAGS_REG))])]
20345   "!optimize_size 
20346    && (INTVAL (operands[2]) == 3
20347        || INTVAL (operands[2]) == 5
20348        || INTVAL (operands[2]) == 9)"
20349   [(set (match_dup 0) (match_dup 1))
20350    (set (match_dup 0)
20351         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20352                  (match_dup 0)))]
20353   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20354
20355 (define_peephole2
20356   [(parallel
20357     [(set (match_operand:DI 0 "register_operand" "")
20358           (mult:DI (match_operand:DI 1 "register_operand" "")
20359                    (match_operand:DI 2 "const_int_operand" "")))
20360      (clobber (reg:CC FLAGS_REG))])]
20361   "TARGET_64BIT
20362    && (INTVAL (operands[2]) == 3
20363        || INTVAL (operands[2]) == 5
20364        || INTVAL (operands[2]) == 9)"
20365   [(set (match_dup 0)
20366         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20367                  (match_dup 1)))]
20368   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20369
20370 (define_peephole2
20371   [(parallel
20372     [(set (match_operand:DI 0 "register_operand" "")
20373           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20374                    (match_operand:DI 2 "const_int_operand" "")))
20375      (clobber (reg:CC FLAGS_REG))])]
20376   "TARGET_64BIT
20377    && !optimize_size 
20378    && (INTVAL (operands[2]) == 3
20379        || INTVAL (operands[2]) == 5
20380        || INTVAL (operands[2]) == 9)"
20381   [(set (match_dup 0) (match_dup 1))
20382    (set (match_dup 0)
20383         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20384                  (match_dup 0)))]
20385   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20386
20387 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20388 ;; imul $32bit_imm, reg, reg is direct decoded.
20389 (define_peephole2
20390   [(match_scratch:DI 3 "r")
20391    (parallel [(set (match_operand:DI 0 "register_operand" "")
20392                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20393                             (match_operand:DI 2 "immediate_operand" "")))
20394               (clobber (reg:CC FLAGS_REG))])]
20395   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20396    && !satisfies_constraint_K (operands[2])"
20397   [(set (match_dup 3) (match_dup 1))
20398    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20399               (clobber (reg:CC FLAGS_REG))])]
20400 "")
20401
20402 (define_peephole2
20403   [(match_scratch:SI 3 "r")
20404    (parallel [(set (match_operand:SI 0 "register_operand" "")
20405                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20406                             (match_operand:SI 2 "immediate_operand" "")))
20407               (clobber (reg:CC FLAGS_REG))])]
20408   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20409    && !satisfies_constraint_K (operands[2])"
20410   [(set (match_dup 3) (match_dup 1))
20411    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20412               (clobber (reg:CC FLAGS_REG))])]
20413 "")
20414
20415 (define_peephole2
20416   [(match_scratch:SI 3 "r")
20417    (parallel [(set (match_operand:DI 0 "register_operand" "")
20418                    (zero_extend:DI
20419                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20420                               (match_operand:SI 2 "immediate_operand" ""))))
20421               (clobber (reg:CC FLAGS_REG))])]
20422   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20423    && !satisfies_constraint_K (operands[2])"
20424   [(set (match_dup 3) (match_dup 1))
20425    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20426               (clobber (reg:CC FLAGS_REG))])]
20427 "")
20428
20429 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20430 ;; Convert it into imul reg, reg
20431 ;; It would be better to force assembler to encode instruction using long
20432 ;; immediate, but there is apparently no way to do so.
20433 (define_peephole2
20434   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20435                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20436                             (match_operand:DI 2 "const_int_operand" "")))
20437               (clobber (reg:CC FLAGS_REG))])
20438    (match_scratch:DI 3 "r")]
20439   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20440    && satisfies_constraint_K (operands[2])"
20441   [(set (match_dup 3) (match_dup 2))
20442    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20443               (clobber (reg:CC FLAGS_REG))])]
20444 {
20445   if (!rtx_equal_p (operands[0], operands[1]))
20446     emit_move_insn (operands[0], operands[1]);
20447 })
20448
20449 (define_peephole2
20450   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20451                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20452                             (match_operand:SI 2 "const_int_operand" "")))
20453               (clobber (reg:CC FLAGS_REG))])
20454    (match_scratch:SI 3 "r")]
20455   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20456    && satisfies_constraint_K (operands[2])"
20457   [(set (match_dup 3) (match_dup 2))
20458    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20459               (clobber (reg:CC FLAGS_REG))])]
20460 {
20461   if (!rtx_equal_p (operands[0], operands[1]))
20462     emit_move_insn (operands[0], operands[1]);
20463 })
20464
20465 (define_peephole2
20466   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20467                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20468                             (match_operand:HI 2 "immediate_operand" "")))
20469               (clobber (reg:CC FLAGS_REG))])
20470    (match_scratch:HI 3 "r")]
20471   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20472   [(set (match_dup 3) (match_dup 2))
20473    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20474               (clobber (reg:CC FLAGS_REG))])]
20475 {
20476   if (!rtx_equal_p (operands[0], operands[1]))
20477     emit_move_insn (operands[0], operands[1]);
20478 })
20479
20480 ;; After splitting up read-modify operations, array accesses with memory
20481 ;; operands might end up in form:
20482 ;;  sall    $2, %eax
20483 ;;  movl    4(%esp), %edx
20484 ;;  addl    %edx, %eax
20485 ;; instead of pre-splitting:
20486 ;;  sall    $2, %eax
20487 ;;  addl    4(%esp), %eax
20488 ;; Turn it into:
20489 ;;  movl    4(%esp), %edx
20490 ;;  leal    (%edx,%eax,4), %eax
20491
20492 (define_peephole2
20493   [(parallel [(set (match_operand 0 "register_operand" "")
20494                    (ashift (match_operand 1 "register_operand" "")
20495                            (match_operand 2 "const_int_operand" "")))
20496                (clobber (reg:CC FLAGS_REG))])
20497    (set (match_operand 3 "register_operand")
20498         (match_operand 4 "x86_64_general_operand" ""))
20499    (parallel [(set (match_operand 5 "register_operand" "")
20500                    (plus (match_operand 6 "register_operand" "")
20501                          (match_operand 7 "register_operand" "")))
20502                    (clobber (reg:CC FLAGS_REG))])]
20503   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20504    /* Validate MODE for lea.  */
20505    && ((!TARGET_PARTIAL_REG_STALL
20506         && (GET_MODE (operands[0]) == QImode
20507             || GET_MODE (operands[0]) == HImode))
20508        || GET_MODE (operands[0]) == SImode 
20509        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20510    /* We reorder load and the shift.  */
20511    && !rtx_equal_p (operands[1], operands[3])
20512    && !reg_overlap_mentioned_p (operands[0], operands[4])
20513    /* Last PLUS must consist of operand 0 and 3.  */
20514    && !rtx_equal_p (operands[0], operands[3])
20515    && (rtx_equal_p (operands[3], operands[6])
20516        || rtx_equal_p (operands[3], operands[7]))
20517    && (rtx_equal_p (operands[0], operands[6])
20518        || rtx_equal_p (operands[0], operands[7]))
20519    /* The intermediate operand 0 must die or be same as output.  */
20520    && (rtx_equal_p (operands[0], operands[5])
20521        || peep2_reg_dead_p (3, operands[0]))"
20522   [(set (match_dup 3) (match_dup 4))
20523    (set (match_dup 0) (match_dup 1))]
20524 {
20525   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20526   int scale = 1 << INTVAL (operands[2]);
20527   rtx index = gen_lowpart (Pmode, operands[1]);
20528   rtx base = gen_lowpart (Pmode, operands[3]);
20529   rtx dest = gen_lowpart (mode, operands[5]);
20530
20531   operands[1] = gen_rtx_PLUS (Pmode, base,
20532                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20533   if (mode != Pmode)
20534     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20535   operands[0] = dest;
20536 })
20537 \f
20538 ;; Call-value patterns last so that the wildcard operand does not
20539 ;; disrupt insn-recog's switch tables.
20540
20541 (define_insn "*call_value_pop_0"
20542   [(set (match_operand 0 "" "")
20543         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20544               (match_operand:SI 2 "" "")))
20545    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20546                             (match_operand:SI 3 "immediate_operand" "")))]
20547   "!TARGET_64BIT"
20548 {
20549   if (SIBLING_CALL_P (insn))
20550     return "jmp\t%P1";
20551   else
20552     return "call\t%P1";
20553 }
20554   [(set_attr "type" "callv")])
20555
20556 (define_insn "*call_value_pop_1"
20557   [(set (match_operand 0 "" "")
20558         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20559               (match_operand:SI 2 "" "")))
20560    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20561                             (match_operand:SI 3 "immediate_operand" "i")))]
20562   "!TARGET_64BIT"
20563 {
20564   if (constant_call_address_operand (operands[1], Pmode))
20565     {
20566       if (SIBLING_CALL_P (insn))
20567         return "jmp\t%P1";
20568       else
20569         return "call\t%P1";
20570     }
20571   if (SIBLING_CALL_P (insn))
20572     return "jmp\t%A1";
20573   else
20574     return "call\t%A1";
20575 }
20576   [(set_attr "type" "callv")])
20577
20578 (define_insn "*call_value_0"
20579   [(set (match_operand 0 "" "")
20580         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20581               (match_operand:SI 2 "" "")))]
20582   "!TARGET_64BIT"
20583 {
20584   if (SIBLING_CALL_P (insn))
20585     return "jmp\t%P1";
20586   else
20587     return "call\t%P1";
20588 }
20589   [(set_attr "type" "callv")])
20590
20591 (define_insn "*call_value_0_rex64"
20592   [(set (match_operand 0 "" "")
20593         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20594               (match_operand:DI 2 "const_int_operand" "")))]
20595   "TARGET_64BIT"
20596 {
20597   if (SIBLING_CALL_P (insn))
20598     return "jmp\t%P1";
20599   else
20600     return "call\t%P1";
20601 }
20602   [(set_attr "type" "callv")])
20603
20604 (define_insn "*call_value_1"
20605   [(set (match_operand 0 "" "")
20606         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20607               (match_operand:SI 2 "" "")))]
20608   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20609 {
20610   if (constant_call_address_operand (operands[1], Pmode))
20611     return "call\t%P1";
20612   return "call\t%A1";
20613 }
20614   [(set_attr "type" "callv")])
20615
20616 (define_insn "*sibcall_value_1"
20617   [(set (match_operand 0 "" "")
20618         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20619               (match_operand:SI 2 "" "")))]
20620   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20621 {
20622   if (constant_call_address_operand (operands[1], Pmode))
20623     return "jmp\t%P1";
20624   return "jmp\t%A1";
20625 }
20626   [(set_attr "type" "callv")])
20627
20628 (define_insn "*call_value_1_rex64"
20629   [(set (match_operand 0 "" "")
20630         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20631               (match_operand:DI 2 "" "")))]
20632   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20633 {
20634   if (constant_call_address_operand (operands[1], Pmode))
20635     return "call\t%P1";
20636   return "call\t%A1";
20637 }
20638   [(set_attr "type" "callv")])
20639
20640 (define_insn "*sibcall_value_1_rex64"
20641   [(set (match_operand 0 "" "")
20642         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20643               (match_operand:DI 2 "" "")))]
20644   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20645   "jmp\t%P1"
20646   [(set_attr "type" "callv")])
20647
20648 (define_insn "*sibcall_value_1_rex64_v"
20649   [(set (match_operand 0 "" "")
20650         (call (mem:QI (reg:DI 40))
20651               (match_operand:DI 1 "" "")))]
20652   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20653   "jmp\t*%%r11"
20654   [(set_attr "type" "callv")])
20655 \f
20656 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20657 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20658 ;; caught for use by garbage collectors and the like.  Using an insn that
20659 ;; maps to SIGILL makes it more likely the program will rightfully die.
20660 ;; Keeping with tradition, "6" is in honor of #UD.
20661 (define_insn "trap"
20662   [(trap_if (const_int 1) (const_int 6))]
20663   ""
20664   { return ASM_SHORT "0x0b0f"; }
20665   [(set_attr "length" "2")])
20666
20667 (define_expand "sse_prologue_save"
20668   [(parallel [(set (match_operand:BLK 0 "" "")
20669                    (unspec:BLK [(reg:DI 21)
20670                                 (reg:DI 22)
20671                                 (reg:DI 23)
20672                                 (reg:DI 24)
20673                                 (reg:DI 25)
20674                                 (reg:DI 26)
20675                                 (reg:DI 27)
20676                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20677               (use (match_operand:DI 1 "register_operand" ""))
20678               (use (match_operand:DI 2 "immediate_operand" ""))
20679               (use (label_ref:DI (match_operand 3 "" "")))])]
20680   "TARGET_64BIT"
20681   "")
20682
20683 (define_insn "*sse_prologue_save_insn"
20684   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20685                           (match_operand:DI 4 "const_int_operand" "n")))
20686         (unspec:BLK [(reg:DI 21)
20687                      (reg:DI 22)
20688                      (reg:DI 23)
20689                      (reg:DI 24)
20690                      (reg:DI 25)
20691                      (reg:DI 26)
20692                      (reg:DI 27)
20693                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20694    (use (match_operand:DI 1 "register_operand" "r"))
20695    (use (match_operand:DI 2 "const_int_operand" "i"))
20696    (use (label_ref:DI (match_operand 3 "" "X")))]
20697   "TARGET_64BIT
20698    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20699    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20700   "*
20701 {
20702   int i;
20703   operands[0] = gen_rtx_MEM (Pmode,
20704                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20705   output_asm_insn (\"jmp\\t%A1\", operands);
20706   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20707     {
20708       operands[4] = adjust_address (operands[0], DImode, i*16);
20709       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20710       PUT_MODE (operands[4], TImode);
20711       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20712         output_asm_insn (\"rex\", operands);
20713       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20714     }
20715   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20716                              CODE_LABEL_NUMBER (operands[3]));
20717   RET;
20718 }
20719   "
20720   [(set_attr "type" "other")
20721    (set_attr "length_immediate" "0")
20722    (set_attr "length_address" "0")
20723    (set_attr "length" "135")
20724    (set_attr "memory" "store")
20725    (set_attr "modrm" "0")
20726    (set_attr "mode" "DI")])
20727
20728 (define_expand "prefetch"
20729   [(prefetch (match_operand 0 "address_operand" "")
20730              (match_operand:SI 1 "const_int_operand" "")
20731              (match_operand:SI 2 "const_int_operand" ""))]
20732   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20733 {
20734   int rw = INTVAL (operands[1]);
20735   int locality = INTVAL (operands[2]);
20736
20737   gcc_assert (rw == 0 || rw == 1);
20738   gcc_assert (locality >= 0 && locality <= 3);
20739   gcc_assert (GET_MODE (operands[0]) == Pmode
20740               || GET_MODE (operands[0]) == VOIDmode);
20741
20742   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20743      supported by SSE counterpart or the SSE prefetch is not available
20744      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20745      of locality.  */
20746   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20747     operands[2] = GEN_INT (3);
20748   else
20749     operands[1] = const0_rtx;
20750 })
20751
20752 (define_insn "*prefetch_sse"
20753   [(prefetch (match_operand:SI 0 "address_operand" "p")
20754              (const_int 0)
20755              (match_operand:SI 1 "const_int_operand" ""))]
20756   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20757 {
20758   static const char * const patterns[4] = {
20759    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20760   };
20761
20762   int locality = INTVAL (operands[1]);
20763   gcc_assert (locality >= 0 && locality <= 3);
20764
20765   return patterns[locality];  
20766 }
20767   [(set_attr "type" "sse")
20768    (set_attr "memory" "none")])
20769
20770 (define_insn "*prefetch_sse_rex"
20771   [(prefetch (match_operand:DI 0 "address_operand" "p")
20772              (const_int 0)
20773              (match_operand:SI 1 "const_int_operand" ""))]
20774   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20775 {
20776   static const char * const patterns[4] = {
20777    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20778   };
20779
20780   int locality = INTVAL (operands[1]);
20781   gcc_assert (locality >= 0 && locality <= 3);
20782
20783   return patterns[locality];  
20784 }
20785   [(set_attr "type" "sse")
20786    (set_attr "memory" "none")])
20787
20788 (define_insn "*prefetch_3dnow"
20789   [(prefetch (match_operand:SI 0 "address_operand" "p")
20790              (match_operand:SI 1 "const_int_operand" "n")
20791              (const_int 3))]
20792   "TARGET_3DNOW && !TARGET_64BIT"
20793 {
20794   if (INTVAL (operands[1]) == 0)
20795     return "prefetch\t%a0";
20796   else
20797     return "prefetchw\t%a0";
20798 }
20799   [(set_attr "type" "mmx")
20800    (set_attr "memory" "none")])
20801
20802 (define_insn "*prefetch_3dnow_rex"
20803   [(prefetch (match_operand:DI 0 "address_operand" "p")
20804              (match_operand:SI 1 "const_int_operand" "n")
20805              (const_int 3))]
20806   "TARGET_3DNOW && TARGET_64BIT"
20807 {
20808   if (INTVAL (operands[1]) == 0)
20809     return "prefetch\t%a0";
20810   else
20811     return "prefetchw\t%a0";
20812 }
20813   [(set_attr "type" "mmx")
20814    (set_attr "memory" "none")])
20815
20816 (define_expand "stack_protect_set"
20817   [(match_operand 0 "memory_operand" "")
20818    (match_operand 1 "memory_operand" "")]
20819   ""
20820 {
20821 #ifdef TARGET_THREAD_SSP_OFFSET
20822   if (TARGET_64BIT)
20823     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20824                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20825   else
20826     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20827                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20828 #else
20829   if (TARGET_64BIT)
20830     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20831   else
20832     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20833 #endif
20834   DONE;
20835 })
20836
20837 (define_insn "stack_protect_set_si"
20838   [(set (match_operand:SI 0 "memory_operand" "=m")
20839         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20840    (set (match_scratch:SI 2 "=&r") (const_int 0))
20841    (clobber (reg:CC FLAGS_REG))]
20842   ""
20843   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20844   [(set_attr "type" "multi")])
20845
20846 (define_insn "stack_protect_set_di"
20847   [(set (match_operand:DI 0 "memory_operand" "=m")
20848         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20849    (set (match_scratch:DI 2 "=&r") (const_int 0))
20850    (clobber (reg:CC FLAGS_REG))]
20851   "TARGET_64BIT"
20852   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20853   [(set_attr "type" "multi")])
20854
20855 (define_insn "stack_tls_protect_set_si"
20856   [(set (match_operand:SI 0 "memory_operand" "=m")
20857         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20858    (set (match_scratch:SI 2 "=&r") (const_int 0))
20859    (clobber (reg:CC FLAGS_REG))]
20860   ""
20861   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20862   [(set_attr "type" "multi")])
20863
20864 (define_insn "stack_tls_protect_set_di"
20865   [(set (match_operand:DI 0 "memory_operand" "=m")
20866         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20867    (set (match_scratch:DI 2 "=&r") (const_int 0))
20868    (clobber (reg:CC FLAGS_REG))]
20869   "TARGET_64BIT"
20870   {
20871      /* The kernel uses a different segment register for performance reasons; a
20872         system call would not have to trash the userspace segment register,
20873         which would be expensive */
20874      if (ix86_cmodel != CM_KERNEL)
20875         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20876      else
20877         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20878   }
20879   [(set_attr "type" "multi")])
20880
20881 (define_expand "stack_protect_test"
20882   [(match_operand 0 "memory_operand" "")
20883    (match_operand 1 "memory_operand" "")
20884    (match_operand 2 "" "")]
20885   ""
20886 {
20887   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20888   ix86_compare_op0 = operands[0];
20889   ix86_compare_op1 = operands[1];
20890   ix86_compare_emitted = flags;
20891
20892 #ifdef TARGET_THREAD_SSP_OFFSET
20893   if (TARGET_64BIT)
20894     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20895                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20896   else
20897     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20898                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20899 #else
20900   if (TARGET_64BIT)
20901     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20902   else
20903     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20904 #endif
20905   emit_jump_insn (gen_beq (operands[2]));
20906   DONE;
20907 })
20908
20909 (define_insn "stack_protect_test_si"
20910   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20911         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20912                      (match_operand:SI 2 "memory_operand" "m")]
20913                     UNSPEC_SP_TEST))
20914    (clobber (match_scratch:SI 3 "=&r"))]
20915   ""
20916   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20917   [(set_attr "type" "multi")])
20918
20919 (define_insn "stack_protect_test_di"
20920   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20921         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20922                      (match_operand:DI 2 "memory_operand" "m")]
20923                     UNSPEC_SP_TEST))
20924    (clobber (match_scratch:DI 3 "=&r"))]
20925   "TARGET_64BIT"
20926   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20927   [(set_attr "type" "multi")])
20928
20929 (define_insn "stack_tls_protect_test_si"
20930   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20931         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20932                      (match_operand:SI 2 "const_int_operand" "i")]
20933                     UNSPEC_SP_TLS_TEST))
20934    (clobber (match_scratch:SI 3 "=r"))]
20935   ""
20936   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20937   [(set_attr "type" "multi")])
20938
20939 (define_insn "stack_tls_protect_test_di"
20940   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20941         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20942                      (match_operand:DI 2 "const_int_operand" "i")]
20943                     UNSPEC_SP_TLS_TEST))
20944    (clobber (match_scratch:DI 3 "=r"))]
20945   "TARGET_64BIT"
20946   {
20947      /* The kernel uses a different segment register for performance reasons; a
20948         system call would not have to trash the userspace segment register,
20949         which would be expensive */
20950      if (ix86_cmodel != CM_KERNEL)
20951         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20952      else
20953         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20954   }
20955   [(set_attr "type" "multi")])
20956
20957 (include "sse.md")
20958 (include "mmx.md")
20959 (include "sync.md")