OSDN Git Service

* config/i386/i386.md (extendsfdf2, extendsfxf2, extenddfxf2): Do not
[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 ;; Avoid vector decoded forms of the instruction.
4163 (define_peephole2
4164   [(match_scratch:DF 2 "Y")
4165    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4166         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4167   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4168   [(set (match_dup 2) (match_dup 1))
4169    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4170   "")
4171
4172 (define_peephole2
4173   [(match_scratch:SF 2 "x")
4174    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4175         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4176   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4177   [(set (match_dup 2) (match_dup 1))
4178    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4179   "")
4180
4181 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4182   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4183         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4184   "TARGET_FISTTP
4185    && FLOAT_MODE_P (GET_MODE (operands[1]))
4186    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4187          && (TARGET_64BIT || <MODE>mode != DImode))
4188         && TARGET_SSE_MATH)
4189    && !(reload_completed || reload_in_progress)"
4190   "#"
4191   "&& 1"
4192   [(const_int 0)]
4193 {
4194   if (memory_operand (operands[0], VOIDmode))
4195     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4196   else
4197     {
4198       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4199       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4200                                                             operands[1],
4201                                                             operands[2]));
4202     }
4203   DONE;
4204 }
4205   [(set_attr "type" "fisttp")
4206    (set_attr "mode" "<MODE>")])
4207
4208 (define_insn "fix_trunc<mode>_i387_fisttp"
4209   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4210         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4211    (clobber (match_scratch:XF 2 "=&1f"))]
4212   "TARGET_FISTTP
4213    && FLOAT_MODE_P (GET_MODE (operands[1]))
4214    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4215          && (TARGET_64BIT || <MODE>mode != DImode))
4216         && TARGET_SSE_MATH)"
4217   "* return output_fix_trunc (insn, operands, 1);"
4218   [(set_attr "type" "fisttp")
4219    (set_attr "mode" "<MODE>")])
4220
4221 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4222   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4224    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4225    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4226   "TARGET_FISTTP
4227    && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229         && (TARGET_64BIT || <MODE>mode != DImode))
4230         && TARGET_SSE_MATH)"
4231   "#"
4232   [(set_attr "type" "fisttp")
4233    (set_attr "mode" "<MODE>")])
4234
4235 (define_split
4236   [(set (match_operand:X87MODEI 0 "register_operand" "")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4238    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4239    (clobber (match_scratch 3 ""))]
4240   "reload_completed"
4241   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4242               (clobber (match_dup 3))])
4243    (set (match_dup 0) (match_dup 2))]
4244   "")
4245
4246 (define_split
4247   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4248         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4249    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4250    (clobber (match_scratch 3 ""))]
4251   "reload_completed"
4252   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4253               (clobber (match_dup 3))])]
4254   "")
4255
4256 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4257 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4258 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4259 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4260 ;; function in i386.c.
4261 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4262   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4263         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4264    (clobber (reg:CC FLAGS_REG))]
4265   "TARGET_80387 && !TARGET_FISTTP
4266    && FLOAT_MODE_P (GET_MODE (operands[1]))
4267    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4268          && (TARGET_64BIT || <MODE>mode != DImode))
4269    && !(reload_completed || reload_in_progress)"
4270   "#"
4271   "&& 1"
4272   [(const_int 0)]
4273 {
4274   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4275
4276   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4277   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4278   if (memory_operand (operands[0], VOIDmode))
4279     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4280                                          operands[2], operands[3]));
4281   else
4282     {
4283       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4284       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4285                                                      operands[2], operands[3],
4286                                                      operands[4]));
4287     }
4288   DONE;
4289 }
4290   [(set_attr "type" "fistp")
4291    (set_attr "i387_cw" "trunc")
4292    (set_attr "mode" "<MODE>")])
4293
4294 (define_insn "fix_truncdi_i387"
4295   [(set (match_operand:DI 0 "memory_operand" "=m")
4296         (fix:DI (match_operand 1 "register_operand" "f")))
4297    (use (match_operand:HI 2 "memory_operand" "m"))
4298    (use (match_operand:HI 3 "memory_operand" "m"))
4299    (clobber (match_scratch:XF 4 "=&1f"))]
4300   "TARGET_80387 && !TARGET_FISTTP
4301    && FLOAT_MODE_P (GET_MODE (operands[1]))
4302    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303   "* return output_fix_trunc (insn, operands, 0);"
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "DI")])
4307
4308 (define_insn "fix_truncdi_i387_with_temp"
4309   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4310         (fix:DI (match_operand 1 "register_operand" "f,f")))
4311    (use (match_operand:HI 2 "memory_operand" "m,m"))
4312    (use (match_operand:HI 3 "memory_operand" "m,m"))
4313    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4314    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4315   "TARGET_80387 && !TARGET_FISTTP
4316    && FLOAT_MODE_P (GET_MODE (operands[1]))
4317    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4318   "#"
4319   [(set_attr "type" "fistp")
4320    (set_attr "i387_cw" "trunc")
4321    (set_attr "mode" "DI")])
4322
4323 (define_split 
4324   [(set (match_operand:DI 0 "register_operand" "")
4325         (fix:DI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:DI 4 "memory_operand" ""))
4329    (clobber (match_scratch 5 ""))]
4330   "reload_completed"
4331   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4332               (use (match_dup 2))
4333               (use (match_dup 3))
4334               (clobber (match_dup 5))])
4335    (set (match_dup 0) (match_dup 4))]
4336   "")
4337
4338 (define_split 
4339   [(set (match_operand:DI 0 "memory_operand" "")
4340         (fix:DI (match_operand 1 "register_operand" "")))
4341    (use (match_operand:HI 2 "memory_operand" ""))
4342    (use (match_operand:HI 3 "memory_operand" ""))
4343    (clobber (match_operand:DI 4 "memory_operand" ""))
4344    (clobber (match_scratch 5 ""))]
4345   "reload_completed"
4346   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4347               (use (match_dup 2))
4348               (use (match_dup 3))
4349               (clobber (match_dup 5))])]
4350   "")
4351
4352 (define_insn "fix_trunc<mode>_i387"
4353   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4354         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4355    (use (match_operand:HI 2 "memory_operand" "m"))
4356    (use (match_operand:HI 3 "memory_operand" "m"))]
4357   "TARGET_80387 && !TARGET_FISTTP
4358    && FLOAT_MODE_P (GET_MODE (operands[1]))
4359    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360   "* return output_fix_trunc (insn, operands, 0);"
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "<MODE>")])
4364
4365 (define_insn "fix_trunc<mode>_i387_with_temp"
4366   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4367         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && !TARGET_FISTTP
4372    && FLOAT_MODE_P (GET_MODE (operands[1]))
4373    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374   "#"
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "<MODE>")])
4378
4379 (define_split 
4380   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4381         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4382    (use (match_operand:HI 2 "memory_operand" ""))
4383    (use (match_operand:HI 3 "memory_operand" ""))
4384    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4385   "reload_completed"
4386   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4387               (use (match_dup 2))
4388               (use (match_dup 3))])
4389    (set (match_dup 0) (match_dup 4))]
4390   "")
4391
4392 (define_split 
4393   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4394         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4398   "reload_completed"
4399   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4400               (use (match_dup 2))
4401               (use (match_dup 3))])]
4402   "")
4403
4404 (define_insn "x86_fnstcw_1"
4405   [(set (match_operand:HI 0 "memory_operand" "=m")
4406         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4407   "TARGET_80387"
4408   "fnstcw\t%0"
4409   [(set_attr "length" "2")
4410    (set_attr "mode" "HI")
4411    (set_attr "unit" "i387")])
4412
4413 (define_insn "x86_fldcw_1"
4414   [(set (reg:HI FPSR_REG)
4415         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4416   "TARGET_80387"
4417   "fldcw\t%0"
4418   [(set_attr "length" "2")
4419    (set_attr "mode" "HI")
4420    (set_attr "unit" "i387")
4421    (set_attr "athlon_decode" "vector")])
4422 \f
4423 ;; Conversion between fixed point and floating point.
4424
4425 ;; Even though we only accept memory inputs, the backend _really_
4426 ;; wants to be able to do this between registers.
4427
4428 (define_expand "floathisf2"
4429   [(set (match_operand:SF 0 "register_operand" "")
4430         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4431   "TARGET_80387 || TARGET_SSE_MATH"
4432 {
4433   if (TARGET_SSE_MATH)
4434     {
4435       emit_insn (gen_floatsisf2 (operands[0],
4436                                  convert_to_mode (SImode, operands[1], 0)));
4437       DONE;
4438     }
4439 })
4440
4441 (define_insn "*floathisf2_i387"
4442   [(set (match_operand:SF 0 "register_operand" "=f,f")
4443         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4444   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4445   "@
4446    fild%z1\t%1
4447    #"
4448   [(set_attr "type" "fmov,multi")
4449    (set_attr "mode" "SF")
4450    (set_attr "unit" "*,i387")
4451    (set_attr "fp_int_src" "true")])
4452
4453 (define_expand "floatsisf2"
4454   [(set (match_operand:SF 0 "register_operand" "")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4456   "TARGET_80387 || TARGET_SSE_MATH"
4457   "")
4458
4459 (define_insn "*floatsisf2_mixed"
4460   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4461         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4462   "TARGET_MIX_SSE_I387"
4463   "@
4464    fild%z1\t%1
4465    #
4466    cvtsi2ss\t{%1, %0|%0, %1}
4467    cvtsi2ss\t{%1, %0|%0, %1}"
4468   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4469    (set_attr "mode" "SF")
4470    (set_attr "unit" "*,i387,*,*")
4471    (set_attr "athlon_decode" "*,*,vector,double")
4472    (set_attr "fp_int_src" "true")])
4473
4474 (define_insn "*floatsisf2_sse"
4475   [(set (match_operand:SF 0 "register_operand" "=x,x")
4476         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4477   "TARGET_SSE_MATH"
4478   "cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "vector,double")
4482    (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_i387"
4485   [(set (match_operand:SF 0 "register_operand" "=f,f")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4487   "TARGET_80387"
4488   "@
4489    fild%z1\t%1
4490    #"
4491   [(set_attr "type" "fmov,multi")
4492    (set_attr "mode" "SF")
4493    (set_attr "unit" "*,i387")
4494    (set_attr "fp_int_src" "true")])
4495
4496 (define_expand "floatdisf2"
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4499   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4500   "")
4501
4502 (define_insn "*floatdisf2_mixed"
4503   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4504         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4505   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4506   "@
4507    fild%z1\t%1
4508    #
4509    cvtsi2ss{q}\t{%1, %0|%0, %1}
4510    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4511   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4512    (set_attr "mode" "SF")
4513    (set_attr "unit" "*,i387,*,*")
4514    (set_attr "athlon_decode" "*,*,vector,double")
4515    (set_attr "fp_int_src" "true")])
4516
4517 (define_insn "*floatdisf2_sse"
4518   [(set (match_operand:SF 0 "register_operand" "=x,x")
4519         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4520   "TARGET_64BIT && TARGET_SSE_MATH"
4521   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4522   [(set_attr "type" "sseicvt")
4523    (set_attr "mode" "SF")
4524    (set_attr "athlon_decode" "vector,double")
4525    (set_attr "fp_int_src" "true")])
4526
4527 (define_insn "*floatdisf2_i387"
4528   [(set (match_operand:SF 0 "register_operand" "=f,f")
4529         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4530   "TARGET_80387"
4531   "@
4532    fild%z1\t%1
4533    #"
4534   [(set_attr "type" "fmov,multi")
4535    (set_attr "mode" "SF")
4536    (set_attr "unit" "*,i387")
4537    (set_attr "fp_int_src" "true")])
4538
4539 (define_expand "floathidf2"
4540   [(set (match_operand:DF 0 "register_operand" "")
4541         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4542   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4543 {
4544   if (TARGET_SSE2 && TARGET_SSE_MATH)
4545     {
4546       emit_insn (gen_floatsidf2 (operands[0],
4547                                  convert_to_mode (SImode, operands[1], 0)));
4548       DONE;
4549     }
4550 })
4551
4552 (define_insn "*floathidf2_i387"
4553   [(set (match_operand:DF 0 "register_operand" "=f,f")
4554         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4555   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4556   "@
4557    fild%z1\t%1
4558    #"
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "mode" "DF")
4561    (set_attr "unit" "*,i387")
4562    (set_attr "fp_int_src" "true")])
4563
4564 (define_expand "floatsidf2"
4565   [(set (match_operand:DF 0 "register_operand" "")
4566         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4567   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4568   "")
4569
4570 (define_insn "*floatsidf2_mixed"
4571   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4572         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4573   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4574   "@
4575    fild%z1\t%1
4576    #
4577    cvtsi2sd\t{%1, %0|%0, %1}
4578    cvtsi2sd\t{%1, %0|%0, %1}"
4579   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4580    (set_attr "mode" "DF")
4581    (set_attr "unit" "*,i387,*,*")
4582    (set_attr "athlon_decode" "*,*,double,direct")
4583    (set_attr "fp_int_src" "true")])
4584
4585 (define_insn "*floatsidf2_sse"
4586   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4587         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4588   "TARGET_SSE2 && TARGET_SSE_MATH"
4589   "cvtsi2sd\t{%1, %0|%0, %1}"
4590   [(set_attr "type" "sseicvt")
4591    (set_attr "mode" "DF")
4592    (set_attr "athlon_decode" "double,direct")
4593    (set_attr "fp_int_src" "true")])
4594
4595 (define_insn "*floatsidf2_i387"
4596   [(set (match_operand:DF 0 "register_operand" "=f,f")
4597         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4598   "TARGET_80387"
4599   "@
4600    fild%z1\t%1
4601    #"
4602   [(set_attr "type" "fmov,multi")
4603    (set_attr "mode" "DF")
4604    (set_attr "unit" "*,i387")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_expand "floatdidf2"
4608   [(set (match_operand:DF 0 "register_operand" "")
4609         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4610   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4611   "")
4612
4613 (define_insn "*floatdidf2_mixed"
4614   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4615         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4616   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4617   "@
4618    fild%z1\t%1
4619    #
4620    cvtsi2sd{q}\t{%1, %0|%0, %1}
4621    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4622   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623    (set_attr "mode" "DF")
4624    (set_attr "unit" "*,i387,*,*")
4625    (set_attr "athlon_decode" "*,*,double,direct")
4626    (set_attr "fp_int_src" "true")])
4627
4628 (define_insn "*floatdidf2_sse"
4629   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4630         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4631   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4632   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "sseicvt")
4634    (set_attr "mode" "DF")
4635    (set_attr "athlon_decode" "double,direct")
4636    (set_attr "fp_int_src" "true")])
4637
4638 (define_insn "*floatdidf2_i387"
4639   [(set (match_operand:DF 0 "register_operand" "=f,f")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4641   "TARGET_80387"
4642   "@
4643    fild%z1\t%1
4644    #"
4645   [(set_attr "type" "fmov,multi")
4646    (set_attr "mode" "DF")
4647    (set_attr "unit" "*,i387")
4648    (set_attr "fp_int_src" "true")])
4649
4650 (define_insn "floathixf2"
4651   [(set (match_operand:XF 0 "register_operand" "=f,f")
4652         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4653   "TARGET_80387"
4654   "@
4655    fild%z1\t%1
4656    #"
4657   [(set_attr "type" "fmov,multi")
4658    (set_attr "mode" "XF")
4659    (set_attr "unit" "*,i387")
4660    (set_attr "fp_int_src" "true")])
4661
4662 (define_insn "floatsixf2"
4663   [(set (match_operand:XF 0 "register_operand" "=f,f")
4664         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "XF")
4671    (set_attr "unit" "*,i387")
4672    (set_attr "fp_int_src" "true")])
4673
4674 (define_insn "floatdixf2"
4675   [(set (match_operand:XF 0 "register_operand" "=f,f")
4676         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4677   "TARGET_80387"
4678   "@
4679    fild%z1\t%1
4680    #"
4681   [(set_attr "type" "fmov,multi")
4682    (set_attr "mode" "XF")
4683    (set_attr "unit" "*,i387")
4684    (set_attr "fp_int_src" "true")])
4685
4686 ;; %%% Kill these when reload knows how to do it.
4687 (define_split
4688   [(set (match_operand 0 "fp_register_operand" "")
4689         (float (match_operand 1 "register_operand" "")))]
4690   "reload_completed
4691    && TARGET_80387
4692    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4693   [(const_int 0)]
4694 {
4695   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4696   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4697   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4698   ix86_free_from_memory (GET_MODE (operands[1]));
4699   DONE;
4700 })
4701
4702 (define_expand "floatunssisf2"
4703   [(use (match_operand:SF 0 "register_operand" ""))
4704    (use (match_operand:SI 1 "register_operand" ""))]
4705   "!TARGET_64BIT && TARGET_SSE_MATH"
4706   "x86_emit_floatuns (operands); DONE;")
4707
4708 (define_expand "floatunsdisf2"
4709   [(use (match_operand:SF 0 "register_operand" ""))
4710    (use (match_operand:DI 1 "register_operand" ""))]
4711   "TARGET_64BIT && TARGET_SSE_MATH"
4712   "x86_emit_floatuns (operands); DONE;")
4713
4714 (define_expand "floatunsdidf2"
4715   [(use (match_operand:DF 0 "register_operand" ""))
4716    (use (match_operand:DI 1 "register_operand" ""))]
4717   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4718   "x86_emit_floatuns (operands); DONE;")
4719 \f
4720 ;; SSE extract/set expanders
4721
4722 \f
4723 ;; Add instructions
4724
4725 ;; %%% splits for addditi3
4726
4727 (define_expand "addti3"
4728   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4729         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4730                  (match_operand:TI 2 "x86_64_general_operand" "")))
4731    (clobber (reg:CC FLAGS_REG))]
4732   "TARGET_64BIT"
4733   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4734
4735 (define_insn "*addti3_1"
4736   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4737         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4738                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4739    (clobber (reg:CC FLAGS_REG))]
4740   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4741   "#")
4742
4743 (define_split
4744   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4745         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4746                  (match_operand:TI 2 "general_operand" "")))
4747    (clobber (reg:CC FLAGS_REG))]
4748   "TARGET_64BIT && reload_completed"
4749   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4750                                           UNSPEC_ADD_CARRY))
4751               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4752    (parallel [(set (match_dup 3)
4753                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4754                                      (match_dup 4))
4755                             (match_dup 5)))
4756               (clobber (reg:CC FLAGS_REG))])]
4757   "split_ti (operands+0, 1, operands+0, operands+3);
4758    split_ti (operands+1, 1, operands+1, operands+4);
4759    split_ti (operands+2, 1, operands+2, operands+5);")
4760
4761 ;; %%% splits for addsidi3
4762 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4763 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4764 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4765
4766 (define_expand "adddi3"
4767   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4768         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4769                  (match_operand:DI 2 "x86_64_general_operand" "")))
4770    (clobber (reg:CC FLAGS_REG))]
4771   ""
4772   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4773
4774 (define_insn "*adddi3_1"
4775   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4776         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4777                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4778    (clobber (reg:CC FLAGS_REG))]
4779   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4780   "#")
4781
4782 (define_split
4783   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4784         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4785                  (match_operand:DI 2 "general_operand" "")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "!TARGET_64BIT && reload_completed"
4788   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4789                                           UNSPEC_ADD_CARRY))
4790               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4791    (parallel [(set (match_dup 3)
4792                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4793                                      (match_dup 4))
4794                             (match_dup 5)))
4795               (clobber (reg:CC FLAGS_REG))])]
4796   "split_di (operands+0, 1, operands+0, operands+3);
4797    split_di (operands+1, 1, operands+1, operands+4);
4798    split_di (operands+2, 1, operands+2, operands+5);")
4799
4800 (define_insn "adddi3_carry_rex64"
4801   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4802           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4803                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4804                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4805    (clobber (reg:CC FLAGS_REG))]
4806   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4807   "adc{q}\t{%2, %0|%0, %2}"
4808   [(set_attr "type" "alu")
4809    (set_attr "pent_pair" "pu")
4810    (set_attr "mode" "DI")])
4811
4812 (define_insn "*adddi3_cc_rex64"
4813   [(set (reg:CC FLAGS_REG)
4814         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4815                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4816                    UNSPEC_ADD_CARRY))
4817    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4818         (plus:DI (match_dup 1) (match_dup 2)))]
4819   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4820   "add{q}\t{%2, %0|%0, %2}"
4821   [(set_attr "type" "alu")
4822    (set_attr "mode" "DI")])
4823
4824 (define_insn "addqi3_carry"
4825   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4826           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4827                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4828                    (match_operand:QI 2 "general_operand" "qi,qm")))
4829    (clobber (reg:CC FLAGS_REG))]
4830   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4831   "adc{b}\t{%2, %0|%0, %2}"
4832   [(set_attr "type" "alu")
4833    (set_attr "pent_pair" "pu")
4834    (set_attr "mode" "QI")])
4835
4836 (define_insn "addhi3_carry"
4837   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4838           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4839                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4840                    (match_operand:HI 2 "general_operand" "ri,rm")))
4841    (clobber (reg:CC FLAGS_REG))]
4842   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4843   "adc{w}\t{%2, %0|%0, %2}"
4844   [(set_attr "type" "alu")
4845    (set_attr "pent_pair" "pu")
4846    (set_attr "mode" "HI")])
4847
4848 (define_insn "addsi3_carry"
4849   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4850           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4851                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4852                    (match_operand:SI 2 "general_operand" "ri,rm")))
4853    (clobber (reg:CC FLAGS_REG))]
4854   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4855   "adc{l}\t{%2, %0|%0, %2}"
4856   [(set_attr "type" "alu")
4857    (set_attr "pent_pair" "pu")
4858    (set_attr "mode" "SI")])
4859
4860 (define_insn "*addsi3_carry_zext"
4861   [(set (match_operand:DI 0 "register_operand" "=r")
4862           (zero_extend:DI 
4863             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4864                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4865                      (match_operand:SI 2 "general_operand" "rim"))))
4866    (clobber (reg:CC FLAGS_REG))]
4867   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4868   "adc{l}\t{%2, %k0|%k0, %2}"
4869   [(set_attr "type" "alu")
4870    (set_attr "pent_pair" "pu")
4871    (set_attr "mode" "SI")])
4872
4873 (define_insn "*addsi3_cc"
4874   [(set (reg:CC FLAGS_REG)
4875         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4876                     (match_operand:SI 2 "general_operand" "ri,rm")]
4877                    UNSPEC_ADD_CARRY))
4878    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879         (plus:SI (match_dup 1) (match_dup 2)))]
4880   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4881   "add{l}\t{%2, %0|%0, %2}"
4882   [(set_attr "type" "alu")
4883    (set_attr "mode" "SI")])
4884
4885 (define_insn "addqi3_cc"
4886   [(set (reg:CC FLAGS_REG)
4887         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4888                     (match_operand:QI 2 "general_operand" "qi,qm")]
4889                    UNSPEC_ADD_CARRY))
4890    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4891         (plus:QI (match_dup 1) (match_dup 2)))]
4892   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4893   "add{b}\t{%2, %0|%0, %2}"
4894   [(set_attr "type" "alu")
4895    (set_attr "mode" "QI")])
4896
4897 (define_expand "addsi3"
4898   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4899                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4900                             (match_operand:SI 2 "general_operand" "")))
4901               (clobber (reg:CC FLAGS_REG))])]
4902   ""
4903   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4904
4905 (define_insn "*lea_1"
4906   [(set (match_operand:SI 0 "register_operand" "=r")
4907         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4908   "!TARGET_64BIT"
4909   "lea{l}\t{%a1, %0|%0, %a1}"
4910   [(set_attr "type" "lea")
4911    (set_attr "mode" "SI")])
4912
4913 (define_insn "*lea_1_rex64"
4914   [(set (match_operand:SI 0 "register_operand" "=r")
4915         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4916   "TARGET_64BIT"
4917   "lea{l}\t{%a1, %0|%0, %a1}"
4918   [(set_attr "type" "lea")
4919    (set_attr "mode" "SI")])
4920
4921 (define_insn "*lea_1_zext"
4922   [(set (match_operand:DI 0 "register_operand" "=r")
4923         (zero_extend:DI
4924          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4925   "TARGET_64BIT"
4926   "lea{l}\t{%a1, %k0|%k0, %a1}"
4927   [(set_attr "type" "lea")
4928    (set_attr "mode" "SI")])
4929
4930 (define_insn "*lea_2_rex64"
4931   [(set (match_operand:DI 0 "register_operand" "=r")
4932         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4933   "TARGET_64BIT"
4934   "lea{q}\t{%a1, %0|%0, %a1}"
4935   [(set_attr "type" "lea")
4936    (set_attr "mode" "DI")])
4937
4938 ;; The lea patterns for non-Pmodes needs to be matched by several
4939 ;; insns converted to real lea by splitters.
4940
4941 (define_insn_and_split "*lea_general_1"
4942   [(set (match_operand 0 "register_operand" "=r")
4943         (plus (plus (match_operand 1 "index_register_operand" "l")
4944                     (match_operand 2 "register_operand" "r"))
4945               (match_operand 3 "immediate_operand" "i")))]
4946   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4947     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4948    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4949    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4950    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4951    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4952        || GET_MODE (operands[3]) == VOIDmode)"
4953   "#"
4954   "&& reload_completed"
4955   [(const_int 0)]
4956 {
4957   rtx pat;
4958   operands[0] = gen_lowpart (SImode, operands[0]);
4959   operands[1] = gen_lowpart (Pmode, operands[1]);
4960   operands[2] = gen_lowpart (Pmode, operands[2]);
4961   operands[3] = gen_lowpart (Pmode, operands[3]);
4962   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4963                       operands[3]);
4964   if (Pmode != SImode)
4965     pat = gen_rtx_SUBREG (SImode, pat, 0);
4966   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4967   DONE;
4968 }
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4971
4972 (define_insn_and_split "*lea_general_1_zext"
4973   [(set (match_operand:DI 0 "register_operand" "=r")
4974         (zero_extend:DI
4975           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4976                             (match_operand:SI 2 "register_operand" "r"))
4977                    (match_operand:SI 3 "immediate_operand" "i"))))]
4978   "TARGET_64BIT"
4979   "#"
4980   "&& reload_completed"
4981   [(set (match_dup 0)
4982         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4983                                                      (match_dup 2))
4984                                             (match_dup 3)) 0)))]
4985 {
4986   operands[1] = gen_lowpart (Pmode, operands[1]);
4987   operands[2] = gen_lowpart (Pmode, operands[2]);
4988   operands[3] = gen_lowpart (Pmode, operands[3]);
4989 }
4990   [(set_attr "type" "lea")
4991    (set_attr "mode" "SI")])
4992
4993 (define_insn_and_split "*lea_general_2"
4994   [(set (match_operand 0 "register_operand" "=r")
4995         (plus (mult (match_operand 1 "index_register_operand" "l")
4996                     (match_operand 2 "const248_operand" "i"))
4997               (match_operand 3 "nonmemory_operand" "ri")))]
4998   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4999     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5000    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5001    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5002    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5003        || GET_MODE (operands[3]) == VOIDmode)"
5004   "#"
5005   "&& reload_completed"
5006   [(const_int 0)]
5007 {
5008   rtx pat;
5009   operands[0] = gen_lowpart (SImode, operands[0]);
5010   operands[1] = gen_lowpart (Pmode, operands[1]);
5011   operands[3] = gen_lowpart (Pmode, operands[3]);
5012   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5013                       operands[3]);
5014   if (Pmode != SImode)
5015     pat = gen_rtx_SUBREG (SImode, pat, 0);
5016   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5017   DONE;
5018 }
5019   [(set_attr "type" "lea")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn_and_split "*lea_general_2_zext"
5023   [(set (match_operand:DI 0 "register_operand" "=r")
5024         (zero_extend:DI
5025           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5026                             (match_operand:SI 2 "const248_operand" "n"))
5027                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5028   "TARGET_64BIT"
5029   "#"
5030   "&& reload_completed"
5031   [(set (match_dup 0)
5032         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5033                                                      (match_dup 2))
5034                                             (match_dup 3)) 0)))]
5035 {
5036   operands[1] = gen_lowpart (Pmode, operands[1]);
5037   operands[3] = gen_lowpart (Pmode, operands[3]);
5038 }
5039   [(set_attr "type" "lea")
5040    (set_attr "mode" "SI")])
5041
5042 (define_insn_and_split "*lea_general_3"
5043   [(set (match_operand 0 "register_operand" "=r")
5044         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5045                           (match_operand 2 "const248_operand" "i"))
5046                     (match_operand 3 "register_operand" "r"))
5047               (match_operand 4 "immediate_operand" "i")))]
5048   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5049     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5050    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5051    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5052    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5053   "#"
5054   "&& reload_completed"
5055   [(const_int 0)]
5056 {
5057   rtx pat;
5058   operands[0] = gen_lowpart (SImode, operands[0]);
5059   operands[1] = gen_lowpart (Pmode, operands[1]);
5060   operands[3] = gen_lowpart (Pmode, operands[3]);
5061   operands[4] = gen_lowpart (Pmode, operands[4]);
5062   pat = gen_rtx_PLUS (Pmode,
5063                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5064                                                          operands[2]),
5065                                     operands[3]),
5066                       operands[4]);
5067   if (Pmode != SImode)
5068     pat = gen_rtx_SUBREG (SImode, pat, 0);
5069   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5070   DONE;
5071 }
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn_and_split "*lea_general_3_zext"
5076   [(set (match_operand:DI 0 "register_operand" "=r")
5077         (zero_extend:DI
5078           (plus:SI (plus:SI (mult:SI
5079                               (match_operand:SI 1 "index_register_operand" "l")
5080                               (match_operand:SI 2 "const248_operand" "n"))
5081                             (match_operand:SI 3 "register_operand" "r"))
5082                    (match_operand:SI 4 "immediate_operand" "i"))))]
5083   "TARGET_64BIT"
5084   "#"
5085   "&& reload_completed"
5086   [(set (match_dup 0)
5087         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5088                                                               (match_dup 2))
5089                                                      (match_dup 3))
5090                                             (match_dup 4)) 0)))]
5091 {
5092   operands[1] = gen_lowpart (Pmode, operands[1]);
5093   operands[3] = gen_lowpart (Pmode, operands[3]);
5094   operands[4] = gen_lowpart (Pmode, operands[4]);
5095 }
5096   [(set_attr "type" "lea")
5097    (set_attr "mode" "SI")])
5098
5099 (define_insn "*adddi_1_rex64"
5100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5101         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5102                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5103    (clobber (reg:CC FLAGS_REG))]
5104   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5105 {
5106   switch (get_attr_type (insn))
5107     {
5108     case TYPE_LEA:
5109       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5110       return "lea{q}\t{%a2, %0|%0, %a2}";
5111
5112     case TYPE_INCDEC:
5113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5114       if (operands[2] == const1_rtx)
5115         return "inc{q}\t%0";
5116       else
5117         {
5118           gcc_assert (operands[2] == constm1_rtx);
5119           return "dec{q}\t%0";
5120         }
5121
5122     default:
5123       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5124
5125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5127       if (GET_CODE (operands[2]) == CONST_INT
5128           /* Avoid overflows.  */
5129           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5130           && (INTVAL (operands[2]) == 128
5131               || (INTVAL (operands[2]) < 0
5132                   && INTVAL (operands[2]) != -128)))
5133         {
5134           operands[2] = GEN_INT (-INTVAL (operands[2]));
5135           return "sub{q}\t{%2, %0|%0, %2}";
5136         }
5137       return "add{q}\t{%2, %0|%0, %2}";
5138     }
5139 }
5140   [(set (attr "type")
5141      (cond [(eq_attr "alternative" "2")
5142               (const_string "lea")
5143             ; Current assemblers are broken and do not allow @GOTOFF in
5144             ; ought but a memory context.
5145             (match_operand:DI 2 "pic_symbolic_operand" "")
5146               (const_string "lea")
5147             (match_operand:DI 2 "incdec_operand" "")
5148               (const_string "incdec")
5149            ]
5150            (const_string "alu")))
5151    (set_attr "mode" "DI")])
5152
5153 ;; Convert lea to the lea pattern to avoid flags dependency.
5154 (define_split
5155   [(set (match_operand:DI 0 "register_operand" "")
5156         (plus:DI (match_operand:DI 1 "register_operand" "")
5157                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5158    (clobber (reg:CC FLAGS_REG))]
5159   "TARGET_64BIT && reload_completed
5160    && true_regnum (operands[0]) != true_regnum (operands[1])"
5161   [(set (match_dup 0)
5162         (plus:DI (match_dup 1)
5163                  (match_dup 2)))]
5164   "")
5165
5166 (define_insn "*adddi_2_rex64"
5167   [(set (reg FLAGS_REG)
5168         (compare
5169           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5170                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5171           (const_int 0)))                       
5172    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5173         (plus:DI (match_dup 1) (match_dup 2)))]
5174   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5175    && ix86_binary_operator_ok (PLUS, DImode, operands)
5176    /* Current assemblers are broken and do not allow @GOTOFF in
5177       ought but a memory context.  */
5178    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5179 {
5180   switch (get_attr_type (insn))
5181     {
5182     case TYPE_INCDEC:
5183       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5184       if (operands[2] == const1_rtx)
5185         return "inc{q}\t%0";
5186       else
5187         {
5188           gcc_assert (operands[2] == constm1_rtx);
5189           return "dec{q}\t%0";
5190         }
5191
5192     default:
5193       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194       /* ???? We ought to handle there the 32bit case too
5195          - do we need new constraint?  */
5196       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5197          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5198       if (GET_CODE (operands[2]) == CONST_INT
5199           /* Avoid overflows.  */
5200           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5201           && (INTVAL (operands[2]) == 128
5202               || (INTVAL (operands[2]) < 0
5203                   && INTVAL (operands[2]) != -128)))
5204         {
5205           operands[2] = GEN_INT (-INTVAL (operands[2]));
5206           return "sub{q}\t{%2, %0|%0, %2}";
5207         }
5208       return "add{q}\t{%2, %0|%0, %2}";
5209     }
5210 }
5211   [(set (attr "type")
5212      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5213         (const_string "incdec")
5214         (const_string "alu")))
5215    (set_attr "mode" "DI")])
5216
5217 (define_insn "*adddi_3_rex64"
5218   [(set (reg FLAGS_REG)
5219         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5220                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5221    (clobber (match_scratch:DI 0 "=r"))]
5222   "TARGET_64BIT
5223    && ix86_match_ccmode (insn, CCZmode)
5224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5225    /* Current assemblers are broken and do not allow @GOTOFF in
5226       ought but a memory context.  */
5227    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5228 {
5229   switch (get_attr_type (insn))
5230     {
5231     case TYPE_INCDEC:
5232       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5233       if (operands[2] == const1_rtx)
5234         return "inc{q}\t%0";
5235       else
5236         {
5237           gcc_assert (operands[2] == constm1_rtx);
5238           return "dec{q}\t%0";
5239         }
5240
5241     default:
5242       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5243       /* ???? We ought to handle there the 32bit case too
5244          - do we need new constraint?  */
5245       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5246          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5247       if (GET_CODE (operands[2]) == CONST_INT
5248           /* Avoid overflows.  */
5249           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5250           && (INTVAL (operands[2]) == 128
5251               || (INTVAL (operands[2]) < 0
5252                   && INTVAL (operands[2]) != -128)))
5253         {
5254           operands[2] = GEN_INT (-INTVAL (operands[2]));
5255           return "sub{q}\t{%2, %0|%0, %2}";
5256         }
5257       return "add{q}\t{%2, %0|%0, %2}";
5258     }
5259 }
5260   [(set (attr "type")
5261      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5262         (const_string "incdec")
5263         (const_string "alu")))
5264    (set_attr "mode" "DI")])
5265
5266 ; For comparisons against 1, -1 and 128, we may generate better code
5267 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5268 ; is matched then.  We can't accept general immediate, because for
5269 ; case of overflows,  the result is messed up.
5270 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5271 ; when negated.
5272 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5273 ; only for comparisons not depending on it.
5274 (define_insn "*adddi_4_rex64"
5275   [(set (reg FLAGS_REG)
5276         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5277                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5278    (clobber (match_scratch:DI 0 "=rm"))]
5279   "TARGET_64BIT
5280    &&  ix86_match_ccmode (insn, CCGCmode)"
5281 {
5282   switch (get_attr_type (insn))
5283     {
5284     case TYPE_INCDEC:
5285       if (operands[2] == constm1_rtx)
5286         return "inc{q}\t%0";
5287       else
5288         {
5289           gcc_assert (operands[2] == const1_rtx);
5290           return "dec{q}\t%0";
5291         }
5292
5293     default:
5294       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5296          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5297       if ((INTVAL (operands[2]) == -128
5298            || (INTVAL (operands[2]) > 0
5299                && INTVAL (operands[2]) != 128))
5300           /* Avoid overflows.  */
5301           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5302         return "sub{q}\t{%2, %0|%0, %2}";
5303       operands[2] = GEN_INT (-INTVAL (operands[2]));
5304       return "add{q}\t{%2, %0|%0, %2}";
5305     }
5306 }
5307   [(set (attr "type")
5308      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5309         (const_string "incdec")
5310         (const_string "alu")))
5311    (set_attr "mode" "DI")])
5312
5313 (define_insn "*adddi_5_rex64"
5314   [(set (reg FLAGS_REG)
5315         (compare
5316           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5317                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5318           (const_int 0)))                       
5319    (clobber (match_scratch:DI 0 "=r"))]
5320   "TARGET_64BIT
5321    && ix86_match_ccmode (insn, CCGOCmode)
5322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5323    /* Current assemblers are broken and do not allow @GOTOFF in
5324       ought but a memory context.  */
5325    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5326 {
5327   switch (get_attr_type (insn))
5328     {
5329     case TYPE_INCDEC:
5330       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5331       if (operands[2] == const1_rtx)
5332         return "inc{q}\t%0";
5333       else
5334         {
5335           gcc_assert (operands[2] == constm1_rtx);
5336           return "dec{q}\t%0";
5337         }
5338
5339     default:
5340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5342          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5343       if (GET_CODE (operands[2]) == CONST_INT
5344           /* Avoid overflows.  */
5345           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5346           && (INTVAL (operands[2]) == 128
5347               || (INTVAL (operands[2]) < 0
5348                   && INTVAL (operands[2]) != -128)))
5349         {
5350           operands[2] = GEN_INT (-INTVAL (operands[2]));
5351           return "sub{q}\t{%2, %0|%0, %2}";
5352         }
5353       return "add{q}\t{%2, %0|%0, %2}";
5354     }
5355 }
5356   [(set (attr "type")
5357      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5358         (const_string "incdec")
5359         (const_string "alu")))
5360    (set_attr "mode" "DI")])
5361
5362
5363 (define_insn "*addsi_1"
5364   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5365         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5366                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5367    (clobber (reg:CC FLAGS_REG))]
5368   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5369 {
5370   switch (get_attr_type (insn))
5371     {
5372     case TYPE_LEA:
5373       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5374       return "lea{l}\t{%a2, %0|%0, %a2}";
5375
5376     case TYPE_INCDEC:
5377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378       if (operands[2] == const1_rtx)
5379         return "inc{l}\t%0";
5380       else
5381         {
5382           gcc_assert (operands[2] == constm1_rtx);
5383           return "dec{l}\t%0";
5384         }
5385
5386     default:
5387       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5388
5389       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5390          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5391       if (GET_CODE (operands[2]) == CONST_INT
5392           && (INTVAL (operands[2]) == 128
5393               || (INTVAL (operands[2]) < 0
5394                   && INTVAL (operands[2]) != -128)))
5395         {
5396           operands[2] = GEN_INT (-INTVAL (operands[2]));
5397           return "sub{l}\t{%2, %0|%0, %2}";
5398         }
5399       return "add{l}\t{%2, %0|%0, %2}";
5400     }
5401 }
5402   [(set (attr "type")
5403      (cond [(eq_attr "alternative" "2")
5404               (const_string "lea")
5405             ; Current assemblers are broken and do not allow @GOTOFF in
5406             ; ought but a memory context.
5407             (match_operand:SI 2 "pic_symbolic_operand" "")
5408               (const_string "lea")
5409             (match_operand:SI 2 "incdec_operand" "")
5410               (const_string "incdec")
5411            ]
5412            (const_string "alu")))
5413    (set_attr "mode" "SI")])
5414
5415 ;; Convert lea to the lea pattern to avoid flags dependency.
5416 (define_split
5417   [(set (match_operand 0 "register_operand" "")
5418         (plus (match_operand 1 "register_operand" "")
5419               (match_operand 2 "nonmemory_operand" "")))
5420    (clobber (reg:CC FLAGS_REG))]
5421   "reload_completed
5422    && true_regnum (operands[0]) != true_regnum (operands[1])"
5423   [(const_int 0)]
5424 {
5425   rtx pat;
5426   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5427      may confuse gen_lowpart.  */
5428   if (GET_MODE (operands[0]) != Pmode)
5429     {
5430       operands[1] = gen_lowpart (Pmode, operands[1]);
5431       operands[2] = gen_lowpart (Pmode, operands[2]);
5432     }
5433   operands[0] = gen_lowpart (SImode, operands[0]);
5434   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5435   if (Pmode != SImode)
5436     pat = gen_rtx_SUBREG (SImode, pat, 0);
5437   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5438   DONE;
5439 })
5440
5441 ;; It may seem that nonimmediate operand is proper one for operand 1.
5442 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5443 ;; we take care in ix86_binary_operator_ok to not allow two memory
5444 ;; operands so proper swapping will be done in reload.  This allow
5445 ;; patterns constructed from addsi_1 to match.
5446 (define_insn "addsi_1_zext"
5447   [(set (match_operand:DI 0 "register_operand" "=r,r")
5448         (zero_extend:DI
5449           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5450                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5451    (clobber (reg:CC FLAGS_REG))]
5452   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5453 {
5454   switch (get_attr_type (insn))
5455     {
5456     case TYPE_LEA:
5457       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5458       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5459
5460     case TYPE_INCDEC:
5461       if (operands[2] == const1_rtx)
5462         return "inc{l}\t%k0";
5463       else
5464         {
5465           gcc_assert (operands[2] == constm1_rtx);
5466           return "dec{l}\t%k0";
5467         }
5468
5469     default:
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if (GET_CODE (operands[2]) == CONST_INT
5473           && (INTVAL (operands[2]) == 128
5474               || (INTVAL (operands[2]) < 0
5475                   && INTVAL (operands[2]) != -128)))
5476         {
5477           operands[2] = GEN_INT (-INTVAL (operands[2]));
5478           return "sub{l}\t{%2, %k0|%k0, %2}";
5479         }
5480       return "add{l}\t{%2, %k0|%k0, %2}";
5481     }
5482 }
5483   [(set (attr "type")
5484      (cond [(eq_attr "alternative" "1")
5485               (const_string "lea")
5486             ; Current assemblers are broken and do not allow @GOTOFF in
5487             ; ought but a memory context.
5488             (match_operand:SI 2 "pic_symbolic_operand" "")
5489               (const_string "lea")
5490             (match_operand:SI 2 "incdec_operand" "")
5491               (const_string "incdec")
5492            ]
5493            (const_string "alu")))
5494    (set_attr "mode" "SI")])
5495
5496 ;; Convert lea to the lea pattern to avoid flags dependency.
5497 (define_split
5498   [(set (match_operand:DI 0 "register_operand" "")
5499         (zero_extend:DI
5500           (plus:SI (match_operand:SI 1 "register_operand" "")
5501                    (match_operand:SI 2 "nonmemory_operand" ""))))
5502    (clobber (reg:CC FLAGS_REG))]
5503   "TARGET_64BIT && reload_completed
5504    && true_regnum (operands[0]) != true_regnum (operands[1])"
5505   [(set (match_dup 0)
5506         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5507 {
5508   operands[1] = gen_lowpart (Pmode, operands[1]);
5509   operands[2] = gen_lowpart (Pmode, operands[2]);
5510 })
5511
5512 (define_insn "*addsi_2"
5513   [(set (reg FLAGS_REG)
5514         (compare
5515           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5516                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5517           (const_int 0)))                       
5518    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5519         (plus:SI (match_dup 1) (match_dup 2)))]
5520   "ix86_match_ccmode (insn, CCGOCmode)
5521    && ix86_binary_operator_ok (PLUS, SImode, operands)
5522    /* Current assemblers are broken and do not allow @GOTOFF in
5523       ought but a memory context.  */
5524    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5525 {
5526   switch (get_attr_type (insn))
5527     {
5528     case TYPE_INCDEC:
5529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530       if (operands[2] == const1_rtx)
5531         return "inc{l}\t%0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{l}\t%0";
5536         }
5537
5538     default:
5539       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5540       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5541          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5542       if (GET_CODE (operands[2]) == CONST_INT
5543           && (INTVAL (operands[2]) == 128
5544               || (INTVAL (operands[2]) < 0
5545                   && INTVAL (operands[2]) != -128)))
5546         {
5547           operands[2] = GEN_INT (-INTVAL (operands[2]));
5548           return "sub{l}\t{%2, %0|%0, %2}";
5549         }
5550       return "add{l}\t{%2, %0|%0, %2}";
5551     }
5552 }
5553   [(set (attr "type")
5554      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5555         (const_string "incdec")
5556         (const_string "alu")))
5557    (set_attr "mode" "SI")])
5558
5559 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5560 (define_insn "*addsi_2_zext"
5561   [(set (reg FLAGS_REG)
5562         (compare
5563           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5564                    (match_operand:SI 2 "general_operand" "rmni"))
5565           (const_int 0)))                       
5566    (set (match_operand:DI 0 "register_operand" "=r")
5567         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5568   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5569    && ix86_binary_operator_ok (PLUS, SImode, operands)
5570    /* Current assemblers are broken and do not allow @GOTOFF in
5571       ought but a memory context.  */
5572    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5573 {
5574   switch (get_attr_type (insn))
5575     {
5576     case TYPE_INCDEC:
5577       if (operands[2] == const1_rtx)
5578         return "inc{l}\t%k0";
5579       else
5580         {
5581           gcc_assert (operands[2] == constm1_rtx);
5582           return "dec{l}\t%k0";
5583         }
5584
5585     default:
5586       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5587          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5588       if (GET_CODE (operands[2]) == CONST_INT
5589           && (INTVAL (operands[2]) == 128
5590               || (INTVAL (operands[2]) < 0
5591                   && INTVAL (operands[2]) != -128)))
5592         {
5593           operands[2] = GEN_INT (-INTVAL (operands[2]));
5594           return "sub{l}\t{%2, %k0|%k0, %2}";
5595         }
5596       return "add{l}\t{%2, %k0|%k0, %2}";
5597     }
5598 }
5599   [(set (attr "type")
5600      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5601         (const_string "incdec")
5602         (const_string "alu")))
5603    (set_attr "mode" "SI")])
5604
5605 (define_insn "*addsi_3"
5606   [(set (reg FLAGS_REG)
5607         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5608                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5609    (clobber (match_scratch:SI 0 "=r"))]
5610   "ix86_match_ccmode (insn, CCZmode)
5611    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5612    /* Current assemblers are broken and do not allow @GOTOFF in
5613       ought but a memory context.  */
5614    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5615 {
5616   switch (get_attr_type (insn))
5617     {
5618     case TYPE_INCDEC:
5619       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5620       if (operands[2] == const1_rtx)
5621         return "inc{l}\t%0";
5622       else
5623         {
5624           gcc_assert (operands[2] == constm1_rtx);
5625           return "dec{l}\t%0";
5626         }
5627
5628     default:
5629       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5630       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5631          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5632       if (GET_CODE (operands[2]) == CONST_INT
5633           && (INTVAL (operands[2]) == 128
5634               || (INTVAL (operands[2]) < 0
5635                   && INTVAL (operands[2]) != -128)))
5636         {
5637           operands[2] = GEN_INT (-INTVAL (operands[2]));
5638           return "sub{l}\t{%2, %0|%0, %2}";
5639         }
5640       return "add{l}\t{%2, %0|%0, %2}";
5641     }
5642 }
5643   [(set (attr "type")
5644      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5645         (const_string "incdec")
5646         (const_string "alu")))
5647    (set_attr "mode" "SI")])
5648
5649 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5650 (define_insn "*addsi_3_zext"
5651   [(set (reg FLAGS_REG)
5652         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5653                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5654    (set (match_operand:DI 0 "register_operand" "=r")
5655         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5656   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5657    && ix86_binary_operator_ok (PLUS, SImode, operands)
5658    /* Current assemblers are broken and do not allow @GOTOFF in
5659       ought but a memory context.  */
5660    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5661 {
5662   switch (get_attr_type (insn))
5663     {
5664     case TYPE_INCDEC:
5665       if (operands[2] == const1_rtx)
5666         return "inc{l}\t%k0";
5667       else
5668         {
5669           gcc_assert (operands[2] == constm1_rtx);
5670           return "dec{l}\t%k0";
5671         }
5672
5673     default:
5674       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5675          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5676       if (GET_CODE (operands[2]) == CONST_INT
5677           && (INTVAL (operands[2]) == 128
5678               || (INTVAL (operands[2]) < 0
5679                   && INTVAL (operands[2]) != -128)))
5680         {
5681           operands[2] = GEN_INT (-INTVAL (operands[2]));
5682           return "sub{l}\t{%2, %k0|%k0, %2}";
5683         }
5684       return "add{l}\t{%2, %k0|%k0, %2}";
5685     }
5686 }
5687   [(set (attr "type")
5688      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5689         (const_string "incdec")
5690         (const_string "alu")))
5691    (set_attr "mode" "SI")])
5692
5693 ; For comparisons against 1, -1 and 128, we may generate better code
5694 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5695 ; is matched then.  We can't accept general immediate, because for
5696 ; case of overflows,  the result is messed up.
5697 ; This pattern also don't hold of 0x80000000, since the value overflows
5698 ; when negated.
5699 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5700 ; only for comparisons not depending on it.
5701 (define_insn "*addsi_4"
5702   [(set (reg FLAGS_REG)
5703         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5704                  (match_operand:SI 2 "const_int_operand" "n")))
5705    (clobber (match_scratch:SI 0 "=rm"))]
5706   "ix86_match_ccmode (insn, CCGCmode)
5707    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5708 {
5709   switch (get_attr_type (insn))
5710     {
5711     case TYPE_INCDEC:
5712       if (operands[2] == constm1_rtx)
5713         return "inc{l}\t%0";
5714       else
5715         {
5716           gcc_assert (operands[2] == const1_rtx);
5717           return "dec{l}\t%0";
5718         }
5719
5720     default:
5721       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5722       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5723          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5724       if ((INTVAL (operands[2]) == -128
5725            || (INTVAL (operands[2]) > 0
5726                && INTVAL (operands[2]) != 128)))
5727         return "sub{l}\t{%2, %0|%0, %2}";
5728       operands[2] = GEN_INT (-INTVAL (operands[2]));
5729       return "add{l}\t{%2, %0|%0, %2}";
5730     }
5731 }
5732   [(set (attr "type")
5733      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5734         (const_string "incdec")
5735         (const_string "alu")))
5736    (set_attr "mode" "SI")])
5737
5738 (define_insn "*addsi_5"
5739   [(set (reg FLAGS_REG)
5740         (compare
5741           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5742                    (match_operand:SI 2 "general_operand" "rmni"))
5743           (const_int 0)))                       
5744    (clobber (match_scratch:SI 0 "=r"))]
5745   "ix86_match_ccmode (insn, CCGOCmode)
5746    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5747    /* Current assemblers are broken and do not allow @GOTOFF in
5748       ought but a memory context.  */
5749    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5750 {
5751   switch (get_attr_type (insn))
5752     {
5753     case TYPE_INCDEC:
5754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755       if (operands[2] == const1_rtx)
5756         return "inc{l}\t%0";
5757       else
5758         {
5759           gcc_assert (operands[2] == constm1_rtx);
5760           return "dec{l}\t%0";
5761         }
5762
5763     default:
5764       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5765       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5766          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5767       if (GET_CODE (operands[2]) == CONST_INT
5768           && (INTVAL (operands[2]) == 128
5769               || (INTVAL (operands[2]) < 0
5770                   && INTVAL (operands[2]) != -128)))
5771         {
5772           operands[2] = GEN_INT (-INTVAL (operands[2]));
5773           return "sub{l}\t{%2, %0|%0, %2}";
5774         }
5775       return "add{l}\t{%2, %0|%0, %2}";
5776     }
5777 }
5778   [(set (attr "type")
5779      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5780         (const_string "incdec")
5781         (const_string "alu")))
5782    (set_attr "mode" "SI")])
5783
5784 (define_expand "addhi3"
5785   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5786                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5787                             (match_operand:HI 2 "general_operand" "")))
5788               (clobber (reg:CC FLAGS_REG))])]
5789   "TARGET_HIMODE_MATH"
5790   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5791
5792 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5793 ;; type optimizations enabled by define-splits.  This is not important
5794 ;; for PII, and in fact harmful because of partial register stalls.
5795
5796 (define_insn "*addhi_1_lea"
5797   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5798         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5799                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5800    (clobber (reg:CC FLAGS_REG))]
5801   "!TARGET_PARTIAL_REG_STALL
5802    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5803 {
5804   switch (get_attr_type (insn))
5805     {
5806     case TYPE_LEA:
5807       return "#";
5808     case TYPE_INCDEC:
5809       if (operands[2] == const1_rtx)
5810         return "inc{w}\t%0";
5811       else
5812         {
5813           gcc_assert (operands[2] == constm1_rtx);
5814           return "dec{w}\t%0";
5815         }
5816
5817     default:
5818       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5819          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5820       if (GET_CODE (operands[2]) == CONST_INT
5821           && (INTVAL (operands[2]) == 128
5822               || (INTVAL (operands[2]) < 0
5823                   && INTVAL (operands[2]) != -128)))
5824         {
5825           operands[2] = GEN_INT (-INTVAL (operands[2]));
5826           return "sub{w}\t{%2, %0|%0, %2}";
5827         }
5828       return "add{w}\t{%2, %0|%0, %2}";
5829     }
5830 }
5831   [(set (attr "type")
5832      (if_then_else (eq_attr "alternative" "2")
5833         (const_string "lea")
5834         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5835            (const_string "incdec")
5836            (const_string "alu"))))
5837    (set_attr "mode" "HI,HI,SI")])
5838
5839 (define_insn "*addhi_1"
5840   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5841         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5842                  (match_operand:HI 2 "general_operand" "ri,rm")))
5843    (clobber (reg:CC FLAGS_REG))]
5844   "TARGET_PARTIAL_REG_STALL
5845    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5846 {
5847   switch (get_attr_type (insn))
5848     {
5849     case TYPE_INCDEC:
5850       if (operands[2] == const1_rtx)
5851         return "inc{w}\t%0";
5852       else
5853         {
5854           gcc_assert (operands[2] == constm1_rtx);
5855           return "dec{w}\t%0";
5856         }
5857
5858     default:
5859       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5860          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5861       if (GET_CODE (operands[2]) == CONST_INT
5862           && (INTVAL (operands[2]) == 128
5863               || (INTVAL (operands[2]) < 0
5864                   && INTVAL (operands[2]) != -128)))
5865         {
5866           operands[2] = GEN_INT (-INTVAL (operands[2]));
5867           return "sub{w}\t{%2, %0|%0, %2}";
5868         }
5869       return "add{w}\t{%2, %0|%0, %2}";
5870     }
5871 }
5872   [(set (attr "type")
5873      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5874         (const_string "incdec")
5875         (const_string "alu")))
5876    (set_attr "mode" "HI")])
5877
5878 (define_insn "*addhi_2"
5879   [(set (reg FLAGS_REG)
5880         (compare
5881           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5882                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5883           (const_int 0)))                       
5884    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5885         (plus:HI (match_dup 1) (match_dup 2)))]
5886   "ix86_match_ccmode (insn, CCGOCmode)
5887    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5888 {
5889   switch (get_attr_type (insn))
5890     {
5891     case TYPE_INCDEC:
5892       if (operands[2] == const1_rtx)
5893         return "inc{w}\t%0";
5894       else
5895         {
5896           gcc_assert (operands[2] == constm1_rtx);
5897           return "dec{w}\t%0";
5898         }
5899
5900     default:
5901       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5902          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5903       if (GET_CODE (operands[2]) == CONST_INT
5904           && (INTVAL (operands[2]) == 128
5905               || (INTVAL (operands[2]) < 0
5906                   && INTVAL (operands[2]) != -128)))
5907         {
5908           operands[2] = GEN_INT (-INTVAL (operands[2]));
5909           return "sub{w}\t{%2, %0|%0, %2}";
5910         }
5911       return "add{w}\t{%2, %0|%0, %2}";
5912     }
5913 }
5914   [(set (attr "type")
5915      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5916         (const_string "incdec")
5917         (const_string "alu")))
5918    (set_attr "mode" "HI")])
5919
5920 (define_insn "*addhi_3"
5921   [(set (reg FLAGS_REG)
5922         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5923                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5924    (clobber (match_scratch:HI 0 "=r"))]
5925   "ix86_match_ccmode (insn, CCZmode)
5926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5927 {
5928   switch (get_attr_type (insn))
5929     {
5930     case TYPE_INCDEC:
5931       if (operands[2] == const1_rtx)
5932         return "inc{w}\t%0";
5933       else
5934         {
5935           gcc_assert (operands[2] == constm1_rtx);
5936           return "dec{w}\t%0";
5937         }
5938
5939     default:
5940       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5941          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5942       if (GET_CODE (operands[2]) == CONST_INT
5943           && (INTVAL (operands[2]) == 128
5944               || (INTVAL (operands[2]) < 0
5945                   && INTVAL (operands[2]) != -128)))
5946         {
5947           operands[2] = GEN_INT (-INTVAL (operands[2]));
5948           return "sub{w}\t{%2, %0|%0, %2}";
5949         }
5950       return "add{w}\t{%2, %0|%0, %2}";
5951     }
5952 }
5953   [(set (attr "type")
5954      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5955         (const_string "incdec")
5956         (const_string "alu")))
5957    (set_attr "mode" "HI")])
5958
5959 ; See comments above addsi_4 for details.
5960 (define_insn "*addhi_4"
5961   [(set (reg FLAGS_REG)
5962         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5963                  (match_operand:HI 2 "const_int_operand" "n")))
5964    (clobber (match_scratch:HI 0 "=rm"))]
5965   "ix86_match_ccmode (insn, CCGCmode)
5966    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5967 {
5968   switch (get_attr_type (insn))
5969     {
5970     case TYPE_INCDEC:
5971       if (operands[2] == constm1_rtx)
5972         return "inc{w}\t%0";
5973       else
5974         {
5975           gcc_assert (operands[2] == const1_rtx);
5976           return "dec{w}\t%0";
5977         }
5978
5979     default:
5980       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5981       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5982          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5983       if ((INTVAL (operands[2]) == -128
5984            || (INTVAL (operands[2]) > 0
5985                && INTVAL (operands[2]) != 128)))
5986         return "sub{w}\t{%2, %0|%0, %2}";
5987       operands[2] = GEN_INT (-INTVAL (operands[2]));
5988       return "add{w}\t{%2, %0|%0, %2}";
5989     }
5990 }
5991   [(set (attr "type")
5992      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5993         (const_string "incdec")
5994         (const_string "alu")))
5995    (set_attr "mode" "SI")])
5996
5997
5998 (define_insn "*addhi_5"
5999   [(set (reg FLAGS_REG)
6000         (compare
6001           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6002                    (match_operand:HI 2 "general_operand" "rmni"))
6003           (const_int 0)))                       
6004    (clobber (match_scratch:HI 0 "=r"))]
6005   "ix86_match_ccmode (insn, CCGOCmode)
6006    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6007 {
6008   switch (get_attr_type (insn))
6009     {
6010     case TYPE_INCDEC:
6011       if (operands[2] == const1_rtx)
6012         return "inc{w}\t%0";
6013       else
6014         {
6015           gcc_assert (operands[2] == constm1_rtx);
6016           return "dec{w}\t%0";
6017         }
6018
6019     default:
6020       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6021          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6022       if (GET_CODE (operands[2]) == CONST_INT
6023           && (INTVAL (operands[2]) == 128
6024               || (INTVAL (operands[2]) < 0
6025                   && INTVAL (operands[2]) != -128)))
6026         {
6027           operands[2] = GEN_INT (-INTVAL (operands[2]));
6028           return "sub{w}\t{%2, %0|%0, %2}";
6029         }
6030       return "add{w}\t{%2, %0|%0, %2}";
6031     }
6032 }
6033   [(set (attr "type")
6034      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6035         (const_string "incdec")
6036         (const_string "alu")))
6037    (set_attr "mode" "HI")])
6038
6039 (define_expand "addqi3"
6040   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6041                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6042                             (match_operand:QI 2 "general_operand" "")))
6043               (clobber (reg:CC FLAGS_REG))])]
6044   "TARGET_QIMODE_MATH"
6045   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6046
6047 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6048 (define_insn "*addqi_1_lea"
6049   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6050         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6051                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6052    (clobber (reg:CC FLAGS_REG))]
6053   "!TARGET_PARTIAL_REG_STALL
6054    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6055 {
6056   int widen = (which_alternative == 2);
6057   switch (get_attr_type (insn))
6058     {
6059     case TYPE_LEA:
6060       return "#";
6061     case TYPE_INCDEC:
6062       if (operands[2] == const1_rtx)
6063         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6064       else
6065         {
6066           gcc_assert (operands[2] == constm1_rtx);
6067           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6068         }
6069
6070     default:
6071       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6073       if (GET_CODE (operands[2]) == CONST_INT
6074           && (INTVAL (operands[2]) == 128
6075               || (INTVAL (operands[2]) < 0
6076                   && INTVAL (operands[2]) != -128)))
6077         {
6078           operands[2] = GEN_INT (-INTVAL (operands[2]));
6079           if (widen)
6080             return "sub{l}\t{%2, %k0|%k0, %2}";
6081           else
6082             return "sub{b}\t{%2, %0|%0, %2}";
6083         }
6084       if (widen)
6085         return "add{l}\t{%k2, %k0|%k0, %k2}";
6086       else
6087         return "add{b}\t{%2, %0|%0, %2}";
6088     }
6089 }
6090   [(set (attr "type")
6091      (if_then_else (eq_attr "alternative" "3")
6092         (const_string "lea")
6093         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6094            (const_string "incdec")
6095            (const_string "alu"))))
6096    (set_attr "mode" "QI,QI,SI,SI")])
6097
6098 (define_insn "*addqi_1"
6099   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6100         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6101                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6102    (clobber (reg:CC FLAGS_REG))]
6103   "TARGET_PARTIAL_REG_STALL
6104    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6105 {
6106   int widen = (which_alternative == 2);
6107   switch (get_attr_type (insn))
6108     {
6109     case TYPE_INCDEC:
6110       if (operands[2] == const1_rtx)
6111         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6112       else
6113         {
6114           gcc_assert (operands[2] == constm1_rtx);
6115           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6116         }
6117
6118     default:
6119       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6120          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6121       if (GET_CODE (operands[2]) == CONST_INT
6122           && (INTVAL (operands[2]) == 128
6123               || (INTVAL (operands[2]) < 0
6124                   && INTVAL (operands[2]) != -128)))
6125         {
6126           operands[2] = GEN_INT (-INTVAL (operands[2]));
6127           if (widen)
6128             return "sub{l}\t{%2, %k0|%k0, %2}";
6129           else
6130             return "sub{b}\t{%2, %0|%0, %2}";
6131         }
6132       if (widen)
6133         return "add{l}\t{%k2, %k0|%k0, %k2}";
6134       else
6135         return "add{b}\t{%2, %0|%0, %2}";
6136     }
6137 }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set_attr "mode" "QI,QI,SI")])
6143
6144 (define_insn "*addqi_1_slp"
6145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6146         (plus:QI (match_dup 0)
6147                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6148    (clobber (reg:CC FLAGS_REG))]
6149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6151 {
6152   switch (get_attr_type (insn))
6153     {
6154     case TYPE_INCDEC:
6155       if (operands[1] == const1_rtx)
6156         return "inc{b}\t%0";
6157       else
6158         {
6159           gcc_assert (operands[1] == constm1_rtx);
6160           return "dec{b}\t%0";
6161         }
6162
6163     default:
6164       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6165       if (GET_CODE (operands[1]) == CONST_INT
6166           && INTVAL (operands[1]) < 0)
6167         {
6168           operands[1] = GEN_INT (-INTVAL (operands[1]));
6169           return "sub{b}\t{%1, %0|%0, %1}";
6170         }
6171       return "add{b}\t{%1, %0|%0, %1}";
6172     }
6173 }
6174   [(set (attr "type")
6175      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6176         (const_string "incdec")
6177         (const_string "alu1")))
6178    (set (attr "memory")
6179      (if_then_else (match_operand 1 "memory_operand" "")
6180         (const_string "load")
6181         (const_string "none")))
6182    (set_attr "mode" "QI")])
6183
6184 (define_insn "*addqi_2"
6185   [(set (reg FLAGS_REG)
6186         (compare
6187           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6188                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6189           (const_int 0)))
6190    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6191         (plus:QI (match_dup 1) (match_dup 2)))]
6192   "ix86_match_ccmode (insn, CCGOCmode)
6193    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6194 {
6195   switch (get_attr_type (insn))
6196     {
6197     case TYPE_INCDEC:
6198       if (operands[2] == const1_rtx)
6199         return "inc{b}\t%0";
6200       else
6201         {
6202           gcc_assert (operands[2] == constm1_rtx
6203                       || (GET_CODE (operands[2]) == CONST_INT
6204                           && INTVAL (operands[2]) == 255));
6205           return "dec{b}\t%0";
6206         }
6207
6208     default:
6209       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6210       if (GET_CODE (operands[2]) == CONST_INT
6211           && INTVAL (operands[2]) < 0)
6212         {
6213           operands[2] = GEN_INT (-INTVAL (operands[2]));
6214           return "sub{b}\t{%2, %0|%0, %2}";
6215         }
6216       return "add{b}\t{%2, %0|%0, %2}";
6217     }
6218 }
6219   [(set (attr "type")
6220      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6221         (const_string "incdec")
6222         (const_string "alu")))
6223    (set_attr "mode" "QI")])
6224
6225 (define_insn "*addqi_3"
6226   [(set (reg FLAGS_REG)
6227         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6228                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6229    (clobber (match_scratch:QI 0 "=q"))]
6230   "ix86_match_ccmode (insn, CCZmode)
6231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6232 {
6233   switch (get_attr_type (insn))
6234     {
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return "inc{b}\t%0";
6238       else
6239         {
6240           gcc_assert (operands[2] == constm1_rtx
6241                       || (GET_CODE (operands[2]) == CONST_INT
6242                           && INTVAL (operands[2]) == 255));
6243           return "dec{b}\t%0";
6244         }
6245
6246     default:
6247       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6248       if (GET_CODE (operands[2]) == CONST_INT
6249           && INTVAL (operands[2]) < 0)
6250         {
6251           operands[2] = GEN_INT (-INTVAL (operands[2]));
6252           return "sub{b}\t{%2, %0|%0, %2}";
6253         }
6254       return "add{b}\t{%2, %0|%0, %2}";
6255     }
6256 }
6257   [(set (attr "type")
6258      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6259         (const_string "incdec")
6260         (const_string "alu")))
6261    (set_attr "mode" "QI")])
6262
6263 ; See comments above addsi_4 for details.
6264 (define_insn "*addqi_4"
6265   [(set (reg FLAGS_REG)
6266         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6267                  (match_operand:QI 2 "const_int_operand" "n")))
6268    (clobber (match_scratch:QI 0 "=qm"))]
6269   "ix86_match_ccmode (insn, CCGCmode)
6270    && (INTVAL (operands[2]) & 0xff) != 0x80"
6271 {
6272   switch (get_attr_type (insn))
6273     {
6274     case TYPE_INCDEC:
6275       if (operands[2] == constm1_rtx
6276           || (GET_CODE (operands[2]) == CONST_INT
6277               && INTVAL (operands[2]) == 255))
6278         return "inc{b}\t%0";
6279       else
6280         {
6281           gcc_assert (operands[2] == const1_rtx);
6282           return "dec{b}\t%0";
6283         }
6284
6285     default:
6286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6287       if (INTVAL (operands[2]) < 0)
6288         {
6289           operands[2] = GEN_INT (-INTVAL (operands[2]));
6290           return "add{b}\t{%2, %0|%0, %2}";
6291         }
6292       return "sub{b}\t{%2, %0|%0, %2}";
6293     }
6294 }
6295   [(set (attr "type")
6296      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6297         (const_string "incdec")
6298         (const_string "alu")))
6299    (set_attr "mode" "QI")])
6300
6301
6302 (define_insn "*addqi_5"
6303   [(set (reg FLAGS_REG)
6304         (compare
6305           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6306                    (match_operand:QI 2 "general_operand" "qmni"))
6307           (const_int 0)))
6308    (clobber (match_scratch:QI 0 "=q"))]
6309   "ix86_match_ccmode (insn, CCGOCmode)
6310    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6311 {
6312   switch (get_attr_type (insn))
6313     {
6314     case TYPE_INCDEC:
6315       if (operands[2] == const1_rtx)
6316         return "inc{b}\t%0";
6317       else
6318         {
6319           gcc_assert (operands[2] == constm1_rtx
6320                       || (GET_CODE (operands[2]) == CONST_INT
6321                           && INTVAL (operands[2]) == 255));
6322           return "dec{b}\t%0";
6323         }
6324
6325     default:
6326       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6327       if (GET_CODE (operands[2]) == CONST_INT
6328           && INTVAL (operands[2]) < 0)
6329         {
6330           operands[2] = GEN_INT (-INTVAL (operands[2]));
6331           return "sub{b}\t{%2, %0|%0, %2}";
6332         }
6333       return "add{b}\t{%2, %0|%0, %2}";
6334     }
6335 }
6336   [(set (attr "type")
6337      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6338         (const_string "incdec")
6339         (const_string "alu")))
6340    (set_attr "mode" "QI")])
6341
6342
6343 (define_insn "addqi_ext_1"
6344   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6345                          (const_int 8)
6346                          (const_int 8))
6347         (plus:SI
6348           (zero_extract:SI
6349             (match_operand 1 "ext_register_operand" "0")
6350             (const_int 8)
6351             (const_int 8))
6352           (match_operand:QI 2 "general_operand" "Qmn")))
6353    (clobber (reg:CC FLAGS_REG))]
6354   "!TARGET_64BIT"
6355 {
6356   switch (get_attr_type (insn))
6357     {
6358     case TYPE_INCDEC:
6359       if (operands[2] == const1_rtx)
6360         return "inc{b}\t%h0";
6361       else
6362         {
6363           gcc_assert (operands[2] == constm1_rtx
6364                       || (GET_CODE (operands[2]) == CONST_INT
6365                           && INTVAL (operands[2]) == 255));
6366           return "dec{b}\t%h0";
6367         }
6368
6369     default:
6370       return "add{b}\t{%2, %h0|%h0, %2}";
6371     }
6372 }
6373   [(set (attr "type")
6374      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6375         (const_string "incdec")
6376         (const_string "alu")))
6377    (set_attr "mode" "QI")])
6378
6379 (define_insn "*addqi_ext_1_rex64"
6380   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6381                          (const_int 8)
6382                          (const_int 8))
6383         (plus:SI
6384           (zero_extract:SI
6385             (match_operand 1 "ext_register_operand" "0")
6386             (const_int 8)
6387             (const_int 8))
6388           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6389    (clobber (reg:CC FLAGS_REG))]
6390   "TARGET_64BIT"
6391 {
6392   switch (get_attr_type (insn))
6393     {
6394     case TYPE_INCDEC:
6395       if (operands[2] == const1_rtx)
6396         return "inc{b}\t%h0";
6397       else
6398         {
6399           gcc_assert (operands[2] == constm1_rtx
6400                       || (GET_CODE (operands[2]) == CONST_INT
6401                           && INTVAL (operands[2]) == 255));
6402           return "dec{b}\t%h0";
6403         }
6404
6405     default:
6406       return "add{b}\t{%2, %h0|%h0, %2}";
6407     }
6408 }
6409   [(set (attr "type")
6410      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6411         (const_string "incdec")
6412         (const_string "alu")))
6413    (set_attr "mode" "QI")])
6414
6415 (define_insn "*addqi_ext_2"
6416   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6417                          (const_int 8)
6418                          (const_int 8))
6419         (plus:SI
6420           (zero_extract:SI
6421             (match_operand 1 "ext_register_operand" "%0")
6422             (const_int 8)
6423             (const_int 8))
6424           (zero_extract:SI
6425             (match_operand 2 "ext_register_operand" "Q")
6426             (const_int 8)
6427             (const_int 8))))
6428    (clobber (reg:CC FLAGS_REG))]
6429   ""
6430   "add{b}\t{%h2, %h0|%h0, %h2}"
6431   [(set_attr "type" "alu")
6432    (set_attr "mode" "QI")])
6433
6434 ;; The patterns that match these are at the end of this file.
6435
6436 (define_expand "addxf3"
6437   [(set (match_operand:XF 0 "register_operand" "")
6438         (plus:XF (match_operand:XF 1 "register_operand" "")
6439                  (match_operand:XF 2 "register_operand" "")))]
6440   "TARGET_80387"
6441   "")
6442
6443 (define_expand "adddf3"
6444   [(set (match_operand:DF 0 "register_operand" "")
6445         (plus:DF (match_operand:DF 1 "register_operand" "")
6446                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6447   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6448   "")
6449
6450 (define_expand "addsf3"
6451   [(set (match_operand:SF 0 "register_operand" "")
6452         (plus:SF (match_operand:SF 1 "register_operand" "")
6453                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6454   "TARGET_80387 || TARGET_SSE_MATH"
6455   "")
6456 \f
6457 ;; Subtract instructions
6458
6459 ;; %%% splits for subditi3
6460
6461 (define_expand "subti3"
6462   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6463                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6464                              (match_operand:TI 2 "x86_64_general_operand" "")))
6465               (clobber (reg:CC FLAGS_REG))])]
6466   "TARGET_64BIT"
6467   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6468
6469 (define_insn "*subti3_1"
6470   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6471         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6472                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6473    (clobber (reg:CC FLAGS_REG))]
6474   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6475   "#")
6476
6477 (define_split
6478   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6479         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6480                   (match_operand:TI 2 "general_operand" "")))
6481    (clobber (reg:CC FLAGS_REG))]
6482   "TARGET_64BIT && reload_completed"
6483   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6484               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6485    (parallel [(set (match_dup 3)
6486                    (minus:DI (match_dup 4)
6487                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6488                                       (match_dup 5))))
6489               (clobber (reg:CC FLAGS_REG))])]
6490   "split_ti (operands+0, 1, operands+0, operands+3);
6491    split_ti (operands+1, 1, operands+1, operands+4);
6492    split_ti (operands+2, 1, operands+2, operands+5);")
6493
6494 ;; %%% splits for subsidi3
6495
6496 (define_expand "subdi3"
6497   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6498                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6499                              (match_operand:DI 2 "x86_64_general_operand" "")))
6500               (clobber (reg:CC FLAGS_REG))])]
6501   ""
6502   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6503
6504 (define_insn "*subdi3_1"
6505   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6506         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6507                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6508    (clobber (reg:CC FLAGS_REG))]
6509   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6510   "#")
6511
6512 (define_split
6513   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6514         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6515                   (match_operand:DI 2 "general_operand" "")))
6516    (clobber (reg:CC FLAGS_REG))]
6517   "!TARGET_64BIT && reload_completed"
6518   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6519               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6520    (parallel [(set (match_dup 3)
6521                    (minus:SI (match_dup 4)
6522                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6523                                       (match_dup 5))))
6524               (clobber (reg:CC FLAGS_REG))])]
6525   "split_di (operands+0, 1, operands+0, operands+3);
6526    split_di (operands+1, 1, operands+1, operands+4);
6527    split_di (operands+2, 1, operands+2, operands+5);")
6528
6529 (define_insn "subdi3_carry_rex64"
6530   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6531           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6532             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6533                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6534    (clobber (reg:CC FLAGS_REG))]
6535   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6536   "sbb{q}\t{%2, %0|%0, %2}"
6537   [(set_attr "type" "alu")
6538    (set_attr "pent_pair" "pu")
6539    (set_attr "mode" "DI")])
6540
6541 (define_insn "*subdi_1_rex64"
6542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6544                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6545    (clobber (reg:CC FLAGS_REG))]
6546   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6547   "sub{q}\t{%2, %0|%0, %2}"
6548   [(set_attr "type" "alu")
6549    (set_attr "mode" "DI")])
6550
6551 (define_insn "*subdi_2_rex64"
6552   [(set (reg FLAGS_REG)
6553         (compare
6554           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6555                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6556           (const_int 0)))
6557    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6558         (minus:DI (match_dup 1) (match_dup 2)))]
6559   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6560    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561   "sub{q}\t{%2, %0|%0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "DI")])
6564
6565 (define_insn "*subdi_3_rex63"
6566   [(set (reg FLAGS_REG)
6567         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6568                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6569    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6570         (minus:DI (match_dup 1) (match_dup 2)))]
6571   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6572    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573   "sub{q}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "DI")])
6576
6577 (define_insn "subqi3_carry"
6578   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6579           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6580             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6581                (match_operand:QI 2 "general_operand" "qi,qm"))))
6582    (clobber (reg:CC FLAGS_REG))]
6583   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6584   "sbb{b}\t{%2, %0|%0, %2}"
6585   [(set_attr "type" "alu")
6586    (set_attr "pent_pair" "pu")
6587    (set_attr "mode" "QI")])
6588
6589 (define_insn "subhi3_carry"
6590   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6591           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6592             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6593                (match_operand:HI 2 "general_operand" "ri,rm"))))
6594    (clobber (reg:CC FLAGS_REG))]
6595   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6596   "sbb{w}\t{%2, %0|%0, %2}"
6597   [(set_attr "type" "alu")
6598    (set_attr "pent_pair" "pu")
6599    (set_attr "mode" "HI")])
6600
6601 (define_insn "subsi3_carry"
6602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6603           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6604             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6605                (match_operand:SI 2 "general_operand" "ri,rm"))))
6606    (clobber (reg:CC FLAGS_REG))]
6607   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6608   "sbb{l}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "pent_pair" "pu")
6611    (set_attr "mode" "SI")])
6612
6613 (define_insn "subsi3_carry_zext"
6614   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6615           (zero_extend:DI
6616             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6617               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6618                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sbb{l}\t{%2, %k0|%k0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "pent_pair" "pu")
6624    (set_attr "mode" "SI")])
6625
6626 (define_expand "subsi3"
6627   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6628                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6629                              (match_operand:SI 2 "general_operand" "")))
6630               (clobber (reg:CC FLAGS_REG))])]
6631   ""
6632   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6633
6634 (define_insn "*subsi_1"
6635   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6636         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6637                   (match_operand:SI 2 "general_operand" "ri,rm")))
6638    (clobber (reg:CC FLAGS_REG))]
6639   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6640   "sub{l}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "SI")])
6643
6644 (define_insn "*subsi_1_zext"
6645   [(set (match_operand:DI 0 "register_operand" "=r")
6646         (zero_extend:DI
6647           (minus:SI (match_operand:SI 1 "register_operand" "0")
6648                     (match_operand:SI 2 "general_operand" "rim"))))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6651   "sub{l}\t{%2, %k0|%k0, %2}"
6652   [(set_attr "type" "alu")
6653    (set_attr "mode" "SI")])
6654
6655 (define_insn "*subsi_2"
6656   [(set (reg FLAGS_REG)
6657         (compare
6658           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6659                     (match_operand:SI 2 "general_operand" "ri,rm"))
6660           (const_int 0)))
6661    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6662         (minus:SI (match_dup 1) (match_dup 2)))]
6663   "ix86_match_ccmode (insn, CCGOCmode)
6664    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sub{l}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "SI")])
6668
6669 (define_insn "*subsi_2_zext"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (minus:SI (match_operand:SI 1 "register_operand" "0")
6673                     (match_operand:SI 2 "general_operand" "rim"))
6674           (const_int 0)))
6675    (set (match_operand:DI 0 "register_operand" "=r")
6676         (zero_extend:DI
6677           (minus:SI (match_dup 1)
6678                     (match_dup 2))))]
6679   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6680    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681   "sub{l}\t{%2, %k0|%k0, %2}"
6682   [(set_attr "type" "alu")
6683    (set_attr "mode" "SI")])
6684
6685 (define_insn "*subsi_3"
6686   [(set (reg FLAGS_REG)
6687         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688                  (match_operand:SI 2 "general_operand" "ri,rm")))
6689    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690         (minus:SI (match_dup 1) (match_dup 2)))]
6691   "ix86_match_ccmode (insn, CCmode)
6692    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693   "sub{l}\t{%2, %0|%0, %2}"
6694   [(set_attr "type" "alu")
6695    (set_attr "mode" "SI")])
6696
6697 (define_insn "*subsi_3_zext"
6698   [(set (reg FLAGS_REG)
6699         (compare (match_operand:SI 1 "register_operand" "0")
6700                  (match_operand:SI 2 "general_operand" "rim")))
6701    (set (match_operand:DI 0 "register_operand" "=r")
6702         (zero_extend:DI
6703           (minus:SI (match_dup 1)
6704                     (match_dup 2))))]
6705   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sub{l}\t{%2, %1|%1, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "DI")])
6710
6711 (define_expand "subhi3"
6712   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6713                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6714                              (match_operand:HI 2 "general_operand" "")))
6715               (clobber (reg:CC FLAGS_REG))])]
6716   "TARGET_HIMODE_MATH"
6717   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6718
6719 (define_insn "*subhi_1"
6720   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6722                   (match_operand:HI 2 "general_operand" "ri,rm")))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6725   "sub{w}\t{%2, %0|%0, %2}"
6726   [(set_attr "type" "alu")
6727    (set_attr "mode" "HI")])
6728
6729 (define_insn "*subhi_2"
6730   [(set (reg FLAGS_REG)
6731         (compare
6732           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6733                     (match_operand:HI 2 "general_operand" "ri,rm"))
6734           (const_int 0)))
6735    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6736         (minus:HI (match_dup 1) (match_dup 2)))]
6737   "ix86_match_ccmode (insn, CCGOCmode)
6738    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6739   "sub{w}\t{%2, %0|%0, %2}"
6740   [(set_attr "type" "alu")
6741    (set_attr "mode" "HI")])
6742
6743 (define_insn "*subhi_3"
6744   [(set (reg FLAGS_REG)
6745         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6746                  (match_operand:HI 2 "general_operand" "ri,rm")))
6747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:HI (match_dup 1) (match_dup 2)))]
6749   "ix86_match_ccmode (insn, CCmode)
6750    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6751   "sub{w}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "HI")])
6754
6755 (define_expand "subqi3"
6756   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6757                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6758                              (match_operand:QI 2 "general_operand" "")))
6759               (clobber (reg:CC FLAGS_REG))])]
6760   "TARGET_QIMODE_MATH"
6761   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6762
6763 (define_insn "*subqi_1"
6764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6765         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6766                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6767    (clobber (reg:CC FLAGS_REG))]
6768   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6769   "sub{b}\t{%2, %0|%0, %2}"
6770   [(set_attr "type" "alu")
6771    (set_attr "mode" "QI")])
6772
6773 (define_insn "*subqi_1_slp"
6774   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6775         (minus:QI (match_dup 0)
6776                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6780   "sub{b}\t{%1, %0|%0, %1}"
6781   [(set_attr "type" "alu1")
6782    (set_attr "mode" "QI")])
6783
6784 (define_insn "*subqi_2"
6785   [(set (reg FLAGS_REG)
6786         (compare
6787           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6788                     (match_operand:QI 2 "general_operand" "qi,qm"))
6789           (const_int 0)))
6790    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6791         (minus:HI (match_dup 1) (match_dup 2)))]
6792   "ix86_match_ccmode (insn, CCGOCmode)
6793    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6794   "sub{b}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "mode" "QI")])
6797
6798 (define_insn "*subqi_3"
6799   [(set (reg FLAGS_REG)
6800         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801                  (match_operand:QI 2 "general_operand" "qi,qm")))
6802    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6803         (minus:HI (match_dup 1) (match_dup 2)))]
6804   "ix86_match_ccmode (insn, CCmode)
6805    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6806   "sub{b}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "QI")])
6809
6810 ;; The patterns that match these are at the end of this file.
6811
6812 (define_expand "subxf3"
6813   [(set (match_operand:XF 0 "register_operand" "")
6814         (minus:XF (match_operand:XF 1 "register_operand" "")
6815                   (match_operand:XF 2 "register_operand" "")))]
6816   "TARGET_80387"
6817   "")
6818
6819 (define_expand "subdf3"
6820   [(set (match_operand:DF 0 "register_operand" "")
6821         (minus:DF (match_operand:DF 1 "register_operand" "")
6822                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6823   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6824   "")
6825
6826 (define_expand "subsf3"
6827   [(set (match_operand:SF 0 "register_operand" "")
6828         (minus:SF (match_operand:SF 1 "register_operand" "")
6829                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6830   "TARGET_80387 || TARGET_SSE_MATH"
6831   "")
6832 \f
6833 ;; Multiply instructions
6834
6835 (define_expand "muldi3"
6836   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6837                    (mult:DI (match_operand:DI 1 "register_operand" "")
6838                             (match_operand:DI 2 "x86_64_general_operand" "")))
6839               (clobber (reg:CC FLAGS_REG))])]
6840   "TARGET_64BIT"
6841   "")
6842
6843 (define_insn "*muldi3_1_rex64"
6844   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6845         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6846                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6847    (clobber (reg:CC FLAGS_REG))]
6848   "TARGET_64BIT
6849    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6850   "@
6851    imul{q}\t{%2, %1, %0|%0, %1, %2}
6852    imul{q}\t{%2, %1, %0|%0, %1, %2}
6853    imul{q}\t{%2, %0|%0, %2}"
6854   [(set_attr "type" "imul")
6855    (set_attr "prefix_0f" "0,0,1")
6856    (set (attr "athlon_decode")
6857         (cond [(eq_attr "cpu" "athlon")
6858                   (const_string "vector")
6859                (eq_attr "alternative" "1")
6860                   (const_string "vector")
6861                (and (eq_attr "alternative" "2")
6862                     (match_operand 1 "memory_operand" ""))
6863                   (const_string "vector")]
6864               (const_string "direct")))
6865    (set_attr "mode" "DI")])
6866
6867 (define_expand "mulsi3"
6868   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6869                    (mult:SI (match_operand:SI 1 "register_operand" "")
6870                             (match_operand:SI 2 "general_operand" "")))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   ""
6873   "")
6874
6875 (define_insn "*mulsi3_1"
6876   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6877         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6878                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6881   "@
6882    imul{l}\t{%2, %1, %0|%0, %1, %2}
6883    imul{l}\t{%2, %1, %0|%0, %1, %2}
6884    imul{l}\t{%2, %0|%0, %2}"
6885   [(set_attr "type" "imul")
6886    (set_attr "prefix_0f" "0,0,1")
6887    (set (attr "athlon_decode")
6888         (cond [(eq_attr "cpu" "athlon")
6889                   (const_string "vector")
6890                (eq_attr "alternative" "1")
6891                   (const_string "vector")
6892                (and (eq_attr "alternative" "2")
6893                     (match_operand 1 "memory_operand" ""))
6894                   (const_string "vector")]
6895               (const_string "direct")))
6896    (set_attr "mode" "SI")])
6897
6898 (define_insn "*mulsi3_1_zext"
6899   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6900         (zero_extend:DI
6901           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6902                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6903    (clobber (reg:CC FLAGS_REG))]
6904   "TARGET_64BIT
6905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6906   "@
6907    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6908    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6909    imul{l}\t{%2, %k0|%k0, %2}"
6910   [(set_attr "type" "imul")
6911    (set_attr "prefix_0f" "0,0,1")
6912    (set (attr "athlon_decode")
6913         (cond [(eq_attr "cpu" "athlon")
6914                   (const_string "vector")
6915                (eq_attr "alternative" "1")
6916                   (const_string "vector")
6917                (and (eq_attr "alternative" "2")
6918                     (match_operand 1 "memory_operand" ""))
6919                   (const_string "vector")]
6920               (const_string "direct")))
6921    (set_attr "mode" "SI")])
6922
6923 (define_expand "mulhi3"
6924   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6925                    (mult:HI (match_operand:HI 1 "register_operand" "")
6926                             (match_operand:HI 2 "general_operand" "")))
6927               (clobber (reg:CC FLAGS_REG))])]
6928   "TARGET_HIMODE_MATH"
6929   "")
6930
6931 (define_insn "*mulhi3_1"
6932   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6933         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6934                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6935    (clobber (reg:CC FLAGS_REG))]
6936   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6937   "@
6938    imul{w}\t{%2, %1, %0|%0, %1, %2}
6939    imul{w}\t{%2, %1, %0|%0, %1, %2}
6940    imul{w}\t{%2, %0|%0, %2}"
6941   [(set_attr "type" "imul")
6942    (set_attr "prefix_0f" "0,0,1")
6943    (set (attr "athlon_decode")
6944         (cond [(eq_attr "cpu" "athlon")
6945                   (const_string "vector")
6946                (eq_attr "alternative" "1,2")
6947                   (const_string "vector")]
6948               (const_string "direct")))
6949    (set_attr "mode" "HI")])
6950
6951 (define_expand "mulqi3"
6952   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6953                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6954                             (match_operand:QI 2 "register_operand" "")))
6955               (clobber (reg:CC FLAGS_REG))])]
6956   "TARGET_QIMODE_MATH"
6957   "")
6958
6959 (define_insn "*mulqi3_1"
6960   [(set (match_operand:QI 0 "register_operand" "=a")
6961         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6962                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6963    (clobber (reg:CC FLAGS_REG))]
6964   "TARGET_QIMODE_MATH
6965    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6966   "mul{b}\t%2"
6967   [(set_attr "type" "imul")
6968    (set_attr "length_immediate" "0")
6969    (set (attr "athlon_decode")
6970      (if_then_else (eq_attr "cpu" "athlon")
6971         (const_string "vector")
6972         (const_string "direct")))
6973    (set_attr "mode" "QI")])
6974
6975 (define_expand "umulqihi3"
6976   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6977                    (mult:HI (zero_extend:HI
6978                               (match_operand:QI 1 "nonimmediate_operand" ""))
6979                             (zero_extend:HI
6980                               (match_operand:QI 2 "register_operand" ""))))
6981               (clobber (reg:CC FLAGS_REG))])]
6982   "TARGET_QIMODE_MATH"
6983   "")
6984
6985 (define_insn "*umulqihi3_1"
6986   [(set (match_operand:HI 0 "register_operand" "=a")
6987         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6988                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "TARGET_QIMODE_MATH
6991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6992   "mul{b}\t%2"
6993   [(set_attr "type" "imul")
6994    (set_attr "length_immediate" "0")
6995    (set (attr "athlon_decode")
6996      (if_then_else (eq_attr "cpu" "athlon")
6997         (const_string "vector")
6998         (const_string "direct")))
6999    (set_attr "mode" "QI")])
7000
7001 (define_expand "mulqihi3"
7002   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7003                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7004                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7005               (clobber (reg:CC FLAGS_REG))])]
7006   "TARGET_QIMODE_MATH"
7007   "")
7008
7009 (define_insn "*mulqihi3_insn"
7010   [(set (match_operand:HI 0 "register_operand" "=a")
7011         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7012                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "TARGET_QIMODE_MATH
7015    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7016   "imul{b}\t%2"
7017   [(set_attr "type" "imul")
7018    (set_attr "length_immediate" "0")
7019    (set (attr "athlon_decode")
7020      (if_then_else (eq_attr "cpu" "athlon")
7021         (const_string "vector")
7022         (const_string "direct")))
7023    (set_attr "mode" "QI")])
7024
7025 (define_expand "umulditi3"
7026   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7027                    (mult:TI (zero_extend:TI
7028                               (match_operand:DI 1 "nonimmediate_operand" ""))
7029                             (zero_extend:TI
7030                               (match_operand:DI 2 "register_operand" ""))))
7031               (clobber (reg:CC FLAGS_REG))])]
7032   "TARGET_64BIT"
7033   "")
7034
7035 (define_insn "*umulditi3_insn"
7036   [(set (match_operand:TI 0 "register_operand" "=A")
7037         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7038                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "TARGET_64BIT
7041    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7042   "mul{q}\t%2"
7043   [(set_attr "type" "imul")
7044    (set_attr "length_immediate" "0")
7045    (set (attr "athlon_decode")
7046      (if_then_else (eq_attr "cpu" "athlon")
7047         (const_string "vector")
7048         (const_string "double")))
7049    (set_attr "mode" "DI")])
7050
7051 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7052 (define_expand "umulsidi3"
7053   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7054                    (mult:DI (zero_extend:DI
7055                               (match_operand:SI 1 "nonimmediate_operand" ""))
7056                             (zero_extend:DI
7057                               (match_operand:SI 2 "register_operand" ""))))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "!TARGET_64BIT"
7060   "")
7061
7062 (define_insn "*umulsidi3_insn"
7063   [(set (match_operand:DI 0 "register_operand" "=A")
7064         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7065                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "!TARGET_64BIT
7068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069   "mul{l}\t%2"
7070   [(set_attr "type" "imul")
7071    (set_attr "length_immediate" "0")
7072    (set (attr "athlon_decode")
7073      (if_then_else (eq_attr "cpu" "athlon")
7074         (const_string "vector")
7075         (const_string "double")))
7076    (set_attr "mode" "SI")])
7077
7078 (define_expand "mulditi3"
7079   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7080                    (mult:TI (sign_extend:TI
7081                               (match_operand:DI 1 "nonimmediate_operand" ""))
7082                             (sign_extend:TI
7083                               (match_operand:DI 2 "register_operand" ""))))
7084               (clobber (reg:CC FLAGS_REG))])]
7085   "TARGET_64BIT"
7086   "")
7087
7088 (define_insn "*mulditi3_insn"
7089   [(set (match_operand:TI 0 "register_operand" "=A")
7090         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7091                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_64BIT
7094    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095   "imul{q}\t%2"
7096   [(set_attr "type" "imul")
7097    (set_attr "length_immediate" "0")
7098    (set (attr "athlon_decode")
7099      (if_then_else (eq_attr "cpu" "athlon")
7100         (const_string "vector")
7101         (const_string "double")))
7102    (set_attr "mode" "DI")])
7103
7104 (define_expand "mulsidi3"
7105   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7106                    (mult:DI (sign_extend:DI
7107                               (match_operand:SI 1 "nonimmediate_operand" ""))
7108                             (sign_extend:DI
7109                               (match_operand:SI 2 "register_operand" ""))))
7110               (clobber (reg:CC FLAGS_REG))])]
7111   "!TARGET_64BIT"
7112   "")
7113
7114 (define_insn "*mulsidi3_insn"
7115   [(set (match_operand:DI 0 "register_operand" "=A")
7116         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7117                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7118    (clobber (reg:CC FLAGS_REG))]
7119   "!TARGET_64BIT
7120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7121   "imul{l}\t%2"
7122   [(set_attr "type" "imul")
7123    (set_attr "length_immediate" "0")
7124    (set (attr "athlon_decode")
7125      (if_then_else (eq_attr "cpu" "athlon")
7126         (const_string "vector")
7127         (const_string "double")))
7128    (set_attr "mode" "SI")])
7129
7130 (define_expand "umuldi3_highpart"
7131   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7132                    (truncate:DI
7133                      (lshiftrt:TI
7134                        (mult:TI (zero_extend:TI
7135                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7136                                 (zero_extend:TI
7137                                   (match_operand:DI 2 "register_operand" "")))
7138                        (const_int 64))))
7139               (clobber (match_scratch:DI 3 ""))
7140               (clobber (reg:CC FLAGS_REG))])]
7141   "TARGET_64BIT"
7142   "")
7143
7144 (define_insn "*umuldi3_highpart_rex64"
7145   [(set (match_operand:DI 0 "register_operand" "=d")
7146         (truncate:DI
7147           (lshiftrt:TI
7148             (mult:TI (zero_extend:TI
7149                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7150                      (zero_extend:TI
7151                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7152             (const_int 64))))
7153    (clobber (match_scratch:DI 3 "=1"))
7154    (clobber (reg:CC FLAGS_REG))]
7155   "TARGET_64BIT
7156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7157   "mul{q}\t%2"
7158   [(set_attr "type" "imul")
7159    (set_attr "length_immediate" "0")
7160    (set (attr "athlon_decode")
7161      (if_then_else (eq_attr "cpu" "athlon")
7162         (const_string "vector")
7163         (const_string "double")))
7164    (set_attr "mode" "DI")])
7165
7166 (define_expand "umulsi3_highpart"
7167   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7168                    (truncate:SI
7169                      (lshiftrt:DI
7170                        (mult:DI (zero_extend:DI
7171                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7172                                 (zero_extend:DI
7173                                   (match_operand:SI 2 "register_operand" "")))
7174                        (const_int 32))))
7175               (clobber (match_scratch:SI 3 ""))
7176               (clobber (reg:CC FLAGS_REG))])]
7177   ""
7178   "")
7179
7180 (define_insn "*umulsi3_highpart_insn"
7181   [(set (match_operand:SI 0 "register_operand" "=d")
7182         (truncate:SI
7183           (lshiftrt:DI
7184             (mult:DI (zero_extend:DI
7185                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7186                      (zero_extend:DI
7187                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7188             (const_int 32))))
7189    (clobber (match_scratch:SI 3 "=1"))
7190    (clobber (reg:CC FLAGS_REG))]
7191   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7192   "mul{l}\t%2"
7193   [(set_attr "type" "imul")
7194    (set_attr "length_immediate" "0")
7195    (set (attr "athlon_decode")
7196      (if_then_else (eq_attr "cpu" "athlon")
7197         (const_string "vector")
7198         (const_string "double")))
7199    (set_attr "mode" "SI")])
7200
7201 (define_insn "*umulsi3_highpart_zext"
7202   [(set (match_operand:DI 0 "register_operand" "=d")
7203         (zero_extend:DI (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   "TARGET_64BIT
7213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7214   "mul{l}\t%2"
7215   [(set_attr "type" "imul")
7216    (set_attr "length_immediate" "0")
7217    (set (attr "athlon_decode")
7218      (if_then_else (eq_attr "cpu" "athlon")
7219         (const_string "vector")
7220         (const_string "double")))
7221    (set_attr "mode" "SI")])
7222
7223 (define_expand "smuldi3_highpart"
7224   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7225                    (truncate:DI
7226                      (lshiftrt:TI
7227                        (mult:TI (sign_extend:TI
7228                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7229                                 (sign_extend:TI
7230                                   (match_operand:DI 2 "register_operand" "")))
7231                        (const_int 64))))
7232               (clobber (match_scratch:DI 3 ""))
7233               (clobber (reg:CC FLAGS_REG))])]
7234   "TARGET_64BIT"
7235   "")
7236
7237 (define_insn "*smuldi3_highpart_rex64"
7238   [(set (match_operand:DI 0 "register_operand" "=d")
7239         (truncate:DI
7240           (lshiftrt:TI
7241             (mult:TI (sign_extend:TI
7242                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7243                      (sign_extend:TI
7244                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7245             (const_int 64))))
7246    (clobber (match_scratch:DI 3 "=1"))
7247    (clobber (reg:CC FLAGS_REG))]
7248   "TARGET_64BIT
7249    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7250   "imul{q}\t%2"
7251   [(set_attr "type" "imul")
7252    (set (attr "athlon_decode")
7253      (if_then_else (eq_attr "cpu" "athlon")
7254         (const_string "vector")
7255         (const_string "double")))
7256    (set_attr "mode" "DI")])
7257
7258 (define_expand "smulsi3_highpart"
7259   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7260                    (truncate:SI
7261                      (lshiftrt:DI
7262                        (mult:DI (sign_extend:DI
7263                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7264                                 (sign_extend:DI
7265                                   (match_operand:SI 2 "register_operand" "")))
7266                        (const_int 32))))
7267               (clobber (match_scratch:SI 3 ""))
7268               (clobber (reg:CC FLAGS_REG))])]
7269   ""
7270   "")
7271
7272 (define_insn "*smulsi3_highpart_insn"
7273   [(set (match_operand:SI 0 "register_operand" "=d")
7274         (truncate:SI
7275           (lshiftrt:DI
7276             (mult:DI (sign_extend:DI
7277                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7278                      (sign_extend:DI
7279                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7280             (const_int 32))))
7281    (clobber (match_scratch:SI 3 "=1"))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7284   "imul{l}\t%2"
7285   [(set_attr "type" "imul")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7291
7292 (define_insn "*smulsi3_highpart_zext"
7293   [(set (match_operand:DI 0 "register_operand" "=d")
7294         (zero_extend:DI (truncate:SI
7295           (lshiftrt:DI
7296             (mult:DI (sign_extend:DI
7297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298                      (sign_extend:DI
7299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300             (const_int 32)))))
7301    (clobber (match_scratch:SI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "TARGET_64BIT
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 ;; The patterns that match these are at the end of this file.
7314
7315 (define_expand "mulxf3"
7316   [(set (match_operand:XF 0 "register_operand" "")
7317         (mult:XF (match_operand:XF 1 "register_operand" "")
7318                  (match_operand:XF 2 "register_operand" "")))]
7319   "TARGET_80387"
7320   "")
7321
7322 (define_expand "muldf3"
7323   [(set (match_operand:DF 0 "register_operand" "")
7324         (mult:DF (match_operand:DF 1 "register_operand" "")
7325                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7326   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7327   "")
7328
7329 (define_expand "mulsf3"
7330   [(set (match_operand:SF 0 "register_operand" "")
7331         (mult:SF (match_operand:SF 1 "register_operand" "")
7332                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7333   "TARGET_80387 || TARGET_SSE_MATH"
7334   "")
7335 \f
7336 ;; Divide instructions
7337
7338 (define_insn "divqi3"
7339   [(set (match_operand:QI 0 "register_operand" "=a")
7340         (div:QI (match_operand:HI 1 "register_operand" "0")
7341                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7342    (clobber (reg:CC FLAGS_REG))]
7343   "TARGET_QIMODE_MATH"
7344   "idiv{b}\t%2"
7345   [(set_attr "type" "idiv")
7346    (set_attr "mode" "QI")])
7347
7348 (define_insn "udivqi3"
7349   [(set (match_operand:QI 0 "register_operand" "=a")
7350         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7351                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_QIMODE_MATH"
7354   "div{b}\t%2"
7355   [(set_attr "type" "idiv")
7356    (set_attr "mode" "QI")])
7357
7358 ;; The patterns that match these are at the end of this file.
7359
7360 (define_expand "divxf3"
7361   [(set (match_operand:XF 0 "register_operand" "")
7362         (div:XF (match_operand:XF 1 "register_operand" "")
7363                 (match_operand:XF 2 "register_operand" "")))]
7364   "TARGET_80387"
7365   "")
7366
7367 (define_expand "divdf3"
7368   [(set (match_operand:DF 0 "register_operand" "")
7369         (div:DF (match_operand:DF 1 "register_operand" "")
7370                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7371    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7372    "")
7373  
7374 (define_expand "divsf3"
7375   [(set (match_operand:SF 0 "register_operand" "")
7376         (div:SF (match_operand:SF 1 "register_operand" "")
7377                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7378   "TARGET_80387 || TARGET_SSE_MATH"
7379   "")
7380 \f
7381 ;; Remainder instructions.
7382
7383 (define_expand "divmoddi4"
7384   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7385                    (div:DI (match_operand:DI 1 "register_operand" "")
7386                            (match_operand:DI 2 "nonimmediate_operand" "")))
7387               (set (match_operand:DI 3 "register_operand" "")
7388                    (mod:DI (match_dup 1) (match_dup 2)))
7389               (clobber (reg:CC FLAGS_REG))])]
7390   "TARGET_64BIT"
7391   "")
7392
7393 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7394 ;; Penalize eax case slightly because it results in worse scheduling
7395 ;; of code.
7396 (define_insn "*divmoddi4_nocltd_rex64"
7397   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7398         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7399                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7400    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7401         (mod:DI (match_dup 2) (match_dup 3)))
7402    (clobber (reg:CC FLAGS_REG))]
7403   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7404   "#"
7405   [(set_attr "type" "multi")])
7406
7407 (define_insn "*divmoddi4_cltd_rex64"
7408   [(set (match_operand:DI 0 "register_operand" "=a")
7409         (div:DI (match_operand:DI 2 "register_operand" "a")
7410                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7411    (set (match_operand:DI 1 "register_operand" "=&d")
7412         (mod:DI (match_dup 2) (match_dup 3)))
7413    (clobber (reg:CC FLAGS_REG))]
7414   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7415   "#"
7416   [(set_attr "type" "multi")])
7417
7418 (define_insn "*divmoddi_noext_rex64"
7419   [(set (match_operand:DI 0 "register_operand" "=a")
7420         (div:DI (match_operand:DI 1 "register_operand" "0")
7421                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7422    (set (match_operand:DI 3 "register_operand" "=d")
7423         (mod:DI (match_dup 1) (match_dup 2)))
7424    (use (match_operand:DI 4 "register_operand" "3"))
7425    (clobber (reg:CC FLAGS_REG))]
7426   "TARGET_64BIT"
7427   "idiv{q}\t%2"
7428   [(set_attr "type" "idiv")
7429    (set_attr "mode" "DI")])
7430
7431 (define_split
7432   [(set (match_operand:DI 0 "register_operand" "")
7433         (div:DI (match_operand:DI 1 "register_operand" "")
7434                 (match_operand:DI 2 "nonimmediate_operand" "")))
7435    (set (match_operand:DI 3 "register_operand" "")
7436         (mod:DI (match_dup 1) (match_dup 2)))
7437    (clobber (reg:CC FLAGS_REG))]
7438   "TARGET_64BIT && reload_completed"
7439   [(parallel [(set (match_dup 3)
7440                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7441               (clobber (reg:CC FLAGS_REG))])
7442    (parallel [(set (match_dup 0)
7443                    (div:DI (reg:DI 0) (match_dup 2)))
7444               (set (match_dup 3)
7445                    (mod:DI (reg:DI 0) (match_dup 2)))
7446               (use (match_dup 3))
7447               (clobber (reg:CC FLAGS_REG))])]
7448 {
7449   /* Avoid use of cltd in favor of a mov+shift.  */
7450   if (!TARGET_USE_CLTD && !optimize_size)
7451     {
7452       if (true_regnum (operands[1]))
7453         emit_move_insn (operands[0], operands[1]);
7454       else
7455         emit_move_insn (operands[3], operands[1]);
7456       operands[4] = operands[3];
7457     }
7458   else
7459     {
7460       gcc_assert (!true_regnum (operands[1]));
7461       operands[4] = operands[1];
7462     }
7463 })
7464
7465
7466 (define_expand "divmodsi4"
7467   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7468                    (div:SI (match_operand:SI 1 "register_operand" "")
7469                            (match_operand:SI 2 "nonimmediate_operand" "")))
7470               (set (match_operand:SI 3 "register_operand" "")
7471                    (mod:SI (match_dup 1) (match_dup 2)))
7472               (clobber (reg:CC FLAGS_REG))])]
7473   ""
7474   "")
7475
7476 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7477 ;; Penalize eax case slightly because it results in worse scheduling
7478 ;; of code.
7479 (define_insn "*divmodsi4_nocltd"
7480   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7481         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7482                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7483    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7484         (mod:SI (match_dup 2) (match_dup 3)))
7485    (clobber (reg:CC FLAGS_REG))]
7486   "!optimize_size && !TARGET_USE_CLTD"
7487   "#"
7488   [(set_attr "type" "multi")])
7489
7490 (define_insn "*divmodsi4_cltd"
7491   [(set (match_operand:SI 0 "register_operand" "=a")
7492         (div:SI (match_operand:SI 2 "register_operand" "a")
7493                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7494    (set (match_operand:SI 1 "register_operand" "=&d")
7495         (mod:SI (match_dup 2) (match_dup 3)))
7496    (clobber (reg:CC FLAGS_REG))]
7497   "optimize_size || TARGET_USE_CLTD"
7498   "#"
7499   [(set_attr "type" "multi")])
7500
7501 (define_insn "*divmodsi_noext"
7502   [(set (match_operand:SI 0 "register_operand" "=a")
7503         (div:SI (match_operand:SI 1 "register_operand" "0")
7504                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7505    (set (match_operand:SI 3 "register_operand" "=d")
7506         (mod:SI (match_dup 1) (match_dup 2)))
7507    (use (match_operand:SI 4 "register_operand" "3"))
7508    (clobber (reg:CC FLAGS_REG))]
7509   ""
7510   "idiv{l}\t%2"
7511   [(set_attr "type" "idiv")
7512    (set_attr "mode" "SI")])
7513
7514 (define_split
7515   [(set (match_operand:SI 0 "register_operand" "")
7516         (div:SI (match_operand:SI 1 "register_operand" "")
7517                 (match_operand:SI 2 "nonimmediate_operand" "")))
7518    (set (match_operand:SI 3 "register_operand" "")
7519         (mod:SI (match_dup 1) (match_dup 2)))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "reload_completed"
7522   [(parallel [(set (match_dup 3)
7523                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7524               (clobber (reg:CC FLAGS_REG))])
7525    (parallel [(set (match_dup 0)
7526                    (div:SI (reg:SI 0) (match_dup 2)))
7527               (set (match_dup 3)
7528                    (mod:SI (reg:SI 0) (match_dup 2)))
7529               (use (match_dup 3))
7530               (clobber (reg:CC FLAGS_REG))])]
7531 {
7532   /* Avoid use of cltd in favor of a mov+shift.  */
7533   if (!TARGET_USE_CLTD && !optimize_size)
7534     {
7535       if (true_regnum (operands[1]))
7536         emit_move_insn (operands[0], operands[1]);
7537       else
7538         emit_move_insn (operands[3], operands[1]);
7539       operands[4] = operands[3];
7540     }
7541   else
7542     {
7543       gcc_assert (!true_regnum (operands[1]));
7544       operands[4] = operands[1];
7545     }
7546 })
7547 ;; %%% Split me.
7548 (define_insn "divmodhi4"
7549   [(set (match_operand:HI 0 "register_operand" "=a")
7550         (div:HI (match_operand:HI 1 "register_operand" "0")
7551                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7552    (set (match_operand:HI 3 "register_operand" "=&d")
7553         (mod:HI (match_dup 1) (match_dup 2)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "TARGET_HIMODE_MATH"
7556   "cwtd\;idiv{w}\t%2"
7557   [(set_attr "type" "multi")
7558    (set_attr "length_immediate" "0")
7559    (set_attr "mode" "SI")])
7560
7561 (define_insn "udivmoddi4"
7562   [(set (match_operand:DI 0 "register_operand" "=a")
7563         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7564                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7565    (set (match_operand:DI 3 "register_operand" "=&d")
7566         (umod:DI (match_dup 1) (match_dup 2)))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_64BIT"
7569   "xor{q}\t%3, %3\;div{q}\t%2"
7570   [(set_attr "type" "multi")
7571    (set_attr "length_immediate" "0")
7572    (set_attr "mode" "DI")])
7573
7574 (define_insn "*udivmoddi4_noext"
7575   [(set (match_operand:DI 0 "register_operand" "=a")
7576         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7577                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7578    (set (match_operand:DI 3 "register_operand" "=d")
7579         (umod:DI (match_dup 1) (match_dup 2)))
7580    (use (match_dup 3))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "TARGET_64BIT"
7583   "div{q}\t%2"
7584   [(set_attr "type" "idiv")
7585    (set_attr "mode" "DI")])
7586
7587 (define_split
7588   [(set (match_operand:DI 0 "register_operand" "")
7589         (udiv:DI (match_operand:DI 1 "register_operand" "")
7590                  (match_operand:DI 2 "nonimmediate_operand" "")))
7591    (set (match_operand:DI 3 "register_operand" "")
7592         (umod:DI (match_dup 1) (match_dup 2)))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "TARGET_64BIT && reload_completed"
7595   [(set (match_dup 3) (const_int 0))
7596    (parallel [(set (match_dup 0)
7597                    (udiv:DI (match_dup 1) (match_dup 2)))
7598               (set (match_dup 3)
7599                    (umod:DI (match_dup 1) (match_dup 2)))
7600               (use (match_dup 3))
7601               (clobber (reg:CC FLAGS_REG))])]
7602   "")
7603
7604 (define_insn "udivmodsi4"
7605   [(set (match_operand:SI 0 "register_operand" "=a")
7606         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7607                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7608    (set (match_operand:SI 3 "register_operand" "=&d")
7609         (umod:SI (match_dup 1) (match_dup 2)))
7610    (clobber (reg:CC FLAGS_REG))]
7611   ""
7612   "xor{l}\t%3, %3\;div{l}\t%2"
7613   [(set_attr "type" "multi")
7614    (set_attr "length_immediate" "0")
7615    (set_attr "mode" "SI")])
7616
7617 (define_insn "*udivmodsi4_noext"
7618   [(set (match_operand:SI 0 "register_operand" "=a")
7619         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7620                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:SI 3 "register_operand" "=d")
7622         (umod:SI (match_dup 1) (match_dup 2)))
7623    (use (match_dup 3))
7624    (clobber (reg:CC FLAGS_REG))]
7625   ""
7626   "div{l}\t%2"
7627   [(set_attr "type" "idiv")
7628    (set_attr "mode" "SI")])
7629
7630 (define_split
7631   [(set (match_operand:SI 0 "register_operand" "")
7632         (udiv:SI (match_operand:SI 1 "register_operand" "")
7633                  (match_operand:SI 2 "nonimmediate_operand" "")))
7634    (set (match_operand:SI 3 "register_operand" "")
7635         (umod:SI (match_dup 1) (match_dup 2)))
7636    (clobber (reg:CC FLAGS_REG))]
7637   "reload_completed"
7638   [(set (match_dup 3) (const_int 0))
7639    (parallel [(set (match_dup 0)
7640                    (udiv:SI (match_dup 1) (match_dup 2)))
7641               (set (match_dup 3)
7642                    (umod:SI (match_dup 1) (match_dup 2)))
7643               (use (match_dup 3))
7644               (clobber (reg:CC FLAGS_REG))])]
7645   "")
7646
7647 (define_expand "udivmodhi4"
7648   [(set (match_dup 4) (const_int 0))
7649    (parallel [(set (match_operand:HI 0 "register_operand" "")
7650                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7651                             (match_operand:HI 2 "nonimmediate_operand" "")))
7652               (set (match_operand:HI 3 "register_operand" "")
7653                    (umod:HI (match_dup 1) (match_dup 2)))
7654               (use (match_dup 4))
7655               (clobber (reg:CC FLAGS_REG))])]
7656   "TARGET_HIMODE_MATH"
7657   "operands[4] = gen_reg_rtx (HImode);")
7658
7659 (define_insn "*udivmodhi_noext"
7660   [(set (match_operand:HI 0 "register_operand" "=a")
7661         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7662                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7663    (set (match_operand:HI 3 "register_operand" "=d")
7664         (umod:HI (match_dup 1) (match_dup 2)))
7665    (use (match_operand:HI 4 "register_operand" "3"))
7666    (clobber (reg:CC FLAGS_REG))]
7667   ""
7668   "div{w}\t%2"
7669   [(set_attr "type" "idiv")
7670    (set_attr "mode" "HI")])
7671
7672 ;; We cannot use div/idiv for double division, because it causes
7673 ;; "division by zero" on the overflow and that's not what we expect
7674 ;; from truncate.  Because true (non truncating) double division is
7675 ;; never generated, we can't create this insn anyway.
7676 ;
7677 ;(define_insn ""
7678 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7679 ;       (truncate:SI
7680 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7681 ;                  (zero_extend:DI
7682 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7683 ;   (set (match_operand:SI 3 "register_operand" "=d")
7684 ;       (truncate:SI
7685 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7686 ;   (clobber (reg:CC FLAGS_REG))]
7687 ;  ""
7688 ;  "div{l}\t{%2, %0|%0, %2}"
7689 ;  [(set_attr "type" "idiv")])
7690 \f
7691 ;;- Logical AND instructions
7692
7693 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7694 ;; Note that this excludes ah.
7695
7696 (define_insn "*testdi_1_rex64"
7697   [(set (reg FLAGS_REG)
7698         (compare
7699           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7700                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7701           (const_int 0)))]
7702   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704   "@
7705    test{l}\t{%k1, %k0|%k0, %k1}
7706    test{l}\t{%k1, %k0|%k0, %k1}
7707    test{q}\t{%1, %0|%0, %1}
7708    test{q}\t{%1, %0|%0, %1}
7709    test{q}\t{%1, %0|%0, %1}"
7710   [(set_attr "type" "test")
7711    (set_attr "modrm" "0,1,0,1,1")
7712    (set_attr "mode" "SI,SI,DI,DI,DI")
7713    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7714
7715 (define_insn "testsi_1"
7716   [(set (reg FLAGS_REG)
7717         (compare
7718           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7719                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7720           (const_int 0)))]
7721   "ix86_match_ccmode (insn, CCNOmode)
7722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7723   "test{l}\t{%1, %0|%0, %1}"
7724   [(set_attr "type" "test")
7725    (set_attr "modrm" "0,1,1")
7726    (set_attr "mode" "SI")
7727    (set_attr "pent_pair" "uv,np,uv")])
7728
7729 (define_expand "testsi_ccno_1"
7730   [(set (reg:CCNO FLAGS_REG)
7731         (compare:CCNO
7732           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7733                   (match_operand:SI 1 "nonmemory_operand" ""))
7734           (const_int 0)))]
7735   ""
7736   "")
7737
7738 (define_insn "*testhi_1"
7739   [(set (reg FLAGS_REG)
7740         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7741                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7742                  (const_int 0)))]
7743   "ix86_match_ccmode (insn, CCNOmode)
7744    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7745   "test{w}\t{%1, %0|%0, %1}"
7746   [(set_attr "type" "test")
7747    (set_attr "modrm" "0,1,1")
7748    (set_attr "mode" "HI")
7749    (set_attr "pent_pair" "uv,np,uv")])
7750
7751 (define_expand "testqi_ccz_1"
7752   [(set (reg:CCZ FLAGS_REG)
7753         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7754                              (match_operand:QI 1 "nonmemory_operand" ""))
7755                  (const_int 0)))]
7756   ""
7757   "")
7758
7759 (define_insn "*testqi_1_maybe_si"
7760   [(set (reg FLAGS_REG)
7761         (compare
7762           (and:QI
7763             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7764             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7765           (const_int 0)))]
7766    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7767     && ix86_match_ccmode (insn,
7768                          GET_CODE (operands[1]) == CONST_INT
7769                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7770 {
7771   if (which_alternative == 3)
7772     {
7773       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7774         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7775       return "test{l}\t{%1, %k0|%k0, %1}";
7776     }
7777   return "test{b}\t{%1, %0|%0, %1}";
7778 }
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,1,1")
7781    (set_attr "mode" "QI,QI,QI,SI")
7782    (set_attr "pent_pair" "uv,np,uv,np")])
7783
7784 (define_insn "*testqi_1"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (and:QI
7788             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7789             (match_operand:QI 1 "general_operand" "n,n,qn"))
7790           (const_int 0)))]
7791   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7792    && ix86_match_ccmode (insn, CCNOmode)"
7793   "test{b}\t{%1, %0|%0, %1}"
7794   [(set_attr "type" "test")
7795    (set_attr "modrm" "0,1,1")
7796    (set_attr "mode" "QI")
7797    (set_attr "pent_pair" "uv,np,uv")])
7798
7799 (define_expand "testqi_ext_ccno_0"
7800   [(set (reg:CCNO FLAGS_REG)
7801         (compare:CCNO
7802           (and:SI
7803             (zero_extract:SI
7804               (match_operand 0 "ext_register_operand" "")
7805               (const_int 8)
7806               (const_int 8))
7807             (match_operand 1 "const_int_operand" ""))
7808           (const_int 0)))]
7809   ""
7810   "")
7811
7812 (define_insn "*testqi_ext_0"
7813   [(set (reg FLAGS_REG)
7814         (compare
7815           (and:SI
7816             (zero_extract:SI
7817               (match_operand 0 "ext_register_operand" "Q")
7818               (const_int 8)
7819               (const_int 8))
7820             (match_operand 1 "const_int_operand" "n"))
7821           (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")
7826    (set_attr "length_immediate" "1")
7827    (set_attr "pent_pair" "np")])
7828
7829 (define_insn "*testqi_ext_1"
7830   [(set (reg FLAGS_REG)
7831         (compare
7832           (and:SI
7833             (zero_extract:SI
7834               (match_operand 0 "ext_register_operand" "Q")
7835               (const_int 8)
7836               (const_int 8))
7837             (zero_extend:SI
7838               (match_operand:QI 1 "general_operand" "Qm")))
7839           (const_int 0)))]
7840   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7841    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7842   "test{b}\t{%1, %h0|%h0, %1}"
7843   [(set_attr "type" "test")
7844    (set_attr "mode" "QI")])
7845
7846 (define_insn "*testqi_ext_1_rex64"
7847   [(set (reg FLAGS_REG)
7848         (compare
7849           (and:SI
7850             (zero_extract:SI
7851               (match_operand 0 "ext_register_operand" "Q")
7852               (const_int 8)
7853               (const_int 8))
7854             (zero_extend:SI
7855               (match_operand:QI 1 "register_operand" "Q")))
7856           (const_int 0)))]
7857   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7858   "test{b}\t{%1, %h0|%h0, %1}"
7859   [(set_attr "type" "test")
7860    (set_attr "mode" "QI")])
7861
7862 (define_insn "*testqi_ext_2"
7863   [(set (reg FLAGS_REG)
7864         (compare
7865           (and:SI
7866             (zero_extract:SI
7867               (match_operand 0 "ext_register_operand" "Q")
7868               (const_int 8)
7869               (const_int 8))
7870             (zero_extract:SI
7871               (match_operand 1 "ext_register_operand" "Q")
7872               (const_int 8)
7873               (const_int 8)))
7874           (const_int 0)))]
7875   "ix86_match_ccmode (insn, CCNOmode)"
7876   "test{b}\t{%h1, %h0|%h0, %h1}"
7877   [(set_attr "type" "test")
7878    (set_attr "mode" "QI")])
7879
7880 ;; Combine likes to form bit extractions for some tests.  Humor it.
7881 (define_insn "*testqi_ext_3"
7882   [(set (reg FLAGS_REG)
7883         (compare (zero_extract:SI
7884                    (match_operand 0 "nonimmediate_operand" "rm")
7885                    (match_operand:SI 1 "const_int_operand" "")
7886                    (match_operand:SI 2 "const_int_operand" ""))
7887                  (const_int 0)))]
7888   "ix86_match_ccmode (insn, CCNOmode)
7889    && INTVAL (operands[1]) > 0
7890    && INTVAL (operands[2]) >= 0
7891    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7892    && (GET_MODE (operands[0]) == SImode
7893        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7894        || GET_MODE (operands[0]) == HImode
7895        || GET_MODE (operands[0]) == QImode)"
7896   "#")
7897
7898 (define_insn "*testqi_ext_3_rex64"
7899   [(set (reg FLAGS_REG)
7900         (compare (zero_extract:DI
7901                    (match_operand 0 "nonimmediate_operand" "rm")
7902                    (match_operand:DI 1 "const_int_operand" "")
7903                    (match_operand:DI 2 "const_int_operand" ""))
7904                  (const_int 0)))]
7905   "TARGET_64BIT
7906    && ix86_match_ccmode (insn, CCNOmode)
7907    && INTVAL (operands[1]) > 0
7908    && INTVAL (operands[2]) >= 0
7909    /* Ensure that resulting mask is zero or sign extended operand.  */
7910    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7911        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7912            && INTVAL (operands[1]) > 32))
7913    && (GET_MODE (operands[0]) == SImode
7914        || GET_MODE (operands[0]) == DImode
7915        || GET_MODE (operands[0]) == HImode
7916        || GET_MODE (operands[0]) == QImode)"
7917   "#")
7918
7919 (define_split
7920   [(set (match_operand 0 "flags_reg_operand" "")
7921         (match_operator 1 "compare_operator"
7922           [(zero_extract
7923              (match_operand 2 "nonimmediate_operand" "")
7924              (match_operand 3 "const_int_operand" "")
7925              (match_operand 4 "const_int_operand" ""))
7926            (const_int 0)]))]
7927   "ix86_match_ccmode (insn, CCNOmode)"
7928   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7929 {
7930   rtx val = operands[2];
7931   HOST_WIDE_INT len = INTVAL (operands[3]);
7932   HOST_WIDE_INT pos = INTVAL (operands[4]);
7933   HOST_WIDE_INT mask;
7934   enum machine_mode mode, submode;
7935
7936   mode = GET_MODE (val);
7937   if (GET_CODE (val) == MEM)
7938     {
7939       /* ??? Combine likes to put non-volatile mem extractions in QImode
7940          no matter the size of the test.  So find a mode that works.  */
7941       if (! MEM_VOLATILE_P (val))
7942         {
7943           mode = smallest_mode_for_size (pos + len, MODE_INT);
7944           val = adjust_address (val, mode, 0);
7945         }
7946     }
7947   else if (GET_CODE (val) == SUBREG
7948            && (submode = GET_MODE (SUBREG_REG (val)),
7949                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7950            && pos + len <= GET_MODE_BITSIZE (submode))
7951     {
7952       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7953       mode = submode;
7954       val = SUBREG_REG (val);
7955     }
7956   else if (mode == HImode && pos + len <= 8)
7957     {
7958       /* Small HImode tests can be converted to QImode.  */
7959       mode = QImode;
7960       val = gen_lowpart (QImode, val);
7961     }
7962
7963   if (len == HOST_BITS_PER_WIDE_INT)
7964     mask = -1;
7965   else
7966     mask = ((HOST_WIDE_INT)1 << len) - 1;
7967   mask <<= pos;
7968
7969   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7970 })
7971
7972 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7973 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7974 ;; this is relatively important trick.
7975 ;; Do the conversion only post-reload to avoid limiting of the register class
7976 ;; to QI regs.
7977 (define_split
7978   [(set (match_operand 0 "flags_reg_operand" "")
7979         (match_operator 1 "compare_operator"
7980           [(and (match_operand 2 "register_operand" "")
7981                 (match_operand 3 "const_int_operand" ""))
7982            (const_int 0)]))]
7983    "reload_completed
7984     && QI_REG_P (operands[2])
7985     && GET_MODE (operands[2]) != QImode
7986     && ((ix86_match_ccmode (insn, CCZmode)
7987          && !(INTVAL (operands[3]) & ~(255 << 8)))
7988         || (ix86_match_ccmode (insn, CCNOmode)
7989             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7990   [(set (match_dup 0)
7991         (match_op_dup 1
7992           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7993                    (match_dup 3))
7994            (const_int 0)]))]
7995   "operands[2] = gen_lowpart (SImode, operands[2]);
7996    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7997
7998 (define_split
7999   [(set (match_operand 0 "flags_reg_operand" "")
8000         (match_operator 1 "compare_operator"
8001           [(and (match_operand 2 "nonimmediate_operand" "")
8002                 (match_operand 3 "const_int_operand" ""))
8003            (const_int 0)]))]
8004    "reload_completed
8005     && GET_MODE (operands[2]) != QImode
8006     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8007     && ((ix86_match_ccmode (insn, CCZmode)
8008          && !(INTVAL (operands[3]) & ~255))
8009         || (ix86_match_ccmode (insn, CCNOmode)
8010             && !(INTVAL (operands[3]) & ~127)))"
8011   [(set (match_dup 0)
8012         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8013                          (const_int 0)]))]
8014   "operands[2] = gen_lowpart (QImode, operands[2]);
8015    operands[3] = gen_lowpart (QImode, operands[3]);")
8016
8017
8018 ;; %%% This used to optimize known byte-wide and operations to memory,
8019 ;; and sometimes to QImode registers.  If this is considered useful,
8020 ;; it should be done with splitters.
8021
8022 (define_expand "anddi3"
8023   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8024         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8025                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8026    (clobber (reg:CC FLAGS_REG))]
8027   "TARGET_64BIT"
8028   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8029
8030 (define_insn "*anddi_1_rex64"
8031   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8032         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8033                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8034    (clobber (reg:CC FLAGS_REG))]
8035   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8036 {
8037   switch (get_attr_type (insn))
8038     {
8039     case TYPE_IMOVX:
8040       {
8041         enum machine_mode mode;
8042
8043         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8044         if (INTVAL (operands[2]) == 0xff)
8045           mode = QImode;
8046         else
8047           {
8048             gcc_assert (INTVAL (operands[2]) == 0xffff);
8049             mode = HImode;
8050           }
8051         
8052         operands[1] = gen_lowpart (mode, operands[1]);
8053         if (mode == QImode)
8054           return "movz{bq|x}\t{%1,%0|%0, %1}";
8055         else
8056           return "movz{wq|x}\t{%1,%0|%0, %1}";
8057       }
8058
8059     default:
8060       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8061       if (get_attr_mode (insn) == MODE_SI)
8062         return "and{l}\t{%k2, %k0|%k0, %k2}";
8063       else
8064         return "and{q}\t{%2, %0|%0, %2}";
8065     }
8066 }
8067   [(set_attr "type" "alu,alu,alu,imovx")
8068    (set_attr "length_immediate" "*,*,*,0")
8069    (set_attr "mode" "SI,DI,DI,DI")])
8070
8071 (define_insn "*anddi_2"
8072   [(set (reg FLAGS_REG)
8073         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8074                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8075                  (const_int 0)))
8076    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8077         (and:DI (match_dup 1) (match_dup 2)))]
8078   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8079    && ix86_binary_operator_ok (AND, DImode, operands)"
8080   "@
8081    and{l}\t{%k2, %k0|%k0, %k2}
8082    and{q}\t{%2, %0|%0, %2}
8083    and{q}\t{%2, %0|%0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "mode" "SI,DI,DI")])
8086
8087 (define_expand "andsi3"
8088   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8089         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8090                 (match_operand:SI 2 "general_operand" "")))
8091    (clobber (reg:CC FLAGS_REG))]
8092   ""
8093   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8094
8095 (define_insn "*andsi_1"
8096   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8097         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8098                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "ix86_binary_operator_ok (AND, SImode, operands)"
8101 {
8102   switch (get_attr_type (insn))
8103     {
8104     case TYPE_IMOVX:
8105       {
8106         enum machine_mode mode;
8107
8108         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8109         if (INTVAL (operands[2]) == 0xff)
8110           mode = QImode;
8111         else
8112           {
8113             gcc_assert (INTVAL (operands[2]) == 0xffff);
8114             mode = HImode;
8115           }
8116         
8117         operands[1] = gen_lowpart (mode, operands[1]);
8118         if (mode == QImode)
8119           return "movz{bl|x}\t{%1,%0|%0, %1}";
8120         else
8121           return "movz{wl|x}\t{%1,%0|%0, %1}";
8122       }
8123
8124     default:
8125       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8126       return "and{l}\t{%2, %0|%0, %2}";
8127     }
8128 }
8129   [(set_attr "type" "alu,alu,imovx")
8130    (set_attr "length_immediate" "*,*,0")
8131    (set_attr "mode" "SI")])
8132
8133 (define_split
8134   [(set (match_operand 0 "register_operand" "")
8135         (and (match_dup 0)
8136              (const_int -65536)))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8139   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8140   "operands[1] = gen_lowpart (HImode, operands[0]);")
8141
8142 (define_split
8143   [(set (match_operand 0 "ext_register_operand" "")
8144         (and (match_dup 0)
8145              (const_int -256)))
8146    (clobber (reg:CC FLAGS_REG))]
8147   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8148   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8149   "operands[1] = gen_lowpart (QImode, operands[0]);")
8150
8151 (define_split
8152   [(set (match_operand 0 "ext_register_operand" "")
8153         (and (match_dup 0)
8154              (const_int -65281)))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8157   [(parallel [(set (zero_extract:SI (match_dup 0)
8158                                     (const_int 8)
8159                                     (const_int 8))
8160                    (xor:SI 
8161                      (zero_extract:SI (match_dup 0)
8162                                       (const_int 8)
8163                                       (const_int 8))
8164                      (zero_extract:SI (match_dup 0)
8165                                       (const_int 8)
8166                                       (const_int 8))))
8167               (clobber (reg:CC FLAGS_REG))])]
8168   "operands[0] = gen_lowpart (SImode, operands[0]);")
8169
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_1_zext"
8172   [(set (match_operand:DI 0 "register_operand" "=r")
8173         (zero_extend:DI
8174           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8175                   (match_operand:SI 2 "general_operand" "rim"))))
8176    (clobber (reg:CC FLAGS_REG))]
8177   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8178   "and{l}\t{%2, %k0|%k0, %2}"
8179   [(set_attr "type" "alu")
8180    (set_attr "mode" "SI")])
8181
8182 (define_insn "*andsi_2"
8183   [(set (reg FLAGS_REG)
8184         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8185                          (match_operand:SI 2 "general_operand" "rim,ri"))
8186                  (const_int 0)))
8187    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8188         (and:SI (match_dup 1) (match_dup 2)))]
8189   "ix86_match_ccmode (insn, CCNOmode)
8190    && ix86_binary_operator_ok (AND, SImode, operands)"
8191   "and{l}\t{%2, %0|%0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "SI")])
8194
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 (define_insn "*andsi_2_zext"
8197   [(set (reg FLAGS_REG)
8198         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199                          (match_operand:SI 2 "general_operand" "rim"))
8200                  (const_int 0)))
8201    (set (match_operand:DI 0 "register_operand" "=r")
8202         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8203   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204    && ix86_binary_operator_ok (AND, SImode, operands)"
8205   "and{l}\t{%2, %k0|%k0, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "SI")])
8208
8209 (define_expand "andhi3"
8210   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8211         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8212                 (match_operand:HI 2 "general_operand" "")))
8213    (clobber (reg:CC FLAGS_REG))]
8214   "TARGET_HIMODE_MATH"
8215   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8216
8217 (define_insn "*andhi_1"
8218   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8219         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8220                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "ix86_binary_operator_ok (AND, HImode, operands)"
8223 {
8224   switch (get_attr_type (insn))
8225     {
8226     case TYPE_IMOVX:
8227       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8228       gcc_assert (INTVAL (operands[2]) == 0xff);
8229       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8230
8231     default:
8232       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8233
8234       return "and{w}\t{%2, %0|%0, %2}";
8235     }
8236 }
8237   [(set_attr "type" "alu,alu,imovx")
8238    (set_attr "length_immediate" "*,*,0")
8239    (set_attr "mode" "HI,HI,SI")])
8240
8241 (define_insn "*andhi_2"
8242   [(set (reg FLAGS_REG)
8243         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8244                          (match_operand:HI 2 "general_operand" "rim,ri"))
8245                  (const_int 0)))
8246    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8247         (and:HI (match_dup 1) (match_dup 2)))]
8248   "ix86_match_ccmode (insn, CCNOmode)
8249    && ix86_binary_operator_ok (AND, HImode, operands)"
8250   "and{w}\t{%2, %0|%0, %2}"
8251   [(set_attr "type" "alu")
8252    (set_attr "mode" "HI")])
8253
8254 (define_expand "andqi3"
8255   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8256         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8257                 (match_operand:QI 2 "general_operand" "")))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "TARGET_QIMODE_MATH"
8260   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8261
8262 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8263 (define_insn "*andqi_1"
8264   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8265         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "ix86_binary_operator_ok (AND, QImode, operands)"
8269   "@
8270    and{b}\t{%2, %0|%0, %2}
8271    and{b}\t{%2, %0|%0, %2}
8272    and{l}\t{%k2, %k0|%k0, %k2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "mode" "QI,QI,SI")])
8275
8276 (define_insn "*andqi_1_slp"
8277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8278         (and:QI (match_dup 0)
8279                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8282    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8283   "and{b}\t{%1, %0|%0, %1}"
8284   [(set_attr "type" "alu1")
8285    (set_attr "mode" "QI")])
8286
8287 (define_insn "*andqi_2_maybe_si"
8288   [(set (reg FLAGS_REG)
8289         (compare (and:QI
8290                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8291                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8292                  (const_int 0)))
8293    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8294         (and:QI (match_dup 1) (match_dup 2)))]
8295   "ix86_binary_operator_ok (AND, QImode, operands)
8296    && ix86_match_ccmode (insn,
8297                          GET_CODE (operands[2]) == CONST_INT
8298                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8299 {
8300   if (which_alternative == 2)
8301     {
8302       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8303         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8304       return "and{l}\t{%2, %k0|%k0, %2}";
8305     }
8306   return "and{b}\t{%2, %0|%0, %2}";
8307 }
8308   [(set_attr "type" "alu")
8309    (set_attr "mode" "QI,QI,SI")])
8310
8311 (define_insn "*andqi_2"
8312   [(set (reg FLAGS_REG)
8313         (compare (and:QI
8314                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8315                    (match_operand:QI 2 "general_operand" "qim,qi"))
8316                  (const_int 0)))
8317    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8318         (and:QI (match_dup 1) (match_dup 2)))]
8319   "ix86_match_ccmode (insn, CCNOmode)
8320    && ix86_binary_operator_ok (AND, QImode, operands)"
8321   "and{b}\t{%2, %0|%0, %2}"
8322   [(set_attr "type" "alu")
8323    (set_attr "mode" "QI")])
8324
8325 (define_insn "*andqi_2_slp"
8326   [(set (reg FLAGS_REG)
8327         (compare (and:QI
8328                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8329                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8330                  (const_int 0)))
8331    (set (strict_low_part (match_dup 0))
8332         (and:QI (match_dup 0) (match_dup 1)))]
8333   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8334    && ix86_match_ccmode (insn, CCNOmode)
8335    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8336   "and{b}\t{%1, %0|%0, %1}"
8337   [(set_attr "type" "alu1")
8338    (set_attr "mode" "QI")])
8339
8340 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8341 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8342 ;; for a QImode operand, which of course failed.
8343
8344 (define_insn "andqi_ext_0"
8345   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8346                          (const_int 8)
8347                          (const_int 8))
8348         (and:SI 
8349           (zero_extract:SI
8350             (match_operand 1 "ext_register_operand" "0")
8351             (const_int 8)
8352             (const_int 8))
8353           (match_operand 2 "const_int_operand" "n")))
8354    (clobber (reg:CC FLAGS_REG))]
8355   ""
8356   "and{b}\t{%2, %h0|%h0, %2}"
8357   [(set_attr "type" "alu")
8358    (set_attr "length_immediate" "1")
8359    (set_attr "mode" "QI")])
8360
8361 ;; Generated by peephole translating test to and.  This shows up
8362 ;; often in fp comparisons.
8363
8364 (define_insn "*andqi_ext_0_cc"
8365   [(set (reg FLAGS_REG)
8366         (compare
8367           (and:SI
8368             (zero_extract:SI
8369               (match_operand 1 "ext_register_operand" "0")
8370               (const_int 8)
8371               (const_int 8))
8372             (match_operand 2 "const_int_operand" "n"))
8373           (const_int 0)))
8374    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8375                          (const_int 8)
8376                          (const_int 8))
8377         (and:SI 
8378           (zero_extract:SI
8379             (match_dup 1)
8380             (const_int 8)
8381             (const_int 8))
8382           (match_dup 2)))]
8383   "ix86_match_ccmode (insn, CCNOmode)"
8384   "and{b}\t{%2, %h0|%h0, %2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "length_immediate" "1")
8387    (set_attr "mode" "QI")])
8388
8389 (define_insn "*andqi_ext_1"
8390   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391                          (const_int 8)
8392                          (const_int 8))
8393         (and:SI 
8394           (zero_extract:SI
8395             (match_operand 1 "ext_register_operand" "0")
8396             (const_int 8)
8397             (const_int 8))
8398           (zero_extend:SI
8399             (match_operand:QI 2 "general_operand" "Qm"))))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "!TARGET_64BIT"
8402   "and{b}\t{%2, %h0|%h0, %2}"
8403   [(set_attr "type" "alu")
8404    (set_attr "length_immediate" "0")
8405    (set_attr "mode" "QI")])
8406
8407 (define_insn "*andqi_ext_1_rex64"
8408   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409                          (const_int 8)
8410                          (const_int 8))
8411         (and:SI 
8412           (zero_extract:SI
8413             (match_operand 1 "ext_register_operand" "0")
8414             (const_int 8)
8415             (const_int 8))
8416           (zero_extend:SI
8417             (match_operand 2 "ext_register_operand" "Q"))))
8418    (clobber (reg:CC FLAGS_REG))]
8419   "TARGET_64BIT"
8420   "and{b}\t{%2, %h0|%h0, %2}"
8421   [(set_attr "type" "alu")
8422    (set_attr "length_immediate" "0")
8423    (set_attr "mode" "QI")])
8424
8425 (define_insn "*andqi_ext_2"
8426   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8427                          (const_int 8)
8428                          (const_int 8))
8429         (and:SI
8430           (zero_extract:SI
8431             (match_operand 1 "ext_register_operand" "%0")
8432             (const_int 8)
8433             (const_int 8))
8434           (zero_extract:SI
8435             (match_operand 2 "ext_register_operand" "Q")
8436             (const_int 8)
8437             (const_int 8))))
8438    (clobber (reg:CC FLAGS_REG))]
8439   ""
8440   "and{b}\t{%h2, %h0|%h0, %h2}"
8441   [(set_attr "type" "alu")
8442    (set_attr "length_immediate" "0")
8443    (set_attr "mode" "QI")])
8444
8445 ;; Convert wide AND instructions with immediate operand to shorter QImode
8446 ;; equivalents when possible.
8447 ;; Don't do the splitting with memory operands, since it introduces risk
8448 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8449 ;; for size, but that can (should?) be handled by generic code instead.
8450 (define_split
8451   [(set (match_operand 0 "register_operand" "")
8452         (and (match_operand 1 "register_operand" "")
8453              (match_operand 2 "const_int_operand" "")))
8454    (clobber (reg:CC FLAGS_REG))]
8455    "reload_completed
8456     && QI_REG_P (operands[0])
8457     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458     && !(~INTVAL (operands[2]) & ~(255 << 8))
8459     && GET_MODE (operands[0]) != QImode"
8460   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8461                    (and:SI (zero_extract:SI (match_dup 1)
8462                                             (const_int 8) (const_int 8))
8463                            (match_dup 2)))
8464               (clobber (reg:CC FLAGS_REG))])]
8465   "operands[0] = gen_lowpart (SImode, operands[0]);
8466    operands[1] = gen_lowpart (SImode, operands[1]);
8467    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8468
8469 ;; Since AND can be encoded with sign extended immediate, this is only
8470 ;; profitable when 7th bit is not set.
8471 (define_split
8472   [(set (match_operand 0 "register_operand" "")
8473         (and (match_operand 1 "general_operand" "")
8474              (match_operand 2 "const_int_operand" "")))
8475    (clobber (reg:CC FLAGS_REG))]
8476    "reload_completed
8477     && ANY_QI_REG_P (operands[0])
8478     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8479     && !(~INTVAL (operands[2]) & ~255)
8480     && !(INTVAL (operands[2]) & 128)
8481     && GET_MODE (operands[0]) != QImode"
8482   [(parallel [(set (strict_low_part (match_dup 0))
8483                    (and:QI (match_dup 1)
8484                            (match_dup 2)))
8485               (clobber (reg:CC FLAGS_REG))])]
8486   "operands[0] = gen_lowpart (QImode, operands[0]);
8487    operands[1] = gen_lowpart (QImode, operands[1]);
8488    operands[2] = gen_lowpart (QImode, operands[2]);")
8489 \f
8490 ;; Logical inclusive OR instructions
8491
8492 ;; %%% This used to optimize known byte-wide and operations to memory.
8493 ;; If this is considered useful, it should be done with splitters.
8494
8495 (define_expand "iordi3"
8496   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8497         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8498                 (match_operand:DI 2 "x86_64_general_operand" "")))
8499    (clobber (reg:CC FLAGS_REG))]
8500   "TARGET_64BIT"
8501   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8502
8503 (define_insn "*iordi_1_rex64"
8504   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8505         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8506                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8507    (clobber (reg:CC FLAGS_REG))]
8508   "TARGET_64BIT
8509    && ix86_binary_operator_ok (IOR, DImode, operands)"
8510   "or{q}\t{%2, %0|%0, %2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "mode" "DI")])
8513
8514 (define_insn "*iordi_2_rex64"
8515   [(set (reg FLAGS_REG)
8516         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8517                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8518                  (const_int 0)))
8519    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8520         (ior:DI (match_dup 1) (match_dup 2)))]
8521   "TARGET_64BIT
8522    && ix86_match_ccmode (insn, CCNOmode)
8523    && ix86_binary_operator_ok (IOR, DImode, operands)"
8524   "or{q}\t{%2, %0|%0, %2}"
8525   [(set_attr "type" "alu")
8526    (set_attr "mode" "DI")])
8527
8528 (define_insn "*iordi_3_rex64"
8529   [(set (reg FLAGS_REG)
8530         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8531                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8532                  (const_int 0)))
8533    (clobber (match_scratch:DI 0 "=r"))]
8534   "TARGET_64BIT
8535    && ix86_match_ccmode (insn, CCNOmode)
8536    && ix86_binary_operator_ok (IOR, DImode, operands)"
8537   "or{q}\t{%2, %0|%0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "DI")])
8540
8541
8542 (define_expand "iorsi3"
8543   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8544         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8545                 (match_operand:SI 2 "general_operand" "")))
8546    (clobber (reg:CC FLAGS_REG))]
8547   ""
8548   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8549
8550 (define_insn "*iorsi_1"
8551   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8552         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8553                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "ix86_binary_operator_ok (IOR, SImode, operands)"
8556   "or{l}\t{%2, %0|%0, %2}"
8557   [(set_attr "type" "alu")
8558    (set_attr "mode" "SI")])
8559
8560 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8561 (define_insn "*iorsi_1_zext"
8562   [(set (match_operand:DI 0 "register_operand" "=rm")
8563         (zero_extend:DI
8564           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8565                   (match_operand:SI 2 "general_operand" "rim"))))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8568   "or{l}\t{%2, %k0|%k0, %2}"
8569   [(set_attr "type" "alu")
8570    (set_attr "mode" "SI")])
8571
8572 (define_insn "*iorsi_1_zext_imm"
8573   [(set (match_operand:DI 0 "register_operand" "=rm")
8574         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8575                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT"
8578   "or{l}\t{%2, %k0|%k0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "mode" "SI")])
8581
8582 (define_insn "*iorsi_2"
8583   [(set (reg FLAGS_REG)
8584         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8585                          (match_operand:SI 2 "general_operand" "rim,ri"))
8586                  (const_int 0)))
8587    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8588         (ior:SI (match_dup 1) (match_dup 2)))]
8589   "ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, SImode, operands)"
8591   "or{l}\t{%2, %0|%0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8596 ;; ??? Special case for immediate operand is missing - it is tricky.
8597 (define_insn "*iorsi_2_zext"
8598   [(set (reg FLAGS_REG)
8599         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8600                          (match_operand:SI 2 "general_operand" "rim"))
8601                  (const_int 0)))
8602    (set (match_operand:DI 0 "register_operand" "=r")
8603         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8604   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, SImode, operands)"
8606   "or{l}\t{%2, %k0|%k0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "SI")])
8609
8610 (define_insn "*iorsi_2_zext_imm"
8611   [(set (reg FLAGS_REG)
8612         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8613                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8614                  (const_int 0)))
8615    (set (match_operand:DI 0 "register_operand" "=r")
8616         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8617   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8618    && ix86_binary_operator_ok (IOR, SImode, operands)"
8619   "or{l}\t{%2, %k0|%k0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "SI")])
8622
8623 (define_insn "*iorsi_3"
8624   [(set (reg FLAGS_REG)
8625         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626                          (match_operand:SI 2 "general_operand" "rim"))
8627                  (const_int 0)))
8628    (clobber (match_scratch:SI 0 "=r"))]
8629   "ix86_match_ccmode (insn, CCNOmode)
8630    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8631   "or{l}\t{%2, %0|%0, %2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "SI")])
8634
8635 (define_expand "iorhi3"
8636   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8637         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8638                 (match_operand:HI 2 "general_operand" "")))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "TARGET_HIMODE_MATH"
8641   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8642
8643 (define_insn "*iorhi_1"
8644   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8645         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8646                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8647    (clobber (reg:CC FLAGS_REG))]
8648   "ix86_binary_operator_ok (IOR, HImode, operands)"
8649   "or{w}\t{%2, %0|%0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "mode" "HI")])
8652
8653 (define_insn "*iorhi_2"
8654   [(set (reg FLAGS_REG)
8655         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8656                          (match_operand:HI 2 "general_operand" "rim,ri"))
8657                  (const_int 0)))
8658    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8659         (ior:HI (match_dup 1) (match_dup 2)))]
8660   "ix86_match_ccmode (insn, CCNOmode)
8661    && ix86_binary_operator_ok (IOR, HImode, operands)"
8662   "or{w}\t{%2, %0|%0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "mode" "HI")])
8665
8666 (define_insn "*iorhi_3"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:HI 2 "general_operand" "rim"))
8670                  (const_int 0)))
8671    (clobber (match_scratch:HI 0 "=r"))]
8672   "ix86_match_ccmode (insn, CCNOmode)
8673    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8674   "or{w}\t{%2, %0|%0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "mode" "HI")])
8677
8678 (define_expand "iorqi3"
8679   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8680         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8681                 (match_operand:QI 2 "general_operand" "")))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "TARGET_QIMODE_MATH"
8684   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8685
8686 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8687 (define_insn "*iorqi_1"
8688   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8689         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8690                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8691    (clobber (reg:CC FLAGS_REG))]
8692   "ix86_binary_operator_ok (IOR, QImode, operands)"
8693   "@
8694    or{b}\t{%2, %0|%0, %2}
8695    or{b}\t{%2, %0|%0, %2}
8696    or{l}\t{%k2, %k0|%k0, %k2}"
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "QI,QI,SI")])
8699
8700 (define_insn "*iorqi_1_slp"
8701   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8702         (ior:QI (match_dup 0)
8703                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8706    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8707   "or{b}\t{%1, %0|%0, %1}"
8708   [(set_attr "type" "alu1")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*iorqi_2"
8712   [(set (reg FLAGS_REG)
8713         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8714                          (match_operand:QI 2 "general_operand" "qim,qi"))
8715                  (const_int 0)))
8716    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8717         (ior:QI (match_dup 1) (match_dup 2)))]
8718   "ix86_match_ccmode (insn, CCNOmode)
8719    && ix86_binary_operator_ok (IOR, QImode, operands)"
8720   "or{b}\t{%2, %0|%0, %2}"
8721   [(set_attr "type" "alu")
8722    (set_attr "mode" "QI")])
8723
8724 (define_insn "*iorqi_2_slp"
8725   [(set (reg FLAGS_REG)
8726         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8727                          (match_operand:QI 1 "general_operand" "qim,qi"))
8728                  (const_int 0)))
8729    (set (strict_low_part (match_dup 0))
8730         (ior:QI (match_dup 0) (match_dup 1)))]
8731   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8732    && ix86_match_ccmode (insn, CCNOmode)
8733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8734   "or{b}\t{%1, %0|%0, %1}"
8735   [(set_attr "type" "alu1")
8736    (set_attr "mode" "QI")])
8737
8738 (define_insn "*iorqi_3"
8739   [(set (reg FLAGS_REG)
8740         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8741                          (match_operand:QI 2 "general_operand" "qim"))
8742                  (const_int 0)))
8743    (clobber (match_scratch:QI 0 "=q"))]
8744   "ix86_match_ccmode (insn, CCNOmode)
8745    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8746   "or{b}\t{%2, %0|%0, %2}"
8747   [(set_attr "type" "alu")
8748    (set_attr "mode" "QI")])
8749
8750 (define_insn "iorqi_ext_0"
8751   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8752                          (const_int 8)
8753                          (const_int 8))
8754         (ior:SI 
8755           (zero_extract:SI
8756             (match_operand 1 "ext_register_operand" "0")
8757             (const_int 8)
8758             (const_int 8))
8759           (match_operand 2 "const_int_operand" "n")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8762   "or{b}\t{%2, %h0|%h0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "length_immediate" "1")
8765    (set_attr "mode" "QI")])
8766
8767 (define_insn "*iorqi_ext_1"
8768   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8769                          (const_int 8)
8770                          (const_int 8))
8771         (ior:SI 
8772           (zero_extract:SI
8773             (match_operand 1 "ext_register_operand" "0")
8774             (const_int 8)
8775             (const_int 8))
8776           (zero_extend:SI
8777             (match_operand:QI 2 "general_operand" "Qm"))))
8778    (clobber (reg:CC FLAGS_REG))]
8779   "!TARGET_64BIT
8780    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8781   "or{b}\t{%2, %h0|%h0, %2}"
8782   [(set_attr "type" "alu")
8783    (set_attr "length_immediate" "0")
8784    (set_attr "mode" "QI")])
8785
8786 (define_insn "*iorqi_ext_1_rex64"
8787   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8788                          (const_int 8)
8789                          (const_int 8))
8790         (ior:SI 
8791           (zero_extract:SI
8792             (match_operand 1 "ext_register_operand" "0")
8793             (const_int 8)
8794             (const_int 8))
8795           (zero_extend:SI
8796             (match_operand 2 "ext_register_operand" "Q"))))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "TARGET_64BIT
8799    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8800   "or{b}\t{%2, %h0|%h0, %2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "length_immediate" "0")
8803    (set_attr "mode" "QI")])
8804
8805 (define_insn "*iorqi_ext_2"
8806   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8807                          (const_int 8)
8808                          (const_int 8))
8809         (ior:SI 
8810           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8811                            (const_int 8)
8812                            (const_int 8))
8813           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8814                            (const_int 8)
8815                            (const_int 8))))
8816    (clobber (reg:CC FLAGS_REG))]
8817   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8818   "ior{b}\t{%h2, %h0|%h0, %h2}"
8819   [(set_attr "type" "alu")
8820    (set_attr "length_immediate" "0")
8821    (set_attr "mode" "QI")])
8822
8823 (define_split
8824   [(set (match_operand 0 "register_operand" "")
8825         (ior (match_operand 1 "register_operand" "")
8826              (match_operand 2 "const_int_operand" "")))
8827    (clobber (reg:CC FLAGS_REG))]
8828    "reload_completed
8829     && QI_REG_P (operands[0])
8830     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831     && !(INTVAL (operands[2]) & ~(255 << 8))
8832     && GET_MODE (operands[0]) != QImode"
8833   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8834                    (ior:SI (zero_extract:SI (match_dup 1)
8835                                             (const_int 8) (const_int 8))
8836                            (match_dup 2)))
8837               (clobber (reg:CC FLAGS_REG))])]
8838   "operands[0] = gen_lowpart (SImode, operands[0]);
8839    operands[1] = gen_lowpart (SImode, operands[1]);
8840    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8841
8842 ;; Since OR can be encoded with sign extended immediate, this is only
8843 ;; profitable when 7th bit is set.
8844 (define_split
8845   [(set (match_operand 0 "register_operand" "")
8846         (ior (match_operand 1 "general_operand" "")
8847              (match_operand 2 "const_int_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849    "reload_completed
8850     && ANY_QI_REG_P (operands[0])
8851     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8852     && !(INTVAL (operands[2]) & ~255)
8853     && (INTVAL (operands[2]) & 128)
8854     && GET_MODE (operands[0]) != QImode"
8855   [(parallel [(set (strict_low_part (match_dup 0))
8856                    (ior:QI (match_dup 1)
8857                            (match_dup 2)))
8858               (clobber (reg:CC FLAGS_REG))])]
8859   "operands[0] = gen_lowpart (QImode, operands[0]);
8860    operands[1] = gen_lowpart (QImode, operands[1]);
8861    operands[2] = gen_lowpart (QImode, operands[2]);")
8862 \f
8863 ;; Logical XOR instructions
8864
8865 ;; %%% This used to optimize known byte-wide and operations to memory.
8866 ;; If this is considered useful, it should be done with splitters.
8867
8868 (define_expand "xordi3"
8869   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8870         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8871                 (match_operand:DI 2 "x86_64_general_operand" "")))
8872    (clobber (reg:CC FLAGS_REG))]
8873   "TARGET_64BIT"
8874   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8875
8876 (define_insn "*xordi_1_rex64"
8877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8878         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8879                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "TARGET_64BIT
8882    && ix86_binary_operator_ok (XOR, DImode, operands)"
8883   "@
8884    xor{q}\t{%2, %0|%0, %2}
8885    xor{q}\t{%2, %0|%0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "DI,DI")])
8888
8889 (define_insn "*xordi_2_rex64"
8890   [(set (reg FLAGS_REG)
8891         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8893                  (const_int 0)))
8894    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8895         (xor:DI (match_dup 1) (match_dup 2)))]
8896   "TARGET_64BIT
8897    && ix86_match_ccmode (insn, CCNOmode)
8898    && ix86_binary_operator_ok (XOR, DImode, operands)"
8899   "@
8900    xor{q}\t{%2, %0|%0, %2}
8901    xor{q}\t{%2, %0|%0, %2}"
8902   [(set_attr "type" "alu")
8903    (set_attr "mode" "DI,DI")])
8904
8905 (define_insn "*xordi_3_rex64"
8906   [(set (reg FLAGS_REG)
8907         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8908                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8909                  (const_int 0)))
8910    (clobber (match_scratch:DI 0 "=r"))]
8911   "TARGET_64BIT
8912    && ix86_match_ccmode (insn, CCNOmode)
8913    && ix86_binary_operator_ok (XOR, DImode, operands)"
8914   "xor{q}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "DI")])
8917
8918 (define_expand "xorsi3"
8919   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8920         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8921                 (match_operand:SI 2 "general_operand" "")))
8922    (clobber (reg:CC FLAGS_REG))]
8923   ""
8924   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8925
8926 (define_insn "*xorsi_1"
8927   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8928         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8929                 (match_operand:SI 2 "general_operand" "ri,rm")))
8930    (clobber (reg:CC FLAGS_REG))]
8931   "ix86_binary_operator_ok (XOR, SImode, operands)"
8932   "xor{l}\t{%2, %0|%0, %2}"
8933   [(set_attr "type" "alu")
8934    (set_attr "mode" "SI")])
8935
8936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8937 ;; Add speccase for immediates
8938 (define_insn "*xorsi_1_zext"
8939   [(set (match_operand:DI 0 "register_operand" "=r")
8940         (zero_extend:DI
8941           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942                   (match_operand:SI 2 "general_operand" "rim"))))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8945   "xor{l}\t{%2, %k0|%k0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "SI")])
8948
8949 (define_insn "*xorsi_1_zext_imm"
8950   [(set (match_operand:DI 0 "register_operand" "=r")
8951         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8952                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8953    (clobber (reg:CC FLAGS_REG))]
8954   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8955   "xor{l}\t{%2, %k0|%k0, %2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "mode" "SI")])
8958
8959 (define_insn "*xorsi_2"
8960   [(set (reg FLAGS_REG)
8961         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8962                          (match_operand:SI 2 "general_operand" "rim,ri"))
8963                  (const_int 0)))
8964    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8965         (xor:SI (match_dup 1) (match_dup 2)))]
8966   "ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, SImode, operands)"
8968   "xor{l}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "SI")])
8971
8972 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8973 ;; ??? Special case for immediate operand is missing - it is tricky.
8974 (define_insn "*xorsi_2_zext"
8975   [(set (reg FLAGS_REG)
8976         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8977                          (match_operand:SI 2 "general_operand" "rim"))
8978                  (const_int 0)))
8979    (set (match_operand:DI 0 "register_operand" "=r")
8980         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8981   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, SImode, operands)"
8983   "xor{l}\t{%2, %k0|%k0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8986
8987 (define_insn "*xorsi_2_zext_imm"
8988   [(set (reg FLAGS_REG)
8989         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8991                  (const_int 0)))
8992    (set (match_operand:DI 0 "register_operand" "=r")
8993         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8995    && ix86_binary_operator_ok (XOR, SImode, operands)"
8996   "xor{l}\t{%2, %k0|%k0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "mode" "SI")])
8999
9000 (define_insn "*xorsi_3"
9001   [(set (reg FLAGS_REG)
9002         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003                          (match_operand:SI 2 "general_operand" "rim"))
9004                  (const_int 0)))
9005    (clobber (match_scratch:SI 0 "=r"))]
9006   "ix86_match_ccmode (insn, CCNOmode)
9007    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9008   "xor{l}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "SI")])
9011
9012 (define_expand "xorhi3"
9013   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9014         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9015                 (match_operand:HI 2 "general_operand" "")))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_HIMODE_MATH"
9018   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9019
9020 (define_insn "*xorhi_1"
9021   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9022         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9023                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "ix86_binary_operator_ok (XOR, HImode, operands)"
9026   "xor{w}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "HI")])
9029
9030 (define_insn "*xorhi_2"
9031   [(set (reg FLAGS_REG)
9032         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9033                          (match_operand:HI 2 "general_operand" "rim,ri"))
9034                  (const_int 0)))
9035    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9036         (xor:HI (match_dup 1) (match_dup 2)))]
9037   "ix86_match_ccmode (insn, CCNOmode)
9038    && ix86_binary_operator_ok (XOR, HImode, operands)"
9039   "xor{w}\t{%2, %0|%0, %2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "mode" "HI")])
9042
9043 (define_insn "*xorhi_3"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9046                          (match_operand:HI 2 "general_operand" "rim"))
9047                  (const_int 0)))
9048    (clobber (match_scratch:HI 0 "=r"))]
9049   "ix86_match_ccmode (insn, CCNOmode)
9050    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9051   "xor{w}\t{%2, %0|%0, %2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "mode" "HI")])
9054
9055 (define_expand "xorqi3"
9056   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9057         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9058                 (match_operand:QI 2 "general_operand" "")))
9059    (clobber (reg:CC FLAGS_REG))]
9060   "TARGET_QIMODE_MATH"
9061   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9062
9063 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9064 (define_insn "*xorqi_1"
9065   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9066         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9067                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "ix86_binary_operator_ok (XOR, QImode, operands)"
9070   "@
9071    xor{b}\t{%2, %0|%0, %2}
9072    xor{b}\t{%2, %0|%0, %2}
9073    xor{l}\t{%k2, %k0|%k0, %k2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "mode" "QI,QI,SI")])
9076
9077 (define_insn "*xorqi_1_slp"
9078   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9079         (xor:QI (match_dup 0)
9080                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9083    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9084   "xor{b}\t{%1, %0|%0, %1}"
9085   [(set_attr "type" "alu1")
9086    (set_attr "mode" "QI")])
9087
9088 (define_insn "xorqi_ext_0"
9089   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090                          (const_int 8)
9091                          (const_int 8))
9092         (xor:SI 
9093           (zero_extract:SI
9094             (match_operand 1 "ext_register_operand" "0")
9095             (const_int 8)
9096             (const_int 8))
9097           (match_operand 2 "const_int_operand" "n")))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100   "xor{b}\t{%2, %h0|%h0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "length_immediate" "1")
9103    (set_attr "mode" "QI")])
9104
9105 (define_insn "*xorqi_ext_1"
9106   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9107                          (const_int 8)
9108                          (const_int 8))
9109         (xor:SI 
9110           (zero_extract:SI
9111             (match_operand 1 "ext_register_operand" "0")
9112             (const_int 8)
9113             (const_int 8))
9114           (zero_extend:SI
9115             (match_operand:QI 2 "general_operand" "Qm"))))
9116    (clobber (reg:CC FLAGS_REG))]
9117   "!TARGET_64BIT
9118    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9119   "xor{b}\t{%2, %h0|%h0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "length_immediate" "0")
9122    (set_attr "mode" "QI")])
9123
9124 (define_insn "*xorqi_ext_1_rex64"
9125   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9126                          (const_int 8)
9127                          (const_int 8))
9128         (xor:SI 
9129           (zero_extract:SI
9130             (match_operand 1 "ext_register_operand" "0")
9131             (const_int 8)
9132             (const_int 8))
9133           (zero_extend:SI
9134             (match_operand 2 "ext_register_operand" "Q"))))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "TARGET_64BIT
9137    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138   "xor{b}\t{%2, %h0|%h0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "length_immediate" "0")
9141    (set_attr "mode" "QI")])
9142
9143 (define_insn "*xorqi_ext_2"
9144   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145                          (const_int 8)
9146                          (const_int 8))
9147         (xor:SI 
9148           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9149                            (const_int 8)
9150                            (const_int 8))
9151           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9152                            (const_int 8)
9153                            (const_int 8))))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9156   "xor{b}\t{%h2, %h0|%h0, %h2}"
9157   [(set_attr "type" "alu")
9158    (set_attr "length_immediate" "0")
9159    (set_attr "mode" "QI")])
9160
9161 (define_insn "*xorqi_cc_1"
9162   [(set (reg FLAGS_REG)
9163         (compare
9164           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9165                   (match_operand:QI 2 "general_operand" "qim,qi"))
9166           (const_int 0)))
9167    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9168         (xor:QI (match_dup 1) (match_dup 2)))]
9169   "ix86_match_ccmode (insn, CCNOmode)
9170    && ix86_binary_operator_ok (XOR, QImode, operands)"
9171   "xor{b}\t{%2, %0|%0, %2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_2_slp"
9176   [(set (reg FLAGS_REG)
9177         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9178                          (match_operand:QI 1 "general_operand" "qim,qi"))
9179                  (const_int 0)))
9180    (set (strict_low_part (match_dup 0))
9181         (xor:QI (match_dup 0) (match_dup 1)))]
9182   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9183    && ix86_match_ccmode (insn, CCNOmode)
9184    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9185   "xor{b}\t{%1, %0|%0, %1}"
9186   [(set_attr "type" "alu1")
9187    (set_attr "mode" "QI")])
9188
9189 (define_insn "*xorqi_cc_2"
9190   [(set (reg FLAGS_REG)
9191         (compare
9192           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9193                   (match_operand:QI 2 "general_operand" "qim"))
9194           (const_int 0)))
9195    (clobber (match_scratch:QI 0 "=q"))]
9196   "ix86_match_ccmode (insn, CCNOmode)
9197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9198   "xor{b}\t{%2, %0|%0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_ext_1"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:SI
9206             (zero_extract:SI
9207               (match_operand 1 "ext_register_operand" "0")
9208               (const_int 8)
9209               (const_int 8))
9210             (match_operand:QI 2 "general_operand" "qmn"))
9211           (const_int 0)))
9212    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI 
9216           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9217           (match_dup 2)))]
9218   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219   "xor{b}\t{%2, %h0|%h0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9222
9223 (define_insn "*xorqi_cc_ext_1_rex64"
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 "nonmemory_operand" "Qn"))
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_expand "xorqi_cc_ext_1"
9245   [(parallel [
9246      (set (reg:CCNO FLAGS_REG)
9247           (compare:CCNO
9248             (xor:SI
9249               (zero_extract:SI
9250                 (match_operand 1 "ext_register_operand" "")
9251                 (const_int 8)
9252                 (const_int 8))
9253               (match_operand:QI 2 "general_operand" ""))
9254             (const_int 0)))
9255      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9256                            (const_int 8)
9257                            (const_int 8))
9258           (xor:SI 
9259             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9260             (match_dup 2)))])]
9261   ""
9262   "")
9263
9264 (define_split
9265   [(set (match_operand 0 "register_operand" "")
9266         (xor (match_operand 1 "register_operand" "")
9267              (match_operand 2 "const_int_operand" "")))
9268    (clobber (reg:CC FLAGS_REG))]
9269    "reload_completed
9270     && QI_REG_P (operands[0])
9271     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272     && !(INTVAL (operands[2]) & ~(255 << 8))
9273     && GET_MODE (operands[0]) != QImode"
9274   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9275                    (xor:SI (zero_extract:SI (match_dup 1)
9276                                             (const_int 8) (const_int 8))
9277                            (match_dup 2)))
9278               (clobber (reg:CC FLAGS_REG))])]
9279   "operands[0] = gen_lowpart (SImode, operands[0]);
9280    operands[1] = gen_lowpart (SImode, operands[1]);
9281    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9282
9283 ;; Since XOR can be encoded with sign extended immediate, this is only
9284 ;; profitable when 7th bit is set.
9285 (define_split
9286   [(set (match_operand 0 "register_operand" "")
9287         (xor (match_operand 1 "general_operand" "")
9288              (match_operand 2 "const_int_operand" "")))
9289    (clobber (reg:CC FLAGS_REG))]
9290    "reload_completed
9291     && ANY_QI_REG_P (operands[0])
9292     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9293     && !(INTVAL (operands[2]) & ~255)
9294     && (INTVAL (operands[2]) & 128)
9295     && GET_MODE (operands[0]) != QImode"
9296   [(parallel [(set (strict_low_part (match_dup 0))
9297                    (xor:QI (match_dup 1)
9298                            (match_dup 2)))
9299               (clobber (reg:CC FLAGS_REG))])]
9300   "operands[0] = gen_lowpart (QImode, operands[0]);
9301    operands[1] = gen_lowpart (QImode, operands[1]);
9302    operands[2] = gen_lowpart (QImode, operands[2]);")
9303 \f
9304 ;; Negation instructions
9305
9306 (define_expand "negti2"
9307   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9308                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9309               (clobber (reg:CC FLAGS_REG))])]
9310   "TARGET_64BIT"
9311   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9312
9313 (define_insn "*negti2_1"
9314   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9315         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_64BIT
9318    && ix86_unary_operator_ok (NEG, TImode, operands)"
9319   "#")
9320
9321 (define_split
9322   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9323         (neg:TI (match_operand:TI 1 "general_operand" "")))
9324    (clobber (reg:CC FLAGS_REG))]
9325   "TARGET_64BIT && reload_completed"
9326   [(parallel
9327     [(set (reg:CCZ FLAGS_REG)
9328           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9329      (set (match_dup 0) (neg:DI (match_dup 2)))])
9330    (parallel
9331     [(set (match_dup 1)
9332           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9333                             (match_dup 3))
9334                    (const_int 0)))
9335      (clobber (reg:CC FLAGS_REG))])
9336    (parallel
9337     [(set (match_dup 1)
9338           (neg:DI (match_dup 1)))
9339      (clobber (reg:CC FLAGS_REG))])]
9340   "split_ti (operands+1, 1, operands+2, operands+3);
9341    split_ti (operands+0, 1, operands+0, operands+1);")
9342
9343 (define_expand "negdi2"
9344   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9345                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9346               (clobber (reg:CC FLAGS_REG))])]
9347   ""
9348   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9349
9350 (define_insn "*negdi2_1"
9351   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9352         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "!TARGET_64BIT
9355    && ix86_unary_operator_ok (NEG, DImode, operands)"
9356   "#")
9357
9358 (define_split
9359   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9360         (neg:DI (match_operand:DI 1 "general_operand" "")))
9361    (clobber (reg:CC FLAGS_REG))]
9362   "!TARGET_64BIT && reload_completed"
9363   [(parallel
9364     [(set (reg:CCZ FLAGS_REG)
9365           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9366      (set (match_dup 0) (neg:SI (match_dup 2)))])
9367    (parallel
9368     [(set (match_dup 1)
9369           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9370                             (match_dup 3))
9371                    (const_int 0)))
9372      (clobber (reg:CC FLAGS_REG))])
9373    (parallel
9374     [(set (match_dup 1)
9375           (neg:SI (match_dup 1)))
9376      (clobber (reg:CC FLAGS_REG))])]
9377   "split_di (operands+1, 1, operands+2, operands+3);
9378    split_di (operands+0, 1, operands+0, operands+1);")
9379
9380 (define_insn "*negdi2_1_rex64"
9381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9382         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9385   "neg{q}\t%0"
9386   [(set_attr "type" "negnot")
9387    (set_attr "mode" "DI")])
9388
9389 ;; The problem with neg is that it does not perform (compare x 0),
9390 ;; it really performs (compare 0 x), which leaves us with the zero
9391 ;; flag being the only useful item.
9392
9393 (define_insn "*negdi2_cmpz_rex64"
9394   [(set (reg:CCZ FLAGS_REG)
9395         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9396                      (const_int 0)))
9397    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9398         (neg:DI (match_dup 1)))]
9399   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9400   "neg{q}\t%0"
9401   [(set_attr "type" "negnot")
9402    (set_attr "mode" "DI")])
9403
9404
9405 (define_expand "negsi2"
9406   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9407                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9408               (clobber (reg:CC FLAGS_REG))])]
9409   ""
9410   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9411
9412 (define_insn "*negsi2_1"
9413   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9414         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "ix86_unary_operator_ok (NEG, SImode, operands)"
9417   "neg{l}\t%0"
9418   [(set_attr "type" "negnot")
9419    (set_attr "mode" "SI")])
9420
9421 ;; Combine is quite creative about this pattern.
9422 (define_insn "*negsi2_1_zext"
9423   [(set (match_operand:DI 0 "register_operand" "=r")
9424         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9425                                         (const_int 32)))
9426                      (const_int 32)))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9429   "neg{l}\t%k0"
9430   [(set_attr "type" "negnot")
9431    (set_attr "mode" "SI")])
9432
9433 ;; The problem with neg is that it does not perform (compare x 0),
9434 ;; it really performs (compare 0 x), which leaves us with the zero
9435 ;; flag being the only useful item.
9436
9437 (define_insn "*negsi2_cmpz"
9438   [(set (reg:CCZ FLAGS_REG)
9439         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9440                      (const_int 0)))
9441    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9442         (neg:SI (match_dup 1)))]
9443   "ix86_unary_operator_ok (NEG, SImode, operands)"
9444   "neg{l}\t%0"
9445   [(set_attr "type" "negnot")
9446    (set_attr "mode" "SI")])
9447
9448 (define_insn "*negsi2_cmpz_zext"
9449   [(set (reg:CCZ FLAGS_REG)
9450         (compare:CCZ (lshiftrt:DI
9451                        (neg:DI (ashift:DI
9452                                  (match_operand:DI 1 "register_operand" "0")
9453                                  (const_int 32)))
9454                        (const_int 32))
9455                      (const_int 0)))
9456    (set (match_operand:DI 0 "register_operand" "=r")
9457         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9458                                         (const_int 32)))
9459                      (const_int 32)))]
9460   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9461   "neg{l}\t%k0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "SI")])
9464
9465 (define_expand "neghi2"
9466   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9467                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9468               (clobber (reg:CC FLAGS_REG))])]
9469   "TARGET_HIMODE_MATH"
9470   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9471
9472 (define_insn "*neghi2_1"
9473   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9474         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "ix86_unary_operator_ok (NEG, HImode, operands)"
9477   "neg{w}\t%0"
9478   [(set_attr "type" "negnot")
9479    (set_attr "mode" "HI")])
9480
9481 (define_insn "*neghi2_cmpz"
9482   [(set (reg:CCZ FLAGS_REG)
9483         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9484                      (const_int 0)))
9485    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9486         (neg:HI (match_dup 1)))]
9487   "ix86_unary_operator_ok (NEG, HImode, operands)"
9488   "neg{w}\t%0"
9489   [(set_attr "type" "negnot")
9490    (set_attr "mode" "HI")])
9491
9492 (define_expand "negqi2"
9493   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9494                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9495               (clobber (reg:CC FLAGS_REG))])]
9496   "TARGET_QIMODE_MATH"
9497   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9498
9499 (define_insn "*negqi2_1"
9500   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9501         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "ix86_unary_operator_ok (NEG, QImode, operands)"
9504   "neg{b}\t%0"
9505   [(set_attr "type" "negnot")
9506    (set_attr "mode" "QI")])
9507
9508 (define_insn "*negqi2_cmpz"
9509   [(set (reg:CCZ FLAGS_REG)
9510         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9511                      (const_int 0)))
9512    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9513         (neg:QI (match_dup 1)))]
9514   "ix86_unary_operator_ok (NEG, QImode, operands)"
9515   "neg{b}\t%0"
9516   [(set_attr "type" "negnot")
9517    (set_attr "mode" "QI")])
9518
9519 ;; Changing of sign for FP values is doable using integer unit too.
9520
9521 (define_expand "negsf2"
9522   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9523         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9524   "TARGET_80387 || TARGET_SSE_MATH"
9525   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9526
9527 (define_expand "abssf2"
9528   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9529         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9530   "TARGET_80387 || TARGET_SSE_MATH"
9531   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9532
9533 (define_insn "*absnegsf2_mixed"
9534   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9535         (match_operator:SF 3 "absneg_operator"
9536           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9537    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9538    (clobber (reg:CC FLAGS_REG))]
9539   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9540    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9541   "#")
9542
9543 (define_insn "*absnegsf2_sse"
9544   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9545         (match_operator:SF 3 "absneg_operator"
9546           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9547    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9548    (clobber (reg:CC FLAGS_REG))]
9549   "TARGET_SSE_MATH
9550    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9551   "#")
9552
9553 (define_insn "*absnegsf2_i387"
9554   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9555         (match_operator:SF 3 "absneg_operator"
9556           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9557    (use (match_operand 2 "" ""))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "TARGET_80387 && !TARGET_SSE_MATH
9560    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9561   "#")
9562
9563 (define_expand "copysignsf3"
9564   [(match_operand:SF 0 "register_operand" "")
9565    (match_operand:SF 1 "nonmemory_operand" "")
9566    (match_operand:SF 2 "register_operand" "")]
9567   "TARGET_SSE_MATH"
9568 {
9569   ix86_expand_copysign (operands);
9570   DONE;
9571 })
9572
9573 (define_insn_and_split "copysignsf3_const"
9574   [(set (match_operand:SF 0 "register_operand"          "=x")
9575         (unspec:SF
9576           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9577            (match_operand:SF 2 "register_operand"       "0")
9578            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9579           UNSPEC_COPYSIGN))]
9580   "TARGET_SSE_MATH"
9581   "#"
9582   "&& reload_completed"
9583   [(const_int 0)]
9584 {
9585   ix86_split_copysign_const (operands);
9586   DONE;
9587 })
9588
9589 (define_insn "copysignsf3_var"
9590   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9591         (unspec:SF
9592           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9593            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9594            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9595            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9596           UNSPEC_COPYSIGN))
9597    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9598   "TARGET_SSE_MATH"
9599   "#")
9600
9601 (define_split
9602   [(set (match_operand:SF 0 "register_operand" "")
9603         (unspec:SF
9604           [(match_operand:SF 2 "register_operand" "")
9605            (match_operand:SF 3 "register_operand" "")
9606            (match_operand:V4SF 4 "" "")
9607            (match_operand:V4SF 5 "" "")]
9608           UNSPEC_COPYSIGN))
9609    (clobber (match_scratch:V4SF 1 ""))]
9610   "TARGET_SSE_MATH && reload_completed"
9611   [(const_int 0)]
9612 {
9613   ix86_split_copysign_var (operands);
9614   DONE;
9615 })
9616
9617 (define_expand "negdf2"
9618   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9619         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9620   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9621   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9622
9623 (define_expand "absdf2"
9624   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9625         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9626   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9627   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9628
9629 (define_insn "*absnegdf2_mixed"
9630   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9631         (match_operator:DF 3 "absneg_operator"
9632           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9633    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9636    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9637   "#")
9638
9639 (define_insn "*absnegdf2_sse"
9640   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9641         (match_operator:DF 3 "absneg_operator"
9642           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9643    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "TARGET_SSE2 && TARGET_SSE_MATH
9646    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9647   "#")
9648
9649 (define_insn "*absnegdf2_i387"
9650   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9651         (match_operator:DF 3 "absneg_operator"
9652           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9653    (use (match_operand 2 "" ""))
9654    (clobber (reg:CC FLAGS_REG))]
9655   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9656    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9657   "#")
9658
9659 (define_expand "copysigndf3"
9660   [(match_operand:DF 0 "register_operand" "")
9661    (match_operand:DF 1 "nonmemory_operand" "")
9662    (match_operand:DF 2 "register_operand" "")]
9663   "TARGET_SSE2 && TARGET_SSE_MATH"
9664 {
9665   ix86_expand_copysign (operands);
9666   DONE;
9667 })
9668
9669 (define_insn_and_split "copysigndf3_const"
9670   [(set (match_operand:DF 0 "register_operand"          "=x")
9671         (unspec:DF
9672           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9673            (match_operand:DF 2 "register_operand"       "0")
9674            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9675           UNSPEC_COPYSIGN))]
9676   "TARGET_SSE2 && TARGET_SSE_MATH"
9677   "#"
9678   "&& reload_completed"
9679   [(const_int 0)]
9680 {
9681   ix86_split_copysign_const (operands);
9682   DONE;
9683 })
9684
9685 (define_insn "copysigndf3_var"
9686   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9687         (unspec:DF
9688           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9689            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9690            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9691            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9692           UNSPEC_COPYSIGN))
9693    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9694   "TARGET_SSE2 && TARGET_SSE_MATH"
9695   "#")
9696
9697 (define_split
9698   [(set (match_operand:DF 0 "register_operand" "")
9699         (unspec:DF
9700           [(match_operand:DF 2 "register_operand" "")
9701            (match_operand:DF 3 "register_operand" "")
9702            (match_operand:V2DF 4 "" "")
9703            (match_operand:V2DF 5 "" "")]
9704           UNSPEC_COPYSIGN))
9705    (clobber (match_scratch:V2DF 1 ""))]
9706   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9707   [(const_int 0)]
9708 {
9709   ix86_split_copysign_var (operands);
9710   DONE;
9711 })
9712
9713 (define_expand "negxf2"
9714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9715         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9716   "TARGET_80387"
9717   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9718
9719 (define_expand "absxf2"
9720   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9721         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9722   "TARGET_80387"
9723   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9724
9725 (define_insn "*absnegxf2_i387"
9726   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9727         (match_operator:XF 3 "absneg_operator"
9728           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9729    (use (match_operand 2 "" ""))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "TARGET_80387
9732    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9733   "#")
9734
9735 ;; Splitters for fp abs and neg.
9736
9737 (define_split
9738   [(set (match_operand 0 "fp_register_operand" "")
9739         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9740    (use (match_operand 2 "" ""))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "reload_completed"
9743   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9744
9745 (define_split
9746   [(set (match_operand 0 "register_operand" "")
9747         (match_operator 3 "absneg_operator"
9748           [(match_operand 1 "register_operand" "")]))
9749    (use (match_operand 2 "nonimmediate_operand" ""))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "reload_completed && SSE_REG_P (operands[0])"
9752   [(set (match_dup 0) (match_dup 3))]
9753 {
9754   enum machine_mode mode = GET_MODE (operands[0]);
9755   enum machine_mode vmode = GET_MODE (operands[2]);
9756   rtx tmp;
9757   
9758   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9759   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9760   if (operands_match_p (operands[0], operands[2]))
9761     {
9762       tmp = operands[1];
9763       operands[1] = operands[2];
9764       operands[2] = tmp;
9765     }
9766   if (GET_CODE (operands[3]) == ABS)
9767     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9768   else
9769     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9770   operands[3] = tmp;
9771 })
9772
9773 (define_split
9774   [(set (match_operand:SF 0 "register_operand" "")
9775         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9776    (use (match_operand:V4SF 2 "" ""))
9777    (clobber (reg:CC FLAGS_REG))]
9778   "reload_completed"
9779   [(parallel [(set (match_dup 0) (match_dup 1))
9780               (clobber (reg:CC FLAGS_REG))])]
9781
9782   rtx tmp;
9783   operands[0] = gen_lowpart (SImode, operands[0]);
9784   if (GET_CODE (operands[1]) == ABS)
9785     {
9786       tmp = gen_int_mode (0x7fffffff, SImode);
9787       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9788     }
9789   else
9790     {
9791       tmp = gen_int_mode (0x80000000, SImode);
9792       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9793     }
9794   operands[1] = tmp;
9795 })
9796
9797 (define_split
9798   [(set (match_operand:DF 0 "register_operand" "")
9799         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9800    (use (match_operand 2 "" ""))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "reload_completed"
9803   [(parallel [(set (match_dup 0) (match_dup 1))
9804               (clobber (reg:CC FLAGS_REG))])]
9805 {
9806   rtx tmp;
9807   if (TARGET_64BIT)
9808     {
9809       tmp = gen_lowpart (DImode, operands[0]);
9810       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9811       operands[0] = tmp;
9812
9813       if (GET_CODE (operands[1]) == ABS)
9814         tmp = const0_rtx;
9815       else
9816         tmp = gen_rtx_NOT (DImode, tmp);
9817     }
9818   else
9819     {
9820       operands[0] = gen_highpart (SImode, operands[0]);
9821       if (GET_CODE (operands[1]) == ABS)
9822         {
9823           tmp = gen_int_mode (0x7fffffff, SImode);
9824           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9825         }
9826       else
9827         {
9828           tmp = gen_int_mode (0x80000000, SImode);
9829           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9830         }
9831     }
9832   operands[1] = tmp;
9833 })
9834
9835 (define_split
9836   [(set (match_operand:XF 0 "register_operand" "")
9837         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9838    (use (match_operand 2 "" ""))
9839    (clobber (reg:CC FLAGS_REG))]
9840   "reload_completed"
9841   [(parallel [(set (match_dup 0) (match_dup 1))
9842               (clobber (reg:CC FLAGS_REG))])]
9843 {
9844   rtx tmp;
9845   operands[0] = gen_rtx_REG (SImode,
9846                              true_regnum (operands[0])
9847                              + (TARGET_64BIT ? 1 : 2));
9848   if (GET_CODE (operands[1]) == ABS)
9849     {
9850       tmp = GEN_INT (0x7fff);
9851       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9852     }
9853   else
9854     {
9855       tmp = GEN_INT (0x8000);
9856       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9857     }
9858   operands[1] = tmp;
9859 })
9860
9861 (define_split
9862   [(set (match_operand 0 "memory_operand" "")
9863         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9864    (use (match_operand 2 "" ""))
9865    (clobber (reg:CC FLAGS_REG))]
9866   "reload_completed"
9867   [(parallel [(set (match_dup 0) (match_dup 1))
9868               (clobber (reg:CC FLAGS_REG))])]
9869 {
9870   enum machine_mode mode = GET_MODE (operands[0]);
9871   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9872   rtx tmp;
9873
9874   operands[0] = adjust_address (operands[0], QImode, size - 1);
9875   if (GET_CODE (operands[1]) == ABS)
9876     {
9877       tmp = gen_int_mode (0x7f, QImode);
9878       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9879     }
9880   else
9881     {
9882       tmp = gen_int_mode (0x80, QImode);
9883       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9884     }
9885   operands[1] = tmp;
9886 })
9887
9888 ;; Conditionalize these after reload. If they match before reload, we 
9889 ;; lose the clobber and ability to use integer instructions.
9890
9891 (define_insn "*negsf2_1"
9892   [(set (match_operand:SF 0 "register_operand" "=f")
9893         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9894   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9895   "fchs"
9896   [(set_attr "type" "fsgn")
9897    (set_attr "mode" "SF")])
9898
9899 (define_insn "*negdf2_1"
9900   [(set (match_operand:DF 0 "register_operand" "=f")
9901         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9902   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9903   "fchs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "DF")])
9906
9907 (define_insn "*negxf2_1"
9908   [(set (match_operand:XF 0 "register_operand" "=f")
9909         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9910   "TARGET_80387"
9911   "fchs"
9912   [(set_attr "type" "fsgn")
9913    (set_attr "mode" "XF")])
9914
9915 (define_insn "*abssf2_1"
9916   [(set (match_operand:SF 0 "register_operand" "=f")
9917         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9918   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9919   "fabs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "SF")])
9922
9923 (define_insn "*absdf2_1"
9924   [(set (match_operand:DF 0 "register_operand" "=f")
9925         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9926   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9927   "fabs"
9928   [(set_attr "type" "fsgn")
9929    (set_attr "mode" "DF")])
9930
9931 (define_insn "*absxf2_1"
9932   [(set (match_operand:XF 0 "register_operand" "=f")
9933         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9934   "TARGET_80387"
9935   "fabs"
9936   [(set_attr "type" "fsgn")
9937    (set_attr "mode" "DF")])
9938
9939 (define_insn "*negextendsfdf2"
9940   [(set (match_operand:DF 0 "register_operand" "=f")
9941         (neg:DF (float_extend:DF
9942                   (match_operand:SF 1 "register_operand" "0"))))]
9943   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9944   "fchs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "DF")])
9947
9948 (define_insn "*negextenddfxf2"
9949   [(set (match_operand:XF 0 "register_operand" "=f")
9950         (neg:XF (float_extend:XF
9951                   (match_operand:DF 1 "register_operand" "0"))))]
9952   "TARGET_80387"
9953   "fchs"
9954   [(set_attr "type" "fsgn")
9955    (set_attr "mode" "XF")])
9956
9957 (define_insn "*negextendsfxf2"
9958   [(set (match_operand:XF 0 "register_operand" "=f")
9959         (neg:XF (float_extend:XF
9960                   (match_operand:SF 1 "register_operand" "0"))))]
9961   "TARGET_80387"
9962   "fchs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")])
9965
9966 (define_insn "*absextendsfdf2"
9967   [(set (match_operand:DF 0 "register_operand" "=f")
9968         (abs:DF (float_extend:DF
9969                   (match_operand:SF 1 "register_operand" "0"))))]
9970   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9971   "fabs"
9972   [(set_attr "type" "fsgn")
9973    (set_attr "mode" "DF")])
9974
9975 (define_insn "*absextenddfxf2"
9976   [(set (match_operand:XF 0 "register_operand" "=f")
9977         (abs:XF (float_extend:XF
9978           (match_operand:DF 1 "register_operand" "0"))))]
9979   "TARGET_80387"
9980   "fabs"
9981   [(set_attr "type" "fsgn")
9982    (set_attr "mode" "XF")])
9983
9984 (define_insn "*absextendsfxf2"
9985   [(set (match_operand:XF 0 "register_operand" "=f")
9986         (abs:XF (float_extend:XF
9987           (match_operand:SF 1 "register_operand" "0"))))]
9988   "TARGET_80387"
9989   "fabs"
9990   [(set_attr "type" "fsgn")
9991    (set_attr "mode" "XF")])
9992 \f
9993 ;; One complement instructions
9994
9995 (define_expand "one_cmpldi2"
9996   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9997         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9998   "TARGET_64BIT"
9999   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10000
10001 (define_insn "*one_cmpldi2_1_rex64"
10002   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10003         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10004   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10005   "not{q}\t%0"
10006   [(set_attr "type" "negnot")
10007    (set_attr "mode" "DI")])
10008
10009 (define_insn "*one_cmpldi2_2_rex64"
10010   [(set (reg FLAGS_REG)
10011         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10012                  (const_int 0)))
10013    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10014         (not:DI (match_dup 1)))]
10015   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10016    && ix86_unary_operator_ok (NOT, DImode, operands)"
10017   "#"
10018   [(set_attr "type" "alu1")
10019    (set_attr "mode" "DI")])
10020
10021 (define_split
10022   [(set (match_operand 0 "flags_reg_operand" "")
10023         (match_operator 2 "compare_operator"
10024           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10025            (const_int 0)]))
10026    (set (match_operand:DI 1 "nonimmediate_operand" "")
10027         (not:DI (match_dup 3)))]
10028   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10029   [(parallel [(set (match_dup 0)
10030                    (match_op_dup 2
10031                      [(xor:DI (match_dup 3) (const_int -1))
10032                       (const_int 0)]))
10033               (set (match_dup 1)
10034                    (xor:DI (match_dup 3) (const_int -1)))])]
10035   "")
10036
10037 (define_expand "one_cmplsi2"
10038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10039         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10040   ""
10041   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10042
10043 (define_insn "*one_cmplsi2_1"
10044   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10045         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10046   "ix86_unary_operator_ok (NOT, SImode, operands)"
10047   "not{l}\t%0"
10048   [(set_attr "type" "negnot")
10049    (set_attr "mode" "SI")])
10050
10051 ;; ??? Currently never generated - xor is used instead.
10052 (define_insn "*one_cmplsi2_1_zext"
10053   [(set (match_operand:DI 0 "register_operand" "=r")
10054         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10055   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10056   "not{l}\t%k0"
10057   [(set_attr "type" "negnot")
10058    (set_attr "mode" "SI")])
10059
10060 (define_insn "*one_cmplsi2_2"
10061   [(set (reg FLAGS_REG)
10062         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10063                  (const_int 0)))
10064    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065         (not:SI (match_dup 1)))]
10066   "ix86_match_ccmode (insn, CCNOmode)
10067    && ix86_unary_operator_ok (NOT, SImode, operands)"
10068   "#"
10069   [(set_attr "type" "alu1")
10070    (set_attr "mode" "SI")])
10071
10072 (define_split
10073   [(set (match_operand 0 "flags_reg_operand" "")
10074         (match_operator 2 "compare_operator"
10075           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10076            (const_int 0)]))
10077    (set (match_operand:SI 1 "nonimmediate_operand" "")
10078         (not:SI (match_dup 3)))]
10079   "ix86_match_ccmode (insn, CCNOmode)"
10080   [(parallel [(set (match_dup 0)
10081                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10082                                     (const_int 0)]))
10083               (set (match_dup 1)
10084                    (xor:SI (match_dup 3) (const_int -1)))])]
10085   "")
10086
10087 ;; ??? Currently never generated - xor is used instead.
10088 (define_insn "*one_cmplsi2_2_zext"
10089   [(set (reg FLAGS_REG)
10090         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10091                  (const_int 0)))
10092    (set (match_operand:DI 0 "register_operand" "=r")
10093         (zero_extend:DI (not:SI (match_dup 1))))]
10094   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10095    && ix86_unary_operator_ok (NOT, SImode, operands)"
10096   "#"
10097   [(set_attr "type" "alu1")
10098    (set_attr "mode" "SI")])
10099
10100 (define_split
10101   [(set (match_operand 0 "flags_reg_operand" "")
10102         (match_operator 2 "compare_operator"
10103           [(not:SI (match_operand:SI 3 "register_operand" ""))
10104            (const_int 0)]))
10105    (set (match_operand:DI 1 "register_operand" "")
10106         (zero_extend:DI (not:SI (match_dup 3))))]
10107   "ix86_match_ccmode (insn, CCNOmode)"
10108   [(parallel [(set (match_dup 0)
10109                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10110                                     (const_int 0)]))
10111               (set (match_dup 1)
10112                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10113   "")
10114
10115 (define_expand "one_cmplhi2"
10116   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10117         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10118   "TARGET_HIMODE_MATH"
10119   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10120
10121 (define_insn "*one_cmplhi2_1"
10122   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10123         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10124   "ix86_unary_operator_ok (NOT, HImode, operands)"
10125   "not{w}\t%0"
10126   [(set_attr "type" "negnot")
10127    (set_attr "mode" "HI")])
10128
10129 (define_insn "*one_cmplhi2_2"
10130   [(set (reg FLAGS_REG)
10131         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10132                  (const_int 0)))
10133    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10134         (not:HI (match_dup 1)))]
10135   "ix86_match_ccmode (insn, CCNOmode)
10136    && ix86_unary_operator_ok (NEG, HImode, operands)"
10137   "#"
10138   [(set_attr "type" "alu1")
10139    (set_attr "mode" "HI")])
10140
10141 (define_split
10142   [(set (match_operand 0 "flags_reg_operand" "")
10143         (match_operator 2 "compare_operator"
10144           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10145            (const_int 0)]))
10146    (set (match_operand:HI 1 "nonimmediate_operand" "")
10147         (not:HI (match_dup 3)))]
10148   "ix86_match_ccmode (insn, CCNOmode)"
10149   [(parallel [(set (match_dup 0)
10150                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10151                                     (const_int 0)]))
10152               (set (match_dup 1)
10153                    (xor:HI (match_dup 3) (const_int -1)))])]
10154   "")
10155
10156 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10157 (define_expand "one_cmplqi2"
10158   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10159         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10160   "TARGET_QIMODE_MATH"
10161   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10162
10163 (define_insn "*one_cmplqi2_1"
10164   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10165         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10166   "ix86_unary_operator_ok (NOT, QImode, operands)"
10167   "@
10168    not{b}\t%0
10169    not{l}\t%k0"
10170   [(set_attr "type" "negnot")
10171    (set_attr "mode" "QI,SI")])
10172
10173 (define_insn "*one_cmplqi2_2"
10174   [(set (reg FLAGS_REG)
10175         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10176                  (const_int 0)))
10177    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10178         (not:QI (match_dup 1)))]
10179   "ix86_match_ccmode (insn, CCNOmode)
10180    && ix86_unary_operator_ok (NOT, QImode, operands)"
10181   "#"
10182   [(set_attr "type" "alu1")
10183    (set_attr "mode" "QI")])
10184
10185 (define_split
10186   [(set (match_operand 0 "flags_reg_operand" "")
10187         (match_operator 2 "compare_operator"
10188           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10189            (const_int 0)]))
10190    (set (match_operand:QI 1 "nonimmediate_operand" "")
10191         (not:QI (match_dup 3)))]
10192   "ix86_match_ccmode (insn, CCNOmode)"
10193   [(parallel [(set (match_dup 0)
10194                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10195                                     (const_int 0)]))
10196               (set (match_dup 1)
10197                    (xor:QI (match_dup 3) (const_int -1)))])]
10198   "")
10199 \f
10200 ;; Arithmetic shift instructions
10201
10202 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10203 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10204 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10205 ;; from the assembler input.
10206 ;;
10207 ;; This instruction shifts the target reg/mem as usual, but instead of
10208 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10209 ;; is a left shift double, bits are taken from the high order bits of
10210 ;; reg, else if the insn is a shift right double, bits are taken from the
10211 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10212 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10213 ;;
10214 ;; Since sh[lr]d does not change the `reg' operand, that is done
10215 ;; separately, making all shifts emit pairs of shift double and normal
10216 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10217 ;; support a 63 bit shift, each shift where the count is in a reg expands
10218 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10219 ;;
10220 ;; If the shift count is a constant, we need never emit more than one
10221 ;; shift pair, instead using moves and sign extension for counts greater
10222 ;; than 31.
10223
10224 (define_expand "ashlti3"
10225   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10226                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10227                               (match_operand:QI 2 "nonmemory_operand" "")))
10228               (clobber (reg:CC FLAGS_REG))])]
10229   "TARGET_64BIT"
10230 {
10231   if (! immediate_operand (operands[2], QImode))
10232     {
10233       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10234       DONE;
10235     }
10236   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10237   DONE;
10238 })
10239
10240 (define_insn "ashlti3_1"
10241   [(set (match_operand:TI 0 "register_operand" "=r")
10242         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10243                    (match_operand:QI 2 "register_operand" "c")))
10244    (clobber (match_scratch:DI 3 "=&r"))
10245    (clobber (reg:CC FLAGS_REG))]
10246   "TARGET_64BIT"
10247   "#"
10248   [(set_attr "type" "multi")])
10249
10250 (define_insn "*ashlti3_2"
10251   [(set (match_operand:TI 0 "register_operand" "=r")
10252         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10253                    (match_operand:QI 2 "immediate_operand" "O")))
10254    (clobber (reg:CC FLAGS_REG))]
10255   "TARGET_64BIT"
10256   "#"
10257   [(set_attr "type" "multi")])
10258
10259 (define_split
10260   [(set (match_operand:TI 0 "register_operand" "")
10261         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10262                    (match_operand:QI 2 "register_operand" "")))
10263    (clobber (match_scratch:DI 3 ""))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_64BIT && reload_completed"
10266   [(const_int 0)]
10267   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10268
10269 (define_split
10270   [(set (match_operand:TI 0 "register_operand" "")
10271         (ashift:TI (match_operand:TI 1 "register_operand" "")
10272                    (match_operand:QI 2 "immediate_operand" "")))
10273    (clobber (reg:CC FLAGS_REG))]
10274   "TARGET_64BIT && reload_completed"
10275   [(const_int 0)]
10276   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10277
10278 (define_insn "x86_64_shld"
10279   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10280         (ior:DI (ashift:DI (match_dup 0)
10281                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10282                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10283                   (minus:QI (const_int 64) (match_dup 2)))))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "TARGET_64BIT"
10286   "@
10287    shld{q}\t{%2, %1, %0|%0, %1, %2}
10288    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10289   [(set_attr "type" "ishift")
10290    (set_attr "prefix_0f" "1")
10291    (set_attr "mode" "DI")
10292    (set_attr "athlon_decode" "vector")])
10293
10294 (define_expand "x86_64_shift_adj"
10295   [(set (reg:CCZ FLAGS_REG)
10296         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10297                              (const_int 64))
10298                      (const_int 0)))
10299    (set (match_operand:DI 0 "register_operand" "")
10300         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10301                          (match_operand:DI 1 "register_operand" "")
10302                          (match_dup 0)))
10303    (set (match_dup 1)
10304         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10305                          (match_operand:DI 3 "register_operand" "r")
10306                          (match_dup 1)))]
10307   "TARGET_64BIT"
10308   "")
10309
10310 (define_expand "ashldi3"
10311   [(set (match_operand:DI 0 "shiftdi_operand" "")
10312         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10313                    (match_operand:QI 2 "nonmemory_operand" "")))]
10314   ""
10315   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10316
10317 (define_insn "*ashldi3_1_rex64"
10318   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10319         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10320                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10321    (clobber (reg:CC FLAGS_REG))]
10322   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10323 {
10324   switch (get_attr_type (insn))
10325     {
10326     case TYPE_ALU:
10327       gcc_assert (operands[2] == const1_rtx);
10328       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10329       return "add{q}\t{%0, %0|%0, %0}";
10330
10331     case TYPE_LEA:
10332       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10333       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10334       operands[1] = gen_rtx_MULT (DImode, operands[1],
10335                                   GEN_INT (1 << INTVAL (operands[2])));
10336       return "lea{q}\t{%a1, %0|%0, %a1}";
10337
10338     default:
10339       if (REG_P (operands[2]))
10340         return "sal{q}\t{%b2, %0|%0, %b2}";
10341       else if (operands[2] == const1_rtx
10342                && (TARGET_SHIFT1 || optimize_size))
10343         return "sal{q}\t%0";
10344       else
10345         return "sal{q}\t{%2, %0|%0, %2}";
10346     }
10347 }
10348   [(set (attr "type")
10349      (cond [(eq_attr "alternative" "1")
10350               (const_string "lea")
10351             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10352                           (const_int 0))
10353                       (match_operand 0 "register_operand" ""))
10354                  (match_operand 2 "const1_operand" ""))
10355               (const_string "alu")
10356            ]
10357            (const_string "ishift")))
10358    (set_attr "mode" "DI")])
10359
10360 ;; Convert lea to the lea pattern to avoid flags dependency.
10361 (define_split
10362   [(set (match_operand:DI 0 "register_operand" "")
10363         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10364                    (match_operand:QI 2 "immediate_operand" "")))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "TARGET_64BIT && reload_completed
10367    && true_regnum (operands[0]) != true_regnum (operands[1])"
10368   [(set (match_dup 0)
10369         (mult:DI (match_dup 1)
10370                  (match_dup 2)))]
10371   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10372
10373 ;; This pattern can't accept a variable shift count, since shifts by
10374 ;; zero don't affect the flags.  We assume that shifts by constant
10375 ;; zero are optimized away.
10376 (define_insn "*ashldi3_cmp_rex64"
10377   [(set (reg FLAGS_REG)
10378         (compare
10379           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10380                      (match_operand:QI 2 "immediate_operand" "e"))
10381           (const_int 0)))
10382    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10383         (ashift:DI (match_dup 1) (match_dup 2)))]
10384   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10385    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10386    && (optimize_size
10387        || !TARGET_PARTIAL_FLAG_REG_STALL
10388        || (operands[2] == const1_rtx
10389            && (TARGET_SHIFT1
10390                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10391 {
10392   switch (get_attr_type (insn))
10393     {
10394     case TYPE_ALU:
10395       gcc_assert (operands[2] == const1_rtx);
10396       return "add{q}\t{%0, %0|%0, %0}";
10397
10398     default:
10399       if (REG_P (operands[2]))
10400         return "sal{q}\t{%b2, %0|%0, %b2}";
10401       else if (operands[2] == const1_rtx
10402                && (TARGET_SHIFT1 || optimize_size))
10403         return "sal{q}\t%0";
10404       else
10405         return "sal{q}\t{%2, %0|%0, %2}";
10406     }
10407 }
10408   [(set (attr "type")
10409      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10410                           (const_int 0))
10411                       (match_operand 0 "register_operand" ""))
10412                  (match_operand 2 "const1_operand" ""))
10413               (const_string "alu")
10414            ]
10415            (const_string "ishift")))
10416    (set_attr "mode" "DI")])
10417
10418 (define_insn "*ashldi3_cconly_rex64"
10419   [(set (reg FLAGS_REG)
10420         (compare
10421           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10422                      (match_operand:QI 2 "immediate_operand" "e"))
10423           (const_int 0)))
10424    (clobber (match_scratch:DI 0 "=r"))]
10425   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10426    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10427    && (optimize_size
10428        || !TARGET_PARTIAL_FLAG_REG_STALL
10429        || (operands[2] == const1_rtx
10430            && (TARGET_SHIFT1
10431                || TARGET_DOUBLE_WITH_ADD)))"
10432 {
10433   switch (get_attr_type (insn))
10434     {
10435     case TYPE_ALU:
10436       gcc_assert (operands[2] == const1_rtx);
10437       return "add{q}\t{%0, %0|%0, %0}";
10438
10439     default:
10440       if (REG_P (operands[2]))
10441         return "sal{q}\t{%b2, %0|%0, %b2}";
10442       else if (operands[2] == const1_rtx
10443                && (TARGET_SHIFT1 || optimize_size))
10444         return "sal{q}\t%0";
10445       else
10446         return "sal{q}\t{%2, %0|%0, %2}";
10447     }
10448 }
10449   [(set (attr "type")
10450      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10451                           (const_int 0))
10452                       (match_operand 0 "register_operand" ""))
10453                  (match_operand 2 "const1_operand" ""))
10454               (const_string "alu")
10455            ]
10456            (const_string "ishift")))
10457    (set_attr "mode" "DI")])
10458
10459 (define_insn "*ashldi3_1"
10460   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10461         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10462                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10463    (clobber (reg:CC FLAGS_REG))]
10464   "!TARGET_64BIT"
10465   "#"
10466   [(set_attr "type" "multi")])
10467
10468 ;; By default we don't ask for a scratch register, because when DImode
10469 ;; values are manipulated, registers are already at a premium.  But if
10470 ;; we have one handy, we won't turn it away.
10471 (define_peephole2
10472   [(match_scratch:SI 3 "r")
10473    (parallel [(set (match_operand:DI 0 "register_operand" "")
10474                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10475                               (match_operand:QI 2 "nonmemory_operand" "")))
10476               (clobber (reg:CC FLAGS_REG))])
10477    (match_dup 3)]
10478   "!TARGET_64BIT && TARGET_CMOVE"
10479   [(const_int 0)]
10480   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10481
10482 (define_split
10483   [(set (match_operand:DI 0 "register_operand" "")
10484         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10485                    (match_operand:QI 2 "nonmemory_operand" "")))
10486    (clobber (reg:CC FLAGS_REG))]
10487   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10488                      ? flow2_completed : reload_completed)"
10489   [(const_int 0)]
10490   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10491
10492 (define_insn "x86_shld_1"
10493   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10494         (ior:SI (ashift:SI (match_dup 0)
10495                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10496                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10497                   (minus:QI (const_int 32) (match_dup 2)))))
10498    (clobber (reg:CC FLAGS_REG))]
10499   ""
10500   "@
10501    shld{l}\t{%2, %1, %0|%0, %1, %2}
10502    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10503   [(set_attr "type" "ishift")
10504    (set_attr "prefix_0f" "1")
10505    (set_attr "mode" "SI")
10506    (set_attr "pent_pair" "np")
10507    (set_attr "athlon_decode" "vector")])
10508
10509 (define_expand "x86_shift_adj_1"
10510   [(set (reg:CCZ FLAGS_REG)
10511         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10512                              (const_int 32))
10513                      (const_int 0)))
10514    (set (match_operand:SI 0 "register_operand" "")
10515         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10516                          (match_operand:SI 1 "register_operand" "")
10517                          (match_dup 0)))
10518    (set (match_dup 1)
10519         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10520                          (match_operand:SI 3 "register_operand" "r")
10521                          (match_dup 1)))]
10522   "TARGET_CMOVE"
10523   "")
10524
10525 (define_expand "x86_shift_adj_2"
10526   [(use (match_operand:SI 0 "register_operand" ""))
10527    (use (match_operand:SI 1 "register_operand" ""))
10528    (use (match_operand:QI 2 "register_operand" ""))]
10529   ""
10530 {
10531   rtx label = gen_label_rtx ();
10532   rtx tmp;
10533
10534   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10535
10536   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10537   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10538   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10539                               gen_rtx_LABEL_REF (VOIDmode, label),
10540                               pc_rtx);
10541   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10542   JUMP_LABEL (tmp) = label;
10543
10544   emit_move_insn (operands[0], operands[1]);
10545   ix86_expand_clear (operands[1]);
10546
10547   emit_label (label);
10548   LABEL_NUSES (label) = 1;
10549
10550   DONE;
10551 })
10552
10553 (define_expand "ashlsi3"
10554   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10555         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10556                    (match_operand:QI 2 "nonmemory_operand" "")))
10557    (clobber (reg:CC FLAGS_REG))]
10558   ""
10559   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10560
10561 (define_insn "*ashlsi3_1"
10562   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10563         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10564                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10567 {
10568   switch (get_attr_type (insn))
10569     {
10570     case TYPE_ALU:
10571       gcc_assert (operands[2] == const1_rtx);
10572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10573       return "add{l}\t{%0, %0|%0, %0}";
10574
10575     case TYPE_LEA:
10576       return "#";
10577
10578     default:
10579       if (REG_P (operands[2]))
10580         return "sal{l}\t{%b2, %0|%0, %b2}";
10581       else if (operands[2] == const1_rtx
10582                && (TARGET_SHIFT1 || optimize_size))
10583         return "sal{l}\t%0";
10584       else
10585         return "sal{l}\t{%2, %0|%0, %2}";
10586     }
10587 }
10588   [(set (attr "type")
10589      (cond [(eq_attr "alternative" "1")
10590               (const_string "lea")
10591             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10592                           (const_int 0))
10593                       (match_operand 0 "register_operand" ""))
10594                  (match_operand 2 "const1_operand" ""))
10595               (const_string "alu")
10596            ]
10597            (const_string "ishift")))
10598    (set_attr "mode" "SI")])
10599
10600 ;; Convert lea to the lea pattern to avoid flags dependency.
10601 (define_split
10602   [(set (match_operand 0 "register_operand" "")
10603         (ashift (match_operand 1 "index_register_operand" "")
10604                 (match_operand:QI 2 "const_int_operand" "")))
10605    (clobber (reg:CC FLAGS_REG))]
10606   "reload_completed
10607    && true_regnum (operands[0]) != true_regnum (operands[1])
10608    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10609   [(const_int 0)]
10610 {
10611   rtx pat;
10612   enum machine_mode mode = GET_MODE (operands[0]);
10613
10614   if (GET_MODE_SIZE (mode) < 4)
10615     operands[0] = gen_lowpart (SImode, operands[0]);
10616   if (mode != Pmode)
10617     operands[1] = gen_lowpart (Pmode, operands[1]);
10618   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10619
10620   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10621   if (Pmode != SImode)
10622     pat = gen_rtx_SUBREG (SImode, pat, 0);
10623   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10624   DONE;
10625 })
10626
10627 ;; Rare case of shifting RSP is handled by generating move and shift
10628 (define_split
10629   [(set (match_operand 0 "register_operand" "")
10630         (ashift (match_operand 1 "register_operand" "")
10631                 (match_operand:QI 2 "const_int_operand" "")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "reload_completed
10634    && true_regnum (operands[0]) != true_regnum (operands[1])"
10635   [(const_int 0)]
10636 {
10637   rtx pat, clob;
10638   emit_move_insn (operands[0], operands[1]);
10639   pat = gen_rtx_SET (VOIDmode, operands[0],
10640                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10641                                      operands[0], operands[2]));
10642   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10643   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10644   DONE;
10645 })
10646
10647 (define_insn "*ashlsi3_1_zext"
10648   [(set (match_operand:DI 0 "register_operand" "=r,r")
10649         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10650                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10651    (clobber (reg:CC FLAGS_REG))]
10652   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10653 {
10654   switch (get_attr_type (insn))
10655     {
10656     case TYPE_ALU:
10657       gcc_assert (operands[2] == const1_rtx);
10658       return "add{l}\t{%k0, %k0|%k0, %k0}";
10659
10660     case TYPE_LEA:
10661       return "#";
10662
10663     default:
10664       if (REG_P (operands[2]))
10665         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10666       else if (operands[2] == const1_rtx
10667                && (TARGET_SHIFT1 || optimize_size))
10668         return "sal{l}\t%k0";
10669       else
10670         return "sal{l}\t{%2, %k0|%k0, %2}";
10671     }
10672 }
10673   [(set (attr "type")
10674      (cond [(eq_attr "alternative" "1")
10675               (const_string "lea")
10676             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10677                      (const_int 0))
10678                  (match_operand 2 "const1_operand" ""))
10679               (const_string "alu")
10680            ]
10681            (const_string "ishift")))
10682    (set_attr "mode" "SI")])
10683
10684 ;; Convert lea to the lea pattern to avoid flags dependency.
10685 (define_split
10686   [(set (match_operand:DI 0 "register_operand" "")
10687         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10688                                 (match_operand:QI 2 "const_int_operand" ""))))
10689    (clobber (reg:CC FLAGS_REG))]
10690   "TARGET_64BIT && reload_completed
10691    && true_regnum (operands[0]) != true_regnum (operands[1])"
10692   [(set (match_dup 0) (zero_extend:DI
10693                         (subreg:SI (mult:SI (match_dup 1)
10694                                             (match_dup 2)) 0)))]
10695 {
10696   operands[1] = gen_lowpart (Pmode, operands[1]);
10697   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10698 })
10699
10700 ;; This pattern can't accept a variable shift count, since shifts by
10701 ;; zero don't affect the flags.  We assume that shifts by constant
10702 ;; zero are optimized away.
10703 (define_insn "*ashlsi3_cmp"
10704   [(set (reg FLAGS_REG)
10705         (compare
10706           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10707                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10708           (const_int 0)))
10709    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10710         (ashift:SI (match_dup 1) (match_dup 2)))]
10711   "ix86_match_ccmode (insn, CCGOCmode)
10712    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10713    && (optimize_size
10714        || !TARGET_PARTIAL_FLAG_REG_STALL
10715        || (operands[2] == const1_rtx
10716            && (TARGET_SHIFT1
10717                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10718 {
10719   switch (get_attr_type (insn))
10720     {
10721     case TYPE_ALU:
10722       gcc_assert (operands[2] == const1_rtx);
10723       return "add{l}\t{%0, %0|%0, %0}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{l}\t{%b2, %0|%0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{l}\t%0";
10731       else
10732         return "sal{l}\t{%2, %0|%0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737                           (const_int 0))
10738                       (match_operand 0 "register_operand" ""))
10739                  (match_operand 2 "const1_operand" ""))
10740               (const_string "alu")
10741            ]
10742            (const_string "ishift")))
10743    (set_attr "mode" "SI")])
10744
10745 (define_insn "*ashlsi3_cconly"
10746   [(set (reg FLAGS_REG)
10747         (compare
10748           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10749                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10750           (const_int 0)))
10751    (clobber (match_scratch:SI 0 "=r"))]
10752   "ix86_match_ccmode (insn, CCGOCmode)
10753    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10754    && (optimize_size
10755        || !TARGET_PARTIAL_FLAG_REG_STALL
10756        || (operands[2] == const1_rtx
10757            && (TARGET_SHIFT1
10758                || TARGET_DOUBLE_WITH_ADD)))"
10759 {
10760   switch (get_attr_type (insn))
10761     {
10762     case TYPE_ALU:
10763       gcc_assert (operands[2] == const1_rtx);
10764       return "add{l}\t{%0, %0|%0, %0}";
10765
10766     default:
10767       if (REG_P (operands[2]))
10768         return "sal{l}\t{%b2, %0|%0, %b2}";
10769       else if (operands[2] == const1_rtx
10770                && (TARGET_SHIFT1 || optimize_size))
10771         return "sal{l}\t%0";
10772       else
10773         return "sal{l}\t{%2, %0|%0, %2}";
10774     }
10775 }
10776   [(set (attr "type")
10777      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10778                           (const_int 0))
10779                       (match_operand 0 "register_operand" ""))
10780                  (match_operand 2 "const1_operand" ""))
10781               (const_string "alu")
10782            ]
10783            (const_string "ishift")))
10784    (set_attr "mode" "SI")])
10785
10786 (define_insn "*ashlsi3_cmp_zext"
10787   [(set (reg FLAGS_REG)
10788         (compare
10789           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10790                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10791           (const_int 0)))
10792    (set (match_operand:DI 0 "register_operand" "=r")
10793         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10794   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10795    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10796    && (optimize_size
10797        || !TARGET_PARTIAL_FLAG_REG_STALL
10798        || (operands[2] == const1_rtx
10799            && (TARGET_SHIFT1
10800                || TARGET_DOUBLE_WITH_ADD)))"
10801 {
10802   switch (get_attr_type (insn))
10803     {
10804     case TYPE_ALU:
10805       gcc_assert (operands[2] == const1_rtx);
10806       return "add{l}\t{%k0, %k0|%k0, %k0}";
10807
10808     default:
10809       if (REG_P (operands[2]))
10810         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10811       else if (operands[2] == const1_rtx
10812                && (TARGET_SHIFT1 || optimize_size))
10813         return "sal{l}\t%k0";
10814       else
10815         return "sal{l}\t{%2, %k0|%k0, %2}";
10816     }
10817 }
10818   [(set (attr "type")
10819      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820                      (const_int 0))
10821                  (match_operand 2 "const1_operand" ""))
10822               (const_string "alu")
10823            ]
10824            (const_string "ishift")))
10825    (set_attr "mode" "SI")])
10826
10827 (define_expand "ashlhi3"
10828   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10829         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10830                    (match_operand:QI 2 "nonmemory_operand" "")))
10831    (clobber (reg:CC FLAGS_REG))]
10832   "TARGET_HIMODE_MATH"
10833   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10834
10835 (define_insn "*ashlhi3_1_lea"
10836   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10837         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10838                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10839    (clobber (reg:CC FLAGS_REG))]
10840   "!TARGET_PARTIAL_REG_STALL
10841    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10842 {
10843   switch (get_attr_type (insn))
10844     {
10845     case TYPE_LEA:
10846       return "#";
10847     case TYPE_ALU:
10848       gcc_assert (operands[2] == const1_rtx);
10849       return "add{w}\t{%0, %0|%0, %0}";
10850
10851     default:
10852       if (REG_P (operands[2]))
10853         return "sal{w}\t{%b2, %0|%0, %b2}";
10854       else if (operands[2] == const1_rtx
10855                && (TARGET_SHIFT1 || optimize_size))
10856         return "sal{w}\t%0";
10857       else
10858         return "sal{w}\t{%2, %0|%0, %2}";
10859     }
10860 }
10861   [(set (attr "type")
10862      (cond [(eq_attr "alternative" "1")
10863               (const_string "lea")
10864             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10865                           (const_int 0))
10866                       (match_operand 0 "register_operand" ""))
10867                  (match_operand 2 "const1_operand" ""))
10868               (const_string "alu")
10869            ]
10870            (const_string "ishift")))
10871    (set_attr "mode" "HI,SI")])
10872
10873 (define_insn "*ashlhi3_1"
10874   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10875         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10876                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10877    (clobber (reg:CC FLAGS_REG))]
10878   "TARGET_PARTIAL_REG_STALL
10879    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10880 {
10881   switch (get_attr_type (insn))
10882     {
10883     case TYPE_ALU:
10884       gcc_assert (operands[2] == const1_rtx);
10885       return "add{w}\t{%0, %0|%0, %0}";
10886
10887     default:
10888       if (REG_P (operands[2]))
10889         return "sal{w}\t{%b2, %0|%0, %b2}";
10890       else if (operands[2] == const1_rtx
10891                && (TARGET_SHIFT1 || optimize_size))
10892         return "sal{w}\t%0";
10893       else
10894         return "sal{w}\t{%2, %0|%0, %2}";
10895     }
10896 }
10897   [(set (attr "type")
10898      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10899                           (const_int 0))
10900                       (match_operand 0 "register_operand" ""))
10901                  (match_operand 2 "const1_operand" ""))
10902               (const_string "alu")
10903            ]
10904            (const_string "ishift")))
10905    (set_attr "mode" "HI")])
10906
10907 ;; This pattern can't accept a variable shift count, since shifts by
10908 ;; zero don't affect the flags.  We assume that shifts by constant
10909 ;; zero are optimized away.
10910 (define_insn "*ashlhi3_cmp"
10911   [(set (reg FLAGS_REG)
10912         (compare
10913           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10914                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10915           (const_int 0)))
10916    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10917         (ashift:HI (match_dup 1) (match_dup 2)))]
10918   "ix86_match_ccmode (insn, CCGOCmode)
10919    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10920    && (optimize_size
10921        || !TARGET_PARTIAL_FLAG_REG_STALL
10922        || (operands[2] == const1_rtx
10923            && (TARGET_SHIFT1
10924                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10925 {
10926   switch (get_attr_type (insn))
10927     {
10928     case TYPE_ALU:
10929       gcc_assert (operands[2] == const1_rtx);
10930       return "add{w}\t{%0, %0|%0, %0}";
10931
10932     default:
10933       if (REG_P (operands[2]))
10934         return "sal{w}\t{%b2, %0|%0, %b2}";
10935       else if (operands[2] == const1_rtx
10936                && (TARGET_SHIFT1 || optimize_size))
10937         return "sal{w}\t%0";
10938       else
10939         return "sal{w}\t{%2, %0|%0, %2}";
10940     }
10941 }
10942   [(set (attr "type")
10943      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944                           (const_int 0))
10945                       (match_operand 0 "register_operand" ""))
10946                  (match_operand 2 "const1_operand" ""))
10947               (const_string "alu")
10948            ]
10949            (const_string "ishift")))
10950    (set_attr "mode" "HI")])
10951
10952 (define_insn "*ashlhi3_cconly"
10953   [(set (reg FLAGS_REG)
10954         (compare
10955           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10956                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10957           (const_int 0)))
10958    (clobber (match_scratch:HI 0 "=r"))]
10959   "ix86_match_ccmode (insn, CCGOCmode)
10960    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10961    && (optimize_size
10962        || !TARGET_PARTIAL_FLAG_REG_STALL
10963        || (operands[2] == const1_rtx
10964            && (TARGET_SHIFT1
10965                || TARGET_DOUBLE_WITH_ADD)))"
10966 {
10967   switch (get_attr_type (insn))
10968     {
10969     case TYPE_ALU:
10970       gcc_assert (operands[2] == const1_rtx);
10971       return "add{w}\t{%0, %0|%0, %0}";
10972
10973     default:
10974       if (REG_P (operands[2]))
10975         return "sal{w}\t{%b2, %0|%0, %b2}";
10976       else if (operands[2] == const1_rtx
10977                && (TARGET_SHIFT1 || optimize_size))
10978         return "sal{w}\t%0";
10979       else
10980         return "sal{w}\t{%2, %0|%0, %2}";
10981     }
10982 }
10983   [(set (attr "type")
10984      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985                           (const_int 0))
10986                       (match_operand 0 "register_operand" ""))
10987                  (match_operand 2 "const1_operand" ""))
10988               (const_string "alu")
10989            ]
10990            (const_string "ishift")))
10991    (set_attr "mode" "HI")])
10992
10993 (define_expand "ashlqi3"
10994   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10995         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10996                    (match_operand:QI 2 "nonmemory_operand" "")))
10997    (clobber (reg:CC FLAGS_REG))]
10998   "TARGET_QIMODE_MATH"
10999   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11000
11001 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11002
11003 (define_insn "*ashlqi3_1_lea"
11004   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11005         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11006                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11007    (clobber (reg:CC FLAGS_REG))]
11008   "!TARGET_PARTIAL_REG_STALL
11009    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11010 {
11011   switch (get_attr_type (insn))
11012     {
11013     case TYPE_LEA:
11014       return "#";
11015     case TYPE_ALU:
11016       gcc_assert (operands[2] == const1_rtx);
11017       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11018         return "add{l}\t{%k0, %k0|%k0, %k0}";
11019       else
11020         return "add{b}\t{%0, %0|%0, %0}";
11021
11022     default:
11023       if (REG_P (operands[2]))
11024         {
11025           if (get_attr_mode (insn) == MODE_SI)
11026             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027           else
11028             return "sal{b}\t{%b2, %0|%0, %b2}";
11029         }
11030       else if (operands[2] == const1_rtx
11031                && (TARGET_SHIFT1 || optimize_size))
11032         {
11033           if (get_attr_mode (insn) == MODE_SI)
11034             return "sal{l}\t%0";
11035           else
11036             return "sal{b}\t%0";
11037         }
11038       else
11039         {
11040           if (get_attr_mode (insn) == MODE_SI)
11041             return "sal{l}\t{%2, %k0|%k0, %2}";
11042           else
11043             return "sal{b}\t{%2, %0|%0, %2}";
11044         }
11045     }
11046 }
11047   [(set (attr "type")
11048      (cond [(eq_attr "alternative" "2")
11049               (const_string "lea")
11050             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11051                           (const_int 0))
11052                       (match_operand 0 "register_operand" ""))
11053                  (match_operand 2 "const1_operand" ""))
11054               (const_string "alu")
11055            ]
11056            (const_string "ishift")))
11057    (set_attr "mode" "QI,SI,SI")])
11058
11059 (define_insn "*ashlqi3_1"
11060   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11061         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11062                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "TARGET_PARTIAL_REG_STALL
11065    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11066 {
11067   switch (get_attr_type (insn))
11068     {
11069     case TYPE_ALU:
11070       gcc_assert (operands[2] == const1_rtx);
11071       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11072         return "add{l}\t{%k0, %k0|%k0, %k0}";
11073       else
11074         return "add{b}\t{%0, %0|%0, %0}";
11075
11076     default:
11077       if (REG_P (operands[2]))
11078         {
11079           if (get_attr_mode (insn) == MODE_SI)
11080             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11081           else
11082             return "sal{b}\t{%b2, %0|%0, %b2}";
11083         }
11084       else if (operands[2] == const1_rtx
11085                && (TARGET_SHIFT1 || optimize_size))
11086         {
11087           if (get_attr_mode (insn) == MODE_SI)
11088             return "sal{l}\t%0";
11089           else
11090             return "sal{b}\t%0";
11091         }
11092       else
11093         {
11094           if (get_attr_mode (insn) == MODE_SI)
11095             return "sal{l}\t{%2, %k0|%k0, %2}";
11096           else
11097             return "sal{b}\t{%2, %0|%0, %2}";
11098         }
11099     }
11100 }
11101   [(set (attr "type")
11102      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11103                           (const_int 0))
11104                       (match_operand 0 "register_operand" ""))
11105                  (match_operand 2 "const1_operand" ""))
11106               (const_string "alu")
11107            ]
11108            (const_string "ishift")))
11109    (set_attr "mode" "QI,SI")])
11110
11111 ;; This pattern can't accept a variable shift count, since shifts by
11112 ;; zero don't affect the flags.  We assume that shifts by constant
11113 ;; zero are optimized away.
11114 (define_insn "*ashlqi3_cmp"
11115   [(set (reg FLAGS_REG)
11116         (compare
11117           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11118                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11119           (const_int 0)))
11120    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11121         (ashift:QI (match_dup 1) (match_dup 2)))]
11122   "ix86_match_ccmode (insn, CCGOCmode)
11123    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11124    && (optimize_size
11125        || !TARGET_PARTIAL_FLAG_REG_STALL
11126        || (operands[2] == const1_rtx
11127            && (TARGET_SHIFT1
11128                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11129 {
11130   switch (get_attr_type (insn))
11131     {
11132     case TYPE_ALU:
11133       gcc_assert (operands[2] == const1_rtx);
11134       return "add{b}\t{%0, %0|%0, %0}";
11135
11136     default:
11137       if (REG_P (operands[2]))
11138         return "sal{b}\t{%b2, %0|%0, %b2}";
11139       else if (operands[2] == const1_rtx
11140                && (TARGET_SHIFT1 || optimize_size))
11141         return "sal{b}\t%0";
11142       else
11143         return "sal{b}\t{%2, %0|%0, %2}";
11144     }
11145 }
11146   [(set (attr "type")
11147      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11148                           (const_int 0))
11149                       (match_operand 0 "register_operand" ""))
11150                  (match_operand 2 "const1_operand" ""))
11151               (const_string "alu")
11152            ]
11153            (const_string "ishift")))
11154    (set_attr "mode" "QI")])
11155
11156 (define_insn "*ashlqi3_cconly"
11157   [(set (reg FLAGS_REG)
11158         (compare
11159           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11160                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11161           (const_int 0)))
11162    (clobber (match_scratch:QI 0 "=q"))]
11163   "ix86_match_ccmode (insn, CCGOCmode)
11164    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11165    && (optimize_size
11166        || !TARGET_PARTIAL_FLAG_REG_STALL
11167        || (operands[2] == const1_rtx
11168            && (TARGET_SHIFT1
11169                || TARGET_DOUBLE_WITH_ADD)))"
11170 {
11171   switch (get_attr_type (insn))
11172     {
11173     case TYPE_ALU:
11174       gcc_assert (operands[2] == const1_rtx);
11175       return "add{b}\t{%0, %0|%0, %0}";
11176
11177     default:
11178       if (REG_P (operands[2]))
11179         return "sal{b}\t{%b2, %0|%0, %b2}";
11180       else if (operands[2] == const1_rtx
11181                && (TARGET_SHIFT1 || optimize_size))
11182         return "sal{b}\t%0";
11183       else
11184         return "sal{b}\t{%2, %0|%0, %2}";
11185     }
11186 }
11187   [(set (attr "type")
11188      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11189                           (const_int 0))
11190                       (match_operand 0 "register_operand" ""))
11191                  (match_operand 2 "const1_operand" ""))
11192               (const_string "alu")
11193            ]
11194            (const_string "ishift")))
11195    (set_attr "mode" "QI")])
11196
11197 ;; See comment above `ashldi3' about how this works.
11198
11199 (define_expand "ashrti3"
11200   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11201                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11202                                 (match_operand:QI 2 "nonmemory_operand" "")))
11203               (clobber (reg:CC FLAGS_REG))])]
11204   "TARGET_64BIT"
11205 {
11206   if (! immediate_operand (operands[2], QImode))
11207     {
11208       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11209       DONE;
11210     }
11211   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11212   DONE;
11213 })
11214
11215 (define_insn "ashrti3_1"
11216   [(set (match_operand:TI 0 "register_operand" "=r")
11217         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11218                      (match_operand:QI 2 "register_operand" "c")))
11219    (clobber (match_scratch:DI 3 "=&r"))
11220    (clobber (reg:CC FLAGS_REG))]
11221   "TARGET_64BIT"
11222   "#"
11223   [(set_attr "type" "multi")])
11224
11225 (define_insn "*ashrti3_2"
11226   [(set (match_operand:TI 0 "register_operand" "=r")
11227         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11228                      (match_operand:QI 2 "immediate_operand" "O")))
11229    (clobber (reg:CC FLAGS_REG))]
11230   "TARGET_64BIT"
11231   "#"
11232   [(set_attr "type" "multi")])
11233
11234 (define_split
11235   [(set (match_operand:TI 0 "register_operand" "")
11236         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11237                      (match_operand:QI 2 "register_operand" "")))
11238    (clobber (match_scratch:DI 3 ""))
11239    (clobber (reg:CC FLAGS_REG))]
11240   "TARGET_64BIT && reload_completed"
11241   [(const_int 0)]
11242   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11243
11244 (define_split
11245   [(set (match_operand:TI 0 "register_operand" "")
11246         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11247                      (match_operand:QI 2 "immediate_operand" "")))
11248    (clobber (reg:CC FLAGS_REG))]
11249   "TARGET_64BIT && reload_completed"
11250   [(const_int 0)]
11251   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11252
11253 (define_insn "x86_64_shrd"
11254   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11255         (ior:DI (ashiftrt:DI (match_dup 0)
11256                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11257                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11258                   (minus:QI (const_int 64) (match_dup 2)))))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "TARGET_64BIT"
11261   "@
11262    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11263    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11264   [(set_attr "type" "ishift")
11265    (set_attr "prefix_0f" "1")
11266    (set_attr "mode" "DI")
11267    (set_attr "athlon_decode" "vector")])
11268
11269 (define_expand "ashrdi3"
11270   [(set (match_operand:DI 0 "shiftdi_operand" "")
11271         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11272                      (match_operand:QI 2 "nonmemory_operand" "")))]
11273   ""
11274   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11275
11276 (define_insn "*ashrdi3_63_rex64"
11277   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11278         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11279                      (match_operand:DI 2 "const_int_operand" "i,i")))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "TARGET_64BIT && INTVAL (operands[2]) == 63
11282    && (TARGET_USE_CLTD || optimize_size)
11283    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11284   "@
11285    {cqto|cqo}
11286    sar{q}\t{%2, %0|%0, %2}"
11287   [(set_attr "type" "imovx,ishift")
11288    (set_attr "prefix_0f" "0,*")
11289    (set_attr "length_immediate" "0,*")
11290    (set_attr "modrm" "0,1")
11291    (set_attr "mode" "DI")])
11292
11293 (define_insn "*ashrdi3_1_one_bit_rex64"
11294   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11295         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11296                      (match_operand:QI 2 "const1_operand" "")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11299    && (TARGET_SHIFT1 || optimize_size)"
11300   "sar{q}\t%0"
11301   [(set_attr "type" "ishift")
11302    (set (attr "length") 
11303      (if_then_else (match_operand:DI 0 "register_operand" "") 
11304         (const_string "2")
11305         (const_string "*")))])
11306
11307 (define_insn "*ashrdi3_1_rex64"
11308   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11309         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11310                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11313   "@
11314    sar{q}\t{%2, %0|%0, %2}
11315    sar{q}\t{%b2, %0|%0, %b2}"
11316   [(set_attr "type" "ishift")
11317    (set_attr "mode" "DI")])
11318
11319 ;; This pattern can't accept a variable shift count, since shifts by
11320 ;; zero don't affect the flags.  We assume that shifts by constant
11321 ;; zero are optimized away.
11322 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11323   [(set (reg FLAGS_REG)
11324         (compare
11325           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11326                        (match_operand:QI 2 "const1_operand" ""))
11327           (const_int 0)))
11328    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11329         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11330   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11331    && (TARGET_SHIFT1 || optimize_size)
11332    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11333   "sar{q}\t%0"
11334   [(set_attr "type" "ishift")
11335    (set (attr "length") 
11336      (if_then_else (match_operand:DI 0 "register_operand" "") 
11337         (const_string "2")
11338         (const_string "*")))])
11339
11340 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11344                        (match_operand:QI 2 "const1_operand" ""))
11345           (const_int 0)))
11346    (clobber (match_scratch:DI 0 "=r"))]
11347   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11348    && (TARGET_SHIFT1 || optimize_size)
11349    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11350   "sar{q}\t%0"
11351   [(set_attr "type" "ishift")
11352    (set_attr "length" "2")])
11353
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags.  We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrdi3_cmp_rex64"
11358   [(set (reg FLAGS_REG)
11359         (compare
11360           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11361                        (match_operand:QI 2 "const_int_operand" "n"))
11362           (const_int 0)))
11363    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11365   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11366    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11367    && (optimize_size
11368        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11369   "sar{q}\t{%2, %0|%0, %2}"
11370   [(set_attr "type" "ishift")
11371    (set_attr "mode" "DI")])
11372
11373 (define_insn "*ashrdi3_cconly_rex64"
11374   [(set (reg FLAGS_REG)
11375         (compare
11376           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377                        (match_operand:QI 2 "const_int_operand" "n"))
11378           (const_int 0)))
11379    (clobber (match_scratch:DI 0 "=r"))]
11380   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11381    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11382    && (optimize_size
11383        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11384   "sar{q}\t{%2, %0|%0, %2}"
11385   [(set_attr "type" "ishift")
11386    (set_attr "mode" "DI")])
11387
11388 (define_insn "*ashrdi3_1"
11389   [(set (match_operand:DI 0 "register_operand" "=r")
11390         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11391                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11392    (clobber (reg:CC FLAGS_REG))]
11393   "!TARGET_64BIT"
11394   "#"
11395   [(set_attr "type" "multi")])
11396
11397 ;; By default we don't ask for a scratch register, because when DImode
11398 ;; values are manipulated, registers are already at a premium.  But if
11399 ;; we have one handy, we won't turn it away.
11400 (define_peephole2
11401   [(match_scratch:SI 3 "r")
11402    (parallel [(set (match_operand:DI 0 "register_operand" "")
11403                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11404                                 (match_operand:QI 2 "nonmemory_operand" "")))
11405               (clobber (reg:CC FLAGS_REG))])
11406    (match_dup 3)]
11407   "!TARGET_64BIT && TARGET_CMOVE"
11408   [(const_int 0)]
11409   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11410
11411 (define_split
11412   [(set (match_operand:DI 0 "register_operand" "")
11413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11414                      (match_operand:QI 2 "nonmemory_operand" "")))
11415    (clobber (reg:CC FLAGS_REG))]
11416   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11417                      ? flow2_completed : reload_completed)"
11418   [(const_int 0)]
11419   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11420
11421 (define_insn "x86_shrd_1"
11422   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11423         (ior:SI (ashiftrt:SI (match_dup 0)
11424                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11425                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11426                   (minus:QI (const_int 32) (match_dup 2)))))
11427    (clobber (reg:CC FLAGS_REG))]
11428   ""
11429   "@
11430    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11431    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11432   [(set_attr "type" "ishift")
11433    (set_attr "prefix_0f" "1")
11434    (set_attr "pent_pair" "np")
11435    (set_attr "mode" "SI")])
11436
11437 (define_expand "x86_shift_adj_3"
11438   [(use (match_operand:SI 0 "register_operand" ""))
11439    (use (match_operand:SI 1 "register_operand" ""))
11440    (use (match_operand:QI 2 "register_operand" ""))]
11441   ""
11442 {
11443   rtx label = gen_label_rtx ();
11444   rtx tmp;
11445
11446   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11447
11448   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11449   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11450   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11451                               gen_rtx_LABEL_REF (VOIDmode, label),
11452                               pc_rtx);
11453   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11454   JUMP_LABEL (tmp) = label;
11455
11456   emit_move_insn (operands[0], operands[1]);
11457   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11458
11459   emit_label (label);
11460   LABEL_NUSES (label) = 1;
11461
11462   DONE;
11463 })
11464
11465 (define_insn "ashrsi3_31"
11466   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11467         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11468                      (match_operand:SI 2 "const_int_operand" "i,i")))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11471    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11472   "@
11473    {cltd|cdq}
11474    sar{l}\t{%2, %0|%0, %2}"
11475   [(set_attr "type" "imovx,ishift")
11476    (set_attr "prefix_0f" "0,*")
11477    (set_attr "length_immediate" "0,*")
11478    (set_attr "modrm" "0,1")
11479    (set_attr "mode" "SI")])
11480
11481 (define_insn "*ashrsi3_31_zext"
11482   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11483         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11484                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11485    (clobber (reg:CC FLAGS_REG))]
11486   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11487    && INTVAL (operands[2]) == 31
11488    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11489   "@
11490    {cltd|cdq}
11491    sar{l}\t{%2, %k0|%k0, %2}"
11492   [(set_attr "type" "imovx,ishift")
11493    (set_attr "prefix_0f" "0,*")
11494    (set_attr "length_immediate" "0,*")
11495    (set_attr "modrm" "0,1")
11496    (set_attr "mode" "SI")])
11497
11498 (define_expand "ashrsi3"
11499   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11500         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11501                      (match_operand:QI 2 "nonmemory_operand" "")))
11502    (clobber (reg:CC FLAGS_REG))]
11503   ""
11504   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11505
11506 (define_insn "*ashrsi3_1_one_bit"
11507   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11508         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11509                      (match_operand:QI 2 "const1_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11512    && (TARGET_SHIFT1 || optimize_size)"
11513   "sar{l}\t%0"
11514   [(set_attr "type" "ishift")
11515    (set (attr "length") 
11516      (if_then_else (match_operand:SI 0 "register_operand" "") 
11517         (const_string "2")
11518         (const_string "*")))])
11519
11520 (define_insn "*ashrsi3_1_one_bit_zext"
11521   [(set (match_operand:DI 0 "register_operand" "=r")
11522         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11523                                      (match_operand:QI 2 "const1_operand" ""))))
11524    (clobber (reg:CC FLAGS_REG))]
11525   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11526    && (TARGET_SHIFT1 || optimize_size)"
11527   "sar{l}\t%k0"
11528   [(set_attr "type" "ishift")
11529    (set_attr "length" "2")])
11530
11531 (define_insn "*ashrsi3_1"
11532   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11533         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11534                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11535    (clobber (reg:CC FLAGS_REG))]
11536   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11537   "@
11538    sar{l}\t{%2, %0|%0, %2}
11539    sar{l}\t{%b2, %0|%0, %b2}"
11540   [(set_attr "type" "ishift")
11541    (set_attr "mode" "SI")])
11542
11543 (define_insn "*ashrsi3_1_zext"
11544   [(set (match_operand:DI 0 "register_operand" "=r,r")
11545         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11546                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11547    (clobber (reg:CC FLAGS_REG))]
11548   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11549   "@
11550    sar{l}\t{%2, %k0|%k0, %2}
11551    sar{l}\t{%b2, %k0|%k0, %b2}"
11552   [(set_attr "type" "ishift")
11553    (set_attr "mode" "SI")])
11554
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*ashrsi3_one_bit_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const1_operand" ""))
11563           (const_int 0)))
11564    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && (TARGET_SHIFT1 || optimize_size)
11568    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569   "sar{l}\t%0"
11570   [(set_attr "type" "ishift")
11571    (set (attr "length") 
11572      (if_then_else (match_operand:SI 0 "register_operand" "") 
11573         (const_string "2")
11574         (const_string "*")))])
11575
11576 (define_insn "*ashrsi3_one_bit_cconly"
11577   [(set (reg FLAGS_REG)
11578         (compare
11579           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580                        (match_operand:QI 2 "const1_operand" ""))
11581           (const_int 0)))
11582    (clobber (match_scratch:SI 0 "=r"))]
11583   "ix86_match_ccmode (insn, CCGOCmode)
11584    && (TARGET_SHIFT1 || optimize_size)
11585    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586   "sar{l}\t%0"
11587   [(set_attr "type" "ishift")
11588    (set_attr "length" "2")])
11589
11590 (define_insn "*ashrsi3_one_bit_cmp_zext"
11591   [(set (reg FLAGS_REG)
11592         (compare
11593           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594                        (match_operand:QI 2 "const1_operand" ""))
11595           (const_int 0)))
11596    (set (match_operand:DI 0 "register_operand" "=r")
11597         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11598   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11599    && (TARGET_SHIFT1 || optimize_size)
11600    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11601   "sar{l}\t%k0"
11602   [(set_attr "type" "ishift")
11603    (set_attr "length" "2")])
11604
11605 ;; This pattern can't accept a variable shift count, since shifts by
11606 ;; zero don't affect the flags.  We assume that shifts by constant
11607 ;; zero are optimized away.
11608 (define_insn "*ashrsi3_cmp"
11609   [(set (reg FLAGS_REG)
11610         (compare
11611           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11612                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11613           (const_int 0)))
11614    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11615         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11616   "ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11618    && (optimize_size
11619        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11620   "sar{l}\t{%2, %0|%0, %2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "SI")])
11623
11624 (define_insn "*ashrsi3_cconly"
11625   [(set (reg FLAGS_REG)
11626         (compare
11627           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629           (const_int 0)))
11630    (clobber (match_scratch:SI 0 "=r"))]
11631   "ix86_match_ccmode (insn, CCGOCmode)
11632    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11633    && (optimize_size
11634        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11635   "sar{l}\t{%2, %0|%0, %2}"
11636   [(set_attr "type" "ishift")
11637    (set_attr "mode" "SI")])
11638
11639 (define_insn "*ashrsi3_cmp_zext"
11640   [(set (reg FLAGS_REG)
11641         (compare
11642           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11643                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11644           (const_int 0)))
11645    (set (match_operand:DI 0 "register_operand" "=r")
11646         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11647   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11648    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11649    && (optimize_size
11650        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11651   "sar{l}\t{%2, %k0|%k0, %2}"
11652   [(set_attr "type" "ishift")
11653    (set_attr "mode" "SI")])
11654
11655 (define_expand "ashrhi3"
11656   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11657         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11658                      (match_operand:QI 2 "nonmemory_operand" "")))
11659    (clobber (reg:CC FLAGS_REG))]
11660   "TARGET_HIMODE_MATH"
11661   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11662
11663 (define_insn "*ashrhi3_1_one_bit"
11664   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11665         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666                      (match_operand:QI 2 "const1_operand" "")))
11667    (clobber (reg:CC FLAGS_REG))]
11668   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11669    && (TARGET_SHIFT1 || optimize_size)"
11670   "sar{w}\t%0"
11671   [(set_attr "type" "ishift")
11672    (set (attr "length") 
11673      (if_then_else (match_operand 0 "register_operand" "") 
11674         (const_string "2")
11675         (const_string "*")))])
11676
11677 (define_insn "*ashrhi3_1"
11678   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11679         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11680                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11681    (clobber (reg:CC FLAGS_REG))]
11682   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11683   "@
11684    sar{w}\t{%2, %0|%0, %2}
11685    sar{w}\t{%b2, %0|%0, %b2}"
11686   [(set_attr "type" "ishift")
11687    (set_attr "mode" "HI")])
11688
11689 ;; This pattern can't accept a variable shift count, since shifts by
11690 ;; zero don't affect the flags.  We assume that shifts by constant
11691 ;; zero are optimized away.
11692 (define_insn "*ashrhi3_one_bit_cmp"
11693   [(set (reg FLAGS_REG)
11694         (compare
11695           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11696                        (match_operand:QI 2 "const1_operand" ""))
11697           (const_int 0)))
11698    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11699         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11700   "ix86_match_ccmode (insn, CCGOCmode)
11701    && (TARGET_SHIFT1 || optimize_size)
11702    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703   "sar{w}\t%0"
11704   [(set_attr "type" "ishift")
11705    (set (attr "length") 
11706      (if_then_else (match_operand 0 "register_operand" "") 
11707         (const_string "2")
11708         (const_string "*")))])
11709
11710 (define_insn "*ashrhi3_one_bit_cconly"
11711   [(set (reg FLAGS_REG)
11712         (compare
11713           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11714                        (match_operand:QI 2 "const1_operand" ""))
11715           (const_int 0)))
11716    (clobber (match_scratch:HI 0 "=r"))]
11717   "ix86_match_ccmode (insn, CCGOCmode)
11718    && (TARGET_SHIFT1 || optimize_size)
11719    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11720   "sar{w}\t%0"
11721   [(set_attr "type" "ishift")
11722    (set_attr "length" "2")])
11723
11724 ;; This pattern can't accept a variable shift count, since shifts by
11725 ;; zero don't affect the flags.  We assume that shifts by constant
11726 ;; zero are optimized away.
11727 (define_insn "*ashrhi3_cmp"
11728   [(set (reg FLAGS_REG)
11729         (compare
11730           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11731                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11732           (const_int 0)))
11733    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11735   "ix86_match_ccmode (insn, CCGOCmode)
11736    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11737    && (optimize_size
11738        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11739   "sar{w}\t{%2, %0|%0, %2}"
11740   [(set_attr "type" "ishift")
11741    (set_attr "mode" "HI")])
11742
11743 (define_insn "*ashrhi3_cconly"
11744   [(set (reg FLAGS_REG)
11745         (compare
11746           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11748           (const_int 0)))
11749    (clobber (match_scratch:HI 0 "=r"))]
11750   "ix86_match_ccmode (insn, CCGOCmode)
11751    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11752    && (optimize_size
11753        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11754   "sar{w}\t{%2, %0|%0, %2}"
11755   [(set_attr "type" "ishift")
11756    (set_attr "mode" "HI")])
11757
11758 (define_expand "ashrqi3"
11759   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11760         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11761                      (match_operand:QI 2 "nonmemory_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "TARGET_QIMODE_MATH"
11764   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11765
11766 (define_insn "*ashrqi3_1_one_bit"
11767   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11768         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11769                      (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "sar{b}\t%0"
11774   [(set_attr "type" "ishift")
11775    (set (attr "length") 
11776      (if_then_else (match_operand 0 "register_operand" "") 
11777         (const_string "2")
11778         (const_string "*")))])
11779
11780 (define_insn "*ashrqi3_1_one_bit_slp"
11781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11782         (ashiftrt:QI (match_dup 0)
11783                      (match_operand:QI 1 "const1_operand" "")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11786    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11787    && (TARGET_SHIFT1 || optimize_size)"
11788   "sar{b}\t%0"
11789   [(set_attr "type" "ishift1")
11790    (set (attr "length") 
11791      (if_then_else (match_operand 0 "register_operand" "") 
11792         (const_string "2")
11793         (const_string "*")))])
11794
11795 (define_insn "*ashrqi3_1"
11796   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11797         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11798                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11801   "@
11802    sar{b}\t{%2, %0|%0, %2}
11803    sar{b}\t{%b2, %0|%0, %b2}"
11804   [(set_attr "type" "ishift")
11805    (set_attr "mode" "QI")])
11806
11807 (define_insn "*ashrqi3_1_slp"
11808   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11809         (ashiftrt:QI (match_dup 0)
11810                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11814   "@
11815    sar{b}\t{%1, %0|%0, %1}
11816    sar{b}\t{%b1, %0|%0, %b1}"
11817   [(set_attr "type" "ishift1")
11818    (set_attr "mode" "QI")])
11819
11820 ;; This pattern can't accept a variable shift count, since shifts by
11821 ;; zero don't affect the flags.  We assume that shifts by constant
11822 ;; zero are optimized away.
11823 (define_insn "*ashrqi3_one_bit_cmp"
11824   [(set (reg FLAGS_REG)
11825         (compare
11826           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11827                        (match_operand:QI 2 "const1_operand" "I"))
11828           (const_int 0)))
11829    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11830         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11831   "ix86_match_ccmode (insn, CCGOCmode)
11832    && (TARGET_SHIFT1 || optimize_size)
11833    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11834   "sar{b}\t%0"
11835   [(set_attr "type" "ishift")
11836    (set (attr "length") 
11837      (if_then_else (match_operand 0 "register_operand" "") 
11838         (const_string "2")
11839         (const_string "*")))])
11840
11841 (define_insn "*ashrqi3_one_bit_cconly"
11842   [(set (reg FLAGS_REG)
11843         (compare
11844           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11845                        (match_operand:QI 2 "const1_operand" "I"))
11846           (const_int 0)))
11847    (clobber (match_scratch:QI 0 "=q"))]
11848   "ix86_match_ccmode (insn, CCGOCmode)
11849    && (TARGET_SHIFT1 || optimize_size)
11850    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11851   "sar{b}\t%0"
11852   [(set_attr "type" "ishift")
11853    (set_attr "length" "2")])
11854
11855 ;; This pattern can't accept a variable shift count, since shifts by
11856 ;; zero don't affect the flags.  We assume that shifts by constant
11857 ;; zero are optimized away.
11858 (define_insn "*ashrqi3_cmp"
11859   [(set (reg FLAGS_REG)
11860         (compare
11861           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11862                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11863           (const_int 0)))
11864    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11865         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11866   "ix86_match_ccmode (insn, CCGOCmode)
11867    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11868    && (optimize_size
11869        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870   "sar{b}\t{%2, %0|%0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "QI")])
11873
11874 (define_insn "*ashrqi3_cconly"
11875   [(set (reg FLAGS_REG)
11876         (compare
11877           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11878                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11879           (const_int 0)))
11880    (clobber (match_scratch:QI 0 "=q"))]
11881   "ix86_match_ccmode (insn, CCGOCmode)
11882    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11883    && (optimize_size
11884        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11885   "sar{b}\t{%2, %0|%0, %2}"
11886   [(set_attr "type" "ishift")
11887    (set_attr "mode" "QI")])
11888
11889 \f
11890 ;; Logical shift instructions
11891
11892 ;; See comment above `ashldi3' about how this works.
11893
11894 (define_expand "lshrti3"
11895   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11896                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11897                                 (match_operand:QI 2 "nonmemory_operand" "")))
11898               (clobber (reg:CC FLAGS_REG))])]
11899   "TARGET_64BIT"
11900 {
11901   if (! immediate_operand (operands[2], QImode))
11902     {
11903       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11904       DONE;
11905     }
11906   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11907   DONE;
11908 })
11909
11910 (define_insn "lshrti3_1"
11911   [(set (match_operand:TI 0 "register_operand" "=r")
11912         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11913                      (match_operand:QI 2 "register_operand" "c")))
11914    (clobber (match_scratch:DI 3 "=&r"))
11915    (clobber (reg:CC FLAGS_REG))]
11916   "TARGET_64BIT"
11917   "#"
11918   [(set_attr "type" "multi")])
11919
11920 (define_insn "*lshrti3_2"
11921   [(set (match_operand:TI 0 "register_operand" "=r")
11922         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11923                      (match_operand:QI 2 "immediate_operand" "O")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "TARGET_64BIT"
11926   "#"
11927   [(set_attr "type" "multi")])
11928
11929 (define_split 
11930   [(set (match_operand:TI 0 "register_operand" "")
11931         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11932                      (match_operand:QI 2 "register_operand" "")))
11933    (clobber (match_scratch:DI 3 ""))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "TARGET_64BIT && reload_completed"
11936   [(const_int 0)]
11937   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11938
11939 (define_split 
11940   [(set (match_operand:TI 0 "register_operand" "")
11941         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11942                      (match_operand:QI 2 "immediate_operand" "")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "TARGET_64BIT && reload_completed"
11945   [(const_int 0)]
11946   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11947
11948 (define_expand "lshrdi3"
11949   [(set (match_operand:DI 0 "shiftdi_operand" "")
11950         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11951                      (match_operand:QI 2 "nonmemory_operand" "")))]
11952   ""
11953   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11954
11955 (define_insn "*lshrdi3_1_one_bit_rex64"
11956   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11957         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11958                      (match_operand:QI 2 "const1_operand" "")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11961    && (TARGET_SHIFT1 || optimize_size)"
11962   "shr{q}\t%0"
11963   [(set_attr "type" "ishift")
11964    (set (attr "length") 
11965      (if_then_else (match_operand:DI 0 "register_operand" "") 
11966         (const_string "2")
11967         (const_string "*")))])
11968
11969 (define_insn "*lshrdi3_1_rex64"
11970   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11971         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11972                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11975   "@
11976    shr{q}\t{%2, %0|%0, %2}
11977    shr{q}\t{%b2, %0|%0, %b2}"
11978   [(set_attr "type" "ishift")
11979    (set_attr "mode" "DI")])
11980
11981 ;; This pattern can't accept a variable shift count, since shifts by
11982 ;; zero don't affect the flags.  We assume that shifts by constant
11983 ;; zero are optimized away.
11984 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11985   [(set (reg FLAGS_REG)
11986         (compare
11987           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11988                        (match_operand:QI 2 "const1_operand" ""))
11989           (const_int 0)))
11990    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11991         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11992   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11993    && (TARGET_SHIFT1 || optimize_size)
11994    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995   "shr{q}\t%0"
11996   [(set_attr "type" "ishift")
11997    (set (attr "length") 
11998      (if_then_else (match_operand:DI 0 "register_operand" "") 
11999         (const_string "2")
12000         (const_string "*")))])
12001
12002 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12003   [(set (reg FLAGS_REG)
12004         (compare
12005           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12006                        (match_operand:QI 2 "const1_operand" ""))
12007           (const_int 0)))
12008    (clobber (match_scratch:DI 0 "=r"))]
12009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010    && (TARGET_SHIFT1 || optimize_size)
12011    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12012   "shr{q}\t%0"
12013   [(set_attr "type" "ishift")
12014    (set_attr "length" "2")])
12015
12016 ;; This pattern can't accept a variable shift count, since shifts by
12017 ;; zero don't affect the flags.  We assume that shifts by constant
12018 ;; zero are optimized away.
12019 (define_insn "*lshrdi3_cmp_rex64"
12020   [(set (reg FLAGS_REG)
12021         (compare
12022           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12023                        (match_operand:QI 2 "const_int_operand" "e"))
12024           (const_int 0)))
12025    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12027   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12028    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12029    && (optimize_size
12030        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12031   "shr{q}\t{%2, %0|%0, %2}"
12032   [(set_attr "type" "ishift")
12033    (set_attr "mode" "DI")])
12034
12035 (define_insn "*lshrdi3_cconly_rex64"
12036   [(set (reg FLAGS_REG)
12037         (compare
12038           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12039                        (match_operand:QI 2 "const_int_operand" "e"))
12040           (const_int 0)))
12041    (clobber (match_scratch:DI 0 "=r"))]
12042   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12043    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12044    && (optimize_size
12045        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12046   "shr{q}\t{%2, %0|%0, %2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "DI")])
12049
12050 (define_insn "*lshrdi3_1"
12051   [(set (match_operand:DI 0 "register_operand" "=r")
12052         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12053                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "!TARGET_64BIT"
12056   "#"
12057   [(set_attr "type" "multi")])
12058
12059 ;; By default we don't ask for a scratch register, because when DImode
12060 ;; values are manipulated, registers are already at a premium.  But if
12061 ;; we have one handy, we won't turn it away.
12062 (define_peephole2
12063   [(match_scratch:SI 3 "r")
12064    (parallel [(set (match_operand:DI 0 "register_operand" "")
12065                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12066                                 (match_operand:QI 2 "nonmemory_operand" "")))
12067               (clobber (reg:CC FLAGS_REG))])
12068    (match_dup 3)]
12069   "!TARGET_64BIT && TARGET_CMOVE"
12070   [(const_int 0)]
12071   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12072
12073 (define_split 
12074   [(set (match_operand:DI 0 "register_operand" "")
12075         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12076                      (match_operand:QI 2 "nonmemory_operand" "")))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12079                      ? flow2_completed : reload_completed)"
12080   [(const_int 0)]
12081   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12082
12083 (define_expand "lshrsi3"
12084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086                      (match_operand:QI 2 "nonmemory_operand" "")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   ""
12089   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12090
12091 (define_insn "*lshrsi3_1_one_bit"
12092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094                      (match_operand:QI 2 "const1_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12097    && (TARGET_SHIFT1 || optimize_size)"
12098   "shr{l}\t%0"
12099   [(set_attr "type" "ishift")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:SI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12104
12105 (define_insn "*lshrsi3_1_one_bit_zext"
12106   [(set (match_operand:DI 0 "register_operand" "=r")
12107         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12108                      (match_operand:QI 2 "const1_operand" "")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111    && (TARGET_SHIFT1 || optimize_size)"
12112   "shr{l}\t%k0"
12113   [(set_attr "type" "ishift")
12114    (set_attr "length" "2")])
12115
12116 (define_insn "*lshrsi3_1"
12117   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12118         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12119                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12120    (clobber (reg:CC FLAGS_REG))]
12121   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12122   "@
12123    shr{l}\t{%2, %0|%0, %2}
12124    shr{l}\t{%b2, %0|%0, %b2}"
12125   [(set_attr "type" "ishift")
12126    (set_attr "mode" "SI")])
12127
12128 (define_insn "*lshrsi3_1_zext"
12129   [(set (match_operand:DI 0 "register_operand" "=r,r")
12130         (zero_extend:DI
12131           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12132                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12133    (clobber (reg:CC FLAGS_REG))]
12134   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12135   "@
12136    shr{l}\t{%2, %k0|%k0, %2}
12137    shr{l}\t{%b2, %k0|%k0, %b2}"
12138   [(set_attr "type" "ishift")
12139    (set_attr "mode" "SI")])
12140
12141 ;; This pattern can't accept a variable shift count, since shifts by
12142 ;; zero don't affect the flags.  We assume that shifts by constant
12143 ;; zero are optimized away.
12144 (define_insn "*lshrsi3_one_bit_cmp"
12145   [(set (reg FLAGS_REG)
12146         (compare
12147           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12148                        (match_operand:QI 2 "const1_operand" ""))
12149           (const_int 0)))
12150    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12151         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12152   "ix86_match_ccmode (insn, CCGOCmode)
12153    && (TARGET_SHIFT1 || optimize_size)
12154    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12155   "shr{l}\t%0"
12156   [(set_attr "type" "ishift")
12157    (set (attr "length") 
12158      (if_then_else (match_operand:SI 0 "register_operand" "") 
12159         (const_string "2")
12160         (const_string "*")))])
12161
12162 (define_insn "*lshrsi3_one_bit_cconly"
12163   [(set (reg FLAGS_REG)
12164         (compare
12165           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12166                        (match_operand:QI 2 "const1_operand" ""))
12167           (const_int 0)))
12168    (clobber (match_scratch:SI 0 "=r"))]
12169   "ix86_match_ccmode (insn, CCGOCmode)
12170    && (TARGET_SHIFT1 || optimize_size)
12171    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12172   "shr{l}\t%0"
12173   [(set_attr "type" "ishift")
12174    (set_attr "length" "2")])
12175
12176 (define_insn "*lshrsi3_cmp_one_bit_zext"
12177   [(set (reg FLAGS_REG)
12178         (compare
12179           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12180                        (match_operand:QI 2 "const1_operand" ""))
12181           (const_int 0)))
12182    (set (match_operand:DI 0 "register_operand" "=r")
12183         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12184   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12185    && (TARGET_SHIFT1 || optimize_size)
12186    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12187   "shr{l}\t%k0"
12188   [(set_attr "type" "ishift")
12189    (set_attr "length" "2")])
12190
12191 ;; This pattern can't accept a variable shift count, since shifts by
12192 ;; zero don't affect the flags.  We assume that shifts by constant
12193 ;; zero are optimized away.
12194 (define_insn "*lshrsi3_cmp"
12195   [(set (reg FLAGS_REG)
12196         (compare
12197           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12198                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12199           (const_int 0)))
12200    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12201         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12202   "ix86_match_ccmode (insn, CCGOCmode)
12203    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12204    && (optimize_size
12205        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12206   "shr{l}\t{%2, %0|%0, %2}"
12207   [(set_attr "type" "ishift")
12208    (set_attr "mode" "SI")])
12209
12210 (define_insn "*lshrsi3_cconly"
12211   [(set (reg FLAGS_REG)
12212       (compare
12213         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12214                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12215         (const_int 0)))
12216    (clobber (match_scratch:SI 0 "=r"))]
12217   "ix86_match_ccmode (insn, CCGOCmode)
12218    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12219    && (optimize_size
12220        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12221   "shr{l}\t{%2, %0|%0, %2}"
12222   [(set_attr "type" "ishift")
12223    (set_attr "mode" "SI")])
12224
12225 (define_insn "*lshrsi3_cmp_zext"
12226   [(set (reg FLAGS_REG)
12227         (compare
12228           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12229                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12230           (const_int 0)))
12231    (set (match_operand:DI 0 "register_operand" "=r")
12232         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12233   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12234    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12235    && (optimize_size
12236        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12237   "shr{l}\t{%2, %k0|%k0, %2}"
12238   [(set_attr "type" "ishift")
12239    (set_attr "mode" "SI")])
12240
12241 (define_expand "lshrhi3"
12242   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12243         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12244                      (match_operand:QI 2 "nonmemory_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   "TARGET_HIMODE_MATH"
12247   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12248
12249 (define_insn "*lshrhi3_1_one_bit"
12250   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12251         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12252                      (match_operand:QI 2 "const1_operand" "")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255    && (TARGET_SHIFT1 || optimize_size)"
12256   "shr{w}\t%0"
12257   [(set_attr "type" "ishift")
12258    (set (attr "length") 
12259      (if_then_else (match_operand 0 "register_operand" "") 
12260         (const_string "2")
12261         (const_string "*")))])
12262
12263 (define_insn "*lshrhi3_1"
12264   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12265         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12266                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12267    (clobber (reg:CC FLAGS_REG))]
12268   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12269   "@
12270    shr{w}\t{%2, %0|%0, %2}
12271    shr{w}\t{%b2, %0|%0, %b2}"
12272   [(set_attr "type" "ishift")
12273    (set_attr "mode" "HI")])
12274
12275 ;; This pattern can't accept a variable shift count, since shifts by
12276 ;; zero don't affect the flags.  We assume that shifts by constant
12277 ;; zero are optimized away.
12278 (define_insn "*lshrhi3_one_bit_cmp"
12279   [(set (reg FLAGS_REG)
12280         (compare
12281           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12282                        (match_operand:QI 2 "const1_operand" ""))
12283           (const_int 0)))
12284    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12285         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12286   "ix86_match_ccmode (insn, CCGOCmode)
12287    && (TARGET_SHIFT1 || optimize_size)
12288    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289   "shr{w}\t%0"
12290   [(set_attr "type" "ishift")
12291    (set (attr "length") 
12292      (if_then_else (match_operand:SI 0 "register_operand" "") 
12293         (const_string "2")
12294         (const_string "*")))])
12295
12296 (define_insn "*lshrhi3_one_bit_cconly"
12297   [(set (reg FLAGS_REG)
12298         (compare
12299           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12300                        (match_operand:QI 2 "const1_operand" ""))
12301           (const_int 0)))
12302    (clobber (match_scratch:HI 0 "=r"))]
12303   "ix86_match_ccmode (insn, CCGOCmode)
12304    && (TARGET_SHIFT1 || optimize_size)
12305    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12306   "shr{w}\t%0"
12307   [(set_attr "type" "ishift")
12308    (set_attr "length" "2")])
12309
12310 ;; This pattern can't accept a variable shift count, since shifts by
12311 ;; zero don't affect the flags.  We assume that shifts by constant
12312 ;; zero are optimized away.
12313 (define_insn "*lshrhi3_cmp"
12314   [(set (reg FLAGS_REG)
12315         (compare
12316           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12317                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12318           (const_int 0)))
12319    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12321   "ix86_match_ccmode (insn, CCGOCmode)
12322    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323    && (optimize_size
12324        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12325   "shr{w}\t{%2, %0|%0, %2}"
12326   [(set_attr "type" "ishift")
12327    (set_attr "mode" "HI")])
12328
12329 (define_insn "*lshrhi3_cconly"
12330   [(set (reg FLAGS_REG)
12331         (compare
12332           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12333                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12334           (const_int 0)))
12335    (clobber (match_scratch:HI 0 "=r"))]
12336   "ix86_match_ccmode (insn, CCGOCmode)
12337    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12338    && (optimize_size
12339        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12340   "shr{w}\t{%2, %0|%0, %2}"
12341   [(set_attr "type" "ishift")
12342    (set_attr "mode" "HI")])
12343
12344 (define_expand "lshrqi3"
12345   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12346         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12347                      (match_operand:QI 2 "nonmemory_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_QIMODE_MATH"
12350   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12351
12352 (define_insn "*lshrqi3_1_one_bit"
12353   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12354         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12355                      (match_operand:QI 2 "const1_operand" "")))
12356    (clobber (reg:CC FLAGS_REG))]
12357   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12358    && (TARGET_SHIFT1 || optimize_size)"
12359   "shr{b}\t%0"
12360   [(set_attr "type" "ishift")
12361    (set (attr "length") 
12362      (if_then_else (match_operand 0 "register_operand" "") 
12363         (const_string "2")
12364         (const_string "*")))])
12365
12366 (define_insn "*lshrqi3_1_one_bit_slp"
12367   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12368         (lshiftrt:QI (match_dup 0)
12369                      (match_operand:QI 1 "const1_operand" "")))
12370    (clobber (reg:CC FLAGS_REG))]
12371   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12372    && (TARGET_SHIFT1 || optimize_size)"
12373   "shr{b}\t%0"
12374   [(set_attr "type" "ishift1")
12375    (set (attr "length") 
12376      (if_then_else (match_operand 0 "register_operand" "") 
12377         (const_string "2")
12378         (const_string "*")))])
12379
12380 (define_insn "*lshrqi3_1"
12381   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12382         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12383                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12384    (clobber (reg:CC FLAGS_REG))]
12385   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12386   "@
12387    shr{b}\t{%2, %0|%0, %2}
12388    shr{b}\t{%b2, %0|%0, %b2}"
12389   [(set_attr "type" "ishift")
12390    (set_attr "mode" "QI")])
12391
12392 (define_insn "*lshrqi3_1_slp"
12393   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12394         (lshiftrt:QI (match_dup 0)
12395                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12398    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12399   "@
12400    shr{b}\t{%1, %0|%0, %1}
12401    shr{b}\t{%b1, %0|%0, %b1}"
12402   [(set_attr "type" "ishift1")
12403    (set_attr "mode" "QI")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrqi2_one_bit_cmp"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12412                        (match_operand:QI 2 "const1_operand" ""))
12413           (const_int 0)))
12414    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12415         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12416   "ix86_match_ccmode (insn, CCGOCmode)
12417    && (TARGET_SHIFT1 || optimize_size)
12418    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12419   "shr{b}\t%0"
12420   [(set_attr "type" "ishift")
12421    (set (attr "length") 
12422      (if_then_else (match_operand:SI 0 "register_operand" "") 
12423         (const_string "2")
12424         (const_string "*")))])
12425
12426 (define_insn "*lshrqi2_one_bit_cconly"
12427   [(set (reg FLAGS_REG)
12428         (compare
12429           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12430                        (match_operand:QI 2 "const1_operand" ""))
12431           (const_int 0)))
12432    (clobber (match_scratch:QI 0 "=q"))]
12433   "ix86_match_ccmode (insn, CCGOCmode)
12434    && (TARGET_SHIFT1 || optimize_size)
12435    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12436   "shr{b}\t%0"
12437   [(set_attr "type" "ishift")
12438    (set_attr "length" "2")])
12439
12440 ;; This pattern can't accept a variable shift count, since shifts by
12441 ;; zero don't affect the flags.  We assume that shifts by constant
12442 ;; zero are optimized away.
12443 (define_insn "*lshrqi2_cmp"
12444   [(set (reg FLAGS_REG)
12445         (compare
12446           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12448           (const_int 0)))
12449    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12450         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12451   "ix86_match_ccmode (insn, CCGOCmode)
12452    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12453    && (optimize_size
12454        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12455   "shr{b}\t{%2, %0|%0, %2}"
12456   [(set_attr "type" "ishift")
12457    (set_attr "mode" "QI")])
12458
12459 (define_insn "*lshrqi2_cconly"
12460   [(set (reg FLAGS_REG)
12461         (compare
12462           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12463                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12464           (const_int 0)))
12465    (clobber (match_scratch:QI 0 "=q"))]
12466   "ix86_match_ccmode (insn, CCGOCmode)
12467    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12468    && (optimize_size
12469        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12470   "shr{b}\t{%2, %0|%0, %2}"
12471   [(set_attr "type" "ishift")
12472    (set_attr "mode" "QI")])
12473 \f
12474 ;; Rotate instructions
12475
12476 (define_expand "rotldi3"
12477   [(set (match_operand:DI 0 "shiftdi_operand" "")
12478         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12479                    (match_operand:QI 2 "nonmemory_operand" "")))
12480    (clobber (reg:CC FLAGS_REG))]
12481  ""
12482 {
12483   if (TARGET_64BIT)
12484     {
12485       ix86_expand_binary_operator (ROTATE, DImode, operands);
12486       DONE;
12487     }
12488   if (!const_1_to_31_operand (operands[2], VOIDmode))
12489     FAIL;
12490   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12491   DONE;
12492 })
12493
12494 ;; Implement rotation using two double-precision shift instructions
12495 ;; and a scratch register.   
12496 (define_insn_and_split "ix86_rotldi3"
12497  [(set (match_operand:DI 0 "register_operand" "=r")
12498        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12499                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12500   (clobber (reg:CC FLAGS_REG))
12501   (clobber (match_scratch:SI 3 "=&r"))]
12502  "!TARGET_64BIT"
12503  "" 
12504  "&& reload_completed"
12505  [(set (match_dup 3) (match_dup 4))
12506   (parallel
12507    [(set (match_dup 4)
12508          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12509                  (lshiftrt:SI (match_dup 5)
12510                               (minus:QI (const_int 32) (match_dup 2)))))
12511     (clobber (reg:CC FLAGS_REG))])
12512   (parallel
12513    [(set (match_dup 5)
12514          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12515                  (lshiftrt:SI (match_dup 3)
12516                               (minus:QI (const_int 32) (match_dup 2)))))
12517     (clobber (reg:CC FLAGS_REG))])]
12518  "split_di (operands, 1, operands + 4, operands + 5);")
12519  
12520 (define_insn "*rotlsi3_1_one_bit_rex64"
12521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12522         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12523                    (match_operand:QI 2 "const1_operand" "")))
12524    (clobber (reg:CC FLAGS_REG))]
12525   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12526    && (TARGET_SHIFT1 || optimize_size)"
12527   "rol{q}\t%0"
12528   [(set_attr "type" "rotate")
12529    (set (attr "length") 
12530      (if_then_else (match_operand:DI 0 "register_operand" "") 
12531         (const_string "2")
12532         (const_string "*")))])
12533
12534 (define_insn "*rotldi3_1_rex64"
12535   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12536         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12537                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12538    (clobber (reg:CC FLAGS_REG))]
12539   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12540   "@
12541    rol{q}\t{%2, %0|%0, %2}
12542    rol{q}\t{%b2, %0|%0, %b2}"
12543   [(set_attr "type" "rotate")
12544    (set_attr "mode" "DI")])
12545
12546 (define_expand "rotlsi3"
12547   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12548         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12549                    (match_operand:QI 2 "nonmemory_operand" "")))
12550    (clobber (reg:CC FLAGS_REG))]
12551   ""
12552   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12553
12554 (define_insn "*rotlsi3_1_one_bit"
12555   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12556         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12557                    (match_operand:QI 2 "const1_operand" "")))
12558    (clobber (reg:CC FLAGS_REG))]
12559   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12560    && (TARGET_SHIFT1 || optimize_size)"
12561   "rol{l}\t%0"
12562   [(set_attr "type" "rotate")
12563    (set (attr "length") 
12564      (if_then_else (match_operand:SI 0 "register_operand" "") 
12565         (const_string "2")
12566         (const_string "*")))])
12567
12568 (define_insn "*rotlsi3_1_one_bit_zext"
12569   [(set (match_operand:DI 0 "register_operand" "=r")
12570         (zero_extend:DI
12571           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12572                      (match_operand:QI 2 "const1_operand" ""))))
12573    (clobber (reg:CC FLAGS_REG))]
12574   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12575    && (TARGET_SHIFT1 || optimize_size)"
12576   "rol{l}\t%k0"
12577   [(set_attr "type" "rotate")
12578    (set_attr "length" "2")])
12579
12580 (define_insn "*rotlsi3_1"
12581   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12582         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12583                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12584    (clobber (reg:CC FLAGS_REG))]
12585   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12586   "@
12587    rol{l}\t{%2, %0|%0, %2}
12588    rol{l}\t{%b2, %0|%0, %b2}"
12589   [(set_attr "type" "rotate")
12590    (set_attr "mode" "SI")])
12591
12592 (define_insn "*rotlsi3_1_zext"
12593   [(set (match_operand:DI 0 "register_operand" "=r,r")
12594         (zero_extend:DI
12595           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12596                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12599   "@
12600    rol{l}\t{%2, %k0|%k0, %2}
12601    rol{l}\t{%b2, %k0|%k0, %b2}"
12602   [(set_attr "type" "rotate")
12603    (set_attr "mode" "SI")])
12604
12605 (define_expand "rotlhi3"
12606   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12607         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12608                    (match_operand:QI 2 "nonmemory_operand" "")))
12609    (clobber (reg:CC FLAGS_REG))]
12610   "TARGET_HIMODE_MATH"
12611   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12612
12613 (define_insn "*rotlhi3_1_one_bit"
12614   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12615         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12616                    (match_operand:QI 2 "const1_operand" "")))
12617    (clobber (reg:CC FLAGS_REG))]
12618   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12619    && (TARGET_SHIFT1 || optimize_size)"
12620   "rol{w}\t%0"
12621   [(set_attr "type" "rotate")
12622    (set (attr "length") 
12623      (if_then_else (match_operand 0 "register_operand" "") 
12624         (const_string "2")
12625         (const_string "*")))])
12626
12627 (define_insn "*rotlhi3_1"
12628   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12629         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12630                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12631    (clobber (reg:CC FLAGS_REG))]
12632   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12633   "@
12634    rol{w}\t{%2, %0|%0, %2}
12635    rol{w}\t{%b2, %0|%0, %b2}"
12636   [(set_attr "type" "rotate")
12637    (set_attr "mode" "HI")])
12638
12639 (define_expand "rotlqi3"
12640   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12641         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12642                    (match_operand:QI 2 "nonmemory_operand" "")))
12643    (clobber (reg:CC FLAGS_REG))]
12644   "TARGET_QIMODE_MATH"
12645   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12646
12647 (define_insn "*rotlqi3_1_one_bit_slp"
12648   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12649         (rotate:QI (match_dup 0)
12650                    (match_operand:QI 1 "const1_operand" "")))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12653    && (TARGET_SHIFT1 || optimize_size)"
12654   "rol{b}\t%0"
12655   [(set_attr "type" "rotate1")
12656    (set (attr "length") 
12657      (if_then_else (match_operand 0 "register_operand" "") 
12658         (const_string "2")
12659         (const_string "*")))])
12660
12661 (define_insn "*rotlqi3_1_one_bit"
12662   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12663         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12664                    (match_operand:QI 2 "const1_operand" "")))
12665    (clobber (reg:CC FLAGS_REG))]
12666   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12667    && (TARGET_SHIFT1 || optimize_size)"
12668   "rol{b}\t%0"
12669   [(set_attr "type" "rotate")
12670    (set (attr "length") 
12671      (if_then_else (match_operand 0 "register_operand" "") 
12672         (const_string "2")
12673         (const_string "*")))])
12674
12675 (define_insn "*rotlqi3_1_slp"
12676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12677         (rotate:QI (match_dup 0)
12678                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12679    (clobber (reg:CC FLAGS_REG))]
12680   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12681    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12682   "@
12683    rol{b}\t{%1, %0|%0, %1}
12684    rol{b}\t{%b1, %0|%0, %b1}"
12685   [(set_attr "type" "rotate1")
12686    (set_attr "mode" "QI")])
12687
12688 (define_insn "*rotlqi3_1"
12689   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12690         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12691                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12692    (clobber (reg:CC FLAGS_REG))]
12693   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12694   "@
12695    rol{b}\t{%2, %0|%0, %2}
12696    rol{b}\t{%b2, %0|%0, %b2}"
12697   [(set_attr "type" "rotate")
12698    (set_attr "mode" "QI")])
12699
12700 (define_expand "rotrdi3"
12701   [(set (match_operand:DI 0 "shiftdi_operand" "")
12702         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12703                    (match_operand:QI 2 "nonmemory_operand" "")))
12704    (clobber (reg:CC FLAGS_REG))]
12705  ""
12706 {
12707   if (TARGET_64BIT)
12708     {
12709       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12710       DONE;
12711     }
12712   if (!const_1_to_31_operand (operands[2], VOIDmode))
12713     FAIL;
12714   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12715   DONE;
12716 })
12717   
12718 ;; Implement rotation using two double-precision shift instructions
12719 ;; and a scratch register.   
12720 (define_insn_and_split "ix86_rotrdi3"
12721  [(set (match_operand:DI 0 "register_operand" "=r")
12722        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12723                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12724   (clobber (reg:CC FLAGS_REG))
12725   (clobber (match_scratch:SI 3 "=&r"))]
12726  "!TARGET_64BIT"
12727  ""
12728  "&& reload_completed"
12729  [(set (match_dup 3) (match_dup 4))
12730   (parallel
12731    [(set (match_dup 4)
12732          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12733                  (ashift:SI (match_dup 5)
12734                             (minus:QI (const_int 32) (match_dup 2)))))
12735     (clobber (reg:CC FLAGS_REG))])
12736   (parallel
12737    [(set (match_dup 5)
12738          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12739                  (ashift:SI (match_dup 3)
12740                             (minus:QI (const_int 32) (match_dup 2)))))
12741     (clobber (reg:CC FLAGS_REG))])]
12742  "split_di (operands, 1, operands + 4, operands + 5);")
12743
12744 (define_insn "*rotrdi3_1_one_bit_rex64"
12745   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12746         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12747                      (match_operand:QI 2 "const1_operand" "")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12750    && (TARGET_SHIFT1 || optimize_size)"
12751   "ror{q}\t%0"
12752   [(set_attr "type" "rotate")
12753    (set (attr "length") 
12754      (if_then_else (match_operand:DI 0 "register_operand" "") 
12755         (const_string "2")
12756         (const_string "*")))])
12757
12758 (define_insn "*rotrdi3_1_rex64"
12759   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12760         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12761                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12764   "@
12765    ror{q}\t{%2, %0|%0, %2}
12766    ror{q}\t{%b2, %0|%0, %b2}"
12767   [(set_attr "type" "rotate")
12768    (set_attr "mode" "DI")])
12769
12770 (define_expand "rotrsi3"
12771   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12772         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12773                      (match_operand:QI 2 "nonmemory_operand" "")))
12774    (clobber (reg:CC FLAGS_REG))]
12775   ""
12776   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12777
12778 (define_insn "*rotrsi3_1_one_bit"
12779   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12780         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12781                      (match_operand:QI 2 "const1_operand" "")))
12782    (clobber (reg:CC FLAGS_REG))]
12783   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12784    && (TARGET_SHIFT1 || optimize_size)"
12785   "ror{l}\t%0"
12786   [(set_attr "type" "rotate")
12787    (set (attr "length") 
12788      (if_then_else (match_operand:SI 0 "register_operand" "") 
12789         (const_string "2")
12790         (const_string "*")))])
12791
12792 (define_insn "*rotrsi3_1_one_bit_zext"
12793   [(set (match_operand:DI 0 "register_operand" "=r")
12794         (zero_extend:DI
12795           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12796                        (match_operand:QI 2 "const1_operand" ""))))
12797    (clobber (reg:CC FLAGS_REG))]
12798   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12799    && (TARGET_SHIFT1 || optimize_size)"
12800   "ror{l}\t%k0"
12801   [(set_attr "type" "rotate")
12802    (set (attr "length") 
12803      (if_then_else (match_operand:SI 0 "register_operand" "") 
12804         (const_string "2")
12805         (const_string "*")))])
12806
12807 (define_insn "*rotrsi3_1"
12808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12809         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12810                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12813   "@
12814    ror{l}\t{%2, %0|%0, %2}
12815    ror{l}\t{%b2, %0|%0, %b2}"
12816   [(set_attr "type" "rotate")
12817    (set_attr "mode" "SI")])
12818
12819 (define_insn "*rotrsi3_1_zext"
12820   [(set (match_operand:DI 0 "register_operand" "=r,r")
12821         (zero_extend:DI
12822           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12823                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12826   "@
12827    ror{l}\t{%2, %k0|%k0, %2}
12828    ror{l}\t{%b2, %k0|%k0, %b2}"
12829   [(set_attr "type" "rotate")
12830    (set_attr "mode" "SI")])
12831
12832 (define_expand "rotrhi3"
12833   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12834         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12835                      (match_operand:QI 2 "nonmemory_operand" "")))
12836    (clobber (reg:CC FLAGS_REG))]
12837   "TARGET_HIMODE_MATH"
12838   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12839
12840 (define_insn "*rotrhi3_one_bit"
12841   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12842         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12843                      (match_operand:QI 2 "const1_operand" "")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12846    && (TARGET_SHIFT1 || optimize_size)"
12847   "ror{w}\t%0"
12848   [(set_attr "type" "rotate")
12849    (set (attr "length") 
12850      (if_then_else (match_operand 0 "register_operand" "") 
12851         (const_string "2")
12852         (const_string "*")))])
12853
12854 (define_insn "*rotrhi3"
12855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12856         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12857                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12860   "@
12861    ror{w}\t{%2, %0|%0, %2}
12862    ror{w}\t{%b2, %0|%0, %b2}"
12863   [(set_attr "type" "rotate")
12864    (set_attr "mode" "HI")])
12865
12866 (define_expand "rotrqi3"
12867   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12869                      (match_operand:QI 2 "nonmemory_operand" "")))
12870    (clobber (reg:CC FLAGS_REG))]
12871   "TARGET_QIMODE_MATH"
12872   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12873
12874 (define_insn "*rotrqi3_1_one_bit"
12875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12876         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12877                      (match_operand:QI 2 "const1_operand" "")))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12880    && (TARGET_SHIFT1 || optimize_size)"
12881   "ror{b}\t%0"
12882   [(set_attr "type" "rotate")
12883    (set (attr "length") 
12884      (if_then_else (match_operand 0 "register_operand" "") 
12885         (const_string "2")
12886         (const_string "*")))])
12887
12888 (define_insn "*rotrqi3_1_one_bit_slp"
12889   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12890         (rotatert:QI (match_dup 0)
12891                      (match_operand:QI 1 "const1_operand" "")))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12894    && (TARGET_SHIFT1 || optimize_size)"
12895   "ror{b}\t%0"
12896   [(set_attr "type" "rotate1")
12897    (set (attr "length") 
12898      (if_then_else (match_operand 0 "register_operand" "") 
12899         (const_string "2")
12900         (const_string "*")))])
12901
12902 (define_insn "*rotrqi3_1"
12903   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12904         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12905                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12906    (clobber (reg:CC FLAGS_REG))]
12907   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12908   "@
12909    ror{b}\t{%2, %0|%0, %2}
12910    ror{b}\t{%b2, %0|%0, %b2}"
12911   [(set_attr "type" "rotate")
12912    (set_attr "mode" "QI")])
12913
12914 (define_insn "*rotrqi3_1_slp"
12915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12916         (rotatert:QI (match_dup 0)
12917                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12918    (clobber (reg:CC FLAGS_REG))]
12919   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12921   "@
12922    ror{b}\t{%1, %0|%0, %1}
12923    ror{b}\t{%b1, %0|%0, %b1}"
12924   [(set_attr "type" "rotate1")
12925    (set_attr "mode" "QI")])
12926 \f
12927 ;; Bit set / bit test instructions
12928
12929 (define_expand "extv"
12930   [(set (match_operand:SI 0 "register_operand" "")
12931         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12932                          (match_operand:SI 2 "const8_operand" "")
12933                          (match_operand:SI 3 "const8_operand" "")))]
12934   ""
12935 {
12936   /* Handle extractions from %ah et al.  */
12937   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12938     FAIL;
12939
12940   /* From mips.md: extract_bit_field doesn't verify that our source
12941      matches the predicate, so check it again here.  */
12942   if (! ext_register_operand (operands[1], VOIDmode))
12943     FAIL;
12944 })
12945
12946 (define_expand "extzv"
12947   [(set (match_operand:SI 0 "register_operand" "")
12948         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12949                          (match_operand:SI 2 "const8_operand" "")
12950                          (match_operand:SI 3 "const8_operand" "")))]
12951   ""
12952 {
12953   /* Handle extractions from %ah et al.  */
12954   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12955     FAIL;
12956
12957   /* From mips.md: extract_bit_field doesn't verify that our source
12958      matches the predicate, so check it again here.  */
12959   if (! ext_register_operand (operands[1], VOIDmode))
12960     FAIL;
12961 })
12962
12963 (define_expand "insv"
12964   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12965                       (match_operand 1 "const8_operand" "")
12966                       (match_operand 2 "const8_operand" ""))
12967         (match_operand 3 "register_operand" ""))]
12968   ""
12969 {
12970   /* Handle insertions to %ah et al.  */
12971   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12972     FAIL;
12973
12974   /* From mips.md: insert_bit_field doesn't verify that our source
12975      matches the predicate, so check it again here.  */
12976   if (! ext_register_operand (operands[0], VOIDmode))
12977     FAIL;
12978
12979   if (TARGET_64BIT)
12980     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12981   else
12982     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12983
12984   DONE;
12985 })
12986
12987 ;; %%% bts, btr, btc, bt.
12988 ;; In general these instructions are *slow* when applied to memory,
12989 ;; since they enforce atomic operation.  When applied to registers,
12990 ;; it depends on the cpu implementation.  They're never faster than
12991 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12992 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12993 ;; within the instruction itself, so operating on bits in the high
12994 ;; 32-bits of a register becomes easier.
12995 ;;
12996 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12997 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12998 ;; negdf respectively, so they can never be disabled entirely.
12999
13000 (define_insn "*btsq"
13001   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13002                          (const_int 1)
13003                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13004         (const_int 1))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13007   "bts{q} %1,%0"
13008   [(set_attr "type" "alu1")])
13009
13010 (define_insn "*btrq"
13011   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13012                          (const_int 1)
13013                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13014         (const_int 0))
13015    (clobber (reg:CC FLAGS_REG))]
13016   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13017   "btr{q} %1,%0"
13018   [(set_attr "type" "alu1")])
13019
13020 (define_insn "*btcq"
13021   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13022                          (const_int 1)
13023                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13024         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13025    (clobber (reg:CC FLAGS_REG))]
13026   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13027   "btc{q} %1,%0"
13028   [(set_attr "type" "alu1")])
13029
13030 ;; Allow Nocona to avoid these instructions if a register is available.
13031
13032 (define_peephole2
13033   [(match_scratch:DI 2 "r")
13034    (parallel [(set (zero_extract:DI
13035                      (match_operand:DI 0 "register_operand" "")
13036                      (const_int 1)
13037                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13038                    (const_int 1))
13039               (clobber (reg:CC FLAGS_REG))])]
13040   "TARGET_64BIT && !TARGET_USE_BT"
13041   [(const_int 0)]
13042 {
13043   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13044   rtx op1;
13045
13046   if (HOST_BITS_PER_WIDE_INT >= 64)
13047     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13048   else if (i < HOST_BITS_PER_WIDE_INT)
13049     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13050   else
13051     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13052
13053   op1 = immed_double_const (lo, hi, DImode);
13054   if (i >= 31)
13055     {
13056       emit_move_insn (operands[2], op1);
13057       op1 = operands[2];
13058     }
13059
13060   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13061   DONE;
13062 })
13063
13064 (define_peephole2
13065   [(match_scratch:DI 2 "r")
13066    (parallel [(set (zero_extract:DI
13067                      (match_operand:DI 0 "register_operand" "")
13068                      (const_int 1)
13069                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13070                    (const_int 0))
13071               (clobber (reg:CC FLAGS_REG))])]
13072   "TARGET_64BIT && !TARGET_USE_BT"
13073   [(const_int 0)]
13074 {
13075   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13076   rtx op1;
13077
13078   if (HOST_BITS_PER_WIDE_INT >= 64)
13079     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13080   else if (i < HOST_BITS_PER_WIDE_INT)
13081     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13082   else
13083     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13084
13085   op1 = immed_double_const (~lo, ~hi, DImode);
13086   if (i >= 32)
13087     {
13088       emit_move_insn (operands[2], op1);
13089       op1 = operands[2];
13090     }
13091
13092   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13093   DONE;
13094 })
13095
13096 (define_peephole2
13097   [(match_scratch:DI 2 "r")
13098    (parallel [(set (zero_extract:DI
13099                      (match_operand:DI 0 "register_operand" "")
13100                      (const_int 1)
13101                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13102               (not:DI (zero_extract:DI
13103                         (match_dup 0) (const_int 1) (match_dup 1))))
13104               (clobber (reg:CC FLAGS_REG))])]
13105   "TARGET_64BIT && !TARGET_USE_BT"
13106   [(const_int 0)]
13107 {
13108   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13109   rtx op1;
13110
13111   if (HOST_BITS_PER_WIDE_INT >= 64)
13112     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13113   else if (i < HOST_BITS_PER_WIDE_INT)
13114     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13115   else
13116     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13117
13118   op1 = immed_double_const (lo, hi, DImode);
13119   if (i >= 31)
13120     {
13121       emit_move_insn (operands[2], op1);
13122       op1 = operands[2];
13123     }
13124
13125   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13126   DONE;
13127 })
13128 \f
13129 ;; Store-flag instructions.
13130
13131 ;; For all sCOND expanders, also expand the compare or test insn that
13132 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13133
13134 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13135 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13136 ;; way, which can later delete the movzx if only QImode is needed.
13137
13138 (define_expand "seq"
13139   [(set (match_operand:QI 0 "register_operand" "")
13140         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13141   ""
13142   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13143
13144 (define_expand "sne"
13145   [(set (match_operand:QI 0 "register_operand" "")
13146         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13147   ""
13148   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13149
13150 (define_expand "sgt"
13151   [(set (match_operand:QI 0 "register_operand" "")
13152         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13153   ""
13154   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13155
13156 (define_expand "sgtu"
13157   [(set (match_operand:QI 0 "register_operand" "")
13158         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13159   ""
13160   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13161
13162 (define_expand "slt"
13163   [(set (match_operand:QI 0 "register_operand" "")
13164         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13165   ""
13166   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13167
13168 (define_expand "sltu"
13169   [(set (match_operand:QI 0 "register_operand" "")
13170         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13171   ""
13172   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13173
13174 (define_expand "sge"
13175   [(set (match_operand:QI 0 "register_operand" "")
13176         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13177   ""
13178   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13179
13180 (define_expand "sgeu"
13181   [(set (match_operand:QI 0 "register_operand" "")
13182         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13183   ""
13184   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13185
13186 (define_expand "sle"
13187   [(set (match_operand:QI 0 "register_operand" "")
13188         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13189   ""
13190   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13191
13192 (define_expand "sleu"
13193   [(set (match_operand:QI 0 "register_operand" "")
13194         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13195   ""
13196   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13197
13198 (define_expand "sunordered"
13199   [(set (match_operand:QI 0 "register_operand" "")
13200         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13201   "TARGET_80387 || TARGET_SSE"
13202   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13203
13204 (define_expand "sordered"
13205   [(set (match_operand:QI 0 "register_operand" "")
13206         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13207   "TARGET_80387"
13208   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13209
13210 (define_expand "suneq"
13211   [(set (match_operand:QI 0 "register_operand" "")
13212         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13213   "TARGET_80387 || TARGET_SSE"
13214   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13215
13216 (define_expand "sunge"
13217   [(set (match_operand:QI 0 "register_operand" "")
13218         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13219   "TARGET_80387 || TARGET_SSE"
13220   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13221
13222 (define_expand "sungt"
13223   [(set (match_operand:QI 0 "register_operand" "")
13224         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13225   "TARGET_80387 || TARGET_SSE"
13226   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13227
13228 (define_expand "sunle"
13229   [(set (match_operand:QI 0 "register_operand" "")
13230         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13231   "TARGET_80387 || TARGET_SSE"
13232   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13233
13234 (define_expand "sunlt"
13235   [(set (match_operand:QI 0 "register_operand" "")
13236         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13237   "TARGET_80387 || TARGET_SSE"
13238   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13239
13240 (define_expand "sltgt"
13241   [(set (match_operand:QI 0 "register_operand" "")
13242         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13243   "TARGET_80387 || TARGET_SSE"
13244   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13245
13246 (define_insn "*setcc_1"
13247   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13248         (match_operator:QI 1 "ix86_comparison_operator"
13249           [(reg FLAGS_REG) (const_int 0)]))]
13250   ""
13251   "set%C1\t%0"
13252   [(set_attr "type" "setcc")
13253    (set_attr "mode" "QI")])
13254
13255 (define_insn "*setcc_2"
13256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13257         (match_operator:QI 1 "ix86_comparison_operator"
13258           [(reg FLAGS_REG) (const_int 0)]))]
13259   ""
13260   "set%C1\t%0"
13261   [(set_attr "type" "setcc")
13262    (set_attr "mode" "QI")])
13263
13264 ;; In general it is not safe to assume too much about CCmode registers,
13265 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13266 ;; conditions this is safe on x86, so help combine not create
13267 ;;
13268 ;;      seta    %al
13269 ;;      testb   %al, %al
13270 ;;      sete    %al
13271
13272 (define_split 
13273   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13274         (ne:QI (match_operator 1 "ix86_comparison_operator"
13275                  [(reg FLAGS_REG) (const_int 0)])
13276             (const_int 0)))]
13277   ""
13278   [(set (match_dup 0) (match_dup 1))]
13279 {
13280   PUT_MODE (operands[1], QImode);
13281 })
13282
13283 (define_split 
13284   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13285         (ne:QI (match_operator 1 "ix86_comparison_operator"
13286                  [(reg FLAGS_REG) (const_int 0)])
13287             (const_int 0)))]
13288   ""
13289   [(set (match_dup 0) (match_dup 1))]
13290 {
13291   PUT_MODE (operands[1], QImode);
13292 })
13293
13294 (define_split 
13295   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13296         (eq:QI (match_operator 1 "ix86_comparison_operator"
13297                  [(reg FLAGS_REG) (const_int 0)])
13298             (const_int 0)))]
13299   ""
13300   [(set (match_dup 0) (match_dup 1))]
13301 {
13302   rtx new_op1 = copy_rtx (operands[1]);
13303   operands[1] = new_op1;
13304   PUT_MODE (new_op1, QImode);
13305   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13306                                              GET_MODE (XEXP (new_op1, 0))));
13307
13308   /* Make sure that (a) the CCmode we have for the flags is strong
13309      enough for the reversed compare or (b) we have a valid FP compare.  */
13310   if (! ix86_comparison_operator (new_op1, VOIDmode))
13311     FAIL;
13312 })
13313
13314 (define_split 
13315   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13316         (eq:QI (match_operator 1 "ix86_comparison_operator"
13317                  [(reg FLAGS_REG) (const_int 0)])
13318             (const_int 0)))]
13319   ""
13320   [(set (match_dup 0) (match_dup 1))]
13321 {
13322   rtx new_op1 = copy_rtx (operands[1]);
13323   operands[1] = new_op1;
13324   PUT_MODE (new_op1, QImode);
13325   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13326                                              GET_MODE (XEXP (new_op1, 0))));
13327
13328   /* Make sure that (a) the CCmode we have for the flags is strong
13329      enough for the reversed compare or (b) we have a valid FP compare.  */
13330   if (! ix86_comparison_operator (new_op1, VOIDmode))
13331     FAIL;
13332 })
13333
13334 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13335 ;; subsequent logical operations are used to imitate conditional moves.
13336 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13337 ;; it directly.
13338
13339 (define_insn "*sse_setccsf"
13340   [(set (match_operand:SF 0 "register_operand" "=x")
13341         (match_operator:SF 1 "sse_comparison_operator"
13342           [(match_operand:SF 2 "register_operand" "0")
13343            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13344   "TARGET_SSE"
13345   "cmp%D1ss\t{%3, %0|%0, %3}"
13346   [(set_attr "type" "ssecmp")
13347    (set_attr "mode" "SF")])
13348
13349 (define_insn "*sse_setccdf"
13350   [(set (match_operand:DF 0 "register_operand" "=Y")
13351         (match_operator:DF 1 "sse_comparison_operator"
13352           [(match_operand:DF 2 "register_operand" "0")
13353            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13354   "TARGET_SSE2"
13355   "cmp%D1sd\t{%3, %0|%0, %3}"
13356   [(set_attr "type" "ssecmp")
13357    (set_attr "mode" "DF")])
13358 \f
13359 ;; Basic conditional jump instructions.
13360 ;; We ignore the overflow flag for signed branch instructions.
13361
13362 ;; For all bCOND expanders, also expand the compare or test insn that
13363 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13364
13365 (define_expand "beq"
13366   [(set (pc)
13367         (if_then_else (match_dup 1)
13368                       (label_ref (match_operand 0 "" ""))
13369                       (pc)))]
13370   ""
13371   "ix86_expand_branch (EQ, operands[0]); DONE;")
13372
13373 (define_expand "bne"
13374   [(set (pc)
13375         (if_then_else (match_dup 1)
13376                       (label_ref (match_operand 0 "" ""))
13377                       (pc)))]
13378   ""
13379   "ix86_expand_branch (NE, operands[0]); DONE;")
13380
13381 (define_expand "bgt"
13382   [(set (pc)
13383         (if_then_else (match_dup 1)
13384                       (label_ref (match_operand 0 "" ""))
13385                       (pc)))]
13386   ""
13387   "ix86_expand_branch (GT, operands[0]); DONE;")
13388
13389 (define_expand "bgtu"
13390   [(set (pc)
13391         (if_then_else (match_dup 1)
13392                       (label_ref (match_operand 0 "" ""))
13393                       (pc)))]
13394   ""
13395   "ix86_expand_branch (GTU, operands[0]); DONE;")
13396
13397 (define_expand "blt"
13398   [(set (pc)
13399         (if_then_else (match_dup 1)
13400                       (label_ref (match_operand 0 "" ""))
13401                       (pc)))]
13402   ""
13403   "ix86_expand_branch (LT, operands[0]); DONE;")
13404
13405 (define_expand "bltu"
13406   [(set (pc)
13407         (if_then_else (match_dup 1)
13408                       (label_ref (match_operand 0 "" ""))
13409                       (pc)))]
13410   ""
13411   "ix86_expand_branch (LTU, operands[0]); DONE;")
13412
13413 (define_expand "bge"
13414   [(set (pc)
13415         (if_then_else (match_dup 1)
13416                       (label_ref (match_operand 0 "" ""))
13417                       (pc)))]
13418   ""
13419   "ix86_expand_branch (GE, operands[0]); DONE;")
13420
13421 (define_expand "bgeu"
13422   [(set (pc)
13423         (if_then_else (match_dup 1)
13424                       (label_ref (match_operand 0 "" ""))
13425                       (pc)))]
13426   ""
13427   "ix86_expand_branch (GEU, operands[0]); DONE;")
13428
13429 (define_expand "ble"
13430   [(set (pc)
13431         (if_then_else (match_dup 1)
13432                       (label_ref (match_operand 0 "" ""))
13433                       (pc)))]
13434   ""
13435   "ix86_expand_branch (LE, operands[0]); DONE;")
13436
13437 (define_expand "bleu"
13438   [(set (pc)
13439         (if_then_else (match_dup 1)
13440                       (label_ref (match_operand 0 "" ""))
13441                       (pc)))]
13442   ""
13443   "ix86_expand_branch (LEU, operands[0]); DONE;")
13444
13445 (define_expand "bunordered"
13446   [(set (pc)
13447         (if_then_else (match_dup 1)
13448                       (label_ref (match_operand 0 "" ""))
13449                       (pc)))]
13450   "TARGET_80387 || TARGET_SSE_MATH"
13451   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13452
13453 (define_expand "bordered"
13454   [(set (pc)
13455         (if_then_else (match_dup 1)
13456                       (label_ref (match_operand 0 "" ""))
13457                       (pc)))]
13458   "TARGET_80387 || TARGET_SSE_MATH"
13459   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13460
13461 (define_expand "buneq"
13462   [(set (pc)
13463         (if_then_else (match_dup 1)
13464                       (label_ref (match_operand 0 "" ""))
13465                       (pc)))]
13466   "TARGET_80387 || TARGET_SSE_MATH"
13467   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13468
13469 (define_expand "bunge"
13470   [(set (pc)
13471         (if_then_else (match_dup 1)
13472                       (label_ref (match_operand 0 "" ""))
13473                       (pc)))]
13474   "TARGET_80387 || TARGET_SSE_MATH"
13475   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13476
13477 (define_expand "bungt"
13478   [(set (pc)
13479         (if_then_else (match_dup 1)
13480                       (label_ref (match_operand 0 "" ""))
13481                       (pc)))]
13482   "TARGET_80387 || TARGET_SSE_MATH"
13483   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13484
13485 (define_expand "bunle"
13486   [(set (pc)
13487         (if_then_else (match_dup 1)
13488                       (label_ref (match_operand 0 "" ""))
13489                       (pc)))]
13490   "TARGET_80387 || TARGET_SSE_MATH"
13491   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13492
13493 (define_expand "bunlt"
13494   [(set (pc)
13495         (if_then_else (match_dup 1)
13496                       (label_ref (match_operand 0 "" ""))
13497                       (pc)))]
13498   "TARGET_80387 || TARGET_SSE_MATH"
13499   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13500
13501 (define_expand "bltgt"
13502   [(set (pc)
13503         (if_then_else (match_dup 1)
13504                       (label_ref (match_operand 0 "" ""))
13505                       (pc)))]
13506   "TARGET_80387 || TARGET_SSE_MATH"
13507   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13508
13509 (define_insn "*jcc_1"
13510   [(set (pc)
13511         (if_then_else (match_operator 1 "ix86_comparison_operator"
13512                                       [(reg FLAGS_REG) (const_int 0)])
13513                       (label_ref (match_operand 0 "" ""))
13514                       (pc)))]
13515   ""
13516   "%+j%C1\t%l0"
13517   [(set_attr "type" "ibr")
13518    (set_attr "modrm" "0")
13519    (set (attr "length")
13520            (if_then_else (and (ge (minus (match_dup 0) (pc))
13521                                   (const_int -126))
13522                               (lt (minus (match_dup 0) (pc))
13523                                   (const_int 128)))
13524              (const_int 2)
13525              (const_int 6)))])
13526
13527 (define_insn "*jcc_2"
13528   [(set (pc)
13529         (if_then_else (match_operator 1 "ix86_comparison_operator"
13530                                       [(reg FLAGS_REG) (const_int 0)])
13531                       (pc)
13532                       (label_ref (match_operand 0 "" ""))))]
13533   ""
13534   "%+j%c1\t%l0"
13535   [(set_attr "type" "ibr")
13536    (set_attr "modrm" "0")
13537    (set (attr "length")
13538            (if_then_else (and (ge (minus (match_dup 0) (pc))
13539                                   (const_int -126))
13540                               (lt (minus (match_dup 0) (pc))
13541                                   (const_int 128)))
13542              (const_int 2)
13543              (const_int 6)))])
13544
13545 ;; In general it is not safe to assume too much about CCmode registers,
13546 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13547 ;; conditions this is safe on x86, so help combine not create
13548 ;;
13549 ;;      seta    %al
13550 ;;      testb   %al, %al
13551 ;;      je      Lfoo
13552
13553 (define_split 
13554   [(set (pc)
13555         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13556                                       [(reg FLAGS_REG) (const_int 0)])
13557                           (const_int 0))
13558                       (label_ref (match_operand 1 "" ""))
13559                       (pc)))]
13560   ""
13561   [(set (pc)
13562         (if_then_else (match_dup 0)
13563                       (label_ref (match_dup 1))
13564                       (pc)))]
13565 {
13566   PUT_MODE (operands[0], VOIDmode);
13567 })
13568   
13569 (define_split 
13570   [(set (pc)
13571         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13572                                       [(reg FLAGS_REG) (const_int 0)])
13573                           (const_int 0))
13574                       (label_ref (match_operand 1 "" ""))
13575                       (pc)))]
13576   ""
13577   [(set (pc)
13578         (if_then_else (match_dup 0)
13579                       (label_ref (match_dup 1))
13580                       (pc)))]
13581 {
13582   rtx new_op0 = copy_rtx (operands[0]);
13583   operands[0] = new_op0;
13584   PUT_MODE (new_op0, VOIDmode);
13585   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13586                                              GET_MODE (XEXP (new_op0, 0))));
13587
13588   /* Make sure that (a) the CCmode we have for the flags is strong
13589      enough for the reversed compare or (b) we have a valid FP compare.  */
13590   if (! ix86_comparison_operator (new_op0, VOIDmode))
13591     FAIL;
13592 })
13593
13594 ;; Define combination compare-and-branch fp compare instructions to use
13595 ;; during early optimization.  Splitting the operation apart early makes
13596 ;; for bad code when we want to reverse the operation.
13597
13598 (define_insn "*fp_jcc_1_mixed"
13599   [(set (pc)
13600         (if_then_else (match_operator 0 "comparison_operator"
13601                         [(match_operand 1 "register_operand" "f,x")
13602                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13603           (label_ref (match_operand 3 "" ""))
13604           (pc)))
13605    (clobber (reg:CCFP FPSR_REG))
13606    (clobber (reg:CCFP FLAGS_REG))]
13607   "TARGET_MIX_SSE_I387
13608    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13609    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13610    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13611   "#")
13612
13613 (define_insn "*fp_jcc_1_sse"
13614   [(set (pc)
13615         (if_then_else (match_operator 0 "comparison_operator"
13616                         [(match_operand 1 "register_operand" "x")
13617                          (match_operand 2 "nonimmediate_operand" "xm")])
13618           (label_ref (match_operand 3 "" ""))
13619           (pc)))
13620    (clobber (reg:CCFP FPSR_REG))
13621    (clobber (reg:CCFP FLAGS_REG))]
13622   "TARGET_SSE_MATH
13623    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13624    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13625    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13626   "#")
13627
13628 (define_insn "*fp_jcc_1_387"
13629   [(set (pc)
13630         (if_then_else (match_operator 0 "comparison_operator"
13631                         [(match_operand 1 "register_operand" "f")
13632                          (match_operand 2 "register_operand" "f")])
13633           (label_ref (match_operand 3 "" ""))
13634           (pc)))
13635    (clobber (reg:CCFP FPSR_REG))
13636    (clobber (reg:CCFP FLAGS_REG))]
13637   "TARGET_CMOVE && TARGET_80387
13638    && FLOAT_MODE_P (GET_MODE (operands[1]))
13639    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13641   "#")
13642
13643 (define_insn "*fp_jcc_2_mixed"
13644   [(set (pc)
13645         (if_then_else (match_operator 0 "comparison_operator"
13646                         [(match_operand 1 "register_operand" "f,x")
13647                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13648           (pc)
13649           (label_ref (match_operand 3 "" ""))))
13650    (clobber (reg:CCFP FPSR_REG))
13651    (clobber (reg:CCFP FLAGS_REG))]
13652   "TARGET_MIX_SSE_I387
13653    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13654    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13655    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13656   "#")
13657
13658 (define_insn "*fp_jcc_2_sse"
13659   [(set (pc)
13660         (if_then_else (match_operator 0 "comparison_operator"
13661                         [(match_operand 1 "register_operand" "x")
13662                          (match_operand 2 "nonimmediate_operand" "xm")])
13663           (pc)
13664           (label_ref (match_operand 3 "" ""))))
13665    (clobber (reg:CCFP FPSR_REG))
13666    (clobber (reg:CCFP FLAGS_REG))]
13667   "TARGET_SSE_MATH
13668    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13669    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13670    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13671   "#")
13672
13673 (define_insn "*fp_jcc_2_387"
13674   [(set (pc)
13675         (if_then_else (match_operator 0 "comparison_operator"
13676                         [(match_operand 1 "register_operand" "f")
13677                          (match_operand 2 "register_operand" "f")])
13678           (pc)
13679           (label_ref (match_operand 3 "" ""))))
13680    (clobber (reg:CCFP FPSR_REG))
13681    (clobber (reg:CCFP FLAGS_REG))]
13682   "TARGET_CMOVE && TARGET_80387
13683    && FLOAT_MODE_P (GET_MODE (operands[1]))
13684    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13685    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13686   "#")
13687
13688 (define_insn "*fp_jcc_3_387"
13689   [(set (pc)
13690         (if_then_else (match_operator 0 "comparison_operator"
13691                         [(match_operand 1 "register_operand" "f")
13692                          (match_operand 2 "nonimmediate_operand" "fm")])
13693           (label_ref (match_operand 3 "" ""))
13694           (pc)))
13695    (clobber (reg:CCFP FPSR_REG))
13696    (clobber (reg:CCFP FLAGS_REG))
13697    (clobber (match_scratch:HI 4 "=a"))]
13698   "TARGET_80387
13699    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13700    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13701    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13702    && SELECT_CC_MODE (GET_CODE (operands[0]),
13703                       operands[1], operands[2]) == CCFPmode
13704    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13705   "#")
13706
13707 (define_insn "*fp_jcc_4_387"
13708   [(set (pc)
13709         (if_then_else (match_operator 0 "comparison_operator"
13710                         [(match_operand 1 "register_operand" "f")
13711                          (match_operand 2 "nonimmediate_operand" "fm")])
13712           (pc)
13713           (label_ref (match_operand 3 "" ""))))
13714    (clobber (reg:CCFP FPSR_REG))
13715    (clobber (reg:CCFP FLAGS_REG))
13716    (clobber (match_scratch:HI 4 "=a"))]
13717   "TARGET_80387
13718    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13719    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13720    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13721    && SELECT_CC_MODE (GET_CODE (operands[0]),
13722                       operands[1], operands[2]) == CCFPmode
13723    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13724   "#")
13725
13726 (define_insn "*fp_jcc_5_387"
13727   [(set (pc)
13728         (if_then_else (match_operator 0 "comparison_operator"
13729                         [(match_operand 1 "register_operand" "f")
13730                          (match_operand 2 "register_operand" "f")])
13731           (label_ref (match_operand 3 "" ""))
13732           (pc)))
13733    (clobber (reg:CCFP FPSR_REG))
13734    (clobber (reg:CCFP FLAGS_REG))
13735    (clobber (match_scratch:HI 4 "=a"))]
13736   "TARGET_80387
13737    && FLOAT_MODE_P (GET_MODE (operands[1]))
13738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740   "#")
13741
13742 (define_insn "*fp_jcc_6_387"
13743   [(set (pc)
13744         (if_then_else (match_operator 0 "comparison_operator"
13745                         [(match_operand 1 "register_operand" "f")
13746                          (match_operand 2 "register_operand" "f")])
13747           (pc)
13748           (label_ref (match_operand 3 "" ""))))
13749    (clobber (reg:CCFP FPSR_REG))
13750    (clobber (reg:CCFP FLAGS_REG))
13751    (clobber (match_scratch:HI 4 "=a"))]
13752   "TARGET_80387
13753    && FLOAT_MODE_P (GET_MODE (operands[1]))
13754    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756   "#")
13757
13758 (define_insn "*fp_jcc_7_387"
13759   [(set (pc)
13760         (if_then_else (match_operator 0 "comparison_operator"
13761                         [(match_operand 1 "register_operand" "f")
13762                          (match_operand 2 "const0_operand" "X")])
13763           (label_ref (match_operand 3 "" ""))
13764           (pc)))
13765    (clobber (reg:CCFP FPSR_REG))
13766    (clobber (reg:CCFP FLAGS_REG))
13767    (clobber (match_scratch:HI 4 "=a"))]
13768   "TARGET_80387
13769    && FLOAT_MODE_P (GET_MODE (operands[1]))
13770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772    && SELECT_CC_MODE (GET_CODE (operands[0]),
13773                       operands[1], operands[2]) == CCFPmode
13774    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13775   "#")
13776
13777 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13778 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13779 ;; with a precedence over other operators and is always put in the first
13780 ;; place. Swap condition and operands to match ficom instruction.
13781
13782 (define_insn "*fp_jcc_8<mode>_387"
13783   [(set (pc)
13784         (if_then_else (match_operator 0 "comparison_operator"
13785                         [(match_operator 1 "float_operator"
13786                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13787                            (match_operand 3 "register_operand" "f,f")])
13788           (label_ref (match_operand 4 "" ""))
13789           (pc)))
13790    (clobber (reg:CCFP FPSR_REG))
13791    (clobber (reg:CCFP FLAGS_REG))
13792    (clobber (match_scratch:HI 5 "=a,a"))]
13793   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13794    && FLOAT_MODE_P (GET_MODE (operands[3]))
13795    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13796    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13797    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13798    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13799   "#")
13800
13801 (define_split
13802   [(set (pc)
13803         (if_then_else (match_operator 0 "comparison_operator"
13804                         [(match_operand 1 "register_operand" "")
13805                          (match_operand 2 "nonimmediate_operand" "")])
13806           (match_operand 3 "" "")
13807           (match_operand 4 "" "")))
13808    (clobber (reg:CCFP FPSR_REG))
13809    (clobber (reg:CCFP FLAGS_REG))]
13810   "reload_completed"
13811   [(const_int 0)]
13812 {
13813   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13814                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13815   DONE;
13816 })
13817
13818 (define_split
13819   [(set (pc)
13820         (if_then_else (match_operator 0 "comparison_operator"
13821                         [(match_operand 1 "register_operand" "")
13822                          (match_operand 2 "general_operand" "")])
13823           (match_operand 3 "" "")
13824           (match_operand 4 "" "")))
13825    (clobber (reg:CCFP FPSR_REG))
13826    (clobber (reg:CCFP FLAGS_REG))
13827    (clobber (match_scratch:HI 5 "=a"))]
13828   "reload_completed"
13829   [(const_int 0)]
13830 {
13831   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13832                         operands[3], operands[4], operands[5], NULL_RTX);
13833   DONE;
13834 })
13835
13836 (define_split
13837   [(set (pc)
13838         (if_then_else (match_operator 0 "comparison_operator"
13839                         [(match_operator 1 "float_operator"
13840                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13841                            (match_operand 3 "register_operand" "")])
13842           (match_operand 4 "" "")
13843           (match_operand 5 "" "")))
13844    (clobber (reg:CCFP FPSR_REG))
13845    (clobber (reg:CCFP FLAGS_REG))
13846    (clobber (match_scratch:HI 6 "=a"))]
13847   "reload_completed"
13848   [(const_int 0)]
13849 {
13850   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13851   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13852                         operands[3], operands[7],
13853                         operands[4], operands[5], operands[6], NULL_RTX);
13854   DONE;
13855 })
13856
13857 ;; %%% Kill this when reload knows how to do it.
13858 (define_split
13859   [(set (pc)
13860         (if_then_else (match_operator 0 "comparison_operator"
13861                         [(match_operator 1 "float_operator"
13862                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13863                            (match_operand 3 "register_operand" "")])
13864           (match_operand 4 "" "")
13865           (match_operand 5 "" "")))
13866    (clobber (reg:CCFP FPSR_REG))
13867    (clobber (reg:CCFP FLAGS_REG))
13868    (clobber (match_scratch:HI 6 "=a"))]
13869   "reload_completed"
13870   [(const_int 0)]
13871 {
13872   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13873   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13874   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13875                         operands[3], operands[7],
13876                         operands[4], operands[5], operands[6], operands[2]);
13877   DONE;
13878 })
13879 \f
13880 ;; Unconditional and other jump instructions
13881
13882 (define_insn "jump"
13883   [(set (pc)
13884         (label_ref (match_operand 0 "" "")))]
13885   ""
13886   "jmp\t%l0"
13887   [(set_attr "type" "ibr")
13888    (set (attr "length")
13889            (if_then_else (and (ge (minus (match_dup 0) (pc))
13890                                   (const_int -126))
13891                               (lt (minus (match_dup 0) (pc))
13892                                   (const_int 128)))
13893              (const_int 2)
13894              (const_int 5)))
13895    (set_attr "modrm" "0")])
13896
13897 (define_expand "indirect_jump"
13898   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13899   ""
13900   "")
13901
13902 (define_insn "*indirect_jump"
13903   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13904   "!TARGET_64BIT"
13905   "jmp\t%A0"
13906   [(set_attr "type" "ibr")
13907    (set_attr "length_immediate" "0")])
13908
13909 (define_insn "*indirect_jump_rtx64"
13910   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13911   "TARGET_64BIT"
13912   "jmp\t%A0"
13913   [(set_attr "type" "ibr")
13914    (set_attr "length_immediate" "0")])
13915
13916 (define_expand "tablejump"
13917   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13918               (use (label_ref (match_operand 1 "" "")))])]
13919   ""
13920 {
13921   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13922      relative.  Convert the relative address to an absolute address.  */
13923   if (flag_pic)
13924     {
13925       rtx op0, op1;
13926       enum rtx_code code;
13927
13928       if (TARGET_64BIT)
13929         {
13930           code = PLUS;
13931           op0 = operands[0];
13932           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13933         }
13934       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13935         {
13936           code = PLUS;
13937           op0 = operands[0];
13938           op1 = pic_offset_table_rtx;
13939         }
13940       else
13941         {
13942           code = MINUS;
13943           op0 = pic_offset_table_rtx;
13944           op1 = operands[0];
13945         }
13946
13947       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13948                                          OPTAB_DIRECT);
13949     }
13950 })
13951
13952 (define_insn "*tablejump_1"
13953   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13954    (use (label_ref (match_operand 1 "" "")))]
13955   "!TARGET_64BIT"
13956   "jmp\t%A0"
13957   [(set_attr "type" "ibr")
13958    (set_attr "length_immediate" "0")])
13959
13960 (define_insn "*tablejump_1_rtx64"
13961   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13962    (use (label_ref (match_operand 1 "" "")))]
13963   "TARGET_64BIT"
13964   "jmp\t%A0"
13965   [(set_attr "type" "ibr")
13966    (set_attr "length_immediate" "0")])
13967 \f
13968 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13969
13970 (define_peephole2
13971   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13972    (set (match_operand:QI 1 "register_operand" "")
13973         (match_operator:QI 2 "ix86_comparison_operator"
13974           [(reg FLAGS_REG) (const_int 0)]))
13975    (set (match_operand 3 "q_regs_operand" "")
13976         (zero_extend (match_dup 1)))]
13977   "(peep2_reg_dead_p (3, operands[1])
13978     || operands_match_p (operands[1], operands[3]))
13979    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13980   [(set (match_dup 4) (match_dup 0))
13981    (set (strict_low_part (match_dup 5))
13982         (match_dup 2))]
13983 {
13984   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13985   operands[5] = gen_lowpart (QImode, operands[3]);
13986   ix86_expand_clear (operands[3]);
13987 })
13988
13989 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
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    (parallel [(set (match_operand 3 "q_regs_operand" "")
13997                    (zero_extend (match_dup 1)))
13998               (clobber (reg:CC FLAGS_REG))])]
13999   "(peep2_reg_dead_p (3, operands[1])
14000     || operands_match_p (operands[1], operands[3]))
14001    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14002   [(set (match_dup 4) (match_dup 0))
14003    (set (strict_low_part (match_dup 5))
14004         (match_dup 2))]
14005 {
14006   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14007   operands[5] = gen_lowpart (QImode, operands[3]);
14008   ix86_expand_clear (operands[3]);
14009 })
14010 \f
14011 ;; Call instructions.
14012
14013 ;; The predicates normally associated with named expanders are not properly
14014 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14015 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14016
14017 ;; Call subroutine returning no value.
14018
14019 (define_expand "call_pop"
14020   [(parallel [(call (match_operand:QI 0 "" "")
14021                     (match_operand:SI 1 "" ""))
14022               (set (reg:SI SP_REG)
14023                    (plus:SI (reg:SI SP_REG)
14024                             (match_operand:SI 3 "" "")))])]
14025   "!TARGET_64BIT"
14026 {
14027   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14028   DONE;
14029 })
14030
14031 (define_insn "*call_pop_0"
14032   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14033          (match_operand:SI 1 "" ""))
14034    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14035                             (match_operand:SI 2 "immediate_operand" "")))]
14036   "!TARGET_64BIT"
14037 {
14038   if (SIBLING_CALL_P (insn))
14039     return "jmp\t%P0";
14040   else
14041     return "call\t%P0";
14042 }
14043   [(set_attr "type" "call")])
14044   
14045 (define_insn "*call_pop_1"
14046   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14047          (match_operand:SI 1 "" ""))
14048    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14049                             (match_operand:SI 2 "immediate_operand" "i")))]
14050   "!TARGET_64BIT"
14051 {
14052   if (constant_call_address_operand (operands[0], Pmode))
14053     {
14054       if (SIBLING_CALL_P (insn))
14055         return "jmp\t%P0";
14056       else
14057         return "call\t%P0";
14058     }
14059   if (SIBLING_CALL_P (insn))
14060     return "jmp\t%A0";
14061   else
14062     return "call\t%A0";
14063 }
14064   [(set_attr "type" "call")])
14065
14066 (define_expand "call"
14067   [(call (match_operand:QI 0 "" "")
14068          (match_operand 1 "" ""))
14069    (use (match_operand 2 "" ""))]
14070   ""
14071 {
14072   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14073   DONE;
14074 })
14075
14076 (define_expand "sibcall"
14077   [(call (match_operand:QI 0 "" "")
14078          (match_operand 1 "" ""))
14079    (use (match_operand 2 "" ""))]
14080   ""
14081 {
14082   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14083   DONE;
14084 })
14085
14086 (define_insn "*call_0"
14087   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14088          (match_operand 1 "" ""))]
14089   ""
14090 {
14091   if (SIBLING_CALL_P (insn))
14092     return "jmp\t%P0";
14093   else
14094     return "call\t%P0";
14095 }
14096   [(set_attr "type" "call")])
14097
14098 (define_insn "*call_1"
14099   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14100          (match_operand 1 "" ""))]
14101   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14102 {
14103   if (constant_call_address_operand (operands[0], Pmode))
14104     return "call\t%P0";
14105   return "call\t%A0";
14106 }
14107   [(set_attr "type" "call")])
14108
14109 (define_insn "*sibcall_1"
14110   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14111          (match_operand 1 "" ""))]
14112   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14113 {
14114   if (constant_call_address_operand (operands[0], Pmode))
14115     return "jmp\t%P0";
14116   return "jmp\t%A0";
14117 }
14118   [(set_attr "type" "call")])
14119
14120 (define_insn "*call_1_rex64"
14121   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14122          (match_operand 1 "" ""))]
14123   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14124 {
14125   if (constant_call_address_operand (operands[0], Pmode))
14126     return "call\t%P0";
14127   return "call\t%A0";
14128 }
14129   [(set_attr "type" "call")])
14130
14131 (define_insn "*sibcall_1_rex64"
14132   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14133          (match_operand 1 "" ""))]
14134   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14135   "jmp\t%P0"
14136   [(set_attr "type" "call")])
14137
14138 (define_insn "*sibcall_1_rex64_v"
14139   [(call (mem:QI (reg:DI 40))
14140          (match_operand 0 "" ""))]
14141   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14142   "jmp\t*%%r11"
14143   [(set_attr "type" "call")])
14144
14145
14146 ;; Call subroutine, returning value in operand 0
14147
14148 (define_expand "call_value_pop"
14149   [(parallel [(set (match_operand 0 "" "")
14150                    (call (match_operand:QI 1 "" "")
14151                          (match_operand:SI 2 "" "")))
14152               (set (reg:SI SP_REG)
14153                    (plus:SI (reg:SI SP_REG)
14154                             (match_operand:SI 4 "" "")))])]
14155   "!TARGET_64BIT"
14156 {
14157   ix86_expand_call (operands[0], operands[1], operands[2],
14158                     operands[3], operands[4], 0);
14159   DONE;
14160 })
14161
14162 (define_expand "call_value"
14163   [(set (match_operand 0 "" "")
14164         (call (match_operand:QI 1 "" "")
14165               (match_operand:SI 2 "" "")))
14166    (use (match_operand:SI 3 "" ""))]
14167   ;; Operand 2 not used on the i386.
14168   ""
14169 {
14170   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14171   DONE;
14172 })
14173
14174 (define_expand "sibcall_value"
14175   [(set (match_operand 0 "" "")
14176         (call (match_operand:QI 1 "" "")
14177               (match_operand:SI 2 "" "")))
14178    (use (match_operand:SI 3 "" ""))]
14179   ;; Operand 2 not used on the i386.
14180   ""
14181 {
14182   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14183   DONE;
14184 })
14185
14186 ;; Call subroutine returning any type.
14187
14188 (define_expand "untyped_call"
14189   [(parallel [(call (match_operand 0 "" "")
14190                     (const_int 0))
14191               (match_operand 1 "" "")
14192               (match_operand 2 "" "")])]
14193   ""
14194 {
14195   int i;
14196
14197   /* In order to give reg-stack an easier job in validating two
14198      coprocessor registers as containing a possible return value,
14199      simply pretend the untyped call returns a complex long double
14200      value.  */
14201
14202   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14203                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14204                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14205                     NULL, 0);
14206
14207   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14208     {
14209       rtx set = XVECEXP (operands[2], 0, i);
14210       emit_move_insn (SET_DEST (set), SET_SRC (set));
14211     }
14212
14213   /* The optimizer does not know that the call sets the function value
14214      registers we stored in the result block.  We avoid problems by
14215      claiming that all hard registers are used and clobbered at this
14216      point.  */
14217   emit_insn (gen_blockage (const0_rtx));
14218
14219   DONE;
14220 })
14221 \f
14222 ;; Prologue and epilogue instructions
14223
14224 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14225 ;; all of memory.  This blocks insns from being moved across this point.
14226
14227 (define_insn "blockage"
14228   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14229   ""
14230   ""
14231   [(set_attr "length" "0")])
14232
14233 ;; Insn emitted into the body of a function to return from a function.
14234 ;; This is only done if the function's epilogue is known to be simple.
14235 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14236
14237 (define_expand "return"
14238   [(return)]
14239   "ix86_can_use_return_insn_p ()"
14240 {
14241   if (current_function_pops_args)
14242     {
14243       rtx popc = GEN_INT (current_function_pops_args);
14244       emit_jump_insn (gen_return_pop_internal (popc));
14245       DONE;
14246     }
14247 })
14248
14249 (define_insn "return_internal"
14250   [(return)]
14251   "reload_completed"
14252   "ret"
14253   [(set_attr "length" "1")
14254    (set_attr "length_immediate" "0")
14255    (set_attr "modrm" "0")])
14256
14257 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14258 ;; instruction Athlon and K8 have.
14259
14260 (define_insn "return_internal_long"
14261   [(return)
14262    (unspec [(const_int 0)] UNSPEC_REP)]
14263   "reload_completed"
14264   "rep {;} ret"
14265   [(set_attr "length" "1")
14266    (set_attr "length_immediate" "0")
14267    (set_attr "prefix_rep" "1")
14268    (set_attr "modrm" "0")])
14269
14270 (define_insn "return_pop_internal"
14271   [(return)
14272    (use (match_operand:SI 0 "const_int_operand" ""))]
14273   "reload_completed"
14274   "ret\t%0"
14275   [(set_attr "length" "3")
14276    (set_attr "length_immediate" "2")
14277    (set_attr "modrm" "0")])
14278
14279 (define_insn "return_indirect_internal"
14280   [(return)
14281    (use (match_operand:SI 0 "register_operand" "r"))]
14282   "reload_completed"
14283   "jmp\t%A0"
14284   [(set_attr "type" "ibr")
14285    (set_attr "length_immediate" "0")])
14286
14287 (define_insn "nop"
14288   [(const_int 0)]
14289   ""
14290   "nop"
14291   [(set_attr "length" "1")
14292    (set_attr "length_immediate" "0")
14293    (set_attr "modrm" "0")])
14294
14295 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14296 ;; branch prediction penalty for the third jump in a 16-byte
14297 ;; block on K8.
14298
14299 (define_insn "align"
14300   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14301   ""
14302 {
14303 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14304   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14305 #else
14306   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14307      The align insn is used to avoid 3 jump instructions in the row to improve
14308      branch prediction and the benefits hardly outweigh the cost of extra 8
14309      nops on the average inserted by full alignment pseudo operation.  */
14310 #endif
14311   return "";
14312 }
14313   [(set_attr "length" "16")])
14314
14315 (define_expand "prologue"
14316   [(const_int 1)]
14317   ""
14318   "ix86_expand_prologue (); DONE;")
14319
14320 (define_insn "set_got"
14321   [(set (match_operand:SI 0 "register_operand" "=r")
14322         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "!TARGET_64BIT"
14325   { return output_set_got (operands[0], NULL_RTX); }
14326   [(set_attr "type" "multi")
14327    (set_attr "length" "12")])
14328
14329 (define_insn "set_got_labelled"
14330   [(set (match_operand:SI 0 "register_operand" "=r")
14331         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14332          UNSPEC_SET_GOT))
14333    (clobber (reg:CC FLAGS_REG))]
14334   "!TARGET_64BIT"
14335   { return output_set_got (operands[0], operands[1]); }
14336   [(set_attr "type" "multi")
14337    (set_attr "length" "12")])
14338
14339 (define_insn "set_got_rex64"
14340   [(set (match_operand:DI 0 "register_operand" "=r")
14341         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14342   "TARGET_64BIT"
14343   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14344   [(set_attr "type" "lea")
14345    (set_attr "length" "6")])
14346
14347 (define_expand "epilogue"
14348   [(const_int 1)]
14349   ""
14350   "ix86_expand_epilogue (1); DONE;")
14351
14352 (define_expand "sibcall_epilogue"
14353   [(const_int 1)]
14354   ""
14355   "ix86_expand_epilogue (0); DONE;")
14356
14357 (define_expand "eh_return"
14358   [(use (match_operand 0 "register_operand" ""))]
14359   ""
14360 {
14361   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14362
14363   /* Tricky bit: we write the address of the handler to which we will
14364      be returning into someone else's stack frame, one word below the
14365      stack address we wish to restore.  */
14366   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14367   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14368   tmp = gen_rtx_MEM (Pmode, tmp);
14369   emit_move_insn (tmp, ra);
14370
14371   if (Pmode == SImode)
14372     emit_jump_insn (gen_eh_return_si (sa));
14373   else
14374     emit_jump_insn (gen_eh_return_di (sa));
14375   emit_barrier ();
14376   DONE;
14377 })
14378
14379 (define_insn_and_split "eh_return_si"
14380   [(set (pc) 
14381         (unspec [(match_operand:SI 0 "register_operand" "c")]
14382                  UNSPEC_EH_RETURN))]
14383   "!TARGET_64BIT"
14384   "#"
14385   "reload_completed"
14386   [(const_int 1)]
14387   "ix86_expand_epilogue (2); DONE;")
14388
14389 (define_insn_and_split "eh_return_di"
14390   [(set (pc) 
14391         (unspec [(match_operand:DI 0 "register_operand" "c")]
14392                  UNSPEC_EH_RETURN))]
14393   "TARGET_64BIT"
14394   "#"
14395   "reload_completed"
14396   [(const_int 1)]
14397   "ix86_expand_epilogue (2); DONE;")
14398
14399 (define_insn "leave"
14400   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14401    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14402    (clobber (mem:BLK (scratch)))]
14403   "!TARGET_64BIT"
14404   "leave"
14405   [(set_attr "type" "leave")])
14406
14407 (define_insn "leave_rex64"
14408   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14409    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14410    (clobber (mem:BLK (scratch)))]
14411   "TARGET_64BIT"
14412   "leave"
14413   [(set_attr "type" "leave")])
14414 \f
14415 (define_expand "ffssi2"
14416   [(parallel
14417      [(set (match_operand:SI 0 "register_operand" "") 
14418            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14419       (clobber (match_scratch:SI 2 ""))
14420       (clobber (reg:CC FLAGS_REG))])]
14421   ""
14422   "")
14423
14424 (define_insn_and_split "*ffs_cmove"
14425   [(set (match_operand:SI 0 "register_operand" "=r") 
14426         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14427    (clobber (match_scratch:SI 2 "=&r"))
14428    (clobber (reg:CC FLAGS_REG))]
14429   "TARGET_CMOVE"
14430   "#"
14431   "&& reload_completed"
14432   [(set (match_dup 2) (const_int -1))
14433    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14434               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14435    (set (match_dup 0) (if_then_else:SI
14436                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14437                         (match_dup 2)
14438                         (match_dup 0)))
14439    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14440               (clobber (reg:CC FLAGS_REG))])]
14441   "")
14442
14443 (define_insn_and_split "*ffs_no_cmove"
14444   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14445         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14446    (clobber (match_scratch:SI 2 "=&q"))
14447    (clobber (reg:CC FLAGS_REG))]
14448   ""
14449   "#"
14450   "reload_completed"
14451   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14452               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14453    (set (strict_low_part (match_dup 3))
14454         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14455    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14456               (clobber (reg:CC FLAGS_REG))])
14457    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14458               (clobber (reg:CC FLAGS_REG))])
14459    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460               (clobber (reg:CC FLAGS_REG))])]
14461 {
14462   operands[3] = gen_lowpart (QImode, operands[2]);
14463   ix86_expand_clear (operands[2]);
14464 })
14465
14466 (define_insn "*ffssi_1"
14467   [(set (reg:CCZ FLAGS_REG)
14468         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14469                      (const_int 0)))
14470    (set (match_operand:SI 0 "register_operand" "=r")
14471         (ctz:SI (match_dup 1)))]
14472   ""
14473   "bsf{l}\t{%1, %0|%0, %1}"
14474   [(set_attr "prefix_0f" "1")])
14475
14476 (define_expand "ffsdi2"
14477   [(parallel
14478      [(set (match_operand:DI 0 "register_operand" "") 
14479            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14480       (clobber (match_scratch:DI 2 ""))
14481       (clobber (reg:CC FLAGS_REG))])]
14482   "TARGET_64BIT && TARGET_CMOVE"
14483   "")
14484
14485 (define_insn_and_split "*ffs_rex64"
14486   [(set (match_operand:DI 0 "register_operand" "=r") 
14487         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14488    (clobber (match_scratch:DI 2 "=&r"))
14489    (clobber (reg:CC FLAGS_REG))]
14490   "TARGET_64BIT && TARGET_CMOVE"
14491   "#"
14492   "&& reload_completed"
14493   [(set (match_dup 2) (const_int -1))
14494    (parallel [(set (reg:CCZ FLAGS_REG)
14495                    (compare:CCZ (match_dup 1) (const_int 0)))
14496               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14497    (set (match_dup 0) (if_then_else:DI
14498                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14499                         (match_dup 2)
14500                         (match_dup 0)))
14501    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14502               (clobber (reg:CC FLAGS_REG))])]
14503   "")
14504
14505 (define_insn "*ffsdi_1"
14506   [(set (reg:CCZ FLAGS_REG)
14507         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14508                      (const_int 0)))
14509    (set (match_operand:DI 0 "register_operand" "=r")
14510         (ctz:DI (match_dup 1)))]
14511   "TARGET_64BIT"
14512   "bsf{q}\t{%1, %0|%0, %1}"
14513   [(set_attr "prefix_0f" "1")])
14514
14515 (define_insn "ctzsi2"
14516   [(set (match_operand:SI 0 "register_operand" "=r")
14517         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14518    (clobber (reg:CC FLAGS_REG))]
14519   ""
14520   "bsf{l}\t{%1, %0|%0, %1}"
14521   [(set_attr "prefix_0f" "1")])
14522
14523 (define_insn "ctzdi2"
14524   [(set (match_operand:DI 0 "register_operand" "=r")
14525         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14526    (clobber (reg:CC FLAGS_REG))]
14527   "TARGET_64BIT"
14528   "bsf{q}\t{%1, %0|%0, %1}"
14529   [(set_attr "prefix_0f" "1")])
14530
14531 (define_expand "clzsi2"
14532   [(parallel
14533      [(set (match_operand:SI 0 "register_operand" "")
14534            (minus:SI (const_int 31)
14535                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14536       (clobber (reg:CC FLAGS_REG))])
14537    (parallel
14538      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14539       (clobber (reg:CC FLAGS_REG))])]
14540   ""
14541   "")
14542
14543 (define_insn "*bsr"
14544   [(set (match_operand:SI 0 "register_operand" "=r")
14545         (minus:SI (const_int 31)
14546                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14547    (clobber (reg:CC FLAGS_REG))]
14548   ""
14549   "bsr{l}\t{%1, %0|%0, %1}"
14550   [(set_attr "prefix_0f" "1")])
14551
14552 (define_expand "clzdi2"
14553   [(parallel
14554      [(set (match_operand:DI 0 "register_operand" "")
14555            (minus:DI (const_int 63)
14556                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14557       (clobber (reg:CC FLAGS_REG))])
14558    (parallel
14559      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14560       (clobber (reg:CC FLAGS_REG))])]
14561   "TARGET_64BIT"
14562   "")
14563
14564 (define_insn "*bsr_rex64"
14565   [(set (match_operand:DI 0 "register_operand" "=r")
14566         (minus:DI (const_int 63)
14567                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14568    (clobber (reg:CC FLAGS_REG))]
14569   "TARGET_64BIT"
14570   "bsr{q}\t{%1, %0|%0, %1}"
14571   [(set_attr "prefix_0f" "1")])
14572 \f
14573 ;; Thread-local storage patterns for ELF.
14574 ;;
14575 ;; Note that these code sequences must appear exactly as shown
14576 ;; in order to allow linker relaxation.
14577
14578 (define_insn "*tls_global_dynamic_32_gnu"
14579   [(set (match_operand:SI 0 "register_operand" "=a")
14580         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14581                     (match_operand:SI 2 "tls_symbolic_operand" "")
14582                     (match_operand:SI 3 "call_insn_operand" "")]
14583                     UNSPEC_TLS_GD))
14584    (clobber (match_scratch:SI 4 "=d"))
14585    (clobber (match_scratch:SI 5 "=c"))
14586    (clobber (reg:CC FLAGS_REG))]
14587   "!TARGET_64BIT && TARGET_GNU_TLS"
14588   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14589   [(set_attr "type" "multi")
14590    (set_attr "length" "12")])
14591
14592 (define_insn "*tls_global_dynamic_32_sun"
14593   [(set (match_operand:SI 0 "register_operand" "=a")
14594         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595                     (match_operand:SI 2 "tls_symbolic_operand" "")
14596                     (match_operand:SI 3 "call_insn_operand" "")]
14597                     UNSPEC_TLS_GD))
14598    (clobber (match_scratch:SI 4 "=d"))
14599    (clobber (match_scratch:SI 5 "=c"))
14600    (clobber (reg:CC FLAGS_REG))]
14601   "!TARGET_64BIT && TARGET_SUN_TLS"
14602   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14603         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14604   [(set_attr "type" "multi")
14605    (set_attr "length" "14")])
14606
14607 (define_expand "tls_global_dynamic_32"
14608   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14609                    (unspec:SI
14610                     [(match_dup 2)
14611                      (match_operand:SI 1 "tls_symbolic_operand" "")
14612                      (match_dup 3)]
14613                     UNSPEC_TLS_GD))
14614               (clobber (match_scratch:SI 4 ""))
14615               (clobber (match_scratch:SI 5 ""))
14616               (clobber (reg:CC FLAGS_REG))])]
14617   ""
14618 {
14619   if (flag_pic)
14620     operands[2] = pic_offset_table_rtx;
14621   else
14622     {
14623       operands[2] = gen_reg_rtx (Pmode);
14624       emit_insn (gen_set_got (operands[2]));
14625     }
14626   if (TARGET_GNU2_TLS)
14627     {
14628        emit_insn (gen_tls_dynamic_gnu2_32
14629                   (operands[0], operands[1], operands[2]));
14630        DONE;
14631     }
14632   operands[3] = ix86_tls_get_addr ();
14633 })
14634
14635 (define_insn "*tls_global_dynamic_64"
14636   [(set (match_operand:DI 0 "register_operand" "=a")
14637         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14638                  (match_operand:DI 3 "" "")))
14639    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14640               UNSPEC_TLS_GD)]
14641   "TARGET_64BIT"
14642   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14643   [(set_attr "type" "multi")
14644    (set_attr "length" "16")])
14645
14646 (define_expand "tls_global_dynamic_64"
14647   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14648                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14649               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14650                          UNSPEC_TLS_GD)])]
14651   ""
14652 {
14653   if (TARGET_GNU2_TLS)
14654     {
14655        emit_insn (gen_tls_dynamic_gnu2_64
14656                   (operands[0], operands[1]));
14657        DONE;
14658     }
14659   operands[2] = ix86_tls_get_addr ();
14660 })
14661
14662 (define_insn "*tls_local_dynamic_base_32_gnu"
14663   [(set (match_operand:SI 0 "register_operand" "=a")
14664         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14665                     (match_operand:SI 2 "call_insn_operand" "")]
14666                    UNSPEC_TLS_LD_BASE))
14667    (clobber (match_scratch:SI 3 "=d"))
14668    (clobber (match_scratch:SI 4 "=c"))
14669    (clobber (reg:CC FLAGS_REG))]
14670   "!TARGET_64BIT && TARGET_GNU_TLS"
14671   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14672   [(set_attr "type" "multi")
14673    (set_attr "length" "11")])
14674
14675 (define_insn "*tls_local_dynamic_base_32_sun"
14676   [(set (match_operand:SI 0 "register_operand" "=a")
14677         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14678                     (match_operand:SI 2 "call_insn_operand" "")]
14679                    UNSPEC_TLS_LD_BASE))
14680    (clobber (match_scratch:SI 3 "=d"))
14681    (clobber (match_scratch:SI 4 "=c"))
14682    (clobber (reg:CC FLAGS_REG))]
14683   "!TARGET_64BIT && TARGET_SUN_TLS"
14684   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14685         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14686   [(set_attr "type" "multi")
14687    (set_attr "length" "13")])
14688
14689 (define_expand "tls_local_dynamic_base_32"
14690   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14691                    (unspec:SI [(match_dup 1) (match_dup 2)]
14692                               UNSPEC_TLS_LD_BASE))
14693               (clobber (match_scratch:SI 3 ""))
14694               (clobber (match_scratch:SI 4 ""))
14695               (clobber (reg:CC FLAGS_REG))])]
14696   ""
14697 {
14698   if (flag_pic)
14699     operands[1] = pic_offset_table_rtx;
14700   else
14701     {
14702       operands[1] = gen_reg_rtx (Pmode);
14703       emit_insn (gen_set_got (operands[1]));
14704     }
14705   if (TARGET_GNU2_TLS)
14706     {
14707        emit_insn (gen_tls_dynamic_gnu2_32
14708                   (operands[0], ix86_tls_module_base (), operands[1]));
14709        DONE;
14710     }
14711   operands[2] = ix86_tls_get_addr ();
14712 })
14713
14714 (define_insn "*tls_local_dynamic_base_64"
14715   [(set (match_operand:DI 0 "register_operand" "=a")
14716         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14717                  (match_operand:DI 2 "" "")))
14718    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14719   "TARGET_64BIT"
14720   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14721   [(set_attr "type" "multi")
14722    (set_attr "length" "12")])
14723
14724 (define_expand "tls_local_dynamic_base_64"
14725   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14726                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14727               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14728   ""
14729 {
14730   if (TARGET_GNU2_TLS)
14731     {
14732        emit_insn (gen_tls_dynamic_gnu2_64
14733                   (operands[0], ix86_tls_module_base ()));
14734        DONE;
14735     }
14736   operands[1] = ix86_tls_get_addr ();
14737 })
14738
14739 ;; Local dynamic of a single variable is a lose.  Show combine how
14740 ;; to convert that back to global dynamic.
14741
14742 (define_insn_and_split "*tls_local_dynamic_32_once"
14743   [(set (match_operand:SI 0 "register_operand" "=a")
14744         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14745                              (match_operand:SI 2 "call_insn_operand" "")]
14746                             UNSPEC_TLS_LD_BASE)
14747                  (const:SI (unspec:SI
14748                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14749                             UNSPEC_DTPOFF))))
14750    (clobber (match_scratch:SI 4 "=d"))
14751    (clobber (match_scratch:SI 5 "=c"))
14752    (clobber (reg:CC FLAGS_REG))]
14753   ""
14754   "#"
14755   ""
14756   [(parallel [(set (match_dup 0)
14757                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14758                               UNSPEC_TLS_GD))
14759               (clobber (match_dup 4))
14760               (clobber (match_dup 5))
14761               (clobber (reg:CC FLAGS_REG))])]
14762   "")
14763
14764 ;; Load and add the thread base pointer from %gs:0.
14765
14766 (define_insn "*load_tp_si"
14767   [(set (match_operand:SI 0 "register_operand" "=r")
14768         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14769   "!TARGET_64BIT"
14770   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14771   [(set_attr "type" "imov")
14772    (set_attr "modrm" "0")
14773    (set_attr "length" "7")
14774    (set_attr "memory" "load")
14775    (set_attr "imm_disp" "false")])
14776
14777 (define_insn "*add_tp_si"
14778   [(set (match_operand:SI 0 "register_operand" "=r")
14779         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14780                  (match_operand:SI 1 "register_operand" "0")))
14781    (clobber (reg:CC FLAGS_REG))]
14782   "!TARGET_64BIT"
14783   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14784   [(set_attr "type" "alu")
14785    (set_attr "modrm" "0")
14786    (set_attr "length" "7")
14787    (set_attr "memory" "load")
14788    (set_attr "imm_disp" "false")])
14789
14790 (define_insn "*load_tp_di"
14791   [(set (match_operand:DI 0 "register_operand" "=r")
14792         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14793   "TARGET_64BIT"
14794   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14795   [(set_attr "type" "imov")
14796    (set_attr "modrm" "0")
14797    (set_attr "length" "7")
14798    (set_attr "memory" "load")
14799    (set_attr "imm_disp" "false")])
14800
14801 (define_insn "*add_tp_di"
14802   [(set (match_operand:DI 0 "register_operand" "=r")
14803         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14804                  (match_operand:DI 1 "register_operand" "0")))
14805    (clobber (reg:CC FLAGS_REG))]
14806   "TARGET_64BIT"
14807   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14808   [(set_attr "type" "alu")
14809    (set_attr "modrm" "0")
14810    (set_attr "length" "7")
14811    (set_attr "memory" "load")
14812    (set_attr "imm_disp" "false")])
14813
14814 ;; GNU2 TLS patterns can be split.
14815
14816 (define_expand "tls_dynamic_gnu2_32"
14817   [(set (match_dup 3)
14818         (plus:SI (match_operand:SI 2 "register_operand" "")
14819                  (const:SI
14820                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14821                              UNSPEC_TLSDESC))))
14822    (parallel
14823     [(set (match_operand:SI 0 "register_operand" "")
14824           (unspec:SI [(match_dup 1) (match_dup 3)
14825                       (match_dup 2) (reg:SI SP_REG)]
14826                       UNSPEC_TLSDESC))
14827      (clobber (reg:CC FLAGS_REG))])]
14828   "!TARGET_64BIT && TARGET_GNU2_TLS"
14829 {
14830   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14831   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14832 })
14833
14834 (define_insn "*tls_dynamic_lea_32"
14835   [(set (match_operand:SI 0 "register_operand" "=r")
14836         (plus:SI (match_operand:SI 1 "register_operand" "b")
14837                  (const:SI
14838                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14839                               UNSPEC_TLSDESC))))]
14840   "!TARGET_64BIT && TARGET_GNU2_TLS"
14841   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14842   [(set_attr "type" "lea")
14843    (set_attr "mode" "SI")
14844    (set_attr "length" "6")
14845    (set_attr "length_address" "4")])
14846
14847 (define_insn "*tls_dynamic_call_32"
14848   [(set (match_operand:SI 0 "register_operand" "=a")
14849         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14850                     (match_operand:SI 2 "register_operand" "0")
14851                     ;; we have to make sure %ebx still points to the GOT
14852                     (match_operand:SI 3 "register_operand" "b")
14853                     (reg:SI SP_REG)]
14854                    UNSPEC_TLSDESC))
14855    (clobber (reg:CC FLAGS_REG))]
14856   "!TARGET_64BIT && TARGET_GNU2_TLS"
14857   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14858   [(set_attr "type" "call")
14859    (set_attr "length" "2")
14860    (set_attr "length_address" "0")])
14861
14862 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14863   [(set (match_operand:SI 0 "register_operand" "=&a")
14864         (plus:SI
14865          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14866                      (match_operand:SI 4 "" "")
14867                      (match_operand:SI 2 "register_operand" "b")
14868                      (reg:SI SP_REG)]
14869                     UNSPEC_TLSDESC)
14870          (const:SI (unspec:SI
14871                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14872                     UNSPEC_DTPOFF))))
14873    (clobber (reg:CC FLAGS_REG))]
14874   "!TARGET_64BIT && TARGET_GNU2_TLS"
14875   "#"
14876   ""
14877   [(set (match_dup 0) (match_dup 5))]
14878 {
14879   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14880   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14881 })
14882
14883 (define_expand "tls_dynamic_gnu2_64"
14884   [(set (match_dup 2)
14885         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14886                    UNSPEC_TLSDESC))
14887    (parallel
14888     [(set (match_operand:DI 0 "register_operand" "")
14889           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14890                      UNSPEC_TLSDESC))
14891      (clobber (reg:CC FLAGS_REG))])]
14892   "TARGET_64BIT && TARGET_GNU2_TLS"
14893 {
14894   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14895   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14896 })
14897
14898 (define_insn "*tls_dynamic_lea_64"
14899   [(set (match_operand:DI 0 "register_operand" "=r")
14900         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14901                    UNSPEC_TLSDESC))]
14902   "TARGET_64BIT && TARGET_GNU2_TLS"
14903   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14904   [(set_attr "type" "lea")
14905    (set_attr "mode" "DI")
14906    (set_attr "length" "7")
14907    (set_attr "length_address" "4")])
14908
14909 (define_insn "*tls_dynamic_call_64"
14910   [(set (match_operand:DI 0 "register_operand" "=a")
14911         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14912                     (match_operand:DI 2 "register_operand" "0")
14913                     (reg:DI SP_REG)]
14914                    UNSPEC_TLSDESC))
14915    (clobber (reg:CC FLAGS_REG))]
14916   "TARGET_64BIT && TARGET_GNU2_TLS"
14917   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14918   [(set_attr "type" "call")
14919    (set_attr "length" "2")
14920    (set_attr "length_address" "0")])
14921
14922 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14923   [(set (match_operand:DI 0 "register_operand" "=&a")
14924         (plus:DI
14925          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14926                      (match_operand:DI 3 "" "")
14927                      (reg:DI SP_REG)]
14928                     UNSPEC_TLSDESC)
14929          (const:DI (unspec:DI
14930                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14931                     UNSPEC_DTPOFF))))
14932    (clobber (reg:CC FLAGS_REG))]
14933   "TARGET_64BIT && TARGET_GNU2_TLS"
14934   "#"
14935   ""
14936   [(set (match_dup 0) (match_dup 4))]
14937 {
14938   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14939   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14940 })
14941
14942 ;;
14943 \f
14944 ;; These patterns match the binary 387 instructions for addM3, subM3,
14945 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14946 ;; SFmode.  The first is the normal insn, the second the same insn but
14947 ;; with one operand a conversion, and the third the same insn but with
14948 ;; the other operand a conversion.  The conversion may be SFmode or
14949 ;; SImode if the target mode DFmode, but only SImode if the target mode
14950 ;; is SFmode.
14951
14952 ;; Gcc is slightly more smart about handling normal two address instructions
14953 ;; so use special patterns for add and mull.
14954
14955 (define_insn "*fop_sf_comm_mixed"
14956   [(set (match_operand:SF 0 "register_operand" "=f,x")
14957         (match_operator:SF 3 "binary_fp_operator"
14958                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14959                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14960   "TARGET_MIX_SSE_I387
14961    && COMMUTATIVE_ARITH_P (operands[3])
14962    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14963   "* return output_387_binary_op (insn, operands);"
14964   [(set (attr "type") 
14965         (if_then_else (eq_attr "alternative" "1")
14966            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14967               (const_string "ssemul")
14968               (const_string "sseadd"))
14969            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14970               (const_string "fmul")
14971               (const_string "fop"))))
14972    (set_attr "mode" "SF")])
14973
14974 (define_insn "*fop_sf_comm_sse"
14975   [(set (match_operand:SF 0 "register_operand" "=x")
14976         (match_operator:SF 3 "binary_fp_operator"
14977                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14978                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14979   "TARGET_SSE_MATH
14980    && COMMUTATIVE_ARITH_P (operands[3])
14981    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14982   "* return output_387_binary_op (insn, operands);"
14983   [(set (attr "type") 
14984         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14985            (const_string "ssemul")
14986            (const_string "sseadd")))
14987    (set_attr "mode" "SF")])
14988
14989 (define_insn "*fop_sf_comm_i387"
14990   [(set (match_operand:SF 0 "register_operand" "=f")
14991         (match_operator:SF 3 "binary_fp_operator"
14992                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14993                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14994   "TARGET_80387
14995    && COMMUTATIVE_ARITH_P (operands[3])
14996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14997   "* return output_387_binary_op (insn, operands);"
14998   [(set (attr "type") 
14999         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15000            (const_string "fmul")
15001            (const_string "fop")))
15002    (set_attr "mode" "SF")])
15003
15004 (define_insn "*fop_sf_1_mixed"
15005   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15006         (match_operator:SF 3 "binary_fp_operator"
15007                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15008                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15009   "TARGET_MIX_SSE_I387
15010    && !COMMUTATIVE_ARITH_P (operands[3])
15011    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15012   "* return output_387_binary_op (insn, operands);"
15013   [(set (attr "type") 
15014         (cond [(and (eq_attr "alternative" "2")
15015                     (match_operand:SF 3 "mult_operator" ""))
15016                  (const_string "ssemul")
15017                (and (eq_attr "alternative" "2")
15018                     (match_operand:SF 3 "div_operator" ""))
15019                  (const_string "ssediv")
15020                (eq_attr "alternative" "2")
15021                  (const_string "sseadd")
15022                (match_operand:SF 3 "mult_operator" "") 
15023                  (const_string "fmul")
15024                (match_operand:SF 3 "div_operator" "") 
15025                  (const_string "fdiv")
15026               ]
15027               (const_string "fop")))
15028    (set_attr "mode" "SF")])
15029
15030 (define_insn "*fop_sf_1_sse"
15031   [(set (match_operand:SF 0 "register_operand" "=x")
15032         (match_operator:SF 3 "binary_fp_operator"
15033                         [(match_operand:SF 1 "register_operand" "0")
15034                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15035   "TARGET_SSE_MATH
15036    && !COMMUTATIVE_ARITH_P (operands[3])"
15037   "* return output_387_binary_op (insn, operands);"
15038   [(set (attr "type") 
15039         (cond [(match_operand:SF 3 "mult_operator" "")
15040                  (const_string "ssemul")
15041                (match_operand:SF 3 "div_operator" "")
15042                  (const_string "ssediv")
15043               ]
15044               (const_string "sseadd")))
15045    (set_attr "mode" "SF")])
15046
15047 ;; This pattern is not fully shadowed by the pattern above.
15048 (define_insn "*fop_sf_1_i387"
15049   [(set (match_operand:SF 0 "register_operand" "=f,f")
15050         (match_operator:SF 3 "binary_fp_operator"
15051                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15052                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15053   "TARGET_80387 && !TARGET_SSE_MATH
15054    && !COMMUTATIVE_ARITH_P (operands[3])
15055    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15056   "* return output_387_binary_op (insn, operands);"
15057   [(set (attr "type") 
15058         (cond [(match_operand:SF 3 "mult_operator" "") 
15059                  (const_string "fmul")
15060                (match_operand:SF 3 "div_operator" "") 
15061                  (const_string "fdiv")
15062               ]
15063               (const_string "fop")))
15064    (set_attr "mode" "SF")])
15065
15066 ;; ??? Add SSE splitters for these!
15067 (define_insn "*fop_sf_2<mode>_i387"
15068   [(set (match_operand:SF 0 "register_operand" "=f,f")
15069         (match_operator:SF 3 "binary_fp_operator"
15070           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15071            (match_operand:SF 2 "register_operand" "0,0")]))]
15072   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15073   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15074   [(set (attr "type") 
15075         (cond [(match_operand:SF 3 "mult_operator" "") 
15076                  (const_string "fmul")
15077                (match_operand:SF 3 "div_operator" "") 
15078                  (const_string "fdiv")
15079               ]
15080               (const_string "fop")))
15081    (set_attr "fp_int_src" "true")
15082    (set_attr "mode" "<MODE>")])
15083
15084 (define_insn "*fop_sf_3<mode>_i387"
15085   [(set (match_operand:SF 0 "register_operand" "=f,f")
15086         (match_operator:SF 3 "binary_fp_operator"
15087           [(match_operand:SF 1 "register_operand" "0,0")
15088            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15089   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15090   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15091   [(set (attr "type") 
15092         (cond [(match_operand:SF 3 "mult_operator" "") 
15093                  (const_string "fmul")
15094                (match_operand:SF 3 "div_operator" "") 
15095                  (const_string "fdiv")
15096               ]
15097               (const_string "fop")))
15098    (set_attr "fp_int_src" "true")
15099    (set_attr "mode" "<MODE>")])
15100
15101 (define_insn "*fop_df_comm_mixed"
15102   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15103         (match_operator:DF 3 "binary_fp_operator"
15104                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15105                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15106   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15107    && COMMUTATIVE_ARITH_P (operands[3])
15108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15109   "* return output_387_binary_op (insn, operands);"
15110   [(set (attr "type") 
15111         (if_then_else (eq_attr "alternative" "1")
15112            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15113               (const_string "ssemul")
15114               (const_string "sseadd"))
15115            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15116               (const_string "fmul")
15117               (const_string "fop"))))
15118    (set_attr "mode" "DF")])
15119
15120 (define_insn "*fop_df_comm_sse"
15121   [(set (match_operand:DF 0 "register_operand" "=Y")
15122         (match_operator:DF 3 "binary_fp_operator"
15123                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15124                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15125   "TARGET_SSE2 && TARGET_SSE_MATH
15126    && COMMUTATIVE_ARITH_P (operands[3])
15127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15128   "* return output_387_binary_op (insn, operands);"
15129   [(set (attr "type") 
15130         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15131            (const_string "ssemul")
15132            (const_string "sseadd")))
15133    (set_attr "mode" "DF")])
15134
15135 (define_insn "*fop_df_comm_i387"
15136   [(set (match_operand:DF 0 "register_operand" "=f")
15137         (match_operator:DF 3 "binary_fp_operator"
15138                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15139                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15140   "TARGET_80387
15141    && COMMUTATIVE_ARITH_P (operands[3])
15142    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15143   "* return output_387_binary_op (insn, operands);"
15144   [(set (attr "type") 
15145         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15146            (const_string "fmul")
15147            (const_string "fop")))
15148    (set_attr "mode" "DF")])
15149
15150 (define_insn "*fop_df_1_mixed"
15151   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15152         (match_operator:DF 3 "binary_fp_operator"
15153                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15154                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15155   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15156    && !COMMUTATIVE_ARITH_P (operands[3])
15157    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15158   "* return output_387_binary_op (insn, operands);"
15159   [(set (attr "type") 
15160         (cond [(and (eq_attr "alternative" "2")
15161                     (match_operand:DF 3 "mult_operator" ""))
15162                  (const_string "ssemul")
15163                (and (eq_attr "alternative" "2")
15164                     (match_operand:DF 3 "div_operator" ""))
15165                  (const_string "ssediv")
15166                (eq_attr "alternative" "2")
15167                  (const_string "sseadd")
15168                (match_operand:DF 3 "mult_operator" "") 
15169                  (const_string "fmul")
15170                (match_operand:DF 3 "div_operator" "") 
15171                  (const_string "fdiv")
15172               ]
15173               (const_string "fop")))
15174    (set_attr "mode" "DF")])
15175
15176 (define_insn "*fop_df_1_sse"
15177   [(set (match_operand:DF 0 "register_operand" "=Y")
15178         (match_operator:DF 3 "binary_fp_operator"
15179                         [(match_operand:DF 1 "register_operand" "0")
15180                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15181   "TARGET_SSE2 && TARGET_SSE_MATH
15182    && !COMMUTATIVE_ARITH_P (operands[3])"
15183   "* return output_387_binary_op (insn, operands);"
15184   [(set_attr "mode" "DF")
15185    (set (attr "type") 
15186         (cond [(match_operand:DF 3 "mult_operator" "")
15187                  (const_string "ssemul")
15188                (match_operand:DF 3 "div_operator" "")
15189                  (const_string "ssediv")
15190               ]
15191               (const_string "sseadd")))])
15192
15193 ;; This pattern is not fully shadowed by the pattern above.
15194 (define_insn "*fop_df_1_i387"
15195   [(set (match_operand:DF 0 "register_operand" "=f,f")
15196         (match_operator:DF 3 "binary_fp_operator"
15197                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15198                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15199   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15200    && !COMMUTATIVE_ARITH_P (operands[3])
15201    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15202   "* return output_387_binary_op (insn, operands);"
15203   [(set (attr "type") 
15204         (cond [(match_operand:DF 3 "mult_operator" "") 
15205                  (const_string "fmul")
15206                (match_operand:DF 3 "div_operator" "")
15207                  (const_string "fdiv")
15208               ]
15209               (const_string "fop")))
15210    (set_attr "mode" "DF")])
15211
15212 ;; ??? Add SSE splitters for these!
15213 (define_insn "*fop_df_2<mode>_i387"
15214   [(set (match_operand:DF 0 "register_operand" "=f,f")
15215         (match_operator:DF 3 "binary_fp_operator"
15216            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15217             (match_operand:DF 2 "register_operand" "0,0")]))]
15218   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15219    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15220   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15221   [(set (attr "type") 
15222         (cond [(match_operand:DF 3 "mult_operator" "") 
15223                  (const_string "fmul")
15224                (match_operand:DF 3 "div_operator" "") 
15225                  (const_string "fdiv")
15226               ]
15227               (const_string "fop")))
15228    (set_attr "fp_int_src" "true")
15229    (set_attr "mode" "<MODE>")])
15230
15231 (define_insn "*fop_df_3<mode>_i387"
15232   [(set (match_operand:DF 0 "register_operand" "=f,f")
15233         (match_operator:DF 3 "binary_fp_operator"
15234            [(match_operand:DF 1 "register_operand" "0,0")
15235             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15236   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15237    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15238   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15239   [(set (attr "type") 
15240         (cond [(match_operand:DF 3 "mult_operator" "") 
15241                  (const_string "fmul")
15242                (match_operand:DF 3 "div_operator" "") 
15243                  (const_string "fdiv")
15244               ]
15245               (const_string "fop")))
15246    (set_attr "fp_int_src" "true")
15247    (set_attr "mode" "<MODE>")])
15248
15249 (define_insn "*fop_df_4_i387"
15250   [(set (match_operand:DF 0 "register_operand" "=f,f")
15251         (match_operator:DF 3 "binary_fp_operator"
15252            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15253             (match_operand:DF 2 "register_operand" "0,f")]))]
15254   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15255    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15256   "* return output_387_binary_op (insn, operands);"
15257   [(set (attr "type") 
15258         (cond [(match_operand:DF 3 "mult_operator" "") 
15259                  (const_string "fmul")
15260                (match_operand:DF 3 "div_operator" "") 
15261                  (const_string "fdiv")
15262               ]
15263               (const_string "fop")))
15264    (set_attr "mode" "SF")])
15265
15266 (define_insn "*fop_df_5_i387"
15267   [(set (match_operand:DF 0 "register_operand" "=f,f")
15268         (match_operator:DF 3 "binary_fp_operator"
15269           [(match_operand:DF 1 "register_operand" "0,f")
15270            (float_extend:DF
15271             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15272   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15273   "* return output_387_binary_op (insn, operands);"
15274   [(set (attr "type") 
15275         (cond [(match_operand:DF 3 "mult_operator" "") 
15276                  (const_string "fmul")
15277                (match_operand:DF 3 "div_operator" "") 
15278                  (const_string "fdiv")
15279               ]
15280               (const_string "fop")))
15281    (set_attr "mode" "SF")])
15282
15283 (define_insn "*fop_df_6_i387"
15284   [(set (match_operand:DF 0 "register_operand" "=f,f")
15285         (match_operator:DF 3 "binary_fp_operator"
15286           [(float_extend:DF
15287             (match_operand:SF 1 "register_operand" "0,f"))
15288            (float_extend:DF
15289             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15290   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15291   "* return output_387_binary_op (insn, operands);"
15292   [(set (attr "type") 
15293         (cond [(match_operand:DF 3 "mult_operator" "") 
15294                  (const_string "fmul")
15295                (match_operand:DF 3 "div_operator" "") 
15296                  (const_string "fdiv")
15297               ]
15298               (const_string "fop")))
15299    (set_attr "mode" "SF")])
15300
15301 (define_insn "*fop_xf_comm_i387"
15302   [(set (match_operand:XF 0 "register_operand" "=f")
15303         (match_operator:XF 3 "binary_fp_operator"
15304                         [(match_operand:XF 1 "register_operand" "%0")
15305                          (match_operand:XF 2 "register_operand" "f")]))]
15306   "TARGET_80387
15307    && COMMUTATIVE_ARITH_P (operands[3])"
15308   "* return output_387_binary_op (insn, operands);"
15309   [(set (attr "type") 
15310         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15311            (const_string "fmul")
15312            (const_string "fop")))
15313    (set_attr "mode" "XF")])
15314
15315 (define_insn "*fop_xf_1_i387"
15316   [(set (match_operand:XF 0 "register_operand" "=f,f")
15317         (match_operator:XF 3 "binary_fp_operator"
15318                         [(match_operand:XF 1 "register_operand" "0,f")
15319                          (match_operand:XF 2 "register_operand" "f,0")]))]
15320   "TARGET_80387
15321    && !COMMUTATIVE_ARITH_P (operands[3])"
15322   "* return output_387_binary_op (insn, operands);"
15323   [(set (attr "type") 
15324         (cond [(match_operand:XF 3 "mult_operator" "") 
15325                  (const_string "fmul")
15326                (match_operand:XF 3 "div_operator" "") 
15327                  (const_string "fdiv")
15328               ]
15329               (const_string "fop")))
15330    (set_attr "mode" "XF")])
15331
15332 (define_insn "*fop_xf_2<mode>_i387"
15333   [(set (match_operand:XF 0 "register_operand" "=f,f")
15334         (match_operator:XF 3 "binary_fp_operator"
15335            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15336             (match_operand:XF 2 "register_operand" "0,0")]))]
15337   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15338   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15339   [(set (attr "type") 
15340         (cond [(match_operand:XF 3 "mult_operator" "") 
15341                  (const_string "fmul")
15342                (match_operand:XF 3 "div_operator" "") 
15343                  (const_string "fdiv")
15344               ]
15345               (const_string "fop")))
15346    (set_attr "fp_int_src" "true")
15347    (set_attr "mode" "<MODE>")])
15348
15349 (define_insn "*fop_xf_3<mode>_i387"
15350   [(set (match_operand:XF 0 "register_operand" "=f,f")
15351         (match_operator:XF 3 "binary_fp_operator"
15352           [(match_operand:XF 1 "register_operand" "0,0")
15353            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15354   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15355   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15356   [(set (attr "type") 
15357         (cond [(match_operand:XF 3 "mult_operator" "") 
15358                  (const_string "fmul")
15359                (match_operand:XF 3 "div_operator" "") 
15360                  (const_string "fdiv")
15361               ]
15362               (const_string "fop")))
15363    (set_attr "fp_int_src" "true")
15364    (set_attr "mode" "<MODE>")])
15365
15366 (define_insn "*fop_xf_4_i387"
15367   [(set (match_operand:XF 0 "register_operand" "=f,f")
15368         (match_operator:XF 3 "binary_fp_operator"
15369            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15370             (match_operand:XF 2 "register_operand" "0,f")]))]
15371   "TARGET_80387"
15372   "* return output_387_binary_op (insn, operands);"
15373   [(set (attr "type") 
15374         (cond [(match_operand:XF 3 "mult_operator" "") 
15375                  (const_string "fmul")
15376                (match_operand:XF 3 "div_operator" "") 
15377                  (const_string "fdiv")
15378               ]
15379               (const_string "fop")))
15380    (set_attr "mode" "SF")])
15381
15382 (define_insn "*fop_xf_5_i387"
15383   [(set (match_operand:XF 0 "register_operand" "=f,f")
15384         (match_operator:XF 3 "binary_fp_operator"
15385           [(match_operand:XF 1 "register_operand" "0,f")
15386            (float_extend:XF
15387             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15388   "TARGET_80387"
15389   "* return output_387_binary_op (insn, operands);"
15390   [(set (attr "type") 
15391         (cond [(match_operand:XF 3 "mult_operator" "") 
15392                  (const_string "fmul")
15393                (match_operand:XF 3 "div_operator" "") 
15394                  (const_string "fdiv")
15395               ]
15396               (const_string "fop")))
15397    (set_attr "mode" "SF")])
15398
15399 (define_insn "*fop_xf_6_i387"
15400   [(set (match_operand:XF 0 "register_operand" "=f,f")
15401         (match_operator:XF 3 "binary_fp_operator"
15402           [(float_extend:XF
15403             (match_operand 1 "register_operand" "0,f"))
15404            (float_extend:XF
15405             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15406   "TARGET_80387"
15407   "* return output_387_binary_op (insn, operands);"
15408   [(set (attr "type") 
15409         (cond [(match_operand:XF 3 "mult_operator" "") 
15410                  (const_string "fmul")
15411                (match_operand:XF 3 "div_operator" "") 
15412                  (const_string "fdiv")
15413               ]
15414               (const_string "fop")))
15415    (set_attr "mode" "SF")])
15416
15417 (define_split
15418   [(set (match_operand 0 "register_operand" "")
15419         (match_operator 3 "binary_fp_operator"
15420            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15421             (match_operand 2 "register_operand" "")]))]
15422   "TARGET_80387 && reload_completed
15423    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15424   [(const_int 0)]
15425
15426   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15427   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15428   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15429                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15430                                           GET_MODE (operands[3]),
15431                                           operands[4],
15432                                           operands[2])));
15433   ix86_free_from_memory (GET_MODE (operands[1]));
15434   DONE;
15435 })
15436
15437 (define_split
15438   [(set (match_operand 0 "register_operand" "")
15439         (match_operator 3 "binary_fp_operator"
15440            [(match_operand 1 "register_operand" "")
15441             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15442   "TARGET_80387 && reload_completed
15443    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15444   [(const_int 0)]
15445 {
15446   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15447   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15448   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15449                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15450                                           GET_MODE (operands[3]),
15451                                           operands[1],
15452                                           operands[4])));
15453   ix86_free_from_memory (GET_MODE (operands[2]));
15454   DONE;
15455 })
15456 \f
15457 ;; FPU special functions.
15458
15459 (define_expand "sqrtsf2"
15460   [(set (match_operand:SF 0 "register_operand" "")
15461         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15462   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15463 {
15464   if (!TARGET_SSE_MATH)
15465     operands[1] = force_reg (SFmode, operands[1]);
15466 })
15467
15468 (define_insn "*sqrtsf2_mixed"
15469   [(set (match_operand:SF 0 "register_operand" "=f,x")
15470         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15471   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15472   "@
15473    fsqrt
15474    sqrtss\t{%1, %0|%0, %1}"
15475   [(set_attr "type" "fpspc,sse")
15476    (set_attr "mode" "SF,SF")
15477    (set_attr "athlon_decode" "direct,*")])
15478
15479 (define_insn "*sqrtsf2_sse"
15480   [(set (match_operand:SF 0 "register_operand" "=x")
15481         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15482   "TARGET_SSE_MATH"
15483   "sqrtss\t{%1, %0|%0, %1}"
15484   [(set_attr "type" "sse")
15485    (set_attr "mode" "SF")
15486    (set_attr "athlon_decode" "*")])
15487
15488 (define_insn "*sqrtsf2_i387"
15489   [(set (match_operand:SF 0 "register_operand" "=f")
15490         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15491   "TARGET_USE_FANCY_MATH_387"
15492   "fsqrt"
15493   [(set_attr "type" "fpspc")
15494    (set_attr "mode" "SF")
15495    (set_attr "athlon_decode" "direct")])
15496
15497 (define_expand "sqrtdf2"
15498   [(set (match_operand:DF 0 "register_operand" "")
15499         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15500   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15501 {
15502   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15503     operands[1] = force_reg (DFmode, operands[1]);
15504 })
15505
15506 (define_insn "*sqrtdf2_mixed"
15507   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15508         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15509   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15510   "@
15511    fsqrt
15512    sqrtsd\t{%1, %0|%0, %1}"
15513   [(set_attr "type" "fpspc,sse")
15514    (set_attr "mode" "DF,DF")
15515    (set_attr "athlon_decode" "direct,*")])
15516
15517 (define_insn "*sqrtdf2_sse"
15518   [(set (match_operand:DF 0 "register_operand" "=Y")
15519         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15520   "TARGET_SSE2 && TARGET_SSE_MATH"
15521   "sqrtsd\t{%1, %0|%0, %1}"
15522   [(set_attr "type" "sse")
15523    (set_attr "mode" "DF")
15524    (set_attr "athlon_decode" "*")])
15525
15526 (define_insn "*sqrtdf2_i387"
15527   [(set (match_operand:DF 0 "register_operand" "=f")
15528         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15529   "TARGET_USE_FANCY_MATH_387"
15530   "fsqrt"
15531   [(set_attr "type" "fpspc")
15532    (set_attr "mode" "DF")
15533    (set_attr "athlon_decode" "direct")])
15534
15535 (define_insn "*sqrtextendsfdf2_i387"
15536   [(set (match_operand:DF 0 "register_operand" "=f")
15537         (sqrt:DF (float_extend:DF
15538                   (match_operand:SF 1 "register_operand" "0"))))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15541   "fsqrt"
15542   [(set_attr "type" "fpspc")
15543    (set_attr "mode" "DF")
15544    (set_attr "athlon_decode" "direct")])
15545
15546 (define_insn "sqrtxf2"
15547   [(set (match_operand:XF 0 "register_operand" "=f")
15548         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15549   "TARGET_USE_FANCY_MATH_387"
15550   "fsqrt"
15551   [(set_attr "type" "fpspc")
15552    (set_attr "mode" "XF")
15553    (set_attr "athlon_decode" "direct")])
15554
15555 (define_insn "*sqrtextendsfxf2_i387"
15556   [(set (match_operand:XF 0 "register_operand" "=f")
15557         (sqrt:XF (float_extend:XF
15558                   (match_operand:SF 1 "register_operand" "0"))))]
15559   "TARGET_USE_FANCY_MATH_387"
15560   "fsqrt"
15561   [(set_attr "type" "fpspc")
15562    (set_attr "mode" "XF")
15563    (set_attr "athlon_decode" "direct")])
15564
15565 (define_insn "*sqrtextenddfxf2_i387"
15566   [(set (match_operand:XF 0 "register_operand" "=f")
15567         (sqrt:XF (float_extend:XF
15568                   (match_operand:DF 1 "register_operand" "0"))))]
15569   "TARGET_USE_FANCY_MATH_387"
15570   "fsqrt"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "XF")
15573    (set_attr "athlon_decode" "direct")])
15574
15575 (define_insn "fpremxf4"
15576   [(set (match_operand:XF 0 "register_operand" "=f")
15577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15578                     (match_operand:XF 3 "register_operand" "1")]
15579                    UNSPEC_FPREM_F))
15580    (set (match_operand:XF 1 "register_operand" "=u")
15581         (unspec:XF [(match_dup 2) (match_dup 3)]
15582                    UNSPEC_FPREM_U))
15583    (set (reg:CCFP FPSR_REG)
15584         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15585   "TARGET_USE_FANCY_MATH_387
15586    && flag_unsafe_math_optimizations"
15587   "fprem"
15588   [(set_attr "type" "fpspc")
15589    (set_attr "mode" "XF")])
15590
15591 (define_expand "fmodsf3"
15592   [(use (match_operand:SF 0 "register_operand" ""))
15593    (use (match_operand:SF 1 "register_operand" ""))
15594    (use (match_operand:SF 2 "register_operand" ""))]
15595   "TARGET_USE_FANCY_MATH_387
15596    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15597    && flag_unsafe_math_optimizations"
15598 {
15599   rtx label = gen_label_rtx ();
15600
15601   rtx op1 = gen_reg_rtx (XFmode);
15602   rtx op2 = gen_reg_rtx (XFmode);
15603
15604   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15605   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15606
15607   emit_label (label);
15608
15609   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15610   ix86_emit_fp_unordered_jump (label);
15611
15612   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15613   DONE;
15614 })
15615
15616 (define_expand "fmoddf3"
15617   [(use (match_operand:DF 0 "register_operand" ""))
15618    (use (match_operand:DF 1 "register_operand" ""))
15619    (use (match_operand:DF 2 "register_operand" ""))]
15620   "TARGET_USE_FANCY_MATH_387
15621    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15622    && flag_unsafe_math_optimizations"
15623 {
15624   rtx label = gen_label_rtx ();
15625
15626   rtx op1 = gen_reg_rtx (XFmode);
15627   rtx op2 = gen_reg_rtx (XFmode);
15628
15629   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15630   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15631
15632   emit_label (label);
15633
15634   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15635   ix86_emit_fp_unordered_jump (label);
15636
15637   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15638   DONE;
15639 })
15640
15641 (define_expand "fmodxf3"
15642   [(use (match_operand:XF 0 "register_operand" ""))
15643    (use (match_operand:XF 1 "register_operand" ""))
15644    (use (match_operand:XF 2 "register_operand" ""))]
15645   "TARGET_USE_FANCY_MATH_387
15646    && flag_unsafe_math_optimizations"
15647 {
15648   rtx label = gen_label_rtx ();
15649
15650   emit_label (label);
15651
15652   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15653                            operands[1], operands[2]));
15654   ix86_emit_fp_unordered_jump (label);
15655
15656   emit_move_insn (operands[0], operands[1]);
15657   DONE;
15658 })
15659
15660 (define_insn "fprem1xf4"
15661   [(set (match_operand:XF 0 "register_operand" "=f")
15662         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15663                     (match_operand:XF 3 "register_operand" "1")]
15664                    UNSPEC_FPREM1_F))
15665    (set (match_operand:XF 1 "register_operand" "=u")
15666         (unspec:XF [(match_dup 2) (match_dup 3)]
15667                    UNSPEC_FPREM1_U))
15668    (set (reg:CCFP FPSR_REG)
15669         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15670   "TARGET_USE_FANCY_MATH_387
15671    && flag_unsafe_math_optimizations"
15672   "fprem1"
15673   [(set_attr "type" "fpspc")
15674    (set_attr "mode" "XF")])
15675
15676 (define_expand "dremsf3"
15677   [(use (match_operand:SF 0 "register_operand" ""))
15678    (use (match_operand:SF 1 "register_operand" ""))
15679    (use (match_operand:SF 2 "register_operand" ""))]
15680   "TARGET_USE_FANCY_MATH_387
15681    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15682    && flag_unsafe_math_optimizations"
15683 {
15684   rtx label = gen_label_rtx ();
15685
15686   rtx op1 = gen_reg_rtx (XFmode);
15687   rtx op2 = gen_reg_rtx (XFmode);
15688
15689   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15690   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15691
15692   emit_label (label);
15693
15694   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15695   ix86_emit_fp_unordered_jump (label);
15696
15697   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15698   DONE;
15699 })
15700
15701 (define_expand "dremdf3"
15702   [(use (match_operand:DF 0 "register_operand" ""))
15703    (use (match_operand:DF 1 "register_operand" ""))
15704    (use (match_operand:DF 2 "register_operand" ""))]
15705   "TARGET_USE_FANCY_MATH_387
15706    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15707    && flag_unsafe_math_optimizations"
15708 {
15709   rtx label = gen_label_rtx ();
15710
15711   rtx op1 = gen_reg_rtx (XFmode);
15712   rtx op2 = gen_reg_rtx (XFmode);
15713
15714   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15715   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15716
15717   emit_label (label);
15718
15719   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15720   ix86_emit_fp_unordered_jump (label);
15721
15722   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15723   DONE;
15724 })
15725
15726 (define_expand "dremxf3"
15727   [(use (match_operand:XF 0 "register_operand" ""))
15728    (use (match_operand:XF 1 "register_operand" ""))
15729    (use (match_operand:XF 2 "register_operand" ""))]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15732 {
15733   rtx label = gen_label_rtx ();
15734
15735   emit_label (label);
15736
15737   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15738                             operands[1], operands[2]));
15739   ix86_emit_fp_unordered_jump (label);
15740
15741   emit_move_insn (operands[0], operands[1]);
15742   DONE;
15743 })
15744
15745 (define_insn "*sindf2"
15746   [(set (match_operand:DF 0 "register_operand" "=f")
15747         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15750    && flag_unsafe_math_optimizations"
15751   "fsin"
15752   [(set_attr "type" "fpspc")
15753    (set_attr "mode" "DF")])
15754
15755 (define_insn "*sinsf2"
15756   [(set (match_operand:SF 0 "register_operand" "=f")
15757         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15758   "TARGET_USE_FANCY_MATH_387
15759    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15760    && flag_unsafe_math_optimizations"
15761   "fsin"
15762   [(set_attr "type" "fpspc")
15763    (set_attr "mode" "SF")])
15764
15765 (define_insn "*sinextendsfdf2"
15766   [(set (match_operand:DF 0 "register_operand" "=f")
15767         (unspec:DF [(float_extend:DF
15768                      (match_operand:SF 1 "register_operand" "0"))]
15769                    UNSPEC_SIN))]
15770   "TARGET_USE_FANCY_MATH_387
15771    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15772    && flag_unsafe_math_optimizations"
15773   "fsin"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "DF")])
15776
15777 (define_insn "*sinxf2"
15778   [(set (match_operand:XF 0 "register_operand" "=f")
15779         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && flag_unsafe_math_optimizations"
15782   "fsin"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "XF")])
15785
15786 (define_insn "*cosdf2"
15787   [(set (match_operand:DF 0 "register_operand" "=f")
15788         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15789   "TARGET_USE_FANCY_MATH_387
15790    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15791    && flag_unsafe_math_optimizations"
15792   "fcos"
15793   [(set_attr "type" "fpspc")
15794    (set_attr "mode" "DF")])
15795
15796 (define_insn "*cossf2"
15797   [(set (match_operand:SF 0 "register_operand" "=f")
15798         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15799   "TARGET_USE_FANCY_MATH_387
15800    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15801    && flag_unsafe_math_optimizations"
15802   "fcos"
15803   [(set_attr "type" "fpspc")
15804    (set_attr "mode" "SF")])
15805
15806 (define_insn "*cosextendsfdf2"
15807   [(set (match_operand:DF 0 "register_operand" "=f")
15808         (unspec:DF [(float_extend:DF
15809                      (match_operand:SF 1 "register_operand" "0"))]
15810                    UNSPEC_COS))]
15811   "TARGET_USE_FANCY_MATH_387
15812    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15813    && flag_unsafe_math_optimizations"
15814   "fcos"
15815   [(set_attr "type" "fpspc")
15816    (set_attr "mode" "DF")])
15817
15818 (define_insn "*cosxf2"
15819   [(set (match_operand:XF 0 "register_operand" "=f")
15820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15821   "TARGET_USE_FANCY_MATH_387
15822    && flag_unsafe_math_optimizations"
15823   "fcos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "XF")])
15826
15827 ;; With sincos pattern defined, sin and cos builtin function will be
15828 ;; expanded to sincos pattern with one of its outputs left unused. 
15829 ;; Cse pass  will detected, if two sincos patterns can be combined,
15830 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15831 ;; depending on the unused output.
15832
15833 (define_insn "sincosdf3"
15834   [(set (match_operand:DF 0 "register_operand" "=f")
15835         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15836                    UNSPEC_SINCOS_COS))
15837    (set (match_operand:DF 1 "register_operand" "=u")
15838         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15839   "TARGET_USE_FANCY_MATH_387
15840    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15841    && flag_unsafe_math_optimizations"
15842   "fsincos"
15843   [(set_attr "type" "fpspc")
15844    (set_attr "mode" "DF")])
15845
15846 (define_split
15847   [(set (match_operand:DF 0 "register_operand" "")
15848         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15849                    UNSPEC_SINCOS_COS))
15850    (set (match_operand:DF 1 "register_operand" "")
15851         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15852   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15853    && !reload_completed && !reload_in_progress"
15854   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15855   "")
15856
15857 (define_split
15858   [(set (match_operand:DF 0 "register_operand" "")
15859         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15860                    UNSPEC_SINCOS_COS))
15861    (set (match_operand:DF 1 "register_operand" "")
15862         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15863   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15864    && !reload_completed && !reload_in_progress"
15865   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15866   "")
15867
15868 (define_insn "sincossf3"
15869   [(set (match_operand:SF 0 "register_operand" "=f")
15870         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15871                    UNSPEC_SINCOS_COS))
15872    (set (match_operand:SF 1 "register_operand" "=u")
15873         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15874   "TARGET_USE_FANCY_MATH_387
15875    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15876    && flag_unsafe_math_optimizations"
15877   "fsincos"
15878   [(set_attr "type" "fpspc")
15879    (set_attr "mode" "SF")])
15880
15881 (define_split
15882   [(set (match_operand:SF 0 "register_operand" "")
15883         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15884                    UNSPEC_SINCOS_COS))
15885    (set (match_operand:SF 1 "register_operand" "")
15886         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15887   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15888    && !reload_completed && !reload_in_progress"
15889   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15890   "")
15891
15892 (define_split
15893   [(set (match_operand:SF 0 "register_operand" "")
15894         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15895                    UNSPEC_SINCOS_COS))
15896    (set (match_operand:SF 1 "register_operand" "")
15897         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15898   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15899    && !reload_completed && !reload_in_progress"
15900   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15901   "")
15902
15903 (define_insn "*sincosextendsfdf3"
15904   [(set (match_operand:DF 0 "register_operand" "=f")
15905         (unspec:DF [(float_extend:DF
15906                      (match_operand:SF 2 "register_operand" "0"))]
15907                    UNSPEC_SINCOS_COS))
15908    (set (match_operand:DF 1 "register_operand" "=u")
15909         (unspec:DF [(float_extend:DF
15910                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15911   "TARGET_USE_FANCY_MATH_387
15912    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15913    && flag_unsafe_math_optimizations"
15914   "fsincos"
15915   [(set_attr "type" "fpspc")
15916    (set_attr "mode" "DF")])
15917
15918 (define_split
15919   [(set (match_operand:DF 0 "register_operand" "")
15920         (unspec:DF [(float_extend:DF
15921                      (match_operand:SF 2 "register_operand" ""))]
15922                    UNSPEC_SINCOS_COS))
15923    (set (match_operand:DF 1 "register_operand" "")
15924         (unspec:DF [(float_extend:DF
15925                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15926   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15927    && !reload_completed && !reload_in_progress"
15928   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15929                                    (match_dup 2))] UNSPEC_SIN))]
15930   "")
15931
15932 (define_split
15933   [(set (match_operand:DF 0 "register_operand" "")
15934         (unspec:DF [(float_extend:DF
15935                      (match_operand:SF 2 "register_operand" ""))]
15936                    UNSPEC_SINCOS_COS))
15937    (set (match_operand:DF 1 "register_operand" "")
15938         (unspec:DF [(float_extend:DF
15939                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15940   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15941    && !reload_completed && !reload_in_progress"
15942   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15943                                    (match_dup 2))] UNSPEC_COS))]
15944   "")
15945
15946 (define_insn "sincosxf3"
15947   [(set (match_operand:XF 0 "register_operand" "=f")
15948         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15949                    UNSPEC_SINCOS_COS))
15950    (set (match_operand:XF 1 "register_operand" "=u")
15951         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15952   "TARGET_USE_FANCY_MATH_387
15953    && flag_unsafe_math_optimizations"
15954   "fsincos"
15955   [(set_attr "type" "fpspc")
15956    (set_attr "mode" "XF")])
15957
15958 (define_split
15959   [(set (match_operand:XF 0 "register_operand" "")
15960         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15961                    UNSPEC_SINCOS_COS))
15962    (set (match_operand:XF 1 "register_operand" "")
15963         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15964   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15965    && !reload_completed && !reload_in_progress"
15966   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15967   "")
15968
15969 (define_split
15970   [(set (match_operand:XF 0 "register_operand" "")
15971         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15972                    UNSPEC_SINCOS_COS))
15973    (set (match_operand:XF 1 "register_operand" "")
15974         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15975   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15976    && !reload_completed && !reload_in_progress"
15977   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15978   "")
15979
15980 (define_insn "*tandf3_1"
15981   [(set (match_operand:DF 0 "register_operand" "=f")
15982         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15983                    UNSPEC_TAN_ONE))
15984    (set (match_operand:DF 1 "register_operand" "=u")
15985         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15986   "TARGET_USE_FANCY_MATH_387
15987    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15988    && flag_unsafe_math_optimizations"
15989   "fptan"
15990   [(set_attr "type" "fpspc")
15991    (set_attr "mode" "DF")])
15992
15993 ;; optimize sequence: fptan
15994 ;;                    fstp    %st(0)
15995 ;;                    fld1
15996 ;; into fptan insn.
15997
15998 (define_peephole2
15999   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16000                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16001                              UNSPEC_TAN_ONE))
16002              (set (match_operand:DF 1 "register_operand" "")
16003                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16004    (set (match_dup 0)
16005         (match_operand:DF 3 "immediate_operand" ""))]
16006   "standard_80387_constant_p (operands[3]) == 2"
16007   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16008              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16009   "")
16010
16011 (define_expand "tandf2"
16012   [(parallel [(set (match_dup 2)
16013                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16014                               UNSPEC_TAN_ONE))
16015               (set (match_operand:DF 0 "register_operand" "")
16016                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16017   "TARGET_USE_FANCY_MATH_387
16018    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16019    && flag_unsafe_math_optimizations"
16020 {
16021   operands[2] = gen_reg_rtx (DFmode);
16022 })
16023
16024 (define_insn "*tansf3_1"
16025   [(set (match_operand:SF 0 "register_operand" "=f")
16026         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16027                    UNSPEC_TAN_ONE))
16028    (set (match_operand:SF 1 "register_operand" "=u")
16029         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16030   "TARGET_USE_FANCY_MATH_387
16031    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16032    && flag_unsafe_math_optimizations"
16033   "fptan"
16034   [(set_attr "type" "fpspc")
16035    (set_attr "mode" "SF")])
16036
16037 ;; optimize sequence: fptan
16038 ;;                    fstp    %st(0)
16039 ;;                    fld1
16040 ;; into fptan insn.
16041
16042 (define_peephole2
16043   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16044                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16045                              UNSPEC_TAN_ONE))
16046              (set (match_operand:SF 1 "register_operand" "")
16047                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16048    (set (match_dup 0)
16049         (match_operand:SF 3 "immediate_operand" ""))]
16050   "standard_80387_constant_p (operands[3]) == 2"
16051   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16052              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16053   "")
16054
16055 (define_expand "tansf2"
16056   [(parallel [(set (match_dup 2)
16057                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16058                               UNSPEC_TAN_ONE))
16059               (set (match_operand:SF 0 "register_operand" "")
16060                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16061   "TARGET_USE_FANCY_MATH_387
16062    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16063    && flag_unsafe_math_optimizations"
16064 {
16065   operands[2] = gen_reg_rtx (SFmode);
16066 })
16067
16068 (define_insn "*tanxf3_1"
16069   [(set (match_operand:XF 0 "register_operand" "=f")
16070         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16071                    UNSPEC_TAN_ONE))
16072    (set (match_operand:XF 1 "register_operand" "=u")
16073         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16074   "TARGET_USE_FANCY_MATH_387
16075    && flag_unsafe_math_optimizations"
16076   "fptan"
16077   [(set_attr "type" "fpspc")
16078    (set_attr "mode" "XF")])
16079
16080 ;; optimize sequence: fptan
16081 ;;                    fstp    %st(0)
16082 ;;                    fld1
16083 ;; into fptan insn.
16084
16085 (define_peephole2
16086   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16087                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16088                              UNSPEC_TAN_ONE))
16089              (set (match_operand:XF 1 "register_operand" "")
16090                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16091    (set (match_dup 0)
16092         (match_operand:XF 3 "immediate_operand" ""))]
16093   "standard_80387_constant_p (operands[3]) == 2"
16094   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16095              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16096   "")
16097
16098 (define_expand "tanxf2"
16099   [(parallel [(set (match_dup 2)
16100                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16101                               UNSPEC_TAN_ONE))
16102               (set (match_operand:XF 0 "register_operand" "")
16103                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16104   "TARGET_USE_FANCY_MATH_387
16105    && flag_unsafe_math_optimizations"
16106 {
16107   operands[2] = gen_reg_rtx (XFmode);
16108 })
16109
16110 (define_insn "atan2df3_1"
16111   [(set (match_operand:DF 0 "register_operand" "=f")
16112         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16113                     (match_operand:DF 1 "register_operand" "u")]
16114                    UNSPEC_FPATAN))
16115    (clobber (match_scratch:DF 3 "=1"))]
16116   "TARGET_USE_FANCY_MATH_387
16117    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16118    && flag_unsafe_math_optimizations"
16119   "fpatan"
16120   [(set_attr "type" "fpspc")
16121    (set_attr "mode" "DF")])
16122
16123 (define_expand "atan2df3"
16124   [(use (match_operand:DF 0 "register_operand" ""))
16125    (use (match_operand:DF 2 "register_operand" ""))
16126    (use (match_operand:DF 1 "register_operand" ""))]
16127   "TARGET_USE_FANCY_MATH_387
16128    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16129    && flag_unsafe_math_optimizations"
16130 {
16131   rtx copy = gen_reg_rtx (DFmode);
16132   emit_move_insn (copy, operands[1]);
16133   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16134   DONE;
16135 })
16136
16137 (define_expand "atandf2"
16138   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16139                    (unspec:DF [(match_dup 2)
16140                                (match_operand:DF 1 "register_operand" "")]
16141                     UNSPEC_FPATAN))
16142               (clobber (match_scratch:DF 3 ""))])]
16143   "TARGET_USE_FANCY_MATH_387
16144    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16145    && flag_unsafe_math_optimizations"
16146 {
16147   operands[2] = gen_reg_rtx (DFmode);
16148   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16149 })
16150
16151 (define_insn "atan2sf3_1"
16152   [(set (match_operand:SF 0 "register_operand" "=f")
16153         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16154                     (match_operand:SF 1 "register_operand" "u")]
16155                    UNSPEC_FPATAN))
16156    (clobber (match_scratch:SF 3 "=1"))]
16157   "TARGET_USE_FANCY_MATH_387
16158    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16159    && flag_unsafe_math_optimizations"
16160   "fpatan"
16161   [(set_attr "type" "fpspc")
16162    (set_attr "mode" "SF")])
16163
16164 (define_expand "atan2sf3"
16165   [(use (match_operand:SF 0 "register_operand" ""))
16166    (use (match_operand:SF 2 "register_operand" ""))
16167    (use (match_operand:SF 1 "register_operand" ""))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16170    && flag_unsafe_math_optimizations"
16171 {
16172   rtx copy = gen_reg_rtx (SFmode);
16173   emit_move_insn (copy, operands[1]);
16174   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16175   DONE;
16176 })
16177
16178 (define_expand "atansf2"
16179   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16180                    (unspec:SF [(match_dup 2)
16181                                (match_operand:SF 1 "register_operand" "")]
16182                     UNSPEC_FPATAN))
16183               (clobber (match_scratch:SF 3 ""))])]
16184   "TARGET_USE_FANCY_MATH_387
16185    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16186    && flag_unsafe_math_optimizations"
16187 {
16188   operands[2] = gen_reg_rtx (SFmode);
16189   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16190 })
16191
16192 (define_insn "atan2xf3_1"
16193   [(set (match_operand:XF 0 "register_operand" "=f")
16194         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16195                     (match_operand:XF 1 "register_operand" "u")]
16196                    UNSPEC_FPATAN))
16197    (clobber (match_scratch:XF 3 "=1"))]
16198   "TARGET_USE_FANCY_MATH_387
16199    && flag_unsafe_math_optimizations"
16200   "fpatan"
16201   [(set_attr "type" "fpspc")
16202    (set_attr "mode" "XF")])
16203
16204 (define_expand "atan2xf3"
16205   [(use (match_operand:XF 0 "register_operand" ""))
16206    (use (match_operand:XF 2 "register_operand" ""))
16207    (use (match_operand:XF 1 "register_operand" ""))]
16208   "TARGET_USE_FANCY_MATH_387
16209    && flag_unsafe_math_optimizations"
16210 {
16211   rtx copy = gen_reg_rtx (XFmode);
16212   emit_move_insn (copy, operands[1]);
16213   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16214   DONE;
16215 })
16216
16217 (define_expand "atanxf2"
16218   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16219                    (unspec:XF [(match_dup 2)
16220                                (match_operand:XF 1 "register_operand" "")]
16221                     UNSPEC_FPATAN))
16222               (clobber (match_scratch:XF 3 ""))])]
16223   "TARGET_USE_FANCY_MATH_387
16224    && flag_unsafe_math_optimizations"
16225 {
16226   operands[2] = gen_reg_rtx (XFmode);
16227   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16228 })
16229
16230 (define_expand "asindf2"
16231   [(set (match_dup 2)
16232         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16233    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16234    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16235    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16236    (parallel [(set (match_dup 7)
16237                    (unspec:XF [(match_dup 6) (match_dup 2)]
16238                               UNSPEC_FPATAN))
16239               (clobber (match_scratch:XF 8 ""))])
16240    (set (match_operand:DF 0 "register_operand" "")
16241         (float_truncate:DF (match_dup 7)))]
16242   "TARGET_USE_FANCY_MATH_387
16243    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16244    && flag_unsafe_math_optimizations"
16245 {
16246   int i;
16247
16248   for (i=2; i<8; i++)
16249     operands[i] = gen_reg_rtx (XFmode);
16250
16251   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16252 })
16253
16254 (define_expand "asinsf2"
16255   [(set (match_dup 2)
16256         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16257    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16258    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16259    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16260    (parallel [(set (match_dup 7)
16261                    (unspec:XF [(match_dup 6) (match_dup 2)]
16262                               UNSPEC_FPATAN))
16263               (clobber (match_scratch:XF 8 ""))])
16264    (set (match_operand:SF 0 "register_operand" "")
16265         (float_truncate:SF (match_dup 7)))]
16266   "TARGET_USE_FANCY_MATH_387
16267    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16268    && flag_unsafe_math_optimizations"
16269 {
16270   int i;
16271
16272   for (i=2; i<8; i++)
16273     operands[i] = gen_reg_rtx (XFmode);
16274
16275   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16276 })
16277
16278 (define_expand "asinxf2"
16279   [(set (match_dup 2)
16280         (mult:XF (match_operand:XF 1 "register_operand" "")
16281                  (match_dup 1)))
16282    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16283    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16284    (parallel [(set (match_operand:XF 0 "register_operand" "")
16285                    (unspec:XF [(match_dup 5) (match_dup 1)]
16286                               UNSPEC_FPATAN))
16287               (clobber (match_scratch:XF 6 ""))])]
16288   "TARGET_USE_FANCY_MATH_387
16289    && flag_unsafe_math_optimizations"
16290 {
16291   int i;
16292
16293   for (i=2; i<6; i++)
16294     operands[i] = gen_reg_rtx (XFmode);
16295
16296   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16297 })
16298
16299 (define_expand "acosdf2"
16300   [(set (match_dup 2)
16301         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16302    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16303    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16304    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16305    (parallel [(set (match_dup 7)
16306                    (unspec:XF [(match_dup 2) (match_dup 6)]
16307                               UNSPEC_FPATAN))
16308               (clobber (match_scratch:XF 8 ""))])
16309    (set (match_operand:DF 0 "register_operand" "")
16310         (float_truncate:DF (match_dup 7)))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16313    && flag_unsafe_math_optimizations"
16314 {
16315   int i;
16316
16317   for (i=2; i<8; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319
16320   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16321 })
16322
16323 (define_expand "acossf2"
16324   [(set (match_dup 2)
16325         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16326    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16327    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16328    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16329    (parallel [(set (match_dup 7)
16330                    (unspec:XF [(match_dup 2) (match_dup 6)]
16331                               UNSPEC_FPATAN))
16332               (clobber (match_scratch:XF 8 ""))])
16333    (set (match_operand:SF 0 "register_operand" "")
16334         (float_truncate:SF (match_dup 7)))]
16335   "TARGET_USE_FANCY_MATH_387
16336    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16337    && flag_unsafe_math_optimizations"
16338 {
16339   int i;
16340
16341   for (i=2; i<8; i++)
16342     operands[i] = gen_reg_rtx (XFmode);
16343
16344   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16345 })
16346
16347 (define_expand "acosxf2"
16348   [(set (match_dup 2)
16349         (mult:XF (match_operand:XF 1 "register_operand" "")
16350                  (match_dup 1)))
16351    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16352    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16353    (parallel [(set (match_operand:XF 0 "register_operand" "")
16354                    (unspec:XF [(match_dup 1) (match_dup 5)]
16355                               UNSPEC_FPATAN))
16356               (clobber (match_scratch:XF 6 ""))])]
16357   "TARGET_USE_FANCY_MATH_387
16358    && flag_unsafe_math_optimizations"
16359 {
16360   int i;
16361
16362   for (i=2; i<6; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16364
16365   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16366 })
16367
16368 (define_insn "fyl2x_xf3"
16369   [(set (match_operand:XF 0 "register_operand" "=f")
16370         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16371                     (match_operand:XF 1 "register_operand" "u")]
16372                    UNSPEC_FYL2X))
16373    (clobber (match_scratch:XF 3 "=1"))]
16374   "TARGET_USE_FANCY_MATH_387
16375    && flag_unsafe_math_optimizations"
16376   "fyl2x"
16377   [(set_attr "type" "fpspc")
16378    (set_attr "mode" "XF")])
16379
16380 (define_expand "logsf2"
16381   [(set (match_dup 2)
16382         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16383    (parallel [(set (match_dup 4)
16384                    (unspec:XF [(match_dup 2)
16385                                (match_dup 3)] UNSPEC_FYL2X))
16386               (clobber (match_scratch:XF 5 ""))])
16387    (set (match_operand:SF 0 "register_operand" "")
16388         (float_truncate:SF (match_dup 4)))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391    && flag_unsafe_math_optimizations"
16392 {
16393   rtx temp;
16394
16395   operands[2] = gen_reg_rtx (XFmode);
16396   operands[3] = gen_reg_rtx (XFmode);
16397   operands[4] = gen_reg_rtx (XFmode);
16398
16399   temp = standard_80387_constant_rtx (4); /* fldln2 */
16400   emit_move_insn (operands[3], temp);
16401 })
16402
16403 (define_expand "logdf2"
16404   [(set (match_dup 2)
16405         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16406    (parallel [(set (match_dup 4)
16407                    (unspec:XF [(match_dup 2)
16408                                (match_dup 3)] UNSPEC_FYL2X))
16409               (clobber (match_scratch:XF 5 ""))])
16410    (set (match_operand:DF 0 "register_operand" "")
16411         (float_truncate:DF (match_dup 4)))]
16412   "TARGET_USE_FANCY_MATH_387
16413    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16414    && flag_unsafe_math_optimizations"
16415 {
16416   rtx temp;
16417
16418   operands[2] = gen_reg_rtx (XFmode);
16419   operands[3] = gen_reg_rtx (XFmode);
16420   operands[4] = gen_reg_rtx (XFmode);
16421
16422   temp = standard_80387_constant_rtx (4); /* fldln2 */
16423   emit_move_insn (operands[3], temp);
16424 })
16425
16426 (define_expand "logxf2"
16427   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16428                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16429                                (match_dup 2)] UNSPEC_FYL2X))
16430               (clobber (match_scratch:XF 3 ""))])]
16431   "TARGET_USE_FANCY_MATH_387
16432    && flag_unsafe_math_optimizations"
16433 {
16434   rtx temp;
16435
16436   operands[2] = gen_reg_rtx (XFmode);
16437   temp = standard_80387_constant_rtx (4); /* fldln2 */
16438   emit_move_insn (operands[2], temp);
16439 })
16440
16441 (define_expand "log10sf2"
16442   [(set (match_dup 2)
16443         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16444    (parallel [(set (match_dup 4)
16445                    (unspec:XF [(match_dup 2)
16446                                (match_dup 3)] UNSPEC_FYL2X))
16447               (clobber (match_scratch:XF 5 ""))])
16448    (set (match_operand:SF 0 "register_operand" "")
16449         (float_truncate:SF (match_dup 4)))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452    && flag_unsafe_math_optimizations"
16453 {
16454   rtx temp;
16455
16456   operands[2] = gen_reg_rtx (XFmode);
16457   operands[3] = gen_reg_rtx (XFmode);
16458   operands[4] = gen_reg_rtx (XFmode);
16459
16460   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16461   emit_move_insn (operands[3], temp);
16462 })
16463
16464 (define_expand "log10df2"
16465   [(set (match_dup 2)
16466         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16467    (parallel [(set (match_dup 4)
16468                    (unspec:XF [(match_dup 2)
16469                                (match_dup 3)] UNSPEC_FYL2X))
16470               (clobber (match_scratch:XF 5 ""))])
16471    (set (match_operand:DF 0 "register_operand" "")
16472         (float_truncate:DF (match_dup 4)))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16476 {
16477   rtx temp;
16478
16479   operands[2] = gen_reg_rtx (XFmode);
16480   operands[3] = gen_reg_rtx (XFmode);
16481   operands[4] = gen_reg_rtx (XFmode);
16482
16483   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16484   emit_move_insn (operands[3], temp);
16485 })
16486
16487 (define_expand "log10xf2"
16488   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16489                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16490                                (match_dup 2)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 3 ""))])]
16492   "TARGET_USE_FANCY_MATH_387
16493    && flag_unsafe_math_optimizations"
16494 {
16495   rtx temp;
16496
16497   operands[2] = gen_reg_rtx (XFmode);
16498   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16499   emit_move_insn (operands[2], temp);
16500 })
16501
16502 (define_expand "log2sf2"
16503   [(set (match_dup 2)
16504         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16505    (parallel [(set (match_dup 4)
16506                    (unspec:XF [(match_dup 2)
16507                                (match_dup 3)] UNSPEC_FYL2X))
16508               (clobber (match_scratch:XF 5 ""))])
16509    (set (match_operand:SF 0 "register_operand" "")
16510         (float_truncate:SF (match_dup 4)))]
16511   "TARGET_USE_FANCY_MATH_387
16512    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations"
16514 {
16515   operands[2] = gen_reg_rtx (XFmode);
16516   operands[3] = gen_reg_rtx (XFmode);
16517   operands[4] = gen_reg_rtx (XFmode);
16518
16519   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16520 })
16521
16522 (define_expand "log2df2"
16523   [(set (match_dup 2)
16524         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16525    (parallel [(set (match_dup 4)
16526                    (unspec:XF [(match_dup 2)
16527                                (match_dup 3)] UNSPEC_FYL2X))
16528               (clobber (match_scratch:XF 5 ""))])
16529    (set (match_operand:DF 0 "register_operand" "")
16530         (float_truncate:DF (match_dup 4)))]
16531   "TARGET_USE_FANCY_MATH_387
16532    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16533    && flag_unsafe_math_optimizations"
16534 {
16535   operands[2] = gen_reg_rtx (XFmode);
16536   operands[3] = gen_reg_rtx (XFmode);
16537   operands[4] = gen_reg_rtx (XFmode);
16538
16539   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16540 })
16541
16542 (define_expand "log2xf2"
16543   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16544                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16545                                (match_dup 2)] UNSPEC_FYL2X))
16546               (clobber (match_scratch:XF 3 ""))])]
16547   "TARGET_USE_FANCY_MATH_387
16548    && flag_unsafe_math_optimizations"
16549 {
16550   operands[2] = gen_reg_rtx (XFmode);
16551   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16552 })
16553
16554 (define_insn "fyl2xp1_xf3"
16555   [(set (match_operand:XF 0 "register_operand" "=f")
16556         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16557                     (match_operand:XF 1 "register_operand" "u")]
16558                    UNSPEC_FYL2XP1))
16559    (clobber (match_scratch:XF 3 "=1"))]
16560   "TARGET_USE_FANCY_MATH_387
16561    && flag_unsafe_math_optimizations"
16562   "fyl2xp1"
16563   [(set_attr "type" "fpspc")
16564    (set_attr "mode" "XF")])
16565
16566 (define_expand "log1psf2"
16567   [(use (match_operand:SF 0 "register_operand" ""))
16568    (use (match_operand:SF 1 "register_operand" ""))]
16569   "TARGET_USE_FANCY_MATH_387
16570    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16571    && flag_unsafe_math_optimizations"
16572 {
16573   rtx op0 = gen_reg_rtx (XFmode);
16574   rtx op1 = gen_reg_rtx (XFmode);
16575
16576   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16577   ix86_emit_i387_log1p (op0, op1);
16578   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16579   DONE;
16580 })
16581
16582 (define_expand "log1pdf2"
16583   [(use (match_operand:DF 0 "register_operand" ""))
16584    (use (match_operand:DF 1 "register_operand" ""))]
16585   "TARGET_USE_FANCY_MATH_387
16586    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16587    && flag_unsafe_math_optimizations"
16588 {
16589   rtx op0 = gen_reg_rtx (XFmode);
16590   rtx op1 = gen_reg_rtx (XFmode);
16591
16592   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16593   ix86_emit_i387_log1p (op0, op1);
16594   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16595   DONE;
16596 })
16597
16598 (define_expand "log1pxf2"
16599   [(use (match_operand:XF 0 "register_operand" ""))
16600    (use (match_operand:XF 1 "register_operand" ""))]
16601   "TARGET_USE_FANCY_MATH_387
16602    && flag_unsafe_math_optimizations"
16603 {
16604   ix86_emit_i387_log1p (operands[0], operands[1]);
16605   DONE;
16606 })
16607
16608 (define_insn "*fxtractxf3"
16609   [(set (match_operand:XF 0 "register_operand" "=f")
16610         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16611                    UNSPEC_XTRACT_FRACT))
16612    (set (match_operand:XF 1 "register_operand" "=u")
16613         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16614   "TARGET_USE_FANCY_MATH_387
16615    && flag_unsafe_math_optimizations"
16616   "fxtract"
16617   [(set_attr "type" "fpspc")
16618    (set_attr "mode" "XF")])
16619
16620 (define_expand "logbsf2"
16621   [(set (match_dup 2)
16622         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16623    (parallel [(set (match_dup 3)
16624                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16625               (set (match_dup 4)
16626                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16627    (set (match_operand:SF 0 "register_operand" "")
16628         (float_truncate:SF (match_dup 4)))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16631    && flag_unsafe_math_optimizations"
16632 {
16633   operands[2] = gen_reg_rtx (XFmode);
16634   operands[3] = gen_reg_rtx (XFmode);
16635   operands[4] = gen_reg_rtx (XFmode);
16636 })
16637
16638 (define_expand "logbdf2"
16639   [(set (match_dup 2)
16640         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16641    (parallel [(set (match_dup 3)
16642                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16643               (set (match_dup 4)
16644                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16645    (set (match_operand:DF 0 "register_operand" "")
16646         (float_truncate:DF (match_dup 4)))]
16647   "TARGET_USE_FANCY_MATH_387
16648    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16649    && flag_unsafe_math_optimizations"
16650 {
16651   operands[2] = gen_reg_rtx (XFmode);
16652   operands[3] = gen_reg_rtx (XFmode);
16653   operands[4] = gen_reg_rtx (XFmode);
16654 })
16655
16656 (define_expand "logbxf2"
16657   [(parallel [(set (match_dup 2)
16658                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16659                               UNSPEC_XTRACT_FRACT))
16660               (set (match_operand:XF 0 "register_operand" "")
16661                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16662   "TARGET_USE_FANCY_MATH_387
16663    && flag_unsafe_math_optimizations"
16664 {
16665   operands[2] = gen_reg_rtx (XFmode);
16666 })
16667
16668 (define_expand "ilogbsi2"
16669   [(parallel [(set (match_dup 2)
16670                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16671                               UNSPEC_XTRACT_FRACT))
16672               (set (match_operand:XF 3 "register_operand" "")
16673                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16674    (parallel [(set (match_operand:SI 0 "register_operand" "")
16675                    (fix:SI (match_dup 3)))
16676               (clobber (reg:CC FLAGS_REG))])]
16677   "TARGET_USE_FANCY_MATH_387
16678    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16679    && flag_unsafe_math_optimizations"
16680 {
16681   operands[2] = gen_reg_rtx (XFmode);
16682   operands[3] = gen_reg_rtx (XFmode);
16683 })
16684
16685 (define_insn "*f2xm1xf2"
16686   [(set (match_operand:XF 0 "register_operand" "=f")
16687         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16688          UNSPEC_F2XM1))]
16689   "TARGET_USE_FANCY_MATH_387
16690    && flag_unsafe_math_optimizations"
16691   "f2xm1"
16692   [(set_attr "type" "fpspc")
16693    (set_attr "mode" "XF")])
16694
16695 (define_insn "*fscalexf4"
16696   [(set (match_operand:XF 0 "register_operand" "=f")
16697         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16698                     (match_operand:XF 3 "register_operand" "1")]
16699                    UNSPEC_FSCALE_FRACT))
16700    (set (match_operand:XF 1 "register_operand" "=u")
16701         (unspec:XF [(match_dup 2) (match_dup 3)]
16702                    UNSPEC_FSCALE_EXP))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && flag_unsafe_math_optimizations"
16705   "fscale"
16706   [(set_attr "type" "fpspc")
16707    (set_attr "mode" "XF")])
16708
16709 (define_expand "expsf2"
16710   [(set (match_dup 2)
16711         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16712    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16713    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16714    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16715    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16716    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16717    (parallel [(set (match_dup 10)
16718                    (unspec:XF [(match_dup 9) (match_dup 5)]
16719                               UNSPEC_FSCALE_FRACT))
16720               (set (match_dup 11)
16721                    (unspec:XF [(match_dup 9) (match_dup 5)]
16722                               UNSPEC_FSCALE_EXP))])
16723    (set (match_operand:SF 0 "register_operand" "")
16724         (float_truncate:SF (match_dup 10)))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16727    && flag_unsafe_math_optimizations"
16728 {
16729   rtx temp;
16730   int i;
16731
16732   for (i=2; i<12; i++)
16733     operands[i] = gen_reg_rtx (XFmode);
16734   temp = standard_80387_constant_rtx (5); /* fldl2e */
16735   emit_move_insn (operands[3], temp);
16736   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16737 })
16738
16739 (define_expand "expdf2"
16740   [(set (match_dup 2)
16741         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16742    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16743    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16744    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16745    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16746    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16747    (parallel [(set (match_dup 10)
16748                    (unspec:XF [(match_dup 9) (match_dup 5)]
16749                               UNSPEC_FSCALE_FRACT))
16750               (set (match_dup 11)
16751                    (unspec:XF [(match_dup 9) (match_dup 5)]
16752                               UNSPEC_FSCALE_EXP))])
16753    (set (match_operand:DF 0 "register_operand" "")
16754         (float_truncate:DF (match_dup 10)))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16757    && flag_unsafe_math_optimizations"
16758 {
16759   rtx temp;
16760   int i;
16761
16762   for (i=2; i<12; i++)
16763     operands[i] = gen_reg_rtx (XFmode);
16764   temp = standard_80387_constant_rtx (5); /* fldl2e */
16765   emit_move_insn (operands[3], temp);
16766   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16767 })
16768
16769 (define_expand "expxf2"
16770   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16771                                (match_dup 2)))
16772    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16773    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16774    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16775    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16776    (parallel [(set (match_operand:XF 0 "register_operand" "")
16777                    (unspec:XF [(match_dup 8) (match_dup 4)]
16778                               UNSPEC_FSCALE_FRACT))
16779               (set (match_dup 9)
16780                    (unspec:XF [(match_dup 8) (match_dup 4)]
16781                               UNSPEC_FSCALE_EXP))])]
16782   "TARGET_USE_FANCY_MATH_387
16783    && flag_unsafe_math_optimizations"
16784 {
16785   rtx temp;
16786   int i;
16787
16788   for (i=2; i<10; i++)
16789     operands[i] = gen_reg_rtx (XFmode);
16790   temp = standard_80387_constant_rtx (5); /* fldl2e */
16791   emit_move_insn (operands[2], temp);
16792   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16793 })
16794
16795 (define_expand "exp10sf2"
16796   [(set (match_dup 2)
16797         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16798    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16799    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16800    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16801    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16802    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16803    (parallel [(set (match_dup 10)
16804                    (unspec:XF [(match_dup 9) (match_dup 5)]
16805                               UNSPEC_FSCALE_FRACT))
16806               (set (match_dup 11)
16807                    (unspec:XF [(match_dup 9) (match_dup 5)]
16808                               UNSPEC_FSCALE_EXP))])
16809    (set (match_operand:SF 0 "register_operand" "")
16810         (float_truncate:SF (match_dup 10)))]
16811   "TARGET_USE_FANCY_MATH_387
16812    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16813    && flag_unsafe_math_optimizations"
16814 {
16815   rtx temp;
16816   int i;
16817
16818   for (i=2; i<12; i++)
16819     operands[i] = gen_reg_rtx (XFmode);
16820   temp = standard_80387_constant_rtx (6); /* fldl2t */
16821   emit_move_insn (operands[3], temp);
16822   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16823 })
16824
16825 (define_expand "exp10df2"
16826   [(set (match_dup 2)
16827         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16828    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16829    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16830    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16831    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16832    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16833    (parallel [(set (match_dup 10)
16834                    (unspec:XF [(match_dup 9) (match_dup 5)]
16835                               UNSPEC_FSCALE_FRACT))
16836               (set (match_dup 11)
16837                    (unspec:XF [(match_dup 9) (match_dup 5)]
16838                               UNSPEC_FSCALE_EXP))])
16839    (set (match_operand:DF 0 "register_operand" "")
16840         (float_truncate:DF (match_dup 10)))]
16841   "TARGET_USE_FANCY_MATH_387
16842    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16843    && flag_unsafe_math_optimizations"
16844 {
16845   rtx temp;
16846   int i;
16847
16848   for (i=2; i<12; i++)
16849     operands[i] = gen_reg_rtx (XFmode);
16850   temp = standard_80387_constant_rtx (6); /* fldl2t */
16851   emit_move_insn (operands[3], temp);
16852   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16853 })
16854
16855 (define_expand "exp10xf2"
16856   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16857                                (match_dup 2)))
16858    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16859    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16860    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16861    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16862    (parallel [(set (match_operand:XF 0 "register_operand" "")
16863                    (unspec:XF [(match_dup 8) (match_dup 4)]
16864                               UNSPEC_FSCALE_FRACT))
16865               (set (match_dup 9)
16866                    (unspec:XF [(match_dup 8) (match_dup 4)]
16867                               UNSPEC_FSCALE_EXP))])]
16868   "TARGET_USE_FANCY_MATH_387
16869    && flag_unsafe_math_optimizations"
16870 {
16871   rtx temp;
16872   int i;
16873
16874   for (i=2; i<10; i++)
16875     operands[i] = gen_reg_rtx (XFmode);
16876   temp = standard_80387_constant_rtx (6); /* fldl2t */
16877   emit_move_insn (operands[2], temp);
16878   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16879 })
16880
16881 (define_expand "exp2sf2"
16882   [(set (match_dup 2)
16883         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16884    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16885    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16886    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16887    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16888    (parallel [(set (match_dup 8)
16889                    (unspec:XF [(match_dup 7) (match_dup 3)]
16890                               UNSPEC_FSCALE_FRACT))
16891               (set (match_dup 9)
16892                    (unspec:XF [(match_dup 7) (match_dup 3)]
16893                               UNSPEC_FSCALE_EXP))])
16894    (set (match_operand:SF 0 "register_operand" "")
16895         (float_truncate:SF (match_dup 8)))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16898    && flag_unsafe_math_optimizations"
16899 {
16900   int i;
16901
16902   for (i=2; i<10; i++)
16903     operands[i] = gen_reg_rtx (XFmode);
16904   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16905 })
16906
16907 (define_expand "exp2df2"
16908   [(set (match_dup 2)
16909         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16910    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16911    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16912    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16913    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16914    (parallel [(set (match_dup 8)
16915                    (unspec:XF [(match_dup 7) (match_dup 3)]
16916                               UNSPEC_FSCALE_FRACT))
16917               (set (match_dup 9)
16918                    (unspec:XF [(match_dup 7) (match_dup 3)]
16919                               UNSPEC_FSCALE_EXP))])
16920    (set (match_operand:DF 0 "register_operand" "")
16921         (float_truncate:DF (match_dup 8)))]
16922   "TARGET_USE_FANCY_MATH_387
16923    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16924    && flag_unsafe_math_optimizations"
16925 {
16926   int i;
16927
16928   for (i=2; i<10; i++)
16929     operands[i] = gen_reg_rtx (XFmode);
16930   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16931 })
16932
16933 (define_expand "exp2xf2"
16934   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16935    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16936    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16937    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16938    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16939    (parallel [(set (match_operand:XF 0 "register_operand" "")
16940                    (unspec:XF [(match_dup 7) (match_dup 3)]
16941                               UNSPEC_FSCALE_FRACT))
16942               (set (match_dup 8)
16943                    (unspec:XF [(match_dup 7) (match_dup 3)]
16944                               UNSPEC_FSCALE_EXP))])]
16945   "TARGET_USE_FANCY_MATH_387
16946    && flag_unsafe_math_optimizations"
16947 {
16948   int i;
16949
16950   for (i=2; i<9; i++)
16951     operands[i] = gen_reg_rtx (XFmode);
16952   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16953 })
16954
16955 (define_expand "expm1df2"
16956   [(set (match_dup 2)
16957         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16958    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16959    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16960    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16961    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16962    (parallel [(set (match_dup 8)
16963                    (unspec:XF [(match_dup 7) (match_dup 5)]
16964                               UNSPEC_FSCALE_FRACT))
16965                    (set (match_dup 9)
16966                    (unspec:XF [(match_dup 7) (match_dup 5)]
16967                               UNSPEC_FSCALE_EXP))])
16968    (parallel [(set (match_dup 11)
16969                    (unspec:XF [(match_dup 10) (match_dup 9)]
16970                               UNSPEC_FSCALE_FRACT))
16971               (set (match_dup 12)
16972                    (unspec:XF [(match_dup 10) (match_dup 9)]
16973                               UNSPEC_FSCALE_EXP))])
16974    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16975    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16976    (set (match_operand:DF 0 "register_operand" "")
16977         (float_truncate:DF (match_dup 14)))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16980    && flag_unsafe_math_optimizations"
16981 {
16982   rtx temp;
16983   int i;
16984
16985   for (i=2; i<15; i++)
16986     operands[i] = gen_reg_rtx (XFmode);
16987   temp = standard_80387_constant_rtx (5); /* fldl2e */
16988   emit_move_insn (operands[3], temp);
16989   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16990 })
16991
16992 (define_expand "expm1sf2"
16993   [(set (match_dup 2)
16994         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16995    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16996    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16997    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16998    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16999    (parallel [(set (match_dup 8)
17000                    (unspec:XF [(match_dup 7) (match_dup 5)]
17001                               UNSPEC_FSCALE_FRACT))
17002                    (set (match_dup 9)
17003                    (unspec:XF [(match_dup 7) (match_dup 5)]
17004                               UNSPEC_FSCALE_EXP))])
17005    (parallel [(set (match_dup 11)
17006                    (unspec:XF [(match_dup 10) (match_dup 9)]
17007                               UNSPEC_FSCALE_FRACT))
17008               (set (match_dup 12)
17009                    (unspec:XF [(match_dup 10) (match_dup 9)]
17010                               UNSPEC_FSCALE_EXP))])
17011    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17012    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17013    (set (match_operand:SF 0 "register_operand" "")
17014         (float_truncate:SF (match_dup 14)))]
17015   "TARGET_USE_FANCY_MATH_387
17016    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17017    && flag_unsafe_math_optimizations"
17018 {
17019   rtx temp;
17020   int i;
17021
17022   for (i=2; i<15; i++)
17023     operands[i] = gen_reg_rtx (XFmode);
17024   temp = standard_80387_constant_rtx (5); /* fldl2e */
17025   emit_move_insn (operands[3], temp);
17026   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17027 })
17028
17029 (define_expand "expm1xf2"
17030   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031                                (match_dup 2)))
17032    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035    (parallel [(set (match_dup 7)
17036                    (unspec:XF [(match_dup 6) (match_dup 4)]
17037                               UNSPEC_FSCALE_FRACT))
17038                    (set (match_dup 8)
17039                    (unspec:XF [(match_dup 6) (match_dup 4)]
17040                               UNSPEC_FSCALE_EXP))])
17041    (parallel [(set (match_dup 10)
17042                    (unspec:XF [(match_dup 9) (match_dup 8)]
17043                               UNSPEC_FSCALE_FRACT))
17044               (set (match_dup 11)
17045                    (unspec:XF [(match_dup 9) (match_dup 8)]
17046                               UNSPEC_FSCALE_EXP))])
17047    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17048    (set (match_operand:XF 0 "register_operand" "")
17049         (plus:XF (match_dup 12) (match_dup 7)))]
17050   "TARGET_USE_FANCY_MATH_387
17051    && flag_unsafe_math_optimizations"
17052 {
17053   rtx temp;
17054   int i;
17055
17056   for (i=2; i<13; i++)
17057     operands[i] = gen_reg_rtx (XFmode);
17058   temp = standard_80387_constant_rtx (5); /* fldl2e */
17059   emit_move_insn (operands[2], temp);
17060   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17061 })
17062
17063 (define_expand "ldexpdf3"
17064   [(set (match_dup 3)
17065         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17066    (set (match_dup 4)
17067         (float:XF (match_operand:SI 2 "register_operand" "")))
17068    (parallel [(set (match_dup 5)
17069                    (unspec:XF [(match_dup 3) (match_dup 4)]
17070                               UNSPEC_FSCALE_FRACT))
17071               (set (match_dup 6)
17072                    (unspec:XF [(match_dup 3) (match_dup 4)]
17073                               UNSPEC_FSCALE_EXP))])
17074    (set (match_operand:DF 0 "register_operand" "")
17075         (float_truncate:DF (match_dup 5)))]
17076   "TARGET_USE_FANCY_MATH_387
17077    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17078    && flag_unsafe_math_optimizations"
17079 {
17080   int i;
17081
17082   for (i=3; i<7; i++)
17083     operands[i] = gen_reg_rtx (XFmode);
17084 })
17085
17086 (define_expand "ldexpsf3"
17087   [(set (match_dup 3)
17088         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17089    (set (match_dup 4)
17090         (float:XF (match_operand:SI 2 "register_operand" "")))
17091    (parallel [(set (match_dup 5)
17092                    (unspec:XF [(match_dup 3) (match_dup 4)]
17093                               UNSPEC_FSCALE_FRACT))
17094               (set (match_dup 6)
17095                    (unspec:XF [(match_dup 3) (match_dup 4)]
17096                               UNSPEC_FSCALE_EXP))])
17097    (set (match_operand:SF 0 "register_operand" "")
17098         (float_truncate:SF (match_dup 5)))]
17099   "TARGET_USE_FANCY_MATH_387
17100    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17101    && flag_unsafe_math_optimizations"
17102 {
17103   int i;
17104
17105   for (i=3; i<7; i++)
17106     operands[i] = gen_reg_rtx (XFmode);
17107 })
17108
17109 (define_expand "ldexpxf3"
17110   [(set (match_dup 3)
17111         (float:XF (match_operand:SI 2 "register_operand" "")))
17112    (parallel [(set (match_operand:XF 0 " register_operand" "")
17113                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17114                                (match_dup 3)]
17115                               UNSPEC_FSCALE_FRACT))
17116               (set (match_dup 4)
17117                    (unspec:XF [(match_dup 1) (match_dup 3)]
17118                               UNSPEC_FSCALE_EXP))])]
17119   "TARGET_USE_FANCY_MATH_387
17120    && flag_unsafe_math_optimizations"
17121 {
17122   int i;
17123
17124   for (i=3; i<5; i++)
17125     operands[i] = gen_reg_rtx (XFmode);
17126 })
17127 \f
17128
17129 (define_insn "frndintxf2"
17130   [(set (match_operand:XF 0 "register_operand" "=f")
17131         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17132          UNSPEC_FRNDINT))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135   "frndint"
17136   [(set_attr "type" "fpspc")
17137    (set_attr "mode" "XF")])
17138
17139 (define_expand "rintdf2"
17140   [(use (match_operand:DF 0 "register_operand" ""))
17141    (use (match_operand:DF 1 "register_operand" ""))]
17142   "TARGET_USE_FANCY_MATH_387
17143    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17144    && flag_unsafe_math_optimizations"
17145 {
17146   rtx op0 = gen_reg_rtx (XFmode);
17147   rtx op1 = gen_reg_rtx (XFmode);
17148
17149   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17150   emit_insn (gen_frndintxf2 (op0, op1));
17151
17152   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17153   DONE;
17154 })
17155
17156 (define_expand "rintsf2"
17157   [(use (match_operand:SF 0 "register_operand" ""))
17158    (use (match_operand:SF 1 "register_operand" ""))]
17159   "TARGET_USE_FANCY_MATH_387
17160    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17161    && flag_unsafe_math_optimizations"
17162 {
17163   rtx op0 = gen_reg_rtx (XFmode);
17164   rtx op1 = gen_reg_rtx (XFmode);
17165
17166   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17167   emit_insn (gen_frndintxf2 (op0, op1));
17168
17169   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17170   DONE;
17171 })
17172
17173 (define_expand "rintxf2"
17174   [(use (match_operand:XF 0 "register_operand" ""))
17175    (use (match_operand:XF 1 "register_operand" ""))]
17176   "TARGET_USE_FANCY_MATH_387
17177    && flag_unsafe_math_optimizations"
17178 {
17179   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17180   DONE;
17181 })
17182
17183 (define_insn_and_split "*fistdi2_1"
17184   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17185         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17186          UNSPEC_FIST))]
17187   "TARGET_USE_FANCY_MATH_387
17188    && flag_unsafe_math_optimizations
17189    && !(reload_completed || reload_in_progress)"
17190   "#"
17191   "&& 1"
17192   [(const_int 0)]
17193 {
17194   if (memory_operand (operands[0], VOIDmode))
17195     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17196   else
17197     {
17198       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17199       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17200                                          operands[2]));
17201     }
17202   DONE;
17203 }
17204   [(set_attr "type" "fpspc")
17205    (set_attr "mode" "DI")])
17206
17207 (define_insn "fistdi2"
17208   [(set (match_operand:DI 0 "memory_operand" "=m")
17209         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17210          UNSPEC_FIST))
17211    (clobber (match_scratch:XF 2 "=&1f"))]
17212   "TARGET_USE_FANCY_MATH_387
17213    && flag_unsafe_math_optimizations"
17214   "* return output_fix_trunc (insn, operands, 0);"
17215   [(set_attr "type" "fpspc")
17216    (set_attr "mode" "DI")])
17217
17218 (define_insn "fistdi2_with_temp"
17219   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17220         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17221          UNSPEC_FIST))
17222    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17223    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && flag_unsafe_math_optimizations"
17226   "#"
17227   [(set_attr "type" "fpspc")
17228    (set_attr "mode" "DI")])
17229
17230 (define_split 
17231   [(set (match_operand:DI 0 "register_operand" "")
17232         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17233          UNSPEC_FIST))
17234    (clobber (match_operand:DI 2 "memory_operand" ""))
17235    (clobber (match_scratch 3 ""))]
17236   "reload_completed"
17237   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17238               (clobber (match_dup 3))])
17239    (set (match_dup 0) (match_dup 2))]
17240   "")
17241
17242 (define_split 
17243   [(set (match_operand:DI 0 "memory_operand" "")
17244         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17245          UNSPEC_FIST))
17246    (clobber (match_operand:DI 2 "memory_operand" ""))
17247    (clobber (match_scratch 3 ""))]
17248   "reload_completed"
17249   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17250               (clobber (match_dup 3))])]
17251   "")
17252
17253 (define_insn_and_split "*fist<mode>2_1"
17254   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17255         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17256          UNSPEC_FIST))]
17257   "TARGET_USE_FANCY_MATH_387
17258    && flag_unsafe_math_optimizations
17259    && !(reload_completed || reload_in_progress)"
17260   "#"
17261   "&& 1"
17262   [(const_int 0)]
17263 {
17264   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17265   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17266                                         operands[2]));
17267   DONE;
17268 }
17269   [(set_attr "type" "fpspc")
17270    (set_attr "mode" "<MODE>")])
17271
17272 (define_insn "fist<mode>2"
17273   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17274         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17275          UNSPEC_FIST))]
17276   "TARGET_USE_FANCY_MATH_387
17277    && flag_unsafe_math_optimizations"
17278   "* return output_fix_trunc (insn, operands, 0);"
17279   [(set_attr "type" "fpspc")
17280    (set_attr "mode" "<MODE>")])
17281
17282 (define_insn "fist<mode>2_with_temp"
17283   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17284         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17285          UNSPEC_FIST))
17286    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17287   "TARGET_USE_FANCY_MATH_387
17288    && flag_unsafe_math_optimizations"
17289   "#"
17290   [(set_attr "type" "fpspc")
17291    (set_attr "mode" "<MODE>")])
17292
17293 (define_split 
17294   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17295         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17296          UNSPEC_FIST))
17297    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17298   "reload_completed"
17299   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17300                        UNSPEC_FIST))
17301    (set (match_dup 0) (match_dup 2))]
17302   "")
17303
17304 (define_split 
17305   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17306         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17307          UNSPEC_FIST))
17308    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17309   "reload_completed"
17310   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17311                        UNSPEC_FIST))]
17312   "")
17313
17314 (define_expand "lrint<mode>2"
17315   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17316         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17317          UNSPEC_FIST))]
17318   "TARGET_USE_FANCY_MATH_387
17319    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17320    && flag_unsafe_math_optimizations"
17321   "")
17322
17323 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17324 (define_insn_and_split "frndintxf2_floor"
17325   [(set (match_operand:XF 0 "register_operand" "=f")
17326         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17327          UNSPEC_FRNDINT_FLOOR))
17328    (clobber (reg:CC FLAGS_REG))]
17329   "TARGET_USE_FANCY_MATH_387
17330    && flag_unsafe_math_optimizations
17331    && !(reload_completed || reload_in_progress)"
17332   "#"
17333   "&& 1"
17334   [(const_int 0)]
17335 {
17336   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17337
17338   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17339   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17340
17341   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17342                                         operands[2], operands[3]));
17343   DONE;
17344 }
17345   [(set_attr "type" "frndint")
17346    (set_attr "i387_cw" "floor")
17347    (set_attr "mode" "XF")])
17348
17349 (define_insn "frndintxf2_floor_i387"
17350   [(set (match_operand:XF 0 "register_operand" "=f")
17351         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17352          UNSPEC_FRNDINT_FLOOR))
17353    (use (match_operand:HI 2 "memory_operand" "m"))
17354    (use (match_operand:HI 3 "memory_operand" "m"))]
17355   "TARGET_USE_FANCY_MATH_387
17356    && flag_unsafe_math_optimizations"
17357   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17358   [(set_attr "type" "frndint")
17359    (set_attr "i387_cw" "floor")
17360    (set_attr "mode" "XF")])
17361
17362 (define_expand "floorxf2"
17363   [(use (match_operand:XF 0 "register_operand" ""))
17364    (use (match_operand:XF 1 "register_operand" ""))]
17365   "TARGET_USE_FANCY_MATH_387
17366    && flag_unsafe_math_optimizations"
17367 {
17368   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17369   DONE;
17370 })
17371
17372 (define_expand "floordf2"
17373   [(use (match_operand:DF 0 "register_operand" ""))
17374    (use (match_operand:DF 1 "register_operand" ""))]
17375   "TARGET_USE_FANCY_MATH_387
17376    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17377    && flag_unsafe_math_optimizations"
17378 {
17379   rtx op0 = gen_reg_rtx (XFmode);
17380   rtx op1 = gen_reg_rtx (XFmode);
17381
17382   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17383   emit_insn (gen_frndintxf2_floor (op0, op1));
17384
17385   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17386   DONE;
17387 })
17388
17389 (define_expand "floorsf2"
17390   [(use (match_operand:SF 0 "register_operand" ""))
17391    (use (match_operand:SF 1 "register_operand" ""))]
17392   "TARGET_USE_FANCY_MATH_387
17393    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17394    && flag_unsafe_math_optimizations"
17395 {
17396   rtx op0 = gen_reg_rtx (XFmode);
17397   rtx op1 = gen_reg_rtx (XFmode);
17398
17399   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17400   emit_insn (gen_frndintxf2_floor (op0, op1));
17401
17402   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17403   DONE;
17404 })
17405
17406 (define_insn_and_split "*fist<mode>2_floor_1"
17407   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17408         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17409          UNSPEC_FIST_FLOOR))
17410    (clobber (reg:CC FLAGS_REG))]
17411   "TARGET_USE_FANCY_MATH_387
17412    && flag_unsafe_math_optimizations
17413    && !(reload_completed || reload_in_progress)"
17414   "#"
17415   "&& 1"
17416   [(const_int 0)]
17417 {
17418   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17419
17420   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17421   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17422   if (memory_operand (operands[0], VOIDmode))
17423     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17424                                       operands[2], operands[3]));
17425   else
17426     {
17427       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17428       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17429                                                   operands[2], operands[3],
17430                                                   operands[4]));
17431     }
17432   DONE;
17433 }
17434   [(set_attr "type" "fistp")
17435    (set_attr "i387_cw" "floor")
17436    (set_attr "mode" "<MODE>")])
17437
17438 (define_insn "fistdi2_floor"
17439   [(set (match_operand:DI 0 "memory_operand" "=m")
17440         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17441          UNSPEC_FIST_FLOOR))
17442    (use (match_operand:HI 2 "memory_operand" "m"))
17443    (use (match_operand:HI 3 "memory_operand" "m"))
17444    (clobber (match_scratch:XF 4 "=&1f"))]
17445   "TARGET_USE_FANCY_MATH_387
17446    && flag_unsafe_math_optimizations"
17447   "* return output_fix_trunc (insn, operands, 0);"
17448   [(set_attr "type" "fistp")
17449    (set_attr "i387_cw" "floor")
17450    (set_attr "mode" "DI")])
17451
17452 (define_insn "fistdi2_floor_with_temp"
17453   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17454         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17455          UNSPEC_FIST_FLOOR))
17456    (use (match_operand:HI 2 "memory_operand" "m,m"))
17457    (use (match_operand:HI 3 "memory_operand" "m,m"))
17458    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17459    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17460   "TARGET_USE_FANCY_MATH_387
17461    && flag_unsafe_math_optimizations"
17462   "#"
17463   [(set_attr "type" "fistp")
17464    (set_attr "i387_cw" "floor")
17465    (set_attr "mode" "DI")])
17466
17467 (define_split 
17468   [(set (match_operand:DI 0 "register_operand" "")
17469         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17470          UNSPEC_FIST_FLOOR))
17471    (use (match_operand:HI 2 "memory_operand" ""))
17472    (use (match_operand:HI 3 "memory_operand" ""))
17473    (clobber (match_operand:DI 4 "memory_operand" ""))
17474    (clobber (match_scratch 5 ""))]
17475   "reload_completed"
17476   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17477               (use (match_dup 2))
17478               (use (match_dup 3))
17479               (clobber (match_dup 5))])
17480    (set (match_dup 0) (match_dup 4))]
17481   "")
17482
17483 (define_split 
17484   [(set (match_operand:DI 0 "memory_operand" "")
17485         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17486          UNSPEC_FIST_FLOOR))
17487    (use (match_operand:HI 2 "memory_operand" ""))
17488    (use (match_operand:HI 3 "memory_operand" ""))
17489    (clobber (match_operand:DI 4 "memory_operand" ""))
17490    (clobber (match_scratch 5 ""))]
17491   "reload_completed"
17492   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17493               (use (match_dup 2))
17494               (use (match_dup 3))
17495               (clobber (match_dup 5))])]
17496   "")
17497
17498 (define_insn "fist<mode>2_floor"
17499   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17500         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17501          UNSPEC_FIST_FLOOR))
17502    (use (match_operand:HI 2 "memory_operand" "m"))
17503    (use (match_operand:HI 3 "memory_operand" "m"))]
17504   "TARGET_USE_FANCY_MATH_387
17505    && flag_unsafe_math_optimizations"
17506   "* return output_fix_trunc (insn, operands, 0);"
17507   [(set_attr "type" "fistp")
17508    (set_attr "i387_cw" "floor")
17509    (set_attr "mode" "<MODE>")])
17510
17511 (define_insn "fist<mode>2_floor_with_temp"
17512   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17513         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17514          UNSPEC_FIST_FLOOR))
17515    (use (match_operand:HI 2 "memory_operand" "m,m"))
17516    (use (match_operand:HI 3 "memory_operand" "m,m"))
17517    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17518   "TARGET_USE_FANCY_MATH_387
17519    && flag_unsafe_math_optimizations"
17520   "#"
17521   [(set_attr "type" "fistp")
17522    (set_attr "i387_cw" "floor")
17523    (set_attr "mode" "<MODE>")])
17524
17525 (define_split 
17526   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17527         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17528          UNSPEC_FIST_FLOOR))
17529    (use (match_operand:HI 2 "memory_operand" ""))
17530    (use (match_operand:HI 3 "memory_operand" ""))
17531    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17532   "reload_completed"
17533   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17534                                   UNSPEC_FIST_FLOOR))
17535               (use (match_dup 2))
17536               (use (match_dup 3))])
17537    (set (match_dup 0) (match_dup 4))]
17538   "")
17539
17540 (define_split 
17541   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17542         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17543          UNSPEC_FIST_FLOOR))
17544    (use (match_operand:HI 2 "memory_operand" ""))
17545    (use (match_operand:HI 3 "memory_operand" ""))
17546    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17547   "reload_completed"
17548   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17549                                   UNSPEC_FIST_FLOOR))
17550               (use (match_dup 2))
17551               (use (match_dup 3))])]
17552   "")
17553
17554 (define_expand "lfloor<mode>2"
17555   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17556                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17557                     UNSPEC_FIST_FLOOR))
17558               (clobber (reg:CC FLAGS_REG))])]
17559   "TARGET_USE_FANCY_MATH_387
17560    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17561    && flag_unsafe_math_optimizations"
17562   "")
17563
17564 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17565 (define_insn_and_split "frndintxf2_ceil"
17566   [(set (match_operand:XF 0 "register_operand" "=f")
17567         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17568          UNSPEC_FRNDINT_CEIL))
17569    (clobber (reg:CC FLAGS_REG))]
17570   "TARGET_USE_FANCY_MATH_387
17571    && flag_unsafe_math_optimizations
17572    && !(reload_completed || reload_in_progress)"
17573   "#"
17574   "&& 1"
17575   [(const_int 0)]
17576 {
17577   ix86_optimize_mode_switching[I387_CEIL] = 1;
17578
17579   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17580   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17581
17582   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17583                                        operands[2], operands[3]));
17584   DONE;
17585 }
17586   [(set_attr "type" "frndint")
17587    (set_attr "i387_cw" "ceil")
17588    (set_attr "mode" "XF")])
17589
17590 (define_insn "frndintxf2_ceil_i387"
17591   [(set (match_operand:XF 0 "register_operand" "=f")
17592         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17593          UNSPEC_FRNDINT_CEIL))
17594    (use (match_operand:HI 2 "memory_operand" "m"))
17595    (use (match_operand:HI 3 "memory_operand" "m"))]
17596   "TARGET_USE_FANCY_MATH_387
17597    && flag_unsafe_math_optimizations"
17598   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17599   [(set_attr "type" "frndint")
17600    (set_attr "i387_cw" "ceil")
17601    (set_attr "mode" "XF")])
17602
17603 (define_expand "ceilxf2"
17604   [(use (match_operand:XF 0 "register_operand" ""))
17605    (use (match_operand:XF 1 "register_operand" ""))]
17606   "TARGET_USE_FANCY_MATH_387
17607    && flag_unsafe_math_optimizations"
17608 {
17609   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17610   DONE;
17611 })
17612
17613 (define_expand "ceildf2"
17614   [(use (match_operand:DF 0 "register_operand" ""))
17615    (use (match_operand:DF 1 "register_operand" ""))]
17616   "TARGET_USE_FANCY_MATH_387
17617    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17618    && flag_unsafe_math_optimizations"
17619 {
17620   rtx op0 = gen_reg_rtx (XFmode);
17621   rtx op1 = gen_reg_rtx (XFmode);
17622
17623   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17624   emit_insn (gen_frndintxf2_ceil (op0, op1));
17625
17626   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17627   DONE;
17628 })
17629
17630 (define_expand "ceilsf2"
17631   [(use (match_operand:SF 0 "register_operand" ""))
17632    (use (match_operand:SF 1 "register_operand" ""))]
17633   "TARGET_USE_FANCY_MATH_387
17634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17635    && flag_unsafe_math_optimizations"
17636 {
17637   rtx op0 = gen_reg_rtx (XFmode);
17638   rtx op1 = gen_reg_rtx (XFmode);
17639
17640   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17641   emit_insn (gen_frndintxf2_ceil (op0, op1));
17642
17643   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17644   DONE;
17645 })
17646
17647 (define_insn_and_split "*fist<mode>2_ceil_1"
17648   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17649         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17650          UNSPEC_FIST_CEIL))
17651    (clobber (reg:CC FLAGS_REG))]
17652   "TARGET_USE_FANCY_MATH_387
17653    && flag_unsafe_math_optimizations
17654    && !(reload_completed || reload_in_progress)"
17655   "#"
17656   "&& 1"
17657   [(const_int 0)]
17658 {
17659   ix86_optimize_mode_switching[I387_CEIL] = 1;
17660
17661   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17662   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17663   if (memory_operand (operands[0], VOIDmode))
17664     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17665                                      operands[2], operands[3]));
17666   else
17667     {
17668       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17669       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17670                                                  operands[2], operands[3],
17671                                                  operands[4]));
17672     }
17673   DONE;
17674 }
17675   [(set_attr "type" "fistp")
17676    (set_attr "i387_cw" "ceil")
17677    (set_attr "mode" "<MODE>")])
17678
17679 (define_insn "fistdi2_ceil"
17680   [(set (match_operand:DI 0 "memory_operand" "=m")
17681         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17682          UNSPEC_FIST_CEIL))
17683    (use (match_operand:HI 2 "memory_operand" "m"))
17684    (use (match_operand:HI 3 "memory_operand" "m"))
17685    (clobber (match_scratch:XF 4 "=&1f"))]
17686   "TARGET_USE_FANCY_MATH_387
17687    && flag_unsafe_math_optimizations"
17688   "* return output_fix_trunc (insn, operands, 0);"
17689   [(set_attr "type" "fistp")
17690    (set_attr "i387_cw" "ceil")
17691    (set_attr "mode" "DI")])
17692
17693 (define_insn "fistdi2_ceil_with_temp"
17694   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17695         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17696          UNSPEC_FIST_CEIL))
17697    (use (match_operand:HI 2 "memory_operand" "m,m"))
17698    (use (match_operand:HI 3 "memory_operand" "m,m"))
17699    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17700    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17701   "TARGET_USE_FANCY_MATH_387
17702    && flag_unsafe_math_optimizations"
17703   "#"
17704   [(set_attr "type" "fistp")
17705    (set_attr "i387_cw" "ceil")
17706    (set_attr "mode" "DI")])
17707
17708 (define_split 
17709   [(set (match_operand:DI 0 "register_operand" "")
17710         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17711          UNSPEC_FIST_CEIL))
17712    (use (match_operand:HI 2 "memory_operand" ""))
17713    (use (match_operand:HI 3 "memory_operand" ""))
17714    (clobber (match_operand:DI 4 "memory_operand" ""))
17715    (clobber (match_scratch 5 ""))]
17716   "reload_completed"
17717   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17718               (use (match_dup 2))
17719               (use (match_dup 3))
17720               (clobber (match_dup 5))])
17721    (set (match_dup 0) (match_dup 4))]
17722   "")
17723
17724 (define_split 
17725   [(set (match_operand:DI 0 "memory_operand" "")
17726         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17727          UNSPEC_FIST_CEIL))
17728    (use (match_operand:HI 2 "memory_operand" ""))
17729    (use (match_operand:HI 3 "memory_operand" ""))
17730    (clobber (match_operand:DI 4 "memory_operand" ""))
17731    (clobber (match_scratch 5 ""))]
17732   "reload_completed"
17733   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17734               (use (match_dup 2))
17735               (use (match_dup 3))
17736               (clobber (match_dup 5))])]
17737   "")
17738
17739 (define_insn "fist<mode>2_ceil"
17740   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17741         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17742          UNSPEC_FIST_CEIL))
17743    (use (match_operand:HI 2 "memory_operand" "m"))
17744    (use (match_operand:HI 3 "memory_operand" "m"))]
17745   "TARGET_USE_FANCY_MATH_387
17746    && flag_unsafe_math_optimizations"
17747   "* return output_fix_trunc (insn, operands, 0);"
17748   [(set_attr "type" "fistp")
17749    (set_attr "i387_cw" "ceil")
17750    (set_attr "mode" "<MODE>")])
17751
17752 (define_insn "fist<mode>2_ceil_with_temp"
17753   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17754         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17755          UNSPEC_FIST_CEIL))
17756    (use (match_operand:HI 2 "memory_operand" "m,m"))
17757    (use (match_operand:HI 3 "memory_operand" "m,m"))
17758    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17759   "TARGET_USE_FANCY_MATH_387
17760    && flag_unsafe_math_optimizations"
17761   "#"
17762   [(set_attr "type" "fistp")
17763    (set_attr "i387_cw" "ceil")
17764    (set_attr "mode" "<MODE>")])
17765
17766 (define_split 
17767   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17768         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17769          UNSPEC_FIST_CEIL))
17770    (use (match_operand:HI 2 "memory_operand" ""))
17771    (use (match_operand:HI 3 "memory_operand" ""))
17772    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17773   "reload_completed"
17774   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17775                                   UNSPEC_FIST_CEIL))
17776               (use (match_dup 2))
17777               (use (match_dup 3))])
17778    (set (match_dup 0) (match_dup 4))]
17779   "")
17780
17781 (define_split 
17782   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17783         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17784          UNSPEC_FIST_CEIL))
17785    (use (match_operand:HI 2 "memory_operand" ""))
17786    (use (match_operand:HI 3 "memory_operand" ""))
17787    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17788   "reload_completed"
17789   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17790                                   UNSPEC_FIST_CEIL))
17791               (use (match_dup 2))
17792               (use (match_dup 3))])]
17793   "")
17794
17795 (define_expand "lceil<mode>2"
17796   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17797                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17798                     UNSPEC_FIST_CEIL))
17799               (clobber (reg:CC FLAGS_REG))])]
17800   "TARGET_USE_FANCY_MATH_387
17801    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17802    && flag_unsafe_math_optimizations"
17803   "")
17804
17805 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17806 (define_insn_and_split "frndintxf2_trunc"
17807   [(set (match_operand:XF 0 "register_operand" "=f")
17808         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17809          UNSPEC_FRNDINT_TRUNC))
17810    (clobber (reg:CC FLAGS_REG))]
17811   "TARGET_USE_FANCY_MATH_387
17812    && flag_unsafe_math_optimizations
17813    && !(reload_completed || reload_in_progress)"
17814   "#"
17815   "&& 1"
17816   [(const_int 0)]
17817 {
17818   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17819
17820   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17821   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17822
17823   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17824                                         operands[2], operands[3]));
17825   DONE;
17826 }
17827   [(set_attr "type" "frndint")
17828    (set_attr "i387_cw" "trunc")
17829    (set_attr "mode" "XF")])
17830
17831 (define_insn "frndintxf2_trunc_i387"
17832   [(set (match_operand:XF 0 "register_operand" "=f")
17833         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17834          UNSPEC_FRNDINT_TRUNC))
17835    (use (match_operand:HI 2 "memory_operand" "m"))
17836    (use (match_operand:HI 3 "memory_operand" "m"))]
17837   "TARGET_USE_FANCY_MATH_387
17838    && flag_unsafe_math_optimizations"
17839   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17840   [(set_attr "type" "frndint")
17841    (set_attr "i387_cw" "trunc")
17842    (set_attr "mode" "XF")])
17843
17844 (define_expand "btruncxf2"
17845   [(use (match_operand:XF 0 "register_operand" ""))
17846    (use (match_operand:XF 1 "register_operand" ""))]
17847   "TARGET_USE_FANCY_MATH_387
17848    && flag_unsafe_math_optimizations"
17849 {
17850   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17851   DONE;
17852 })
17853
17854 (define_expand "btruncdf2"
17855   [(use (match_operand:DF 0 "register_operand" ""))
17856    (use (match_operand:DF 1 "register_operand" ""))]
17857   "TARGET_USE_FANCY_MATH_387
17858    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17859    && flag_unsafe_math_optimizations"
17860 {
17861   rtx op0 = gen_reg_rtx (XFmode);
17862   rtx op1 = gen_reg_rtx (XFmode);
17863
17864   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17865   emit_insn (gen_frndintxf2_trunc (op0, op1));
17866
17867   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17868   DONE;
17869 })
17870
17871 (define_expand "btruncsf2"
17872   [(use (match_operand:SF 0 "register_operand" ""))
17873    (use (match_operand:SF 1 "register_operand" ""))]
17874   "TARGET_USE_FANCY_MATH_387
17875    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17876    && flag_unsafe_math_optimizations"
17877 {
17878   rtx op0 = gen_reg_rtx (XFmode);
17879   rtx op1 = gen_reg_rtx (XFmode);
17880
17881   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17882   emit_insn (gen_frndintxf2_trunc (op0, op1));
17883
17884   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17885   DONE;
17886 })
17887
17888 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17889 (define_insn_and_split "frndintxf2_mask_pm"
17890   [(set (match_operand:XF 0 "register_operand" "=f")
17891         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17892          UNSPEC_FRNDINT_MASK_PM))
17893    (clobber (reg:CC FLAGS_REG))]
17894   "TARGET_USE_FANCY_MATH_387
17895    && flag_unsafe_math_optimizations
17896    && !(reload_completed || reload_in_progress)"
17897   "#"
17898   "&& 1"
17899   [(const_int 0)]
17900 {
17901   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17902
17903   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17904   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17905
17906   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17907                                           operands[2], operands[3]));
17908   DONE;
17909 }
17910   [(set_attr "type" "frndint")
17911    (set_attr "i387_cw" "mask_pm")
17912    (set_attr "mode" "XF")])
17913
17914 (define_insn "frndintxf2_mask_pm_i387"
17915   [(set (match_operand:XF 0 "register_operand" "=f")
17916         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17917          UNSPEC_FRNDINT_MASK_PM))
17918    (use (match_operand:HI 2 "memory_operand" "m"))
17919    (use (match_operand:HI 3 "memory_operand" "m"))]
17920   "TARGET_USE_FANCY_MATH_387
17921    && flag_unsafe_math_optimizations"
17922   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17923   [(set_attr "type" "frndint")
17924    (set_attr "i387_cw" "mask_pm")
17925    (set_attr "mode" "XF")])
17926
17927 (define_expand "nearbyintxf2"
17928   [(use (match_operand:XF 0 "register_operand" ""))
17929    (use (match_operand:XF 1 "register_operand" ""))]
17930   "TARGET_USE_FANCY_MATH_387
17931    && flag_unsafe_math_optimizations"
17932 {
17933   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17934
17935   DONE;
17936 })
17937
17938 (define_expand "nearbyintdf2"
17939   [(use (match_operand:DF 0 "register_operand" ""))
17940    (use (match_operand:DF 1 "register_operand" ""))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17943    && flag_unsafe_math_optimizations"
17944 {
17945   rtx op0 = gen_reg_rtx (XFmode);
17946   rtx op1 = gen_reg_rtx (XFmode);
17947
17948   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17949   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17950
17951   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17952   DONE;
17953 })
17954
17955 (define_expand "nearbyintsf2"
17956   [(use (match_operand:SF 0 "register_operand" ""))
17957    (use (match_operand:SF 1 "register_operand" ""))]
17958   "TARGET_USE_FANCY_MATH_387
17959    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17960    && flag_unsafe_math_optimizations"
17961 {
17962   rtx op0 = gen_reg_rtx (XFmode);
17963   rtx op1 = gen_reg_rtx (XFmode);
17964
17965   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17966   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17967
17968   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17969   DONE;
17970 })
17971
17972 \f
17973 ;; Block operation instructions
17974
17975 (define_insn "cld"
17976  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17977  ""
17978  "cld"
17979   [(set_attr "type" "cld")])
17980
17981 (define_expand "movmemsi"
17982   [(use (match_operand:BLK 0 "memory_operand" ""))
17983    (use (match_operand:BLK 1 "memory_operand" ""))
17984    (use (match_operand:SI 2 "nonmemory_operand" ""))
17985    (use (match_operand:SI 3 "const_int_operand" ""))]
17986   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17987 {
17988  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17989    DONE;
17990  else
17991    FAIL;
17992 })
17993
17994 (define_expand "movmemdi"
17995   [(use (match_operand:BLK 0 "memory_operand" ""))
17996    (use (match_operand:BLK 1 "memory_operand" ""))
17997    (use (match_operand:DI 2 "nonmemory_operand" ""))
17998    (use (match_operand:DI 3 "const_int_operand" ""))]
17999   "TARGET_64BIT"
18000 {
18001  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18002    DONE;
18003  else
18004    FAIL;
18005 })
18006
18007 ;; Most CPUs don't like single string operations
18008 ;; Handle this case here to simplify previous expander.
18009
18010 (define_expand "strmov"
18011   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18012    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18013    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18014               (clobber (reg:CC FLAGS_REG))])
18015    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18016               (clobber (reg:CC FLAGS_REG))])]
18017   ""
18018 {
18019   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18020
18021   /* If .md ever supports :P for Pmode, these can be directly
18022      in the pattern above.  */
18023   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18024   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18025
18026   if (TARGET_SINGLE_STRINGOP || optimize_size)
18027     {
18028       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18029                                       operands[2], operands[3],
18030                                       operands[5], operands[6]));
18031       DONE;
18032     }
18033
18034   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18035 })
18036
18037 (define_expand "strmov_singleop"
18038   [(parallel [(set (match_operand 1 "memory_operand" "")
18039                    (match_operand 3 "memory_operand" ""))
18040               (set (match_operand 0 "register_operand" "")
18041                    (match_operand 4 "" ""))
18042               (set (match_operand 2 "register_operand" "")
18043                    (match_operand 5 "" ""))
18044               (use (reg:SI DIRFLAG_REG))])]
18045   "TARGET_SINGLE_STRINGOP || optimize_size"
18046   "")
18047
18048 (define_insn "*strmovdi_rex_1"
18049   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18050         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18051    (set (match_operand:DI 0 "register_operand" "=D")
18052         (plus:DI (match_dup 2)
18053                  (const_int 8)))
18054    (set (match_operand:DI 1 "register_operand" "=S")
18055         (plus:DI (match_dup 3)
18056                  (const_int 8)))
18057    (use (reg:SI DIRFLAG_REG))]
18058   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18059   "movsq"
18060   [(set_attr "type" "str")
18061    (set_attr "mode" "DI")
18062    (set_attr "memory" "both")])
18063
18064 (define_insn "*strmovsi_1"
18065   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18066         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18067    (set (match_operand:SI 0 "register_operand" "=D")
18068         (plus:SI (match_dup 2)
18069                  (const_int 4)))
18070    (set (match_operand:SI 1 "register_operand" "=S")
18071         (plus:SI (match_dup 3)
18072                  (const_int 4)))
18073    (use (reg:SI DIRFLAG_REG))]
18074   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18075   "{movsl|movsd}"
18076   [(set_attr "type" "str")
18077    (set_attr "mode" "SI")
18078    (set_attr "memory" "both")])
18079
18080 (define_insn "*strmovsi_rex_1"
18081   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18082         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18083    (set (match_operand:DI 0 "register_operand" "=D")
18084         (plus:DI (match_dup 2)
18085                  (const_int 4)))
18086    (set (match_operand:DI 1 "register_operand" "=S")
18087         (plus:DI (match_dup 3)
18088                  (const_int 4)))
18089    (use (reg:SI DIRFLAG_REG))]
18090   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18091   "{movsl|movsd}"
18092   [(set_attr "type" "str")
18093    (set_attr "mode" "SI")
18094    (set_attr "memory" "both")])
18095
18096 (define_insn "*strmovhi_1"
18097   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18098         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18099    (set (match_operand:SI 0 "register_operand" "=D")
18100         (plus:SI (match_dup 2)
18101                  (const_int 2)))
18102    (set (match_operand:SI 1 "register_operand" "=S")
18103         (plus:SI (match_dup 3)
18104                  (const_int 2)))
18105    (use (reg:SI DIRFLAG_REG))]
18106   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18107   "movsw"
18108   [(set_attr "type" "str")
18109    (set_attr "memory" "both")
18110    (set_attr "mode" "HI")])
18111
18112 (define_insn "*strmovhi_rex_1"
18113   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18114         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18115    (set (match_operand:DI 0 "register_operand" "=D")
18116         (plus:DI (match_dup 2)
18117                  (const_int 2)))
18118    (set (match_operand:DI 1 "register_operand" "=S")
18119         (plus:DI (match_dup 3)
18120                  (const_int 2)))
18121    (use (reg:SI DIRFLAG_REG))]
18122   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18123   "movsw"
18124   [(set_attr "type" "str")
18125    (set_attr "memory" "both")
18126    (set_attr "mode" "HI")])
18127
18128 (define_insn "*strmovqi_1"
18129   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18130         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18131    (set (match_operand:SI 0 "register_operand" "=D")
18132         (plus:SI (match_dup 2)
18133                  (const_int 1)))
18134    (set (match_operand:SI 1 "register_operand" "=S")
18135         (plus:SI (match_dup 3)
18136                  (const_int 1)))
18137    (use (reg:SI DIRFLAG_REG))]
18138   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18139   "movsb"
18140   [(set_attr "type" "str")
18141    (set_attr "memory" "both")
18142    (set_attr "mode" "QI")])
18143
18144 (define_insn "*strmovqi_rex_1"
18145   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18146         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18147    (set (match_operand:DI 0 "register_operand" "=D")
18148         (plus:DI (match_dup 2)
18149                  (const_int 1)))
18150    (set (match_operand:DI 1 "register_operand" "=S")
18151         (plus:DI (match_dup 3)
18152                  (const_int 1)))
18153    (use (reg:SI DIRFLAG_REG))]
18154   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18155   "movsb"
18156   [(set_attr "type" "str")
18157    (set_attr "memory" "both")
18158    (set_attr "mode" "QI")])
18159
18160 (define_expand "rep_mov"
18161   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18162               (set (match_operand 0 "register_operand" "")
18163                    (match_operand 5 "" ""))
18164               (set (match_operand 2 "register_operand" "")
18165                    (match_operand 6 "" ""))
18166               (set (match_operand 1 "memory_operand" "")
18167                    (match_operand 3 "memory_operand" ""))
18168               (use (match_dup 4))
18169               (use (reg:SI DIRFLAG_REG))])]
18170   ""
18171   "")
18172
18173 (define_insn "*rep_movdi_rex64"
18174   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18175    (set (match_operand:DI 0 "register_operand" "=D") 
18176         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18177                             (const_int 3))
18178                  (match_operand:DI 3 "register_operand" "0")))
18179    (set (match_operand:DI 1 "register_operand" "=S") 
18180         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18181                  (match_operand:DI 4 "register_operand" "1")))
18182    (set (mem:BLK (match_dup 3))
18183         (mem:BLK (match_dup 4)))
18184    (use (match_dup 5))
18185    (use (reg:SI DIRFLAG_REG))]
18186   "TARGET_64BIT"
18187   "{rep\;movsq|rep movsq}"
18188   [(set_attr "type" "str")
18189    (set_attr "prefix_rep" "1")
18190    (set_attr "memory" "both")
18191    (set_attr "mode" "DI")])
18192
18193 (define_insn "*rep_movsi"
18194   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18195    (set (match_operand:SI 0 "register_operand" "=D") 
18196         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18197                             (const_int 2))
18198                  (match_operand:SI 3 "register_operand" "0")))
18199    (set (match_operand:SI 1 "register_operand" "=S") 
18200         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18201                  (match_operand:SI 4 "register_operand" "1")))
18202    (set (mem:BLK (match_dup 3))
18203         (mem:BLK (match_dup 4)))
18204    (use (match_dup 5))
18205    (use (reg:SI DIRFLAG_REG))]
18206   "!TARGET_64BIT"
18207   "{rep\;movsl|rep movsd}"
18208   [(set_attr "type" "str")
18209    (set_attr "prefix_rep" "1")
18210    (set_attr "memory" "both")
18211    (set_attr "mode" "SI")])
18212
18213 (define_insn "*rep_movsi_rex64"
18214   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18215    (set (match_operand:DI 0 "register_operand" "=D") 
18216         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18217                             (const_int 2))
18218                  (match_operand:DI 3 "register_operand" "0")))
18219    (set (match_operand:DI 1 "register_operand" "=S") 
18220         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18221                  (match_operand:DI 4 "register_operand" "1")))
18222    (set (mem:BLK (match_dup 3))
18223         (mem:BLK (match_dup 4)))
18224    (use (match_dup 5))
18225    (use (reg:SI DIRFLAG_REG))]
18226   "TARGET_64BIT"
18227   "{rep\;movsl|rep movsd}"
18228   [(set_attr "type" "str")
18229    (set_attr "prefix_rep" "1")
18230    (set_attr "memory" "both")
18231    (set_attr "mode" "SI")])
18232
18233 (define_insn "*rep_movqi"
18234   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18235    (set (match_operand:SI 0 "register_operand" "=D") 
18236         (plus:SI (match_operand:SI 3 "register_operand" "0")
18237                  (match_operand:SI 5 "register_operand" "2")))
18238    (set (match_operand:SI 1 "register_operand" "=S") 
18239         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18240    (set (mem:BLK (match_dup 3))
18241         (mem:BLK (match_dup 4)))
18242    (use (match_dup 5))
18243    (use (reg:SI DIRFLAG_REG))]
18244   "!TARGET_64BIT"
18245   "{rep\;movsb|rep movsb}"
18246   [(set_attr "type" "str")
18247    (set_attr "prefix_rep" "1")
18248    (set_attr "memory" "both")
18249    (set_attr "mode" "SI")])
18250
18251 (define_insn "*rep_movqi_rex64"
18252   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18253    (set (match_operand:DI 0 "register_operand" "=D") 
18254         (plus:DI (match_operand:DI 3 "register_operand" "0")
18255                  (match_operand:DI 5 "register_operand" "2")))
18256    (set (match_operand:DI 1 "register_operand" "=S") 
18257         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18258    (set (mem:BLK (match_dup 3))
18259         (mem:BLK (match_dup 4)))
18260    (use (match_dup 5))
18261    (use (reg:SI DIRFLAG_REG))]
18262   "TARGET_64BIT"
18263   "{rep\;movsb|rep movsb}"
18264   [(set_attr "type" "str")
18265    (set_attr "prefix_rep" "1")
18266    (set_attr "memory" "both")
18267    (set_attr "mode" "SI")])
18268
18269 (define_expand "setmemsi"
18270    [(use (match_operand:BLK 0 "memory_operand" ""))
18271     (use (match_operand:SI 1 "nonmemory_operand" ""))
18272     (use (match_operand 2 "const_int_operand" ""))
18273     (use (match_operand 3 "const_int_operand" ""))]
18274   ""
18275 {
18276  /* If value to set is not zero, use the library routine.  */
18277  if (operands[2] != const0_rtx)
18278    FAIL;
18279
18280  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18281    DONE;
18282  else
18283    FAIL;
18284 })
18285
18286 (define_expand "setmemdi"
18287    [(use (match_operand:BLK 0 "memory_operand" ""))
18288     (use (match_operand:DI 1 "nonmemory_operand" ""))
18289     (use (match_operand 2 "const_int_operand" ""))
18290     (use (match_operand 3 "const_int_operand" ""))]
18291   "TARGET_64BIT"
18292 {
18293  /* If value to set is not zero, use the library routine.  */
18294  if (operands[2] != const0_rtx)
18295    FAIL;
18296
18297  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18298    DONE;
18299  else
18300    FAIL;
18301 })
18302
18303 ;; Most CPUs don't like single string operations
18304 ;; Handle this case here to simplify previous expander.
18305
18306 (define_expand "strset"
18307   [(set (match_operand 1 "memory_operand" "")
18308         (match_operand 2 "register_operand" ""))
18309    (parallel [(set (match_operand 0 "register_operand" "")
18310                    (match_dup 3))
18311               (clobber (reg:CC FLAGS_REG))])]
18312   ""
18313 {
18314   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18315     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18316
18317   /* If .md ever supports :P for Pmode, this can be directly
18318      in the pattern above.  */
18319   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18320                               GEN_INT (GET_MODE_SIZE (GET_MODE
18321                                                       (operands[2]))));
18322   if (TARGET_SINGLE_STRINGOP || optimize_size)
18323     {
18324       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18325                                       operands[3]));
18326       DONE;
18327     }
18328 })
18329
18330 (define_expand "strset_singleop"
18331   [(parallel [(set (match_operand 1 "memory_operand" "")
18332                    (match_operand 2 "register_operand" ""))
18333               (set (match_operand 0 "register_operand" "")
18334                    (match_operand 3 "" ""))
18335               (use (reg:SI DIRFLAG_REG))])]
18336   "TARGET_SINGLE_STRINGOP || optimize_size"
18337   "")
18338
18339 (define_insn "*strsetdi_rex_1"
18340   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18341         (match_operand:DI 2 "register_operand" "a"))
18342    (set (match_operand:DI 0 "register_operand" "=D")
18343         (plus:DI (match_dup 1)
18344                  (const_int 8)))
18345    (use (reg:SI DIRFLAG_REG))]
18346   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18347   "stosq"
18348   [(set_attr "type" "str")
18349    (set_attr "memory" "store")
18350    (set_attr "mode" "DI")])
18351
18352 (define_insn "*strsetsi_1"
18353   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18354         (match_operand:SI 2 "register_operand" "a"))
18355    (set (match_operand:SI 0 "register_operand" "=D")
18356         (plus:SI (match_dup 1)
18357                  (const_int 4)))
18358    (use (reg:SI DIRFLAG_REG))]
18359   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18360   "{stosl|stosd}"
18361   [(set_attr "type" "str")
18362    (set_attr "memory" "store")
18363    (set_attr "mode" "SI")])
18364
18365 (define_insn "*strsetsi_rex_1"
18366   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18367         (match_operand:SI 2 "register_operand" "a"))
18368    (set (match_operand:DI 0 "register_operand" "=D")
18369         (plus:DI (match_dup 1)
18370                  (const_int 4)))
18371    (use (reg:SI DIRFLAG_REG))]
18372   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373   "{stosl|stosd}"
18374   [(set_attr "type" "str")
18375    (set_attr "memory" "store")
18376    (set_attr "mode" "SI")])
18377
18378 (define_insn "*strsethi_1"
18379   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18380         (match_operand:HI 2 "register_operand" "a"))
18381    (set (match_operand:SI 0 "register_operand" "=D")
18382         (plus:SI (match_dup 1)
18383                  (const_int 2)))
18384    (use (reg:SI DIRFLAG_REG))]
18385   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18386   "stosw"
18387   [(set_attr "type" "str")
18388    (set_attr "memory" "store")
18389    (set_attr "mode" "HI")])
18390
18391 (define_insn "*strsethi_rex_1"
18392   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18393         (match_operand:HI 2 "register_operand" "a"))
18394    (set (match_operand:DI 0 "register_operand" "=D")
18395         (plus:DI (match_dup 1)
18396                  (const_int 2)))
18397    (use (reg:SI DIRFLAG_REG))]
18398   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399   "stosw"
18400   [(set_attr "type" "str")
18401    (set_attr "memory" "store")
18402    (set_attr "mode" "HI")])
18403
18404 (define_insn "*strsetqi_1"
18405   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18406         (match_operand:QI 2 "register_operand" "a"))
18407    (set (match_operand:SI 0 "register_operand" "=D")
18408         (plus:SI (match_dup 1)
18409                  (const_int 1)))
18410    (use (reg:SI DIRFLAG_REG))]
18411   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18412   "stosb"
18413   [(set_attr "type" "str")
18414    (set_attr "memory" "store")
18415    (set_attr "mode" "QI")])
18416
18417 (define_insn "*strsetqi_rex_1"
18418   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18419         (match_operand:QI 2 "register_operand" "a"))
18420    (set (match_operand:DI 0 "register_operand" "=D")
18421         (plus:DI (match_dup 1)
18422                  (const_int 1)))
18423    (use (reg:SI DIRFLAG_REG))]
18424   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18425   "stosb"
18426   [(set_attr "type" "str")
18427    (set_attr "memory" "store")
18428    (set_attr "mode" "QI")])
18429
18430 (define_expand "rep_stos"
18431   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18432               (set (match_operand 0 "register_operand" "")
18433                    (match_operand 4 "" ""))
18434               (set (match_operand 2 "memory_operand" "") (const_int 0))
18435               (use (match_operand 3 "register_operand" ""))
18436               (use (match_dup 1))
18437               (use (reg:SI DIRFLAG_REG))])]
18438   ""
18439   "")
18440
18441 (define_insn "*rep_stosdi_rex64"
18442   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18443    (set (match_operand:DI 0 "register_operand" "=D") 
18444         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18445                             (const_int 3))
18446                  (match_operand:DI 3 "register_operand" "0")))
18447    (set (mem:BLK (match_dup 3))
18448         (const_int 0))
18449    (use (match_operand:DI 2 "register_operand" "a"))
18450    (use (match_dup 4))
18451    (use (reg:SI DIRFLAG_REG))]
18452   "TARGET_64BIT"
18453   "{rep\;stosq|rep stosq}"
18454   [(set_attr "type" "str")
18455    (set_attr "prefix_rep" "1")
18456    (set_attr "memory" "store")
18457    (set_attr "mode" "DI")])
18458
18459 (define_insn "*rep_stossi"
18460   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18461    (set (match_operand:SI 0 "register_operand" "=D") 
18462         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18463                             (const_int 2))
18464                  (match_operand:SI 3 "register_operand" "0")))
18465    (set (mem:BLK (match_dup 3))
18466         (const_int 0))
18467    (use (match_operand:SI 2 "register_operand" "a"))
18468    (use (match_dup 4))
18469    (use (reg:SI DIRFLAG_REG))]
18470   "!TARGET_64BIT"
18471   "{rep\;stosl|rep stosd}"
18472   [(set_attr "type" "str")
18473    (set_attr "prefix_rep" "1")
18474    (set_attr "memory" "store")
18475    (set_attr "mode" "SI")])
18476
18477 (define_insn "*rep_stossi_rex64"
18478   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18479    (set (match_operand:DI 0 "register_operand" "=D") 
18480         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18481                             (const_int 2))
18482                  (match_operand:DI 3 "register_operand" "0")))
18483    (set (mem:BLK (match_dup 3))
18484         (const_int 0))
18485    (use (match_operand:SI 2 "register_operand" "a"))
18486    (use (match_dup 4))
18487    (use (reg:SI DIRFLAG_REG))]
18488   "TARGET_64BIT"
18489   "{rep\;stosl|rep stosd}"
18490   [(set_attr "type" "str")
18491    (set_attr "prefix_rep" "1")
18492    (set_attr "memory" "store")
18493    (set_attr "mode" "SI")])
18494
18495 (define_insn "*rep_stosqi"
18496   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18497    (set (match_operand:SI 0 "register_operand" "=D") 
18498         (plus:SI (match_operand:SI 3 "register_operand" "0")
18499                  (match_operand:SI 4 "register_operand" "1")))
18500    (set (mem:BLK (match_dup 3))
18501         (const_int 0))
18502    (use (match_operand:QI 2 "register_operand" "a"))
18503    (use (match_dup 4))
18504    (use (reg:SI DIRFLAG_REG))]
18505   "!TARGET_64BIT"
18506   "{rep\;stosb|rep stosb}"
18507   [(set_attr "type" "str")
18508    (set_attr "prefix_rep" "1")
18509    (set_attr "memory" "store")
18510    (set_attr "mode" "QI")])
18511
18512 (define_insn "*rep_stosqi_rex64"
18513   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18514    (set (match_operand:DI 0 "register_operand" "=D") 
18515         (plus:DI (match_operand:DI 3 "register_operand" "0")
18516                  (match_operand:DI 4 "register_operand" "1")))
18517    (set (mem:BLK (match_dup 3))
18518         (const_int 0))
18519    (use (match_operand:QI 2 "register_operand" "a"))
18520    (use (match_dup 4))
18521    (use (reg:SI DIRFLAG_REG))]
18522   "TARGET_64BIT"
18523   "{rep\;stosb|rep stosb}"
18524   [(set_attr "type" "str")
18525    (set_attr "prefix_rep" "1")
18526    (set_attr "memory" "store")
18527    (set_attr "mode" "QI")])
18528
18529 (define_expand "cmpstrnsi"
18530   [(set (match_operand:SI 0 "register_operand" "")
18531         (compare:SI (match_operand:BLK 1 "general_operand" "")
18532                     (match_operand:BLK 2 "general_operand" "")))
18533    (use (match_operand 3 "general_operand" ""))
18534    (use (match_operand 4 "immediate_operand" ""))]
18535   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18536 {
18537   rtx addr1, addr2, out, outlow, count, countreg, align;
18538
18539   /* Can't use this if the user has appropriated esi or edi.  */
18540   if (global_regs[4] || global_regs[5])
18541     FAIL;
18542
18543   out = operands[0];
18544   if (GET_CODE (out) != REG)
18545     out = gen_reg_rtx (SImode);
18546
18547   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18548   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18549   if (addr1 != XEXP (operands[1], 0))
18550     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18551   if (addr2 != XEXP (operands[2], 0))
18552     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18553
18554   count = operands[3];
18555   countreg = ix86_zero_extend_to_Pmode (count);
18556
18557   /* %%% Iff we are testing strict equality, we can use known alignment
18558      to good advantage.  This may be possible with combine, particularly
18559      once cc0 is dead.  */
18560   align = operands[4];
18561
18562   emit_insn (gen_cld ());
18563   if (GET_CODE (count) == CONST_INT)
18564     {
18565       if (INTVAL (count) == 0)
18566         {
18567           emit_move_insn (operands[0], const0_rtx);
18568           DONE;
18569         }
18570       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18571                                      operands[1], operands[2]));
18572     }
18573   else
18574     {
18575       if (TARGET_64BIT)
18576         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18577       else
18578         emit_insn (gen_cmpsi_1 (countreg, countreg));
18579       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18580                                   operands[1], operands[2]));
18581     }
18582
18583   outlow = gen_lowpart (QImode, out);
18584   emit_insn (gen_cmpintqi (outlow));
18585   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18586
18587   if (operands[0] != out)
18588     emit_move_insn (operands[0], out);
18589
18590   DONE;
18591 })
18592
18593 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18594
18595 (define_expand "cmpintqi"
18596   [(set (match_dup 1)
18597         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18598    (set (match_dup 2)
18599         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18600    (parallel [(set (match_operand:QI 0 "register_operand" "")
18601                    (minus:QI (match_dup 1)
18602                              (match_dup 2)))
18603               (clobber (reg:CC FLAGS_REG))])]
18604   ""
18605   "operands[1] = gen_reg_rtx (QImode);
18606    operands[2] = gen_reg_rtx (QImode);")
18607
18608 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18609 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18610
18611 (define_expand "cmpstrnqi_nz_1"
18612   [(parallel [(set (reg:CC FLAGS_REG)
18613                    (compare:CC (match_operand 4 "memory_operand" "")
18614                                (match_operand 5 "memory_operand" "")))
18615               (use (match_operand 2 "register_operand" ""))
18616               (use (match_operand:SI 3 "immediate_operand" ""))
18617               (use (reg:SI DIRFLAG_REG))
18618               (clobber (match_operand 0 "register_operand" ""))
18619               (clobber (match_operand 1 "register_operand" ""))
18620               (clobber (match_dup 2))])]
18621   ""
18622   "")
18623
18624 (define_insn "*cmpstrnqi_nz_1"
18625   [(set (reg:CC FLAGS_REG)
18626         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18627                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18628    (use (match_operand:SI 6 "register_operand" "2"))
18629    (use (match_operand:SI 3 "immediate_operand" "i"))
18630    (use (reg:SI DIRFLAG_REG))
18631    (clobber (match_operand:SI 0 "register_operand" "=S"))
18632    (clobber (match_operand:SI 1 "register_operand" "=D"))
18633    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18634   "!TARGET_64BIT"
18635   "repz{\;| }cmpsb"
18636   [(set_attr "type" "str")
18637    (set_attr "mode" "QI")
18638    (set_attr "prefix_rep" "1")])
18639
18640 (define_insn "*cmpstrnqi_nz_rex_1"
18641   [(set (reg:CC FLAGS_REG)
18642         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18643                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18644    (use (match_operand:DI 6 "register_operand" "2"))
18645    (use (match_operand:SI 3 "immediate_operand" "i"))
18646    (use (reg:SI DIRFLAG_REG))
18647    (clobber (match_operand:DI 0 "register_operand" "=S"))
18648    (clobber (match_operand:DI 1 "register_operand" "=D"))
18649    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18650   "TARGET_64BIT"
18651   "repz{\;| }cmpsb"
18652   [(set_attr "type" "str")
18653    (set_attr "mode" "QI")
18654    (set_attr "prefix_rep" "1")])
18655
18656 ;; The same, but the count is not known to not be zero.
18657
18658 (define_expand "cmpstrnqi_1"
18659   [(parallel [(set (reg:CC FLAGS_REG)
18660                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18661                                      (const_int 0))
18662                   (compare:CC (match_operand 4 "memory_operand" "")
18663                               (match_operand 5 "memory_operand" ""))
18664                   (const_int 0)))
18665               (use (match_operand:SI 3 "immediate_operand" ""))
18666               (use (reg:CC FLAGS_REG))
18667               (use (reg:SI DIRFLAG_REG))
18668               (clobber (match_operand 0 "register_operand" ""))
18669               (clobber (match_operand 1 "register_operand" ""))
18670               (clobber (match_dup 2))])]
18671   ""
18672   "")
18673
18674 (define_insn "*cmpstrnqi_1"
18675   [(set (reg:CC FLAGS_REG)
18676         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18677                              (const_int 0))
18678           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18679                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18680           (const_int 0)))
18681    (use (match_operand:SI 3 "immediate_operand" "i"))
18682    (use (reg:CC FLAGS_REG))
18683    (use (reg:SI DIRFLAG_REG))
18684    (clobber (match_operand:SI 0 "register_operand" "=S"))
18685    (clobber (match_operand:SI 1 "register_operand" "=D"))
18686    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18687   "!TARGET_64BIT"
18688   "repz{\;| }cmpsb"
18689   [(set_attr "type" "str")
18690    (set_attr "mode" "QI")
18691    (set_attr "prefix_rep" "1")])
18692
18693 (define_insn "*cmpstrnqi_rex_1"
18694   [(set (reg:CC FLAGS_REG)
18695         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18696                              (const_int 0))
18697           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18698                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18699           (const_int 0)))
18700    (use (match_operand:SI 3 "immediate_operand" "i"))
18701    (use (reg:CC FLAGS_REG))
18702    (use (reg:SI DIRFLAG_REG))
18703    (clobber (match_operand:DI 0 "register_operand" "=S"))
18704    (clobber (match_operand:DI 1 "register_operand" "=D"))
18705    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18706   "TARGET_64BIT"
18707   "repz{\;| }cmpsb"
18708   [(set_attr "type" "str")
18709    (set_attr "mode" "QI")
18710    (set_attr "prefix_rep" "1")])
18711
18712 (define_expand "strlensi"
18713   [(set (match_operand:SI 0 "register_operand" "")
18714         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18715                     (match_operand:QI 2 "immediate_operand" "")
18716                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18717   ""
18718 {
18719  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18720    DONE;
18721  else
18722    FAIL;
18723 })
18724
18725 (define_expand "strlendi"
18726   [(set (match_operand:DI 0 "register_operand" "")
18727         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18728                     (match_operand:QI 2 "immediate_operand" "")
18729                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18730   ""
18731 {
18732  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18733    DONE;
18734  else
18735    FAIL;
18736 })
18737
18738 (define_expand "strlenqi_1"
18739   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18740               (use (reg:SI DIRFLAG_REG))
18741               (clobber (match_operand 1 "register_operand" ""))
18742               (clobber (reg:CC FLAGS_REG))])]
18743   ""
18744   "")
18745
18746 (define_insn "*strlenqi_1"
18747   [(set (match_operand:SI 0 "register_operand" "=&c")
18748         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18749                     (match_operand:QI 2 "register_operand" "a")
18750                     (match_operand:SI 3 "immediate_operand" "i")
18751                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18752    (use (reg:SI DIRFLAG_REG))
18753    (clobber (match_operand:SI 1 "register_operand" "=D"))
18754    (clobber (reg:CC FLAGS_REG))]
18755   "!TARGET_64BIT"
18756   "repnz{\;| }scasb"
18757   [(set_attr "type" "str")
18758    (set_attr "mode" "QI")
18759    (set_attr "prefix_rep" "1")])
18760
18761 (define_insn "*strlenqi_rex_1"
18762   [(set (match_operand:DI 0 "register_operand" "=&c")
18763         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18764                     (match_operand:QI 2 "register_operand" "a")
18765                     (match_operand:DI 3 "immediate_operand" "i")
18766                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18767    (use (reg:SI DIRFLAG_REG))
18768    (clobber (match_operand:DI 1 "register_operand" "=D"))
18769    (clobber (reg:CC FLAGS_REG))]
18770   "TARGET_64BIT"
18771   "repnz{\;| }scasb"
18772   [(set_attr "type" "str")
18773    (set_attr "mode" "QI")
18774    (set_attr "prefix_rep" "1")])
18775
18776 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18777 ;; handled in combine, but it is not currently up to the task.
18778 ;; When used for their truth value, the cmpstrn* expanders generate
18779 ;; code like this:
18780 ;;
18781 ;;   repz cmpsb
18782 ;;   seta       %al
18783 ;;   setb       %dl
18784 ;;   cmpb       %al, %dl
18785 ;;   jcc        label
18786 ;;
18787 ;; The intermediate three instructions are unnecessary.
18788
18789 ;; This one handles cmpstrn*_nz_1...
18790 (define_peephole2
18791   [(parallel[
18792      (set (reg:CC FLAGS_REG)
18793           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18794                       (mem:BLK (match_operand 5 "register_operand" ""))))
18795      (use (match_operand 6 "register_operand" ""))
18796      (use (match_operand:SI 3 "immediate_operand" ""))
18797      (use (reg:SI DIRFLAG_REG))
18798      (clobber (match_operand 0 "register_operand" ""))
18799      (clobber (match_operand 1 "register_operand" ""))
18800      (clobber (match_operand 2 "register_operand" ""))])
18801    (set (match_operand:QI 7 "register_operand" "")
18802         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18803    (set (match_operand:QI 8 "register_operand" "")
18804         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18805    (set (reg FLAGS_REG)
18806         (compare (match_dup 7) (match_dup 8)))
18807   ]
18808   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18809   [(parallel[
18810      (set (reg:CC FLAGS_REG)
18811           (compare:CC (mem:BLK (match_dup 4))
18812                       (mem:BLK (match_dup 5))))
18813      (use (match_dup 6))
18814      (use (match_dup 3))
18815      (use (reg:SI DIRFLAG_REG))
18816      (clobber (match_dup 0))
18817      (clobber (match_dup 1))
18818      (clobber (match_dup 2))])]
18819   "")
18820
18821 ;; ...and this one handles cmpstrn*_1.
18822 (define_peephole2
18823   [(parallel[
18824      (set (reg:CC FLAGS_REG)
18825           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18826                                (const_int 0))
18827             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18828                         (mem:BLK (match_operand 5 "register_operand" "")))
18829             (const_int 0)))
18830      (use (match_operand:SI 3 "immediate_operand" ""))
18831      (use (reg:CC FLAGS_REG))
18832      (use (reg:SI DIRFLAG_REG))
18833      (clobber (match_operand 0 "register_operand" ""))
18834      (clobber (match_operand 1 "register_operand" ""))
18835      (clobber (match_operand 2 "register_operand" ""))])
18836    (set (match_operand:QI 7 "register_operand" "")
18837         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18838    (set (match_operand:QI 8 "register_operand" "")
18839         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18840    (set (reg FLAGS_REG)
18841         (compare (match_dup 7) (match_dup 8)))
18842   ]
18843   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18844   [(parallel[
18845      (set (reg:CC FLAGS_REG)
18846           (if_then_else:CC (ne (match_dup 6)
18847                                (const_int 0))
18848             (compare:CC (mem:BLK (match_dup 4))
18849                         (mem:BLK (match_dup 5)))
18850             (const_int 0)))
18851      (use (match_dup 3))
18852      (use (reg:CC FLAGS_REG))
18853      (use (reg:SI DIRFLAG_REG))
18854      (clobber (match_dup 0))
18855      (clobber (match_dup 1))
18856      (clobber (match_dup 2))])]
18857   "")
18858
18859
18860 \f
18861 ;; Conditional move instructions.
18862
18863 (define_expand "movdicc"
18864   [(set (match_operand:DI 0 "register_operand" "")
18865         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18866                          (match_operand:DI 2 "general_operand" "")
18867                          (match_operand:DI 3 "general_operand" "")))]
18868   "TARGET_64BIT"
18869   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18870
18871 (define_insn "x86_movdicc_0_m1_rex64"
18872   [(set (match_operand:DI 0 "register_operand" "=r")
18873         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18874           (const_int -1)
18875           (const_int 0)))
18876    (clobber (reg:CC FLAGS_REG))]
18877   "TARGET_64BIT"
18878   "sbb{q}\t%0, %0"
18879   ; Since we don't have the proper number of operands for an alu insn,
18880   ; fill in all the blanks.
18881   [(set_attr "type" "alu")
18882    (set_attr "pent_pair" "pu")
18883    (set_attr "memory" "none")
18884    (set_attr "imm_disp" "false")
18885    (set_attr "mode" "DI")
18886    (set_attr "length_immediate" "0")])
18887
18888 (define_insn "*movdicc_c_rex64"
18889   [(set (match_operand:DI 0 "register_operand" "=r,r")
18890         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18891                                 [(reg FLAGS_REG) (const_int 0)])
18892                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18893                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18894   "TARGET_64BIT && TARGET_CMOVE
18895    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18896   "@
18897    cmov%O2%C1\t{%2, %0|%0, %2}
18898    cmov%O2%c1\t{%3, %0|%0, %3}"
18899   [(set_attr "type" "icmov")
18900    (set_attr "mode" "DI")])
18901
18902 (define_expand "movsicc"
18903   [(set (match_operand:SI 0 "register_operand" "")
18904         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18905                          (match_operand:SI 2 "general_operand" "")
18906                          (match_operand:SI 3 "general_operand" "")))]
18907   ""
18908   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18909
18910 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18911 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18912 ;; So just document what we're doing explicitly.
18913
18914 (define_insn "x86_movsicc_0_m1"
18915   [(set (match_operand:SI 0 "register_operand" "=r")
18916         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18917           (const_int -1)
18918           (const_int 0)))
18919    (clobber (reg:CC FLAGS_REG))]
18920   ""
18921   "sbb{l}\t%0, %0"
18922   ; Since we don't have the proper number of operands for an alu insn,
18923   ; fill in all the blanks.
18924   [(set_attr "type" "alu")
18925    (set_attr "pent_pair" "pu")
18926    (set_attr "memory" "none")
18927    (set_attr "imm_disp" "false")
18928    (set_attr "mode" "SI")
18929    (set_attr "length_immediate" "0")])
18930
18931 (define_insn "*movsicc_noc"
18932   [(set (match_operand:SI 0 "register_operand" "=r,r")
18933         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18934                                 [(reg FLAGS_REG) (const_int 0)])
18935                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18936                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18937   "TARGET_CMOVE
18938    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18939   "@
18940    cmov%O2%C1\t{%2, %0|%0, %2}
18941    cmov%O2%c1\t{%3, %0|%0, %3}"
18942   [(set_attr "type" "icmov")
18943    (set_attr "mode" "SI")])
18944
18945 (define_expand "movhicc"
18946   [(set (match_operand:HI 0 "register_operand" "")
18947         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18948                          (match_operand:HI 2 "general_operand" "")
18949                          (match_operand:HI 3 "general_operand" "")))]
18950   "TARGET_HIMODE_MATH"
18951   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18952
18953 (define_insn "*movhicc_noc"
18954   [(set (match_operand:HI 0 "register_operand" "=r,r")
18955         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18956                                 [(reg FLAGS_REG) (const_int 0)])
18957                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18958                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18959   "TARGET_CMOVE
18960    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18961   "@
18962    cmov%O2%C1\t{%2, %0|%0, %2}
18963    cmov%O2%c1\t{%3, %0|%0, %3}"
18964   [(set_attr "type" "icmov")
18965    (set_attr "mode" "HI")])
18966
18967 (define_expand "movqicc"
18968   [(set (match_operand:QI 0 "register_operand" "")
18969         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18970                          (match_operand:QI 2 "general_operand" "")
18971                          (match_operand:QI 3 "general_operand" "")))]
18972   "TARGET_QIMODE_MATH"
18973   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18974
18975 (define_insn_and_split "*movqicc_noc"
18976   [(set (match_operand:QI 0 "register_operand" "=r,r")
18977         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18978                                 [(match_operand 4 "flags_reg_operand" "")
18979                                  (const_int 0)])
18980                       (match_operand:QI 2 "register_operand" "r,0")
18981                       (match_operand:QI 3 "register_operand" "0,r")))]
18982   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18983   "#"
18984   "&& reload_completed"
18985   [(set (match_dup 0)
18986         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18987                       (match_dup 2)
18988                       (match_dup 3)))]
18989   "operands[0] = gen_lowpart (SImode, operands[0]);
18990    operands[2] = gen_lowpart (SImode, operands[2]);
18991    operands[3] = gen_lowpart (SImode, operands[3]);"
18992   [(set_attr "type" "icmov")
18993    (set_attr "mode" "SI")])
18994
18995 (define_expand "movsfcc"
18996   [(set (match_operand:SF 0 "register_operand" "")
18997         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18998                          (match_operand:SF 2 "register_operand" "")
18999                          (match_operand:SF 3 "register_operand" "")))]
19000   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19001   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19002
19003 (define_insn "*movsfcc_1_387"
19004   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19005         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19006                                 [(reg FLAGS_REG) (const_int 0)])
19007                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19008                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19009   "TARGET_80387 && TARGET_CMOVE
19010    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19011   "@
19012    fcmov%F1\t{%2, %0|%0, %2}
19013    fcmov%f1\t{%3, %0|%0, %3}
19014    cmov%O2%C1\t{%2, %0|%0, %2}
19015    cmov%O2%c1\t{%3, %0|%0, %3}"
19016   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19017    (set_attr "mode" "SF,SF,SI,SI")])
19018
19019 (define_expand "movdfcc"
19020   [(set (match_operand:DF 0 "register_operand" "")
19021         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19022                          (match_operand:DF 2 "register_operand" "")
19023                          (match_operand:DF 3 "register_operand" "")))]
19024   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19025   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19026
19027 (define_insn "*movdfcc_1"
19028   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19029         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19030                                 [(reg FLAGS_REG) (const_int 0)])
19031                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19032                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19033   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19034    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19035   "@
19036    fcmov%F1\t{%2, %0|%0, %2}
19037    fcmov%f1\t{%3, %0|%0, %3}
19038    #
19039    #"
19040   [(set_attr "type" "fcmov,fcmov,multi,multi")
19041    (set_attr "mode" "DF")])
19042
19043 (define_insn "*movdfcc_1_rex64"
19044   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19045         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19046                                 [(reg FLAGS_REG) (const_int 0)])
19047                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19048                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19049   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19050    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19051   "@
19052    fcmov%F1\t{%2, %0|%0, %2}
19053    fcmov%f1\t{%3, %0|%0, %3}
19054    cmov%O2%C1\t{%2, %0|%0, %2}
19055    cmov%O2%c1\t{%3, %0|%0, %3}"
19056   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19057    (set_attr "mode" "DF")])
19058
19059 (define_split
19060   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19061         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19062                                 [(match_operand 4 "flags_reg_operand" "")
19063                                  (const_int 0)])
19064                       (match_operand:DF 2 "nonimmediate_operand" "")
19065                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19066   "!TARGET_64BIT && reload_completed"
19067   [(set (match_dup 2)
19068         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19069                       (match_dup 5)
19070                       (match_dup 7)))
19071    (set (match_dup 3)
19072         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19073                       (match_dup 6)
19074                       (match_dup 8)))]
19075   "split_di (operands+2, 1, operands+5, operands+6);
19076    split_di (operands+3, 1, operands+7, operands+8);
19077    split_di (operands, 1, operands+2, operands+3);")
19078
19079 (define_expand "movxfcc"
19080   [(set (match_operand:XF 0 "register_operand" "")
19081         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19082                          (match_operand:XF 2 "register_operand" "")
19083                          (match_operand:XF 3 "register_operand" "")))]
19084   "TARGET_80387 && TARGET_CMOVE"
19085   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19086
19087 (define_insn "*movxfcc_1"
19088   [(set (match_operand:XF 0 "register_operand" "=f,f")
19089         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19090                                 [(reg FLAGS_REG) (const_int 0)])
19091                       (match_operand:XF 2 "register_operand" "f,0")
19092                       (match_operand:XF 3 "register_operand" "0,f")))]
19093   "TARGET_80387 && TARGET_CMOVE"
19094   "@
19095    fcmov%F1\t{%2, %0|%0, %2}
19096    fcmov%f1\t{%3, %0|%0, %3}"
19097   [(set_attr "type" "fcmov")
19098    (set_attr "mode" "XF")])
19099
19100 ;; These versions of the min/max patterns are intentionally ignorant of
19101 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19102 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19103 ;; are undefined in this condition, we're certain this is correct.
19104
19105 (define_insn "sminsf3"
19106   [(set (match_operand:SF 0 "register_operand" "=x")
19107         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19108                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19109   "TARGET_SSE_MATH"
19110   "minss\t{%2, %0|%0, %2}"
19111   [(set_attr "type" "sseadd")
19112    (set_attr "mode" "SF")])
19113
19114 (define_insn "smaxsf3"
19115   [(set (match_operand:SF 0 "register_operand" "=x")
19116         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19117                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19118   "TARGET_SSE_MATH"
19119   "maxss\t{%2, %0|%0, %2}"
19120   [(set_attr "type" "sseadd")
19121    (set_attr "mode" "SF")])
19122
19123 (define_insn "smindf3"
19124   [(set (match_operand:DF 0 "register_operand" "=x")
19125         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19126                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19127   "TARGET_SSE2 && TARGET_SSE_MATH"
19128   "minsd\t{%2, %0|%0, %2}"
19129   [(set_attr "type" "sseadd")
19130    (set_attr "mode" "DF")])
19131
19132 (define_insn "smaxdf3"
19133   [(set (match_operand:DF 0 "register_operand" "=x")
19134         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19135                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19136   "TARGET_SSE2 && TARGET_SSE_MATH"
19137   "maxsd\t{%2, %0|%0, %2}"
19138   [(set_attr "type" "sseadd")
19139    (set_attr "mode" "DF")])
19140
19141 ;; These versions of the min/max patterns implement exactly the operations
19142 ;;   min = (op1 < op2 ? op1 : op2)
19143 ;;   max = (!(op1 < op2) ? op1 : op2)
19144 ;; Their operands are not commutative, and thus they may be used in the
19145 ;; presence of -0.0 and NaN.
19146
19147 (define_insn "*ieee_sminsf3"
19148   [(set (match_operand:SF 0 "register_operand" "=x")
19149         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19150                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19151                    UNSPEC_IEEE_MIN))]
19152   "TARGET_SSE_MATH"
19153   "minss\t{%2, %0|%0, %2}"
19154   [(set_attr "type" "sseadd")
19155    (set_attr "mode" "SF")])
19156
19157 (define_insn "*ieee_smaxsf3"
19158   [(set (match_operand:SF 0 "register_operand" "=x")
19159         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19160                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19161                    UNSPEC_IEEE_MAX))]
19162   "TARGET_SSE_MATH"
19163   "maxss\t{%2, %0|%0, %2}"
19164   [(set_attr "type" "sseadd")
19165    (set_attr "mode" "SF")])
19166
19167 (define_insn "*ieee_smindf3"
19168   [(set (match_operand:DF 0 "register_operand" "=x")
19169         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19170                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19171                    UNSPEC_IEEE_MIN))]
19172   "TARGET_SSE2 && TARGET_SSE_MATH"
19173   "minsd\t{%2, %0|%0, %2}"
19174   [(set_attr "type" "sseadd")
19175    (set_attr "mode" "DF")])
19176
19177 (define_insn "*ieee_smaxdf3"
19178   [(set (match_operand:DF 0 "register_operand" "=x")
19179         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19180                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19181                    UNSPEC_IEEE_MAX))]
19182   "TARGET_SSE2 && TARGET_SSE_MATH"
19183   "maxsd\t{%2, %0|%0, %2}"
19184   [(set_attr "type" "sseadd")
19185    (set_attr "mode" "DF")])
19186
19187 ;; Make two stack loads independent:
19188 ;;   fld aa              fld aa
19189 ;;   fld %st(0)     ->   fld bb
19190 ;;   fmul bb             fmul %st(1), %st
19191 ;;
19192 ;; Actually we only match the last two instructions for simplicity.
19193 (define_peephole2
19194   [(set (match_operand 0 "fp_register_operand" "")
19195         (match_operand 1 "fp_register_operand" ""))
19196    (set (match_dup 0)
19197         (match_operator 2 "binary_fp_operator"
19198            [(match_dup 0)
19199             (match_operand 3 "memory_operand" "")]))]
19200   "REGNO (operands[0]) != REGNO (operands[1])"
19201   [(set (match_dup 0) (match_dup 3))
19202    (set (match_dup 0) (match_dup 4))]
19203
19204   ;; The % modifier is not operational anymore in peephole2's, so we have to
19205   ;; swap the operands manually in the case of addition and multiplication.
19206   "if (COMMUTATIVE_ARITH_P (operands[2]))
19207      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19208                                  operands[0], operands[1]);
19209    else
19210      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19211                                  operands[1], operands[0]);")
19212
19213 ;; Conditional addition patterns
19214 (define_expand "addqicc"
19215   [(match_operand:QI 0 "register_operand" "")
19216    (match_operand 1 "comparison_operator" "")
19217    (match_operand:QI 2 "register_operand" "")
19218    (match_operand:QI 3 "const_int_operand" "")]
19219   ""
19220   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19221
19222 (define_expand "addhicc"
19223   [(match_operand:HI 0 "register_operand" "")
19224    (match_operand 1 "comparison_operator" "")
19225    (match_operand:HI 2 "register_operand" "")
19226    (match_operand:HI 3 "const_int_operand" "")]
19227   ""
19228   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19229
19230 (define_expand "addsicc"
19231   [(match_operand:SI 0 "register_operand" "")
19232    (match_operand 1 "comparison_operator" "")
19233    (match_operand:SI 2 "register_operand" "")
19234    (match_operand:SI 3 "const_int_operand" "")]
19235   ""
19236   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19237
19238 (define_expand "adddicc"
19239   [(match_operand:DI 0 "register_operand" "")
19240    (match_operand 1 "comparison_operator" "")
19241    (match_operand:DI 2 "register_operand" "")
19242    (match_operand:DI 3 "const_int_operand" "")]
19243   "TARGET_64BIT"
19244   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19245
19246 \f
19247 ;; Misc patterns (?)
19248
19249 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19250 ;; Otherwise there will be nothing to keep
19251 ;; 
19252 ;; [(set (reg ebp) (reg esp))]
19253 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19254 ;;  (clobber (eflags)]
19255 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19256 ;;
19257 ;; in proper program order.
19258 (define_insn "pro_epilogue_adjust_stack_1"
19259   [(set (match_operand:SI 0 "register_operand" "=r,r")
19260         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19261                  (match_operand:SI 2 "immediate_operand" "i,i")))
19262    (clobber (reg:CC FLAGS_REG))
19263    (clobber (mem:BLK (scratch)))]
19264   "!TARGET_64BIT"
19265 {
19266   switch (get_attr_type (insn))
19267     {
19268     case TYPE_IMOV:
19269       return "mov{l}\t{%1, %0|%0, %1}";
19270
19271     case TYPE_ALU:
19272       if (GET_CODE (operands[2]) == CONST_INT
19273           && (INTVAL (operands[2]) == 128
19274               || (INTVAL (operands[2]) < 0
19275                   && INTVAL (operands[2]) != -128)))
19276         {
19277           operands[2] = GEN_INT (-INTVAL (operands[2]));
19278           return "sub{l}\t{%2, %0|%0, %2}";
19279         }
19280       return "add{l}\t{%2, %0|%0, %2}";
19281
19282     case TYPE_LEA:
19283       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19284       return "lea{l}\t{%a2, %0|%0, %a2}";
19285
19286     default:
19287       gcc_unreachable ();
19288     }
19289 }
19290   [(set (attr "type")
19291         (cond [(eq_attr "alternative" "0")
19292                  (const_string "alu")
19293                (match_operand:SI 2 "const0_operand" "")
19294                  (const_string "imov")
19295               ]
19296               (const_string "lea")))
19297    (set_attr "mode" "SI")])
19298
19299 (define_insn "pro_epilogue_adjust_stack_rex64"
19300   [(set (match_operand:DI 0 "register_operand" "=r,r")
19301         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19302                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19303    (clobber (reg:CC FLAGS_REG))
19304    (clobber (mem:BLK (scratch)))]
19305   "TARGET_64BIT"
19306 {
19307   switch (get_attr_type (insn))
19308     {
19309     case TYPE_IMOV:
19310       return "mov{q}\t{%1, %0|%0, %1}";
19311
19312     case TYPE_ALU:
19313       if (GET_CODE (operands[2]) == CONST_INT
19314           /* Avoid overflows.  */
19315           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19316           && (INTVAL (operands[2]) == 128
19317               || (INTVAL (operands[2]) < 0
19318                   && INTVAL (operands[2]) != -128)))
19319         {
19320           operands[2] = GEN_INT (-INTVAL (operands[2]));
19321           return "sub{q}\t{%2, %0|%0, %2}";
19322         }
19323       return "add{q}\t{%2, %0|%0, %2}";
19324
19325     case TYPE_LEA:
19326       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19327       return "lea{q}\t{%a2, %0|%0, %a2}";
19328
19329     default:
19330       gcc_unreachable ();
19331     }
19332 }
19333   [(set (attr "type")
19334         (cond [(eq_attr "alternative" "0")
19335                  (const_string "alu")
19336                (match_operand:DI 2 "const0_operand" "")
19337                  (const_string "imov")
19338               ]
19339               (const_string "lea")))
19340    (set_attr "mode" "DI")])
19341
19342 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19343   [(set (match_operand:DI 0 "register_operand" "=r,r")
19344         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19345                  (match_operand:DI 3 "immediate_operand" "i,i")))
19346    (use (match_operand:DI 2 "register_operand" "r,r"))
19347    (clobber (reg:CC FLAGS_REG))
19348    (clobber (mem:BLK (scratch)))]
19349   "TARGET_64BIT"
19350 {
19351   switch (get_attr_type (insn))
19352     {
19353     case TYPE_ALU:
19354       return "add{q}\t{%2, %0|%0, %2}";
19355
19356     case TYPE_LEA:
19357       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19358       return "lea{q}\t{%a2, %0|%0, %a2}";
19359
19360     default:
19361       gcc_unreachable ();
19362     }
19363 }
19364   [(set_attr "type" "alu,lea")
19365    (set_attr "mode" "DI")])
19366
19367 (define_expand "allocate_stack_worker"
19368   [(match_operand:SI 0 "register_operand" "")]
19369   "TARGET_STACK_PROBE"
19370 {
19371   if (reload_completed)
19372     {
19373       if (TARGET_64BIT)
19374         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19375       else
19376         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19377     }
19378   else
19379     {
19380       if (TARGET_64BIT)
19381         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19382       else
19383         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19384     }
19385   DONE;
19386 })
19387
19388 (define_insn "allocate_stack_worker_1"
19389   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19390     UNSPECV_STACK_PROBE)
19391    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19392    (clobber (match_scratch:SI 1 "=0"))
19393    (clobber (reg:CC FLAGS_REG))]
19394   "!TARGET_64BIT && TARGET_STACK_PROBE"
19395   "call\t__alloca"
19396   [(set_attr "type" "multi")
19397    (set_attr "length" "5")])
19398
19399 (define_expand "allocate_stack_worker_postreload"
19400   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19401                                     UNSPECV_STACK_PROBE)
19402               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19403               (clobber (match_dup 0))
19404               (clobber (reg:CC FLAGS_REG))])]
19405   ""
19406   "")
19407
19408 (define_insn "allocate_stack_worker_rex64"
19409   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19410     UNSPECV_STACK_PROBE)
19411    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19412    (clobber (match_scratch:DI 1 "=0"))
19413    (clobber (reg:CC FLAGS_REG))]
19414   "TARGET_64BIT && TARGET_STACK_PROBE"
19415   "call\t__alloca"
19416   [(set_attr "type" "multi")
19417    (set_attr "length" "5")])
19418
19419 (define_expand "allocate_stack_worker_rex64_postreload"
19420   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19421                                     UNSPECV_STACK_PROBE)
19422               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19423               (clobber (match_dup 0))
19424               (clobber (reg:CC FLAGS_REG))])]
19425   ""
19426   "")
19427
19428 (define_expand "allocate_stack"
19429   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19430                    (minus:SI (reg:SI SP_REG)
19431                              (match_operand:SI 1 "general_operand" "")))
19432               (clobber (reg:CC FLAGS_REG))])
19433    (parallel [(set (reg:SI SP_REG)
19434                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19435               (clobber (reg:CC FLAGS_REG))])]
19436   "TARGET_STACK_PROBE"
19437 {
19438 #ifdef CHECK_STACK_LIMIT
19439   if (GET_CODE (operands[1]) == CONST_INT
19440       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19441     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19442                            operands[1]));
19443   else 
19444 #endif
19445     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19446                                                             operands[1])));
19447
19448   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19449   DONE;
19450 })
19451
19452 (define_expand "builtin_setjmp_receiver"
19453   [(label_ref (match_operand 0 "" ""))]
19454   "!TARGET_64BIT && flag_pic"
19455 {
19456   if (TARGET_MACHO)
19457     {
19458       rtx xops[3];
19459       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19460       rtx label_rtx = gen_label_rtx ();
19461       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19462       xops[0] = xops[1] = picreg;
19463       xops[2] = gen_rtx_CONST (SImode,
19464                   gen_rtx_MINUS (SImode,
19465                     gen_rtx_LABEL_REF (SImode, label_rtx),
19466                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19467       ix86_expand_binary_operator (MINUS, SImode, xops);
19468     }
19469   else
19470     emit_insn (gen_set_got (pic_offset_table_rtx));
19471   DONE;
19472 })
19473 \f
19474 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19475
19476 (define_split
19477   [(set (match_operand 0 "register_operand" "")
19478         (match_operator 3 "promotable_binary_operator"
19479            [(match_operand 1 "register_operand" "")
19480             (match_operand 2 "aligned_operand" "")]))
19481    (clobber (reg:CC FLAGS_REG))]
19482   "! TARGET_PARTIAL_REG_STALL && reload_completed
19483    && ((GET_MODE (operands[0]) == HImode 
19484         && ((!optimize_size && !TARGET_FAST_PREFIX)
19485             /* ??? next two lines just !satisfies_constraint_K (...) */
19486             || GET_CODE (operands[2]) != CONST_INT
19487             || satisfies_constraint_K (operands[2])))
19488        || (GET_MODE (operands[0]) == QImode 
19489            && (TARGET_PROMOTE_QImode || optimize_size)))"
19490   [(parallel [(set (match_dup 0)
19491                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492               (clobber (reg:CC FLAGS_REG))])]
19493   "operands[0] = gen_lowpart (SImode, operands[0]);
19494    operands[1] = gen_lowpart (SImode, operands[1]);
19495    if (GET_CODE (operands[3]) != ASHIFT)
19496      operands[2] = gen_lowpart (SImode, operands[2]);
19497    PUT_MODE (operands[3], SImode);")
19498
19499 ; Promote the QImode tests, as i386 has encoding of the AND
19500 ; instruction with 32-bit sign-extended immediate and thus the
19501 ; instruction size is unchanged, except in the %eax case for
19502 ; which it is increased by one byte, hence the ! optimize_size.
19503 (define_split
19504   [(set (match_operand 0 "flags_reg_operand" "")
19505         (match_operator 2 "compare_operator"
19506           [(and (match_operand 3 "aligned_operand" "")
19507                 (match_operand 4 "const_int_operand" ""))
19508            (const_int 0)]))
19509    (set (match_operand 1 "register_operand" "")
19510         (and (match_dup 3) (match_dup 4)))]
19511   "! TARGET_PARTIAL_REG_STALL && reload_completed
19512    /* Ensure that the operand will remain sign-extended immediate.  */
19513    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19514    && ! optimize_size
19515    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19516        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19517   [(parallel [(set (match_dup 0)
19518                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19519                                     (const_int 0)]))
19520               (set (match_dup 1)
19521                    (and:SI (match_dup 3) (match_dup 4)))])]
19522 {
19523   operands[4]
19524     = gen_int_mode (INTVAL (operands[4])
19525                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19526   operands[1] = gen_lowpart (SImode, operands[1]);
19527   operands[3] = gen_lowpart (SImode, operands[3]);
19528 })
19529
19530 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19531 ; the TEST instruction with 32-bit sign-extended immediate and thus
19532 ; the instruction size would at least double, which is not what we
19533 ; want even with ! optimize_size.
19534 (define_split
19535   [(set (match_operand 0 "flags_reg_operand" "")
19536         (match_operator 1 "compare_operator"
19537           [(and (match_operand:HI 2 "aligned_operand" "")
19538                 (match_operand:HI 3 "const_int_operand" ""))
19539            (const_int 0)]))]
19540   "! TARGET_PARTIAL_REG_STALL && reload_completed
19541    /* Ensure that the operand will remain sign-extended immediate.  */
19542    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19543    && ! TARGET_FAST_PREFIX
19544    && ! optimize_size"
19545   [(set (match_dup 0)
19546         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19547                          (const_int 0)]))]
19548 {
19549   operands[3]
19550     = gen_int_mode (INTVAL (operands[3])
19551                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19552   operands[2] = gen_lowpart (SImode, operands[2]);
19553 })
19554
19555 (define_split
19556   [(set (match_operand 0 "register_operand" "")
19557         (neg (match_operand 1 "register_operand" "")))
19558    (clobber (reg:CC FLAGS_REG))]
19559   "! TARGET_PARTIAL_REG_STALL && reload_completed
19560    && (GET_MODE (operands[0]) == HImode
19561        || (GET_MODE (operands[0]) == QImode 
19562            && (TARGET_PROMOTE_QImode || optimize_size)))"
19563   [(parallel [(set (match_dup 0)
19564                    (neg:SI (match_dup 1)))
19565               (clobber (reg:CC FLAGS_REG))])]
19566   "operands[0] = gen_lowpart (SImode, operands[0]);
19567    operands[1] = gen_lowpart (SImode, operands[1]);")
19568
19569 (define_split
19570   [(set (match_operand 0 "register_operand" "")
19571         (not (match_operand 1 "register_operand" "")))]
19572   "! TARGET_PARTIAL_REG_STALL && reload_completed
19573    && (GET_MODE (operands[0]) == HImode
19574        || (GET_MODE (operands[0]) == QImode 
19575            && (TARGET_PROMOTE_QImode || optimize_size)))"
19576   [(set (match_dup 0)
19577         (not:SI (match_dup 1)))]
19578   "operands[0] = gen_lowpart (SImode, operands[0]);
19579    operands[1] = gen_lowpart (SImode, operands[1]);")
19580
19581 (define_split 
19582   [(set (match_operand 0 "register_operand" "")
19583         (if_then_else (match_operator 1 "comparison_operator" 
19584                                 [(reg FLAGS_REG) (const_int 0)])
19585                       (match_operand 2 "register_operand" "")
19586                       (match_operand 3 "register_operand" "")))]
19587   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19588    && (GET_MODE (operands[0]) == HImode
19589        || (GET_MODE (operands[0]) == QImode 
19590            && (TARGET_PROMOTE_QImode || optimize_size)))"
19591   [(set (match_dup 0)
19592         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19593   "operands[0] = gen_lowpart (SImode, operands[0]);
19594    operands[2] = gen_lowpart (SImode, operands[2]);
19595    operands[3] = gen_lowpart (SImode, operands[3]);")
19596                         
19597 \f
19598 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19599 ;; transform a complex memory operation into two memory to register operations.
19600
19601 ;; Don't push memory operands
19602 (define_peephole2
19603   [(set (match_operand:SI 0 "push_operand" "")
19604         (match_operand:SI 1 "memory_operand" ""))
19605    (match_scratch:SI 2 "r")]
19606   "!optimize_size && !TARGET_PUSH_MEMORY
19607    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19608   [(set (match_dup 2) (match_dup 1))
19609    (set (match_dup 0) (match_dup 2))]
19610   "")
19611
19612 (define_peephole2
19613   [(set (match_operand:DI 0 "push_operand" "")
19614         (match_operand:DI 1 "memory_operand" ""))
19615    (match_scratch:DI 2 "r")]
19616   "!optimize_size && !TARGET_PUSH_MEMORY
19617    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19618   [(set (match_dup 2) (match_dup 1))
19619    (set (match_dup 0) (match_dup 2))]
19620   "")
19621
19622 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19623 ;; SImode pushes.
19624 (define_peephole2
19625   [(set (match_operand:SF 0 "push_operand" "")
19626         (match_operand:SF 1 "memory_operand" ""))
19627    (match_scratch:SF 2 "r")]
19628   "!optimize_size && !TARGET_PUSH_MEMORY
19629    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19630   [(set (match_dup 2) (match_dup 1))
19631    (set (match_dup 0) (match_dup 2))]
19632   "")
19633
19634 (define_peephole2
19635   [(set (match_operand:HI 0 "push_operand" "")
19636         (match_operand:HI 1 "memory_operand" ""))
19637    (match_scratch:HI 2 "r")]
19638   "!optimize_size && !TARGET_PUSH_MEMORY
19639    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19640   [(set (match_dup 2) (match_dup 1))
19641    (set (match_dup 0) (match_dup 2))]
19642   "")
19643
19644 (define_peephole2
19645   [(set (match_operand:QI 0 "push_operand" "")
19646         (match_operand:QI 1 "memory_operand" ""))
19647    (match_scratch:QI 2 "q")]
19648   "!optimize_size && !TARGET_PUSH_MEMORY
19649    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19650   [(set (match_dup 2) (match_dup 1))
19651    (set (match_dup 0) (match_dup 2))]
19652   "")
19653
19654 ;; Don't move an immediate directly to memory when the instruction
19655 ;; gets too big.
19656 (define_peephole2
19657   [(match_scratch:SI 1 "r")
19658    (set (match_operand:SI 0 "memory_operand" "")
19659         (const_int 0))]
19660   "! optimize_size
19661    && ! TARGET_USE_MOV0
19662    && TARGET_SPLIT_LONG_MOVES
19663    && get_attr_length (insn) >= ix86_cost->large_insn
19664    && peep2_regno_dead_p (0, FLAGS_REG)"
19665   [(parallel [(set (match_dup 1) (const_int 0))
19666               (clobber (reg:CC FLAGS_REG))])
19667    (set (match_dup 0) (match_dup 1))]
19668   "")
19669
19670 (define_peephole2
19671   [(match_scratch:HI 1 "r")
19672    (set (match_operand:HI 0 "memory_operand" "")
19673         (const_int 0))]
19674   "! optimize_size
19675    && ! TARGET_USE_MOV0
19676    && TARGET_SPLIT_LONG_MOVES
19677    && get_attr_length (insn) >= ix86_cost->large_insn
19678    && peep2_regno_dead_p (0, FLAGS_REG)"
19679   [(parallel [(set (match_dup 2) (const_int 0))
19680               (clobber (reg:CC FLAGS_REG))])
19681    (set (match_dup 0) (match_dup 1))]
19682   "operands[2] = gen_lowpart (SImode, operands[1]);")
19683
19684 (define_peephole2
19685   [(match_scratch:QI 1 "q")
19686    (set (match_operand:QI 0 "memory_operand" "")
19687         (const_int 0))]
19688   "! optimize_size
19689    && ! TARGET_USE_MOV0
19690    && TARGET_SPLIT_LONG_MOVES
19691    && get_attr_length (insn) >= ix86_cost->large_insn
19692    && peep2_regno_dead_p (0, FLAGS_REG)"
19693   [(parallel [(set (match_dup 2) (const_int 0))
19694               (clobber (reg:CC FLAGS_REG))])
19695    (set (match_dup 0) (match_dup 1))]
19696   "operands[2] = gen_lowpart (SImode, operands[1]);")
19697
19698 (define_peephole2
19699   [(match_scratch:SI 2 "r")
19700    (set (match_operand:SI 0 "memory_operand" "")
19701         (match_operand:SI 1 "immediate_operand" ""))]
19702   "! optimize_size
19703    && get_attr_length (insn) >= ix86_cost->large_insn
19704    && TARGET_SPLIT_LONG_MOVES"
19705   [(set (match_dup 2) (match_dup 1))
19706    (set (match_dup 0) (match_dup 2))]
19707   "")
19708
19709 (define_peephole2
19710   [(match_scratch:HI 2 "r")
19711    (set (match_operand:HI 0 "memory_operand" "")
19712         (match_operand:HI 1 "immediate_operand" ""))]
19713   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19714   && TARGET_SPLIT_LONG_MOVES"
19715   [(set (match_dup 2) (match_dup 1))
19716    (set (match_dup 0) (match_dup 2))]
19717   "")
19718
19719 (define_peephole2
19720   [(match_scratch:QI 2 "q")
19721    (set (match_operand:QI 0 "memory_operand" "")
19722         (match_operand:QI 1 "immediate_operand" ""))]
19723   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19724   && TARGET_SPLIT_LONG_MOVES"
19725   [(set (match_dup 2) (match_dup 1))
19726    (set (match_dup 0) (match_dup 2))]
19727   "")
19728
19729 ;; Don't compare memory with zero, load and use a test instead.
19730 (define_peephole2
19731   [(set (match_operand 0 "flags_reg_operand" "")
19732         (match_operator 1 "compare_operator"
19733           [(match_operand:SI 2 "memory_operand" "")
19734            (const_int 0)]))
19735    (match_scratch:SI 3 "r")]
19736   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19737   [(set (match_dup 3) (match_dup 2))
19738    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19739   "")
19740
19741 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19742 ;; Don't split NOTs with a displacement operand, because resulting XOR
19743 ;; will not be pairable anyway.
19744 ;;
19745 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19746 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19747 ;; so this split helps here as well.
19748 ;;
19749 ;; Note: Can't do this as a regular split because we can't get proper
19750 ;; lifetime information then.
19751
19752 (define_peephole2
19753   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19754         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19755   "!optimize_size
19756    && peep2_regno_dead_p (0, FLAGS_REG)
19757    && ((TARGET_PENTIUM 
19758         && (GET_CODE (operands[0]) != MEM
19759             || !memory_displacement_operand (operands[0], SImode)))
19760        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19761   [(parallel [(set (match_dup 0)
19762                    (xor:SI (match_dup 1) (const_int -1)))
19763               (clobber (reg:CC FLAGS_REG))])]
19764   "")
19765
19766 (define_peephole2
19767   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19768         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19769   "!optimize_size
19770    && peep2_regno_dead_p (0, FLAGS_REG)
19771    && ((TARGET_PENTIUM 
19772         && (GET_CODE (operands[0]) != MEM
19773             || !memory_displacement_operand (operands[0], HImode)))
19774        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19775   [(parallel [(set (match_dup 0)
19776                    (xor:HI (match_dup 1) (const_int -1)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "")
19779
19780 (define_peephole2
19781   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19782         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19783   "!optimize_size
19784    && peep2_regno_dead_p (0, FLAGS_REG)
19785    && ((TARGET_PENTIUM 
19786         && (GET_CODE (operands[0]) != MEM
19787             || !memory_displacement_operand (operands[0], QImode)))
19788        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19789   [(parallel [(set (match_dup 0)
19790                    (xor:QI (match_dup 1) (const_int -1)))
19791               (clobber (reg:CC FLAGS_REG))])]
19792   "")
19793
19794 ;; Non pairable "test imm, reg" instructions can be translated to
19795 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19796 ;; byte opcode instead of two, have a short form for byte operands),
19797 ;; so do it for other CPUs as well.  Given that the value was dead,
19798 ;; this should not create any new dependencies.  Pass on the sub-word
19799 ;; versions if we're concerned about partial register stalls.
19800
19801 (define_peephole2
19802   [(set (match_operand 0 "flags_reg_operand" "")
19803         (match_operator 1 "compare_operator"
19804           [(and:SI (match_operand:SI 2 "register_operand" "")
19805                    (match_operand:SI 3 "immediate_operand" ""))
19806            (const_int 0)]))]
19807   "ix86_match_ccmode (insn, CCNOmode)
19808    && (true_regnum (operands[2]) != 0
19809        || satisfies_constraint_K (operands[3]))
19810    && peep2_reg_dead_p (1, operands[2])"
19811   [(parallel
19812      [(set (match_dup 0)
19813            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19814                             (const_int 0)]))
19815       (set (match_dup 2)
19816            (and:SI (match_dup 2) (match_dup 3)))])]
19817   "")
19818
19819 ;; We don't need to handle HImode case, because it will be promoted to SImode
19820 ;; on ! TARGET_PARTIAL_REG_STALL
19821
19822 (define_peephole2
19823   [(set (match_operand 0 "flags_reg_operand" "")
19824         (match_operator 1 "compare_operator"
19825           [(and:QI (match_operand:QI 2 "register_operand" "")
19826                    (match_operand:QI 3 "immediate_operand" ""))
19827            (const_int 0)]))]
19828   "! TARGET_PARTIAL_REG_STALL
19829    && ix86_match_ccmode (insn, CCNOmode)
19830    && true_regnum (operands[2]) != 0
19831    && peep2_reg_dead_p (1, operands[2])"
19832   [(parallel
19833      [(set (match_dup 0)
19834            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19835                             (const_int 0)]))
19836       (set (match_dup 2)
19837            (and:QI (match_dup 2) (match_dup 3)))])]
19838   "")
19839
19840 (define_peephole2
19841   [(set (match_operand 0 "flags_reg_operand" "")
19842         (match_operator 1 "compare_operator"
19843           [(and:SI
19844              (zero_extract:SI
19845                (match_operand 2 "ext_register_operand" "")
19846                (const_int 8)
19847                (const_int 8))
19848              (match_operand 3 "const_int_operand" ""))
19849            (const_int 0)]))]
19850   "! TARGET_PARTIAL_REG_STALL
19851    && ix86_match_ccmode (insn, CCNOmode)
19852    && true_regnum (operands[2]) != 0
19853    && peep2_reg_dead_p (1, operands[2])"
19854   [(parallel [(set (match_dup 0)
19855                    (match_op_dup 1
19856                      [(and:SI
19857                         (zero_extract:SI
19858                           (match_dup 2)
19859                           (const_int 8)
19860                           (const_int 8))
19861                         (match_dup 3))
19862                       (const_int 0)]))
19863               (set (zero_extract:SI (match_dup 2)
19864                                     (const_int 8)
19865                                     (const_int 8))
19866                    (and:SI 
19867                      (zero_extract:SI
19868                        (match_dup 2)
19869                        (const_int 8)
19870                        (const_int 8))
19871                      (match_dup 3)))])]
19872   "")
19873
19874 ;; Don't do logical operations with memory inputs.
19875 (define_peephole2
19876   [(match_scratch:SI 2 "r")
19877    (parallel [(set (match_operand:SI 0 "register_operand" "")
19878                    (match_operator:SI 3 "arith_or_logical_operator"
19879                      [(match_dup 0)
19880                       (match_operand:SI 1 "memory_operand" "")]))
19881               (clobber (reg:CC FLAGS_REG))])]
19882   "! optimize_size && ! TARGET_READ_MODIFY"
19883   [(set (match_dup 2) (match_dup 1))
19884    (parallel [(set (match_dup 0)
19885                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19886               (clobber (reg:CC FLAGS_REG))])]
19887   "")
19888
19889 (define_peephole2
19890   [(match_scratch:SI 2 "r")
19891    (parallel [(set (match_operand:SI 0 "register_operand" "")
19892                    (match_operator:SI 3 "arith_or_logical_operator"
19893                      [(match_operand:SI 1 "memory_operand" "")
19894                       (match_dup 0)]))
19895               (clobber (reg:CC FLAGS_REG))])]
19896   "! optimize_size && ! TARGET_READ_MODIFY"
19897   [(set (match_dup 2) (match_dup 1))
19898    (parallel [(set (match_dup 0)
19899                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19900               (clobber (reg:CC FLAGS_REG))])]
19901   "")
19902
19903 ; Don't do logical operations with memory outputs
19904 ;
19905 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19906 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19907 ; the same decoder scheduling characteristics as the original.
19908
19909 (define_peephole2
19910   [(match_scratch:SI 2 "r")
19911    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19912                    (match_operator:SI 3 "arith_or_logical_operator"
19913                      [(match_dup 0)
19914                       (match_operand:SI 1 "nonmemory_operand" "")]))
19915               (clobber (reg:CC FLAGS_REG))])]
19916   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19917   [(set (match_dup 2) (match_dup 0))
19918    (parallel [(set (match_dup 2)
19919                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19920               (clobber (reg:CC FLAGS_REG))])
19921    (set (match_dup 0) (match_dup 2))]
19922   "")
19923
19924 (define_peephole2
19925   [(match_scratch:SI 2 "r")
19926    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19927                    (match_operator:SI 3 "arith_or_logical_operator"
19928                      [(match_operand:SI 1 "nonmemory_operand" "")
19929                       (match_dup 0)]))
19930               (clobber (reg:CC FLAGS_REG))])]
19931   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19932   [(set (match_dup 2) (match_dup 0))
19933    (parallel [(set (match_dup 2)
19934                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19935               (clobber (reg:CC FLAGS_REG))])
19936    (set (match_dup 0) (match_dup 2))]
19937   "")
19938
19939 ;; Attempt to always use XOR for zeroing registers.
19940 (define_peephole2
19941   [(set (match_operand 0 "register_operand" "")
19942         (match_operand 1 "const0_operand" ""))]
19943   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19944    && (! TARGET_USE_MOV0 || optimize_size)
19945    && GENERAL_REG_P (operands[0])
19946    && peep2_regno_dead_p (0, FLAGS_REG)"
19947   [(parallel [(set (match_dup 0) (const_int 0))
19948               (clobber (reg:CC FLAGS_REG))])]
19949 {
19950   operands[0] = gen_lowpart (word_mode, operands[0]);
19951 })
19952
19953 (define_peephole2
19954   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19955         (const_int 0))]
19956   "(GET_MODE (operands[0]) == QImode
19957     || GET_MODE (operands[0]) == HImode)
19958    && (! TARGET_USE_MOV0 || optimize_size)
19959    && peep2_regno_dead_p (0, FLAGS_REG)"
19960   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19961               (clobber (reg:CC FLAGS_REG))])])
19962
19963 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19964 (define_peephole2
19965   [(set (match_operand 0 "register_operand" "")
19966         (const_int -1))]
19967   "(GET_MODE (operands[0]) == HImode
19968     || GET_MODE (operands[0]) == SImode 
19969     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19970    && (optimize_size || TARGET_PENTIUM)
19971    && peep2_regno_dead_p (0, FLAGS_REG)"
19972   [(parallel [(set (match_dup 0) (const_int -1))
19973               (clobber (reg:CC FLAGS_REG))])]
19974   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19975                               operands[0]);")
19976
19977 ;; Attempt to convert simple leas to adds. These can be created by
19978 ;; move expanders.
19979 (define_peephole2
19980   [(set (match_operand:SI 0 "register_operand" "")
19981         (plus:SI (match_dup 0)
19982                  (match_operand:SI 1 "nonmemory_operand" "")))]
19983   "peep2_regno_dead_p (0, FLAGS_REG)"
19984   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19985               (clobber (reg:CC FLAGS_REG))])]
19986   "")
19987
19988 (define_peephole2
19989   [(set (match_operand:SI 0 "register_operand" "")
19990         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19991                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19992   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19993   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19994               (clobber (reg:CC FLAGS_REG))])]
19995   "operands[2] = gen_lowpart (SImode, operands[2]);")
19996
19997 (define_peephole2
19998   [(set (match_operand:DI 0 "register_operand" "")
19999         (plus:DI (match_dup 0)
20000                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20001   "peep2_regno_dead_p (0, FLAGS_REG)"
20002   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20003               (clobber (reg:CC FLAGS_REG))])]
20004   "")
20005
20006 (define_peephole2
20007   [(set (match_operand:SI 0 "register_operand" "")
20008         (mult:SI (match_dup 0)
20009                  (match_operand:SI 1 "const_int_operand" "")))]
20010   "exact_log2 (INTVAL (operands[1])) >= 0
20011    && peep2_regno_dead_p (0, FLAGS_REG)"
20012   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20013               (clobber (reg:CC FLAGS_REG))])]
20014   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20015
20016 (define_peephole2
20017   [(set (match_operand:DI 0 "register_operand" "")
20018         (mult:DI (match_dup 0)
20019                  (match_operand:DI 1 "const_int_operand" "")))]
20020   "exact_log2 (INTVAL (operands[1])) >= 0
20021    && peep2_regno_dead_p (0, FLAGS_REG)"
20022   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20023               (clobber (reg:CC FLAGS_REG))])]
20024   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20025
20026 (define_peephole2
20027   [(set (match_operand:SI 0 "register_operand" "")
20028         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20029                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20030   "exact_log2 (INTVAL (operands[2])) >= 0
20031    && REGNO (operands[0]) == REGNO (operands[1])
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[2])));")
20036
20037 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20038 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20039 ;; many CPUs it is also faster, since special hardware to avoid esp
20040 ;; dependencies is present.
20041
20042 ;; While some of these conversions may be done using splitters, we use peepholes
20043 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20044
20045 ;; Convert prologue esp subtractions to push.
20046 ;; We need register to push.  In order to keep verify_flow_info happy we have
20047 ;; two choices
20048 ;; - use scratch and clobber it in order to avoid dependencies
20049 ;; - use already live register
20050 ;; We can't use the second way right now, since there is no reliable way how to
20051 ;; verify that given register is live.  First choice will also most likely in
20052 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20053 ;; call clobbered registers are dead.  We may want to use base pointer as an
20054 ;; alternative when no register is available later.
20055
20056 (define_peephole2
20057   [(match_scratch:SI 0 "r")
20058    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20059               (clobber (reg:CC FLAGS_REG))
20060               (clobber (mem:BLK (scratch)))])]
20061   "optimize_size || !TARGET_SUB_ESP_4"
20062   [(clobber (match_dup 0))
20063    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20064               (clobber (mem:BLK (scratch)))])])
20065
20066 (define_peephole2
20067   [(match_scratch:SI 0 "r")
20068    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20069               (clobber (reg:CC FLAGS_REG))
20070               (clobber (mem:BLK (scratch)))])]
20071   "optimize_size || !TARGET_SUB_ESP_8"
20072   [(clobber (match_dup 0))
20073    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20074    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20075               (clobber (mem:BLK (scratch)))])])
20076
20077 ;; Convert esp subtractions to push.
20078 (define_peephole2
20079   [(match_scratch:SI 0 "r")
20080    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20081               (clobber (reg:CC FLAGS_REG))])]
20082   "optimize_size || !TARGET_SUB_ESP_4"
20083   [(clobber (match_dup 0))
20084    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20085
20086 (define_peephole2
20087   [(match_scratch:SI 0 "r")
20088    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20089               (clobber (reg:CC FLAGS_REG))])]
20090   "optimize_size || !TARGET_SUB_ESP_8"
20091   [(clobber (match_dup 0))
20092    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20093    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20094
20095 ;; Convert epilogue deallocator to pop.
20096 (define_peephole2
20097   [(match_scratch:SI 0 "r")
20098    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20099               (clobber (reg:CC FLAGS_REG))
20100               (clobber (mem:BLK (scratch)))])]
20101   "optimize_size || !TARGET_ADD_ESP_4"
20102   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20103               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20104               (clobber (mem:BLK (scratch)))])]
20105   "")
20106
20107 ;; Two pops case is tricky, since pop causes dependency on destination register.
20108 ;; We use two registers if available.
20109 (define_peephole2
20110   [(match_scratch:SI 0 "r")
20111    (match_scratch:SI 1 "r")
20112    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20113               (clobber (reg:CC FLAGS_REG))
20114               (clobber (mem:BLK (scratch)))])]
20115   "optimize_size || !TARGET_ADD_ESP_8"
20116   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20117               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20118               (clobber (mem:BLK (scratch)))])
20119    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20120               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20121   "")
20122
20123 (define_peephole2
20124   [(match_scratch:SI 0 "r")
20125    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20126               (clobber (reg:CC FLAGS_REG))
20127               (clobber (mem:BLK (scratch)))])]
20128   "optimize_size"
20129   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20130               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20131               (clobber (mem:BLK (scratch)))])
20132    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20133               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20134   "")
20135
20136 ;; Convert esp additions to pop.
20137 (define_peephole2
20138   [(match_scratch:SI 0 "r")
20139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20140               (clobber (reg:CC FLAGS_REG))])]
20141   ""
20142   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20143               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20144   "")
20145
20146 ;; Two pops case is tricky, since pop causes dependency on destination register.
20147 ;; We use two registers if available.
20148 (define_peephole2
20149   [(match_scratch:SI 0 "r")
20150    (match_scratch:SI 1 "r")
20151    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20152               (clobber (reg:CC FLAGS_REG))])]
20153   ""
20154   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20155               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20156    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20157               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20158   "")
20159
20160 (define_peephole2
20161   [(match_scratch:SI 0 "r")
20162    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20163               (clobber (reg:CC FLAGS_REG))])]
20164   "optimize_size"
20165   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20166               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20167    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20168               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20169   "")
20170 \f
20171 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20172 ;; required and register dies.  Similarly for 128 to plus -128.
20173 (define_peephole2
20174   [(set (match_operand 0 "flags_reg_operand" "")
20175         (match_operator 1 "compare_operator"
20176           [(match_operand 2 "register_operand" "")
20177            (match_operand 3 "const_int_operand" "")]))]
20178   "(INTVAL (operands[3]) == -1
20179     || INTVAL (operands[3]) == 1
20180     || INTVAL (operands[3]) == 128)
20181    && ix86_match_ccmode (insn, CCGCmode)
20182    && peep2_reg_dead_p (1, operands[2])"
20183   [(parallel [(set (match_dup 0)
20184                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20185               (clobber (match_dup 2))])]
20186   "")
20187 \f
20188 (define_peephole2
20189   [(match_scratch:DI 0 "r")
20190    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20191               (clobber (reg:CC FLAGS_REG))
20192               (clobber (mem:BLK (scratch)))])]
20193   "optimize_size || !TARGET_SUB_ESP_4"
20194   [(clobber (match_dup 0))
20195    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20196               (clobber (mem:BLK (scratch)))])])
20197
20198 (define_peephole2
20199   [(match_scratch:DI 0 "r")
20200    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20201               (clobber (reg:CC FLAGS_REG))
20202               (clobber (mem:BLK (scratch)))])]
20203   "optimize_size || !TARGET_SUB_ESP_8"
20204   [(clobber (match_dup 0))
20205    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20206    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20207               (clobber (mem:BLK (scratch)))])])
20208
20209 ;; Convert esp subtractions to push.
20210 (define_peephole2
20211   [(match_scratch:DI 0 "r")
20212    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20213               (clobber (reg:CC FLAGS_REG))])]
20214   "optimize_size || !TARGET_SUB_ESP_4"
20215   [(clobber (match_dup 0))
20216    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20217
20218 (define_peephole2
20219   [(match_scratch:DI 0 "r")
20220    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20221               (clobber (reg:CC FLAGS_REG))])]
20222   "optimize_size || !TARGET_SUB_ESP_8"
20223   [(clobber (match_dup 0))
20224    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20225    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20226
20227 ;; Convert epilogue deallocator to pop.
20228 (define_peephole2
20229   [(match_scratch:DI 0 "r")
20230    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20231               (clobber (reg:CC FLAGS_REG))
20232               (clobber (mem:BLK (scratch)))])]
20233   "optimize_size || !TARGET_ADD_ESP_4"
20234   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20235               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20236               (clobber (mem:BLK (scratch)))])]
20237   "")
20238
20239 ;; Two pops case is tricky, since pop causes dependency on destination register.
20240 ;; We use two registers if available.
20241 (define_peephole2
20242   [(match_scratch:DI 0 "r")
20243    (match_scratch:DI 1 "r")
20244    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20245               (clobber (reg:CC FLAGS_REG))
20246               (clobber (mem:BLK (scratch)))])]
20247   "optimize_size || !TARGET_ADD_ESP_8"
20248   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20249               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20250               (clobber (mem:BLK (scratch)))])
20251    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20252               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20253   "")
20254
20255 (define_peephole2
20256   [(match_scratch:DI 0 "r")
20257    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20258               (clobber (reg:CC FLAGS_REG))
20259               (clobber (mem:BLK (scratch)))])]
20260   "optimize_size"
20261   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20262               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20263               (clobber (mem:BLK (scratch)))])
20264    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20265               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20266   "")
20267
20268 ;; Convert esp additions to pop.
20269 (define_peephole2
20270   [(match_scratch:DI 0 "r")
20271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20272               (clobber (reg:CC FLAGS_REG))])]
20273   ""
20274   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20275               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20276   "")
20277
20278 ;; Two pops case is tricky, since pop causes dependency on destination register.
20279 ;; We use two registers if available.
20280 (define_peephole2
20281   [(match_scratch:DI 0 "r")
20282    (match_scratch:DI 1 "r")
20283    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20284               (clobber (reg:CC FLAGS_REG))])]
20285   ""
20286   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20287               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20288    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20289               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20290   "")
20291
20292 (define_peephole2
20293   [(match_scratch:DI 0 "r")
20294    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20295               (clobber (reg:CC FLAGS_REG))])]
20296   "optimize_size"
20297   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20298               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20299    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20300               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20301   "")
20302 \f
20303 ;; Convert imul by three, five and nine into lea
20304 (define_peephole2
20305   [(parallel
20306     [(set (match_operand:SI 0 "register_operand" "")
20307           (mult:SI (match_operand:SI 1 "register_operand" "")
20308                    (match_operand:SI 2 "const_int_operand" "")))
20309      (clobber (reg:CC FLAGS_REG))])]
20310   "INTVAL (operands[2]) == 3
20311    || INTVAL (operands[2]) == 5
20312    || INTVAL (operands[2]) == 9"
20313   [(set (match_dup 0)
20314         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20315                  (match_dup 1)))]
20316   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20317
20318 (define_peephole2
20319   [(parallel
20320     [(set (match_operand:SI 0 "register_operand" "")
20321           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20322                    (match_operand:SI 2 "const_int_operand" "")))
20323      (clobber (reg:CC FLAGS_REG))])]
20324   "!optimize_size 
20325    && (INTVAL (operands[2]) == 3
20326        || INTVAL (operands[2]) == 5
20327        || INTVAL (operands[2]) == 9)"
20328   [(set (match_dup 0) (match_dup 1))
20329    (set (match_dup 0)
20330         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20331                  (match_dup 0)))]
20332   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20333
20334 (define_peephole2
20335   [(parallel
20336     [(set (match_operand:DI 0 "register_operand" "")
20337           (mult:DI (match_operand:DI 1 "register_operand" "")
20338                    (match_operand:DI 2 "const_int_operand" "")))
20339      (clobber (reg:CC FLAGS_REG))])]
20340   "TARGET_64BIT
20341    && (INTVAL (operands[2]) == 3
20342        || INTVAL (operands[2]) == 5
20343        || INTVAL (operands[2]) == 9)"
20344   [(set (match_dup 0)
20345         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20346                  (match_dup 1)))]
20347   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20348
20349 (define_peephole2
20350   [(parallel
20351     [(set (match_operand:DI 0 "register_operand" "")
20352           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20353                    (match_operand:DI 2 "const_int_operand" "")))
20354      (clobber (reg:CC FLAGS_REG))])]
20355   "TARGET_64BIT
20356    && !optimize_size 
20357    && (INTVAL (operands[2]) == 3
20358        || INTVAL (operands[2]) == 5
20359        || INTVAL (operands[2]) == 9)"
20360   [(set (match_dup 0) (match_dup 1))
20361    (set (match_dup 0)
20362         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20363                  (match_dup 0)))]
20364   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20365
20366 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20367 ;; imul $32bit_imm, reg, reg is direct decoded.
20368 (define_peephole2
20369   [(match_scratch:DI 3 "r")
20370    (parallel [(set (match_operand:DI 0 "register_operand" "")
20371                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20372                             (match_operand:DI 2 "immediate_operand" "")))
20373               (clobber (reg:CC FLAGS_REG))])]
20374   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20375    && !satisfies_constraint_K (operands[2])"
20376   [(set (match_dup 3) (match_dup 1))
20377    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20378               (clobber (reg:CC FLAGS_REG))])]
20379 "")
20380
20381 (define_peephole2
20382   [(match_scratch:SI 3 "r")
20383    (parallel [(set (match_operand:SI 0 "register_operand" "")
20384                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20385                             (match_operand:SI 2 "immediate_operand" "")))
20386               (clobber (reg:CC FLAGS_REG))])]
20387   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20388    && !satisfies_constraint_K (operands[2])"
20389   [(set (match_dup 3) (match_dup 1))
20390    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20391               (clobber (reg:CC FLAGS_REG))])]
20392 "")
20393
20394 (define_peephole2
20395   [(match_scratch:SI 3 "r")
20396    (parallel [(set (match_operand:DI 0 "register_operand" "")
20397                    (zero_extend:DI
20398                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20399                               (match_operand:SI 2 "immediate_operand" ""))))
20400               (clobber (reg:CC FLAGS_REG))])]
20401   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402    && !satisfies_constraint_K (operands[2])"
20403   [(set (match_dup 3) (match_dup 1))
20404    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20405               (clobber (reg:CC FLAGS_REG))])]
20406 "")
20407
20408 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20409 ;; Convert it into imul reg, reg
20410 ;; It would be better to force assembler to encode instruction using long
20411 ;; immediate, but there is apparently no way to do so.
20412 (define_peephole2
20413   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20414                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20415                             (match_operand:DI 2 "const_int_operand" "")))
20416               (clobber (reg:CC FLAGS_REG))])
20417    (match_scratch:DI 3 "r")]
20418   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20419    && satisfies_constraint_K (operands[2])"
20420   [(set (match_dup 3) (match_dup 2))
20421    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20422               (clobber (reg:CC FLAGS_REG))])]
20423 {
20424   if (!rtx_equal_p (operands[0], operands[1]))
20425     emit_move_insn (operands[0], operands[1]);
20426 })
20427
20428 (define_peephole2
20429   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20430                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20431                             (match_operand:SI 2 "const_int_operand" "")))
20432               (clobber (reg:CC FLAGS_REG))])
20433    (match_scratch:SI 3 "r")]
20434   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20435    && satisfies_constraint_K (operands[2])"
20436   [(set (match_dup 3) (match_dup 2))
20437    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20438               (clobber (reg:CC FLAGS_REG))])]
20439 {
20440   if (!rtx_equal_p (operands[0], operands[1]))
20441     emit_move_insn (operands[0], operands[1]);
20442 })
20443
20444 (define_peephole2
20445   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20446                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20447                             (match_operand:HI 2 "immediate_operand" "")))
20448               (clobber (reg:CC FLAGS_REG))])
20449    (match_scratch:HI 3 "r")]
20450   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20451   [(set (match_dup 3) (match_dup 2))
20452    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20453               (clobber (reg:CC FLAGS_REG))])]
20454 {
20455   if (!rtx_equal_p (operands[0], operands[1]))
20456     emit_move_insn (operands[0], operands[1]);
20457 })
20458
20459 ;; After splitting up read-modify operations, array accesses with memory
20460 ;; operands might end up in form:
20461 ;;  sall    $2, %eax
20462 ;;  movl    4(%esp), %edx
20463 ;;  addl    %edx, %eax
20464 ;; instead of pre-splitting:
20465 ;;  sall    $2, %eax
20466 ;;  addl    4(%esp), %eax
20467 ;; Turn it into:
20468 ;;  movl    4(%esp), %edx
20469 ;;  leal    (%edx,%eax,4), %eax
20470
20471 (define_peephole2
20472   [(parallel [(set (match_operand 0 "register_operand" "")
20473                    (ashift (match_operand 1 "register_operand" "")
20474                            (match_operand 2 "const_int_operand" "")))
20475                (clobber (reg:CC FLAGS_REG))])
20476    (set (match_operand 3 "register_operand")
20477         (match_operand 4 "x86_64_general_operand" ""))
20478    (parallel [(set (match_operand 5 "register_operand" "")
20479                    (plus (match_operand 6 "register_operand" "")
20480                          (match_operand 7 "register_operand" "")))
20481                    (clobber (reg:CC FLAGS_REG))])]
20482   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20483    /* Validate MODE for lea.  */
20484    && ((!TARGET_PARTIAL_REG_STALL
20485         && (GET_MODE (operands[0]) == QImode
20486             || GET_MODE (operands[0]) == HImode))
20487        || GET_MODE (operands[0]) == SImode 
20488        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20489    /* We reorder load and the shift.  */
20490    && !rtx_equal_p (operands[1], operands[3])
20491    && !reg_overlap_mentioned_p (operands[0], operands[4])
20492    /* Last PLUS must consist of operand 0 and 3.  */
20493    && !rtx_equal_p (operands[0], operands[3])
20494    && (rtx_equal_p (operands[3], operands[6])
20495        || rtx_equal_p (operands[3], operands[7]))
20496    && (rtx_equal_p (operands[0], operands[6])
20497        || rtx_equal_p (operands[0], operands[7]))
20498    /* The intermediate operand 0 must die or be same as output.  */
20499    && (rtx_equal_p (operands[0], operands[5])
20500        || peep2_reg_dead_p (3, operands[0]))"
20501   [(set (match_dup 3) (match_dup 4))
20502    (set (match_dup 0) (match_dup 1))]
20503 {
20504   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20505   int scale = 1 << INTVAL (operands[2]);
20506   rtx index = gen_lowpart (Pmode, operands[1]);
20507   rtx base = gen_lowpart (Pmode, operands[3]);
20508   rtx dest = gen_lowpart (mode, operands[5]);
20509
20510   operands[1] = gen_rtx_PLUS (Pmode, base,
20511                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20512   if (mode != Pmode)
20513     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20514   operands[0] = dest;
20515 })
20516 \f
20517 ;; Call-value patterns last so that the wildcard operand does not
20518 ;; disrupt insn-recog's switch tables.
20519
20520 (define_insn "*call_value_pop_0"
20521   [(set (match_operand 0 "" "")
20522         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20523               (match_operand:SI 2 "" "")))
20524    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20525                             (match_operand:SI 3 "immediate_operand" "")))]
20526   "!TARGET_64BIT"
20527 {
20528   if (SIBLING_CALL_P (insn))
20529     return "jmp\t%P1";
20530   else
20531     return "call\t%P1";
20532 }
20533   [(set_attr "type" "callv")])
20534
20535 (define_insn "*call_value_pop_1"
20536   [(set (match_operand 0 "" "")
20537         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20538               (match_operand:SI 2 "" "")))
20539    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20540                             (match_operand:SI 3 "immediate_operand" "i")))]
20541   "!TARGET_64BIT"
20542 {
20543   if (constant_call_address_operand (operands[1], Pmode))
20544     {
20545       if (SIBLING_CALL_P (insn))
20546         return "jmp\t%P1";
20547       else
20548         return "call\t%P1";
20549     }
20550   if (SIBLING_CALL_P (insn))
20551     return "jmp\t%A1";
20552   else
20553     return "call\t%A1";
20554 }
20555   [(set_attr "type" "callv")])
20556
20557 (define_insn "*call_value_0"
20558   [(set (match_operand 0 "" "")
20559         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20560               (match_operand:SI 2 "" "")))]
20561   "!TARGET_64BIT"
20562 {
20563   if (SIBLING_CALL_P (insn))
20564     return "jmp\t%P1";
20565   else
20566     return "call\t%P1";
20567 }
20568   [(set_attr "type" "callv")])
20569
20570 (define_insn "*call_value_0_rex64"
20571   [(set (match_operand 0 "" "")
20572         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20573               (match_operand:DI 2 "const_int_operand" "")))]
20574   "TARGET_64BIT"
20575 {
20576   if (SIBLING_CALL_P (insn))
20577     return "jmp\t%P1";
20578   else
20579     return "call\t%P1";
20580 }
20581   [(set_attr "type" "callv")])
20582
20583 (define_insn "*call_value_1"
20584   [(set (match_operand 0 "" "")
20585         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20586               (match_operand:SI 2 "" "")))]
20587   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20588 {
20589   if (constant_call_address_operand (operands[1], Pmode))
20590     return "call\t%P1";
20591   return "call\t%A1";
20592 }
20593   [(set_attr "type" "callv")])
20594
20595 (define_insn "*sibcall_value_1"
20596   [(set (match_operand 0 "" "")
20597         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20598               (match_operand:SI 2 "" "")))]
20599   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20600 {
20601   if (constant_call_address_operand (operands[1], Pmode))
20602     return "jmp\t%P1";
20603   return "jmp\t%A1";
20604 }
20605   [(set_attr "type" "callv")])
20606
20607 (define_insn "*call_value_1_rex64"
20608   [(set (match_operand 0 "" "")
20609         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20610               (match_operand:DI 2 "" "")))]
20611   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20612 {
20613   if (constant_call_address_operand (operands[1], Pmode))
20614     return "call\t%P1";
20615   return "call\t%A1";
20616 }
20617   [(set_attr "type" "callv")])
20618
20619 (define_insn "*sibcall_value_1_rex64"
20620   [(set (match_operand 0 "" "")
20621         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20622               (match_operand:DI 2 "" "")))]
20623   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20624   "jmp\t%P1"
20625   [(set_attr "type" "callv")])
20626
20627 (define_insn "*sibcall_value_1_rex64_v"
20628   [(set (match_operand 0 "" "")
20629         (call (mem:QI (reg:DI 40))
20630               (match_operand:DI 1 "" "")))]
20631   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20632   "jmp\t*%%r11"
20633   [(set_attr "type" "callv")])
20634 \f
20635 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20636 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20637 ;; caught for use by garbage collectors and the like.  Using an insn that
20638 ;; maps to SIGILL makes it more likely the program will rightfully die.
20639 ;; Keeping with tradition, "6" is in honor of #UD.
20640 (define_insn "trap"
20641   [(trap_if (const_int 1) (const_int 6))]
20642   ""
20643   { return ASM_SHORT "0x0b0f"; }
20644   [(set_attr "length" "2")])
20645
20646 (define_expand "sse_prologue_save"
20647   [(parallel [(set (match_operand:BLK 0 "" "")
20648                    (unspec:BLK [(reg:DI 21)
20649                                 (reg:DI 22)
20650                                 (reg:DI 23)
20651                                 (reg:DI 24)
20652                                 (reg:DI 25)
20653                                 (reg:DI 26)
20654                                 (reg:DI 27)
20655                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20656               (use (match_operand:DI 1 "register_operand" ""))
20657               (use (match_operand:DI 2 "immediate_operand" ""))
20658               (use (label_ref:DI (match_operand 3 "" "")))])]
20659   "TARGET_64BIT"
20660   "")
20661
20662 (define_insn "*sse_prologue_save_insn"
20663   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20664                           (match_operand:DI 4 "const_int_operand" "n")))
20665         (unspec:BLK [(reg:DI 21)
20666                      (reg:DI 22)
20667                      (reg:DI 23)
20668                      (reg:DI 24)
20669                      (reg:DI 25)
20670                      (reg:DI 26)
20671                      (reg:DI 27)
20672                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20673    (use (match_operand:DI 1 "register_operand" "r"))
20674    (use (match_operand:DI 2 "const_int_operand" "i"))
20675    (use (label_ref:DI (match_operand 3 "" "X")))]
20676   "TARGET_64BIT
20677    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20678    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20679   "*
20680 {
20681   int i;
20682   operands[0] = gen_rtx_MEM (Pmode,
20683                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20684   output_asm_insn (\"jmp\\t%A1\", operands);
20685   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20686     {
20687       operands[4] = adjust_address (operands[0], DImode, i*16);
20688       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20689       PUT_MODE (operands[4], TImode);
20690       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20691         output_asm_insn (\"rex\", operands);
20692       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20693     }
20694   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20695                              CODE_LABEL_NUMBER (operands[3]));
20696   RET;
20697 }
20698   "
20699   [(set_attr "type" "other")
20700    (set_attr "length_immediate" "0")
20701    (set_attr "length_address" "0")
20702    (set_attr "length" "135")
20703    (set_attr "memory" "store")
20704    (set_attr "modrm" "0")
20705    (set_attr "mode" "DI")])
20706
20707 (define_expand "prefetch"
20708   [(prefetch (match_operand 0 "address_operand" "")
20709              (match_operand:SI 1 "const_int_operand" "")
20710              (match_operand:SI 2 "const_int_operand" ""))]
20711   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20712 {
20713   int rw = INTVAL (operands[1]);
20714   int locality = INTVAL (operands[2]);
20715
20716   gcc_assert (rw == 0 || rw == 1);
20717   gcc_assert (locality >= 0 && locality <= 3);
20718   gcc_assert (GET_MODE (operands[0]) == Pmode
20719               || GET_MODE (operands[0]) == VOIDmode);
20720
20721   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20722      supported by SSE counterpart or the SSE prefetch is not available
20723      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20724      of locality.  */
20725   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20726     operands[2] = GEN_INT (3);
20727   else
20728     operands[1] = const0_rtx;
20729 })
20730
20731 (define_insn "*prefetch_sse"
20732   [(prefetch (match_operand:SI 0 "address_operand" "p")
20733              (const_int 0)
20734              (match_operand:SI 1 "const_int_operand" ""))]
20735   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20736 {
20737   static const char * const patterns[4] = {
20738    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20739   };
20740
20741   int locality = INTVAL (operands[1]);
20742   gcc_assert (locality >= 0 && locality <= 3);
20743
20744   return patterns[locality];  
20745 }
20746   [(set_attr "type" "sse")
20747    (set_attr "memory" "none")])
20748
20749 (define_insn "*prefetch_sse_rex"
20750   [(prefetch (match_operand:DI 0 "address_operand" "p")
20751              (const_int 0)
20752              (match_operand:SI 1 "const_int_operand" ""))]
20753   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20754 {
20755   static const char * const patterns[4] = {
20756    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20757   };
20758
20759   int locality = INTVAL (operands[1]);
20760   gcc_assert (locality >= 0 && locality <= 3);
20761
20762   return patterns[locality];  
20763 }
20764   [(set_attr "type" "sse")
20765    (set_attr "memory" "none")])
20766
20767 (define_insn "*prefetch_3dnow"
20768   [(prefetch (match_operand:SI 0 "address_operand" "p")
20769              (match_operand:SI 1 "const_int_operand" "n")
20770              (const_int 3))]
20771   "TARGET_3DNOW && !TARGET_64BIT"
20772 {
20773   if (INTVAL (operands[1]) == 0)
20774     return "prefetch\t%a0";
20775   else
20776     return "prefetchw\t%a0";
20777 }
20778   [(set_attr "type" "mmx")
20779    (set_attr "memory" "none")])
20780
20781 (define_insn "*prefetch_3dnow_rex"
20782   [(prefetch (match_operand:DI 0 "address_operand" "p")
20783              (match_operand:SI 1 "const_int_operand" "n")
20784              (const_int 3))]
20785   "TARGET_3DNOW && TARGET_64BIT"
20786 {
20787   if (INTVAL (operands[1]) == 0)
20788     return "prefetch\t%a0";
20789   else
20790     return "prefetchw\t%a0";
20791 }
20792   [(set_attr "type" "mmx")
20793    (set_attr "memory" "none")])
20794
20795 (define_expand "stack_protect_set"
20796   [(match_operand 0 "memory_operand" "")
20797    (match_operand 1 "memory_operand" "")]
20798   ""
20799 {
20800 #ifdef TARGET_THREAD_SSP_OFFSET
20801   if (TARGET_64BIT)
20802     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20803                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20804   else
20805     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20806                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20807 #else
20808   if (TARGET_64BIT)
20809     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20810   else
20811     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20812 #endif
20813   DONE;
20814 })
20815
20816 (define_insn "stack_protect_set_si"
20817   [(set (match_operand:SI 0 "memory_operand" "=m")
20818         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20819    (set (match_scratch:SI 2 "=&r") (const_int 0))
20820    (clobber (reg:CC FLAGS_REG))]
20821   ""
20822   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20823   [(set_attr "type" "multi")])
20824
20825 (define_insn "stack_protect_set_di"
20826   [(set (match_operand:DI 0 "memory_operand" "=m")
20827         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20828    (set (match_scratch:DI 2 "=&r") (const_int 0))
20829    (clobber (reg:CC FLAGS_REG))]
20830   "TARGET_64BIT"
20831   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20832   [(set_attr "type" "multi")])
20833
20834 (define_insn "stack_tls_protect_set_si"
20835   [(set (match_operand:SI 0 "memory_operand" "=m")
20836         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20837    (set (match_scratch:SI 2 "=&r") (const_int 0))
20838    (clobber (reg:CC FLAGS_REG))]
20839   ""
20840   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20841   [(set_attr "type" "multi")])
20842
20843 (define_insn "stack_tls_protect_set_di"
20844   [(set (match_operand:DI 0 "memory_operand" "=m")
20845         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20846    (set (match_scratch:DI 2 "=&r") (const_int 0))
20847    (clobber (reg:CC FLAGS_REG))]
20848   "TARGET_64BIT"
20849   {
20850      /* The kernel uses a different segment register for performance reasons; a
20851         system call would not have to trash the userspace segment register,
20852         which would be expensive */
20853      if (ix86_cmodel != CM_KERNEL)
20854         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20855      else
20856         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20857   }
20858   [(set_attr "type" "multi")])
20859
20860 (define_expand "stack_protect_test"
20861   [(match_operand 0 "memory_operand" "")
20862    (match_operand 1 "memory_operand" "")
20863    (match_operand 2 "" "")]
20864   ""
20865 {
20866   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20867   ix86_compare_op0 = operands[0];
20868   ix86_compare_op1 = operands[1];
20869   ix86_compare_emitted = flags;
20870
20871 #ifdef TARGET_THREAD_SSP_OFFSET
20872   if (TARGET_64BIT)
20873     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20874                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20875   else
20876     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20877                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20878 #else
20879   if (TARGET_64BIT)
20880     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20881   else
20882     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20883 #endif
20884   emit_jump_insn (gen_beq (operands[2]));
20885   DONE;
20886 })
20887
20888 (define_insn "stack_protect_test_si"
20889   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20890         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20891                      (match_operand:SI 2 "memory_operand" "m")]
20892                     UNSPEC_SP_TEST))
20893    (clobber (match_scratch:SI 3 "=&r"))]
20894   ""
20895   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20896   [(set_attr "type" "multi")])
20897
20898 (define_insn "stack_protect_test_di"
20899   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20900         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20901                      (match_operand:DI 2 "memory_operand" "m")]
20902                     UNSPEC_SP_TEST))
20903    (clobber (match_scratch:DI 3 "=&r"))]
20904   "TARGET_64BIT"
20905   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20906   [(set_attr "type" "multi")])
20907
20908 (define_insn "stack_tls_protect_test_si"
20909   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20910         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20911                      (match_operand:SI 2 "const_int_operand" "i")]
20912                     UNSPEC_SP_TLS_TEST))
20913    (clobber (match_scratch:SI 3 "=r"))]
20914   ""
20915   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20916   [(set_attr "type" "multi")])
20917
20918 (define_insn "stack_tls_protect_test_di"
20919   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20920         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20921                      (match_operand:DI 2 "const_int_operand" "i")]
20922                     UNSPEC_SP_TLS_TEST))
20923    (clobber (match_scratch:DI 3 "=r"))]
20924   "TARGET_64BIT"
20925   {
20926      /* The kernel uses a different segment register for performance reasons; a
20927         system call would not have to trash the userspace segment register,
20928         which would be expensive */
20929      if (ix86_cmodel != CM_KERNEL)
20930         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20931      else
20932         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20933   }
20934   [(set_attr "type" "multi")])
20935
20936 (include "sse.md")
20937 (include "mmx.md")
20938 (include "sync.md")