OSDN Git Service

ef3f36b69641f3a1a26fe165ea6f8f825002a993
[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   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537     operands[1] = force_reg (SFmode, operands[1]);
3538 })
3539
3540 (define_insn "*extendsfdf2_mixed"
3541   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3545 {
3546   switch (which_alternative)
3547     {
3548     case 0:
3549       return output_387_reg_move (insn, operands);
3550
3551     case 1:
3552       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553         return "fstp%z0\t%y0";
3554       else
3555         return "fst%z0\t%y0";
3556
3557     case 2:
3558       return "cvtss2sd\t{%1, %0|%0, %1}";
3559
3560     default:
3561       gcc_unreachable ();
3562     }
3563 }
3564   [(set_attr "type" "fmov,fmov,ssecvt")
3565    (set_attr "mode" "SF,XF,DF")])
3566
3567 (define_insn "*extendsfdf2_sse"
3568   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570   "TARGET_SSE2 && TARGET_SSE_MATH
3571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572   "cvtss2sd\t{%1, %0|%0, %1}"
3573   [(set_attr "type" "ssecvt")
3574    (set_attr "mode" "DF")])
3575
3576 (define_insn "*extendsfdf2_i387"
3577   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579   "TARGET_80387
3580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581 {
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return output_387_reg_move (insn, operands);
3586
3587     case 1:
3588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589         return "fstp%z0\t%y0";
3590       else
3591         return "fst%z0\t%y0";
3592
3593     default:
3594       gcc_unreachable ();
3595     }
3596 }
3597   [(set_attr "type" "fmov")
3598    (set_attr "mode" "SF,XF")])
3599
3600 (define_expand "extendsfxf2"
3601   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603   "TARGET_80387"
3604 {
3605   /* ??? Needed for compress_float_constant since all fp constants
3606      are LEGITIMATE_CONSTANT_P.  */
3607   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608     {
3609       if (standard_80387_constant_p (operands[1]) > 0)
3610         {
3611           operands[1] = simplify_const_unary_operation
3612             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613           emit_move_insn_1 (operands[0], operands[1]);
3614           DONE;
3615         }
3616       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617     }
3618   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619     operands[1] = force_reg (SFmode, operands[1]);
3620 })
3621
3622 (define_insn "*extendsfxf2_i387"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3625   "TARGET_80387
3626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641     default:
3642       gcc_unreachable ();
3643     }
3644 }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "SF,XF")])
3647
3648 (define_expand "extenddfxf2"
3649   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651   "TARGET_80387"
3652 {
3653   /* ??? Needed for compress_float_constant since all fp constants
3654      are LEGITIMATE_CONSTANT_P.  */
3655   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656     {
3657       if (standard_80387_constant_p (operands[1]) > 0)
3658         {
3659           operands[1] = simplify_const_unary_operation
3660             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661           emit_move_insn_1 (operands[0], operands[1]);
3662           DONE;
3663         }
3664       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665     }
3666   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667     operands[1] = force_reg (DFmode, operands[1]);
3668 })
3669
3670 (define_insn "*extenddfxf2_i387"
3671   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673   "TARGET_80387
3674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675 {
3676   switch (which_alternative)
3677     {
3678     case 0:
3679       return output_387_reg_move (insn, operands);
3680
3681     case 1:
3682       /* There is no non-popping store to memory for XFmode.  So if
3683          we need one, follow the store with a load.  */
3684       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3686       else
3687         return "fstp%z0\t%y0";
3688
3689     default:
3690       gcc_unreachable ();
3691     }
3692 }
3693   [(set_attr "type" "fmov")
3694    (set_attr "mode" "DF,XF")])
3695
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case.  Otherwise this is just like a simple move
3699 ;; insn.  So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3701
3702 ;; Conversion from DFmode to SFmode.
3703
3704 (define_expand "truncdfsf2"
3705   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3706         (float_truncate:SF
3707           (match_operand:DF 1 "nonimmediate_operand" "")))]
3708   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3709 {
3710   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711     operands[1] = force_reg (DFmode, operands[1]);
3712
3713   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3714     ;
3715   else if (flag_unsafe_math_optimizations)
3716     ;
3717   else
3718     {
3719       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3720       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3721       DONE;
3722     }
3723 })
3724
3725 (define_expand "truncdfsf2_with_temp"
3726   [(parallel [(set (match_operand:SF 0 "" "")
3727                    (float_truncate:SF (match_operand:DF 1 "" "")))
3728               (clobber (match_operand:SF 2 "" ""))])]
3729   "")
3730
3731 (define_insn "*truncdfsf_fast_mixed"
3732   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3736 {
3737   switch (which_alternative)
3738     {
3739     case 0:
3740       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741         return "fstp%z0\t%y0";
3742       else
3743         return "fst%z0\t%y0";
3744     case 1:
3745       return output_387_reg_move (insn, operands);
3746     case 2:
3747       return "cvtsd2ss\t{%1, %0|%0, %1}";
3748     default:
3749       gcc_unreachable ();
3750     }
3751 }
3752   [(set_attr "type" "fmov,fmov,ssecvt")
3753    (set_attr "mode" "SF")])
3754
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3759         (float_truncate:SF
3760           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761   "TARGET_SSE2 && TARGET_SSE_MATH"
3762   "cvtsd2ss\t{%1, %0|%0, %1}"
3763   [(set_attr "type" "ssecvt")
3764    (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_fast_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770   "TARGET_80387 && flag_unsafe_math_optimizations"
3771   "* return output_387_reg_move (insn, operands);"
3772   [(set_attr "type" "fmov")
3773    (set_attr "mode" "SF")])
3774
3775 (define_insn "*truncdfsf_mixed"
3776   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3777         (float_truncate:SF
3778           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3779    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3780   "TARGET_MIX_SSE_I387"
3781 {
3782   switch (which_alternative)
3783     {
3784     case 0:
3785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786         return "fstp%z0\t%y0";
3787       else
3788         return "fst%z0\t%y0";
3789     case 1:
3790       return "#";
3791     case 2:
3792       return "cvtsd2ss\t{%1, %0|%0, %1}";
3793     default:
3794       gcc_unreachable ();
3795     }
3796 }
3797   [(set_attr "type" "fmov,multi,ssecvt")
3798    (set_attr "unit" "*,i387,*")
3799    (set_attr "mode" "SF")])
3800
3801 (define_insn "*truncdfsf_i387"
3802   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3806   "TARGET_80387"
3807 {
3808   switch (which_alternative)
3809     {
3810     case 0:
3811       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812         return "fstp%z0\t%y0";
3813       else
3814         return "fst%z0\t%y0";
3815     case 1:
3816       return "#";
3817     default:
3818       gcc_unreachable ();
3819     }
3820 }
3821   [(set_attr "type" "fmov,multi")
3822    (set_attr "unit" "*,i387")
3823    (set_attr "mode" "SF")])
3824
3825 (define_insn "*truncdfsf2_i387_1"
3826   [(set (match_operand:SF 0 "memory_operand" "=m")
3827         (float_truncate:SF
3828           (match_operand:DF 1 "register_operand" "f")))]
3829   "TARGET_80387
3830    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831    && !TARGET_MIX_SSE_I387"
3832 {
3833   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834     return "fstp%z0\t%y0";
3835   else
3836     return "fst%z0\t%y0";
3837 }
3838   [(set_attr "type" "fmov")
3839    (set_attr "mode" "SF")])
3840
3841 (define_split
3842   [(set (match_operand:SF 0 "register_operand" "")
3843         (float_truncate:SF
3844          (match_operand:DF 1 "fp_register_operand" "")))
3845    (clobber (match_operand 2 "" ""))]
3846   "reload_completed"
3847   [(set (match_dup 2) (match_dup 1))
3848    (set (match_dup 0) (match_dup 2))]
3849 {
3850   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3851 })
3852
3853 ;; Conversion from XFmode to SFmode.
3854
3855 (define_expand "truncxfsf2"
3856   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3857                    (float_truncate:SF
3858                     (match_operand:XF 1 "register_operand" "")))
3859               (clobber (match_dup 2))])]
3860   "TARGET_80387"
3861 {
3862   if (flag_unsafe_math_optimizations)
3863     {
3864       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866       if (reg != operands[0])
3867         emit_move_insn (operands[0], reg);
3868       DONE;
3869     }
3870   else
3871     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3872 })
3873
3874 (define_insn "*truncxfsf2_mixed"
3875   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879   "TARGET_MIX_SSE_I387"
3880 {
3881   gcc_assert (!which_alternative);
3882   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883     return "fstp%z0\t%y0";
3884   else
3885     return "fst%z0\t%y0";
3886 }
3887   [(set_attr "type" "fmov,multi,multi,multi")
3888    (set_attr "unit" "*,i387,i387,i387")
3889    (set_attr "mode" "SF")])
3890
3891 (define_insn "truncxfsf2_i387_noop"
3892   [(set (match_operand:SF 0 "register_operand" "=f")
3893         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894   "TARGET_80387 && flag_unsafe_math_optimizations"
3895 {
3896   return output_387_reg_move (insn, operands);
3897 }
3898   [(set_attr "type" "fmov")
3899    (set_attr "mode" "SF")])
3900
3901 (define_insn "*truncxfsf2_i387"
3902   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "f,f,f")))
3905    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3906   "TARGET_80387"
3907 {
3908   gcc_assert (!which_alternative);
3909   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910     return "fstp%z0\t%y0";
3911    else
3912      return "fst%z0\t%y0";
3913 }
3914   [(set_attr "type" "fmov,multi,multi")
3915    (set_attr "unit" "*,i387,i387")
3916    (set_attr "mode" "SF")])
3917
3918 (define_insn "*truncxfsf2_i387_1"
3919   [(set (match_operand:SF 0 "memory_operand" "=m")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "f")))]
3922   "TARGET_80387"
3923 {
3924   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925     return "fstp%z0\t%y0";
3926   else
3927     return "fst%z0\t%y0";
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "SF")])
3931
3932 (define_split
3933   [(set (match_operand:SF 0 "register_operand" "")
3934         (float_truncate:SF
3935          (match_operand:XF 1 "register_operand" "")))
3936    (clobber (match_operand:SF 2 "memory_operand" ""))]
3937   "TARGET_80387 && reload_completed"
3938   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939    (set (match_dup 0) (match_dup 2))]
3940   "")
3941
3942 (define_split
3943   [(set (match_operand:SF 0 "memory_operand" "")
3944         (float_truncate:SF
3945          (match_operand:XF 1 "register_operand" "")))
3946    (clobber (match_operand:SF 2 "memory_operand" ""))]
3947   "TARGET_80387"
3948   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3949   "")
3950
3951 ;; Conversion from XFmode to DFmode.
3952
3953 (define_expand "truncxfdf2"
3954   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3955                    (float_truncate:DF
3956                     (match_operand:XF 1 "register_operand" "")))
3957               (clobber (match_dup 2))])]
3958   "TARGET_80387"
3959 {
3960   if (flag_unsafe_math_optimizations)
3961     {
3962       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964       if (reg != operands[0])
3965         emit_move_insn (operands[0], reg);
3966       DONE;
3967     }
3968   else
3969     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3970 })
3971
3972 (define_insn "*truncxfdf2_mixed"
3973   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3974         (float_truncate:DF
3975          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3978 {
3979   gcc_assert (!which_alternative);
3980   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981     return "fstp%z0\t%y0";
3982   else
3983     return "fst%z0\t%y0";
3984 }
3985   [(set_attr "type" "fmov,multi,multi,multi")
3986    (set_attr "unit" "*,i387,i387,i387")
3987    (set_attr "mode" "DF")])
3988
3989 (define_insn "truncxfdf2_i387_noop"
3990   [(set (match_operand:DF 0 "register_operand" "=f")
3991         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387 && flag_unsafe_math_optimizations"
3993 {
3994   return output_387_reg_move (insn, operands);
3995 }
3996   [(set_attr "type" "fmov")
3997    (set_attr "mode" "DF")])
3998
3999 (define_insn "*truncxfdf2_i387"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4001         (float_truncate:DF
4002          (match_operand:XF 1 "register_operand" "f,f,f")))
4003    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4004   "TARGET_80387"
4005 {
4006   gcc_assert (!which_alternative);
4007   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008     return "fstp%z0\t%y0";
4009   else
4010     return "fst%z0\t%y0";
4011 }
4012   [(set_attr "type" "fmov,multi,multi")
4013    (set_attr "unit" "*,i387,i387")
4014    (set_attr "mode" "DF")])
4015
4016 (define_insn "*truncxfdf2_i387_1"
4017   [(set (match_operand:DF 0 "memory_operand" "=m")
4018         (float_truncate:DF
4019           (match_operand:XF 1 "register_operand" "f")))]
4020   "TARGET_80387"
4021 {
4022   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023     return "fstp%z0\t%y0";
4024   else
4025     return "fst%z0\t%y0";
4026 }
4027   [(set_attr "type" "fmov")
4028    (set_attr "mode" "DF")])
4029
4030 (define_split
4031   [(set (match_operand:DF 0 "register_operand" "")
4032         (float_truncate:DF
4033          (match_operand:XF 1 "register_operand" "")))
4034    (clobber (match_operand:DF 2 "memory_operand" ""))]
4035   "TARGET_80387 && reload_completed"
4036   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037    (set (match_dup 0) (match_dup 2))]
4038   "")
4039
4040 (define_split
4041   [(set (match_operand:DF 0 "memory_operand" "")
4042         (float_truncate:DF
4043          (match_operand:XF 1 "register_operand" "")))
4044    (clobber (match_operand:DF 2 "memory_operand" ""))]
4045   "TARGET_80387"
4046   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4047   "")
4048 \f
4049 ;; Signed conversion to DImode.
4050
4051 (define_expand "fix_truncxfdi2"
4052   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4054               (clobber (reg:CC FLAGS_REG))])]
4055   "TARGET_80387"
4056 {
4057   if (TARGET_FISTTP)
4058    {
4059      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060      DONE;
4061    }
4062 })
4063
4064 (define_expand "fix_trunc<mode>di2"
4065   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067               (clobber (reg:CC FLAGS_REG))])]
4068   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4069 {
4070   if (TARGET_FISTTP
4071       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4072    {
4073      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074      DONE;
4075    }
4076   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4084 })
4085
4086 ;; Signed conversion to SImode.
4087
4088 (define_expand "fix_truncxfsi2"
4089   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4091               (clobber (reg:CC FLAGS_REG))])]
4092   "TARGET_80387"
4093 {
4094   if (TARGET_FISTTP)
4095    {
4096      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097      DONE;
4098    }
4099 })
4100
4101 (define_expand "fix_trunc<mode>si2"
4102   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104               (clobber (reg:CC FLAGS_REG))])]
4105   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4106 {
4107   if (TARGET_FISTTP
4108       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4109    {
4110      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4113   if (SSE_FLOAT_MODE_P (<MODE>mode))
4114    {
4115      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117      if (out != operands[0])
4118         emit_move_insn (operands[0], out);
4119      DONE;
4120    }
4121 })
4122
4123 ;; Signed conversion to HImode.
4124
4125 (define_expand "fix_trunc<mode>hi2"
4126   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128               (clobber (reg:CC FLAGS_REG))])]
4129   "TARGET_80387
4130    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4131 {
4132   if (TARGET_FISTTP)
4133    {
4134      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4135      DONE;
4136    }
4137 })
4138
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141   [(set (match_operand:DI 0 "register_operand" "=r,r")
4142         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144   "cvttss2si{q}\t{%1, %0|%0, %1}"
4145   [(set_attr "type" "sseicvt")
4146    (set_attr "mode" "SF")
4147    (set_attr "athlon_decode" "double,vector")])
4148
4149 (define_insn "fix_truncdfdi_sse"
4150   [(set (match_operand:DI 0 "register_operand" "=r,r")
4151         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "sseicvt")
4155    (set_attr "mode" "DF")
4156    (set_attr "athlon_decode" "double,vector")])
4157
4158 (define_insn "fix_truncsfsi_sse"
4159   [(set (match_operand:SI 0 "register_operand" "=r,r")
4160         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162   "cvttss2si\t{%1, %0|%0, %1}"
4163   [(set_attr "type" "sseicvt")
4164    (set_attr "mode" "DF")
4165    (set_attr "athlon_decode" "double,vector")])
4166
4167 (define_insn "fix_truncdfsi_sse"
4168   [(set (match_operand:SI 0 "register_operand" "=r,r")
4169         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171   "cvttsd2si\t{%1, %0|%0, %1}"
4172   [(set_attr "type" "sseicvt")
4173    (set_attr "mode" "DF")
4174    (set_attr "athlon_decode" "double,vector")])
4175
4176 ;; Avoid vector decoded forms of the instruction.
4177 (define_peephole2
4178   [(match_scratch:DF 2 "Y")
4179    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182   [(set (match_dup 2) (match_dup 1))
4183    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4184   "")
4185
4186 (define_peephole2
4187   [(match_scratch:SF 2 "x")
4188    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191   [(set (match_dup 2) (match_dup 1))
4192    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193   "")
4194
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4198   "TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201          && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)
4203    && !(reload_completed || reload_in_progress)"
4204   "#"
4205   "&& 1"
4206   [(const_int 0)]
4207 {
4208   if (memory_operand (operands[0], VOIDmode))
4209     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4210   else
4211     {
4212       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4214                                                             operands[1],
4215                                                             operands[2]));
4216     }
4217   DONE;
4218 }
4219   [(set_attr "type" "fisttp")
4220    (set_attr "mode" "<MODE>")])
4221
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225    (clobber (match_scratch:XF 2 "=&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   "* return output_fix_trunc (insn, operands, 1);"
4232   [(set_attr "type" "fisttp")
4233    (set_attr "mode" "<MODE>")])
4234
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4240   "TARGET_FISTTP
4241    && FLOAT_MODE_P (GET_MODE (operands[1]))
4242    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243         && (TARGET_64BIT || <MODE>mode != DImode))
4244         && TARGET_SSE_MATH)"
4245   "#"
4246   [(set_attr "type" "fisttp")
4247    (set_attr "mode" "<MODE>")])
4248
4249 (define_split
4250   [(set (match_operand:X87MODEI 0 "register_operand" "")
4251         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253    (clobber (match_scratch 3 ""))]
4254   "reload_completed"
4255   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256               (clobber (match_dup 3))])
4257    (set (match_dup 0) (match_dup 2))]
4258   "")
4259
4260 (define_split
4261   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264    (clobber (match_scratch 3 ""))]
4265   "reload_completed"
4266   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267               (clobber (match_dup 3))])]
4268   "")
4269
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278    (clobber (reg:CC FLAGS_REG))]
4279   "TARGET_80387 && !TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282          && (TARGET_64BIT || <MODE>mode != DImode))
4283    && !(reload_completed || reload_in_progress)"
4284   "#"
4285   "&& 1"
4286   [(const_int 0)]
4287 {
4288   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4289
4290   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292   if (memory_operand (operands[0], VOIDmode))
4293     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294                                          operands[2], operands[3]));
4295   else
4296     {
4297       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299                                                      operands[2], operands[3],
4300                                                      operands[4]));
4301     }
4302   DONE;
4303 }
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "<MODE>")])
4307
4308 (define_insn "fix_truncdi_i387"
4309   [(set (match_operand:DI 0 "memory_operand" "=m")
4310         (fix:DI (match_operand 1 "register_operand" "f")))
4311    (use (match_operand:HI 2 "memory_operand" "m"))
4312    (use (match_operand:HI 3 "memory_operand" "m"))
4313    (clobber (match_scratch:XF 4 "=&1f"))]
4314   "TARGET_80387 && !TARGET_FISTTP
4315    && FLOAT_MODE_P (GET_MODE (operands[1]))
4316    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317   "* return output_fix_trunc (insn, operands, 0);"
4318   [(set_attr "type" "fistp")
4319    (set_attr "i387_cw" "trunc")
4320    (set_attr "mode" "DI")])
4321
4322 (define_insn "fix_truncdi_i387_with_temp"
4323   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324         (fix:DI (match_operand 1 "register_operand" "f,f")))
4325    (use (match_operand:HI 2 "memory_operand" "m,m"))
4326    (use (match_operand:HI 3 "memory_operand" "m,m"))
4327    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332   "#"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "DI")])
4336
4337 (define_split 
4338   [(set (match_operand:DI 0 "register_operand" "")
4339         (fix:DI (match_operand 1 "register_operand" "")))
4340    (use (match_operand:HI 2 "memory_operand" ""))
4341    (use (match_operand:HI 3 "memory_operand" ""))
4342    (clobber (match_operand:DI 4 "memory_operand" ""))
4343    (clobber (match_scratch 5 ""))]
4344   "reload_completed"
4345   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4346               (use (match_dup 2))
4347               (use (match_dup 3))
4348               (clobber (match_dup 5))])
4349    (set (match_dup 0) (match_dup 4))]
4350   "")
4351
4352 (define_split 
4353   [(set (match_operand:DI 0 "memory_operand" "")
4354         (fix:DI (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:DI 4 "memory_operand" ""))
4358    (clobber (match_scratch 5 ""))]
4359   "reload_completed"
4360   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4361               (use (match_dup 2))
4362               (use (match_dup 3))
4363               (clobber (match_dup 5))])]
4364   "")
4365
4366 (define_insn "fix_trunc<mode>_i387"
4367   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369    (use (match_operand:HI 2 "memory_operand" "m"))
4370    (use (match_operand:HI 3 "memory_operand" "m"))]
4371   "TARGET_80387 && !TARGET_FISTTP
4372    && FLOAT_MODE_P (GET_MODE (operands[1]))
4373    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374   "* return output_fix_trunc (insn, operands, 0);"
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "<MODE>")])
4378
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382    (use (match_operand:HI 2 "memory_operand" "m,m"))
4383    (use (match_operand:HI 3 "memory_operand" "m,m"))
4384    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385   "TARGET_80387 && !TARGET_FISTTP
4386    && FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388   "#"
4389   [(set_attr "type" "fistp")
4390    (set_attr "i387_cw" "trunc")
4391    (set_attr "mode" "<MODE>")])
4392
4393 (define_split 
4394   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396    (use (match_operand:HI 2 "memory_operand" ""))
4397    (use (match_operand:HI 3 "memory_operand" ""))
4398    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))])
4403    (set (match_dup 0) (match_dup 4))]
4404   "")
4405
4406 (define_split 
4407   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409    (use (match_operand:HI 2 "memory_operand" ""))
4410    (use (match_operand:HI 3 "memory_operand" ""))
4411    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4412   "reload_completed"
4413   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4414               (use (match_dup 2))
4415               (use (match_dup 3))])]
4416   "")
4417
4418 (define_insn "x86_fnstcw_1"
4419   [(set (match_operand:HI 0 "memory_operand" "=m")
4420         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4421   "TARGET_80387"
4422   "fnstcw\t%0"
4423   [(set_attr "length" "2")
4424    (set_attr "mode" "HI")
4425    (set_attr "unit" "i387")])
4426
4427 (define_insn "x86_fldcw_1"
4428   [(set (reg:HI FPSR_REG)
4429         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4430   "TARGET_80387"
4431   "fldcw\t%0"
4432   [(set_attr "length" "2")
4433    (set_attr "mode" "HI")
4434    (set_attr "unit" "i387")
4435    (set_attr "athlon_decode" "vector")])
4436 \f
4437 ;; Conversion between fixed point and floating point.
4438
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4441
4442 (define_expand "floathisf2"
4443   [(set (match_operand:SF 0 "register_operand" "")
4444         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445   "TARGET_80387 || TARGET_SSE_MATH"
4446 {
4447   if (TARGET_SSE_MATH)
4448     {
4449       emit_insn (gen_floatsisf2 (operands[0],
4450                                  convert_to_mode (SImode, operands[1], 0)));
4451       DONE;
4452     }
4453 })
4454
4455 (define_insn "*floathisf2_i387"
4456   [(set (match_operand:SF 0 "register_operand" "=f,f")
4457         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4459   "@
4460    fild%z1\t%1
4461    #"
4462   [(set_attr "type" "fmov,multi")
4463    (set_attr "mode" "SF")
4464    (set_attr "unit" "*,i387")
4465    (set_attr "fp_int_src" "true")])
4466
4467 (define_expand "floatsisf2"
4468   [(set (match_operand:SF 0 "register_operand" "")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470   "TARGET_80387 || TARGET_SSE_MATH"
4471   "")
4472
4473 (define_insn "*floatsisf2_mixed"
4474   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476   "TARGET_MIX_SSE_I387"
4477   "@
4478    fild%z1\t%1
4479    #
4480    cvtsi2ss\t{%1, %0|%0, %1}
4481    cvtsi2ss\t{%1, %0|%0, %1}"
4482   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483    (set_attr "mode" "SF")
4484    (set_attr "unit" "*,i387,*,*")
4485    (set_attr "athlon_decode" "*,*,vector,double")
4486    (set_attr "fp_int_src" "true")])
4487
4488 (define_insn "*floatsisf2_sse"
4489   [(set (match_operand:SF 0 "register_operand" "=x,x")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4491   "TARGET_SSE_MATH"
4492   "cvtsi2ss\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatsisf2_i387"
4499   [(set (match_operand:SF 0 "register_operand" "=f,f")
4500         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4501   "TARGET_80387"
4502   "@
4503    fild%z1\t%1
4504    #"
4505   [(set_attr "type" "fmov,multi")
4506    (set_attr "mode" "SF")
4507    (set_attr "unit" "*,i387")
4508    (set_attr "fp_int_src" "true")])
4509
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4514   "")
4515
4516 (define_insn "*floatdisf2_mixed"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4520   "@
4521    fild%z1\t%1
4522    #
4523    cvtsi2ss{q}\t{%1, %0|%0, %1}
4524    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "unit" "*,i387,*,*")
4528    (set_attr "athlon_decode" "*,*,vector,double")
4529    (set_attr "fp_int_src" "true")])
4530
4531 (define_insn "*floatdisf2_sse"
4532   [(set (match_operand:SF 0 "register_operand" "=x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534   "TARGET_64BIT && TARGET_SSE_MATH"
4535   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatdisf2_i387"
4542   [(set (match_operand:SF 0 "register_operand" "=f,f")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4544   "TARGET_80387"
4545   "@
4546    fild%z1\t%1
4547    #"
4548   [(set_attr "type" "fmov,multi")
4549    (set_attr "mode" "SF")
4550    (set_attr "unit" "*,i387")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557 {
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4564 })
4565
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "unit" "*,i387")
4576    (set_attr "fp_int_src" "true")])
4577
4578 (define_expand "floatsidf2"
4579   [(set (match_operand:DF 0 "register_operand" "")
4580         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4582   "")
4583
4584 (define_insn "*floatsidf2_mixed"
4585   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4588   "@
4589    fild%z1\t%1
4590    #
4591    cvtsi2sd\t{%1, %0|%0, %1}
4592    cvtsi2sd\t{%1, %0|%0, %1}"
4593   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594    (set_attr "mode" "DF")
4595    (set_attr "unit" "*,i387,*,*")
4596    (set_attr "athlon_decode" "*,*,double,direct")
4597    (set_attr "fp_int_src" "true")])
4598
4599 (define_insn "*floatsidf2_sse"
4600   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602   "TARGET_SSE2 && TARGET_SSE_MATH"
4603   "cvtsi2sd\t{%1, %0|%0, %1}"
4604   [(set_attr "type" "sseicvt")
4605    (set_attr "mode" "DF")
4606    (set_attr "athlon_decode" "double,direct")
4607    (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatsidf2_i387"
4610   [(set (match_operand:DF 0 "register_operand" "=f,f")
4611         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4612   "TARGET_80387"
4613   "@
4614    fild%z1\t%1
4615    #"
4616   [(set_attr "type" "fmov,multi")
4617    (set_attr "mode" "DF")
4618    (set_attr "unit" "*,i387")
4619    (set_attr "fp_int_src" "true")])
4620
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4625   "")
4626
4627 (define_insn "*floatdidf2_mixed"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631   "@
4632    fild%z1\t%1
4633    #
4634    cvtsi2sd{q}\t{%1, %0|%0, %1}
4635    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637    (set_attr "mode" "DF")
4638    (set_attr "unit" "*,i387,*,*")
4639    (set_attr "athlon_decode" "*,*,double,direct")
4640    (set_attr "fp_int_src" "true")])
4641
4642 (define_insn "*floatdidf2_sse"
4643   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "double,direct")
4650    (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatdidf2_i387"
4653   [(set (match_operand:DF 0 "register_operand" "=f,f")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4655   "TARGET_80387"
4656   "@
4657    fild%z1\t%1
4658    #"
4659   [(set_attr "type" "fmov,multi")
4660    (set_attr "mode" "DF")
4661    (set_attr "unit" "*,i387")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "floathixf2"
4665   [(set (match_operand:XF 0 "register_operand" "=f,f")
4666         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "XF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "floatsixf2"
4677   [(set (match_operand:XF 0 "register_operand" "=f,f")
4678         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679   "TARGET_80387"
4680   "@
4681    fild%z1\t%1
4682    #"
4683   [(set_attr "type" "fmov,multi")
4684    (set_attr "mode" "XF")
4685    (set_attr "unit" "*,i387")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatdixf2"
4689   [(set (match_operand:XF 0 "register_operand" "=f,f")
4690         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691   "TARGET_80387"
4692   "@
4693    fild%z1\t%1
4694    #"
4695   [(set_attr "type" "fmov,multi")
4696    (set_attr "mode" "XF")
4697    (set_attr "unit" "*,i387")
4698    (set_attr "fp_int_src" "true")])
4699
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702   [(set (match_operand 0 "fp_register_operand" "")
4703         (float (match_operand 1 "register_operand" "")))]
4704   "reload_completed
4705    && TARGET_80387
4706    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4707   [(const_int 0)]
4708 {
4709   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712   ix86_free_from_memory (GET_MODE (operands[1]));
4713   DONE;
4714 })
4715
4716 (define_expand "floatunssisf2"
4717   [(use (match_operand:SF 0 "register_operand" ""))
4718    (use (match_operand:SI 1 "register_operand" ""))]
4719   "!TARGET_64BIT && TARGET_SSE_MATH"
4720   "x86_emit_floatuns (operands); DONE;")
4721
4722 (define_expand "floatunsdisf2"
4723   [(use (match_operand:SF 0 "register_operand" ""))
4724    (use (match_operand:DI 1 "register_operand" ""))]
4725   "TARGET_64BIT && TARGET_SSE_MATH"
4726   "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdidf2"
4729   [(use (match_operand:DF 0 "register_operand" ""))
4730    (use (match_operand:DI 1 "register_operand" ""))]
4731   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732   "x86_emit_floatuns (operands); DONE;")
4733 \f
4734 ;; SSE extract/set expanders
4735
4736 \f
4737 ;; Add instructions
4738
4739 ;; %%% splits for addditi3
4740
4741 (define_expand "addti3"
4742   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744                  (match_operand:TI 2 "x86_64_general_operand" "")))
4745    (clobber (reg:CC FLAGS_REG))]
4746   "TARGET_64BIT"
4747   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4748
4749 (define_insn "*addti3_1"
4750   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4753    (clobber (reg:CC FLAGS_REG))]
4754   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4755   "#")
4756
4757 (define_split
4758   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760                  (match_operand:TI 2 "general_operand" "")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   "TARGET_64BIT && reload_completed"
4763   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4764                                           UNSPEC_ADD_CARRY))
4765               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766    (parallel [(set (match_dup 3)
4767                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4768                                      (match_dup 4))
4769                             (match_dup 5)))
4770               (clobber (reg:CC FLAGS_REG))])]
4771   "split_ti (operands+0, 1, operands+0, operands+3);
4772    split_ti (operands+1, 1, operands+1, operands+4);
4773    split_ti (operands+2, 1, operands+2, operands+5);")
4774
4775 ;; %%% splits for addsidi3
4776 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4779
4780 (define_expand "adddi3"
4781   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783                  (match_operand:DI 2 "x86_64_general_operand" "")))
4784    (clobber (reg:CC FLAGS_REG))]
4785   ""
4786   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4787
4788 (define_insn "*adddi3_1"
4789   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4792    (clobber (reg:CC FLAGS_REG))]
4793   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794   "#")
4795
4796 (define_split
4797   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799                  (match_operand:DI 2 "general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "!TARGET_64BIT && reload_completed"
4802   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4803                                           UNSPEC_ADD_CARRY))
4804               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805    (parallel [(set (match_dup 3)
4806                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4807                                      (match_dup 4))
4808                             (match_dup 5)))
4809               (clobber (reg:CC FLAGS_REG))])]
4810   "split_di (operands+0, 1, operands+0, operands+3);
4811    split_di (operands+1, 1, operands+1, operands+4);
4812    split_di (operands+2, 1, operands+2, operands+5);")
4813
4814 (define_insn "adddi3_carry_rex64"
4815   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819    (clobber (reg:CC FLAGS_REG))]
4820   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821   "adc{q}\t{%2, %0|%0, %2}"
4822   [(set_attr "type" "alu")
4823    (set_attr "pent_pair" "pu")
4824    (set_attr "mode" "DI")])
4825
4826 (define_insn "*adddi3_cc_rex64"
4827   [(set (reg:CC FLAGS_REG)
4828         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4830                    UNSPEC_ADD_CARRY))
4831    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832         (plus:DI (match_dup 1) (match_dup 2)))]
4833   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834   "add{q}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "mode" "DI")])
4837
4838 (define_insn "addqi3_carry"
4839   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842                    (match_operand:QI 2 "general_operand" "qi,qm")))
4843    (clobber (reg:CC FLAGS_REG))]
4844   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845   "adc{b}\t{%2, %0|%0, %2}"
4846   [(set_attr "type" "alu")
4847    (set_attr "pent_pair" "pu")
4848    (set_attr "mode" "QI")])
4849
4850 (define_insn "addhi3_carry"
4851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854                    (match_operand:HI 2 "general_operand" "ri,rm")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857   "adc{w}\t{%2, %0|%0, %2}"
4858   [(set_attr "type" "alu")
4859    (set_attr "pent_pair" "pu")
4860    (set_attr "mode" "HI")])
4861
4862 (define_insn "addsi3_carry"
4863   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866                    (match_operand:SI 2 "general_operand" "ri,rm")))
4867    (clobber (reg:CC FLAGS_REG))]
4868   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869   "adc{l}\t{%2, %0|%0, %2}"
4870   [(set_attr "type" "alu")
4871    (set_attr "pent_pair" "pu")
4872    (set_attr "mode" "SI")])
4873
4874 (define_insn "*addsi3_carry_zext"
4875   [(set (match_operand:DI 0 "register_operand" "=r")
4876           (zero_extend:DI 
4877             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879                      (match_operand:SI 2 "general_operand" "rim"))))
4880    (clobber (reg:CC FLAGS_REG))]
4881   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882   "adc{l}\t{%2, %k0|%k0, %2}"
4883   [(set_attr "type" "alu")
4884    (set_attr "pent_pair" "pu")
4885    (set_attr "mode" "SI")])
4886
4887 (define_insn "*addsi3_cc"
4888   [(set (reg:CC FLAGS_REG)
4889         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890                     (match_operand:SI 2 "general_operand" "ri,rm")]
4891                    UNSPEC_ADD_CARRY))
4892    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893         (plus:SI (match_dup 1) (match_dup 2)))]
4894   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895   "add{l}\t{%2, %0|%0, %2}"
4896   [(set_attr "type" "alu")
4897    (set_attr "mode" "SI")])
4898
4899 (define_insn "addqi3_cc"
4900   [(set (reg:CC FLAGS_REG)
4901         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902                     (match_operand:QI 2 "general_operand" "qi,qm")]
4903                    UNSPEC_ADD_CARRY))
4904    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905         (plus:QI (match_dup 1) (match_dup 2)))]
4906   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907   "add{b}\t{%2, %0|%0, %2}"
4908   [(set_attr "type" "alu")
4909    (set_attr "mode" "QI")])
4910
4911 (define_expand "addsi3"
4912   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914                             (match_operand:SI 2 "general_operand" "")))
4915               (clobber (reg:CC FLAGS_REG))])]
4916   ""
4917   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4918
4919 (define_insn "*lea_1"
4920   [(set (match_operand:SI 0 "register_operand" "=r")
4921         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4922   "!TARGET_64BIT"
4923   "lea{l}\t{%a1, %0|%0, %a1}"
4924   [(set_attr "type" "lea")
4925    (set_attr "mode" "SI")])
4926
4927 (define_insn "*lea_1_rex64"
4928   [(set (match_operand:SI 0 "register_operand" "=r")
4929         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4930   "TARGET_64BIT"
4931   "lea{l}\t{%a1, %0|%0, %a1}"
4932   [(set_attr "type" "lea")
4933    (set_attr "mode" "SI")])
4934
4935 (define_insn "*lea_1_zext"
4936   [(set (match_operand:DI 0 "register_operand" "=r")
4937         (zero_extend:DI
4938          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4939   "TARGET_64BIT"
4940   "lea{l}\t{%a1, %k0|%k0, %a1}"
4941   [(set_attr "type" "lea")
4942    (set_attr "mode" "SI")])
4943
4944 (define_insn "*lea_2_rex64"
4945   [(set (match_operand:DI 0 "register_operand" "=r")
4946         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4947   "TARGET_64BIT"
4948   "lea{q}\t{%a1, %0|%0, %a1}"
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "DI")])
4951
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4954
4955 (define_insn_and_split "*lea_general_1"
4956   [(set (match_operand 0 "register_operand" "=r")
4957         (plus (plus (match_operand 1 "index_register_operand" "l")
4958                     (match_operand 2 "register_operand" "r"))
4959               (match_operand 3 "immediate_operand" "i")))]
4960   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966        || GET_MODE (operands[3]) == VOIDmode)"
4967   "#"
4968   "&& reload_completed"
4969   [(const_int 0)]
4970 {
4971   rtx pat;
4972   operands[0] = gen_lowpart (SImode, operands[0]);
4973   operands[1] = gen_lowpart (Pmode, operands[1]);
4974   operands[2] = gen_lowpart (Pmode, operands[2]);
4975   operands[3] = gen_lowpart (Pmode, operands[3]);
4976   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4977                       operands[3]);
4978   if (Pmode != SImode)
4979     pat = gen_rtx_SUBREG (SImode, pat, 0);
4980   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4981   DONE;
4982 }
4983   [(set_attr "type" "lea")
4984    (set_attr "mode" "SI")])
4985
4986 (define_insn_and_split "*lea_general_1_zext"
4987   [(set (match_operand:DI 0 "register_operand" "=r")
4988         (zero_extend:DI
4989           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990                             (match_operand:SI 2 "register_operand" "r"))
4991                    (match_operand:SI 3 "immediate_operand" "i"))))]
4992   "TARGET_64BIT"
4993   "#"
4994   "&& reload_completed"
4995   [(set (match_dup 0)
4996         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4997                                                      (match_dup 2))
4998                                             (match_dup 3)) 0)))]
4999 {
5000   operands[1] = gen_lowpart (Pmode, operands[1]);
5001   operands[2] = gen_lowpart (Pmode, operands[2]);
5002   operands[3] = gen_lowpart (Pmode, operands[3]);
5003 }
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2"
5008   [(set (match_operand 0 "register_operand" "=r")
5009         (plus (mult (match_operand 1 "index_register_operand" "l")
5010                     (match_operand 2 "const248_operand" "i"))
5011               (match_operand 3 "nonmemory_operand" "ri")))]
5012   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017        || GET_MODE (operands[3]) == VOIDmode)"
5018   "#"
5019   "&& reload_completed"
5020   [(const_int 0)]
5021 {
5022   rtx pat;
5023   operands[0] = gen_lowpart (SImode, operands[0]);
5024   operands[1] = gen_lowpart (Pmode, operands[1]);
5025   operands[3] = gen_lowpart (Pmode, operands[3]);
5026   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5027                       operands[3]);
5028   if (Pmode != SImode)
5029     pat = gen_rtx_SUBREG (SImode, pat, 0);
5030   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5031   DONE;
5032 }
5033   [(set_attr "type" "lea")
5034    (set_attr "mode" "SI")])
5035
5036 (define_insn_and_split "*lea_general_2_zext"
5037   [(set (match_operand:DI 0 "register_operand" "=r")
5038         (zero_extend:DI
5039           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040                             (match_operand:SI 2 "const248_operand" "n"))
5041                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5042   "TARGET_64BIT"
5043   "#"
5044   "&& reload_completed"
5045   [(set (match_dup 0)
5046         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5047                                                      (match_dup 2))
5048                                             (match_dup 3)) 0)))]
5049 {
5050   operands[1] = gen_lowpart (Pmode, operands[1]);
5051   operands[3] = gen_lowpart (Pmode, operands[3]);
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3"
5057   [(set (match_operand 0 "register_operand" "=r")
5058         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059                           (match_operand 2 "const248_operand" "i"))
5060                     (match_operand 3 "register_operand" "r"))
5061               (match_operand 4 "immediate_operand" "i")))]
5062   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5067   "#"
5068   "&& reload_completed"
5069   [(const_int 0)]
5070 {
5071   rtx pat;
5072   operands[0] = gen_lowpart (SImode, operands[0]);
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076   pat = gen_rtx_PLUS (Pmode,
5077                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5078                                                          operands[2]),
5079                                     operands[3]),
5080                       operands[4]);
5081   if (Pmode != SImode)
5082     pat = gen_rtx_SUBREG (SImode, pat, 0);
5083   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084   DONE;
5085 }
5086   [(set_attr "type" "lea")
5087    (set_attr "mode" "SI")])
5088
5089 (define_insn_and_split "*lea_general_3_zext"
5090   [(set (match_operand:DI 0 "register_operand" "=r")
5091         (zero_extend:DI
5092           (plus:SI (plus:SI (mult:SI
5093                               (match_operand:SI 1 "index_register_operand" "l")
5094                               (match_operand:SI 2 "const248_operand" "n"))
5095                             (match_operand:SI 3 "register_operand" "r"))
5096                    (match_operand:SI 4 "immediate_operand" "i"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5102                                                               (match_dup 2))
5103                                                      (match_dup 3))
5104                                             (match_dup 4)) 0)))]
5105 {
5106   operands[1] = gen_lowpart (Pmode, operands[1]);
5107   operands[3] = gen_lowpart (Pmode, operands[3]);
5108   operands[4] = gen_lowpart (Pmode, operands[4]);
5109 }
5110   [(set_attr "type" "lea")
5111    (set_attr "mode" "SI")])
5112
5113 (define_insn "*adddi_1_rex64"
5114   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117    (clobber (reg:CC FLAGS_REG))]
5118   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5119 {
5120   switch (get_attr_type (insn))
5121     {
5122     case TYPE_LEA:
5123       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124       return "lea{q}\t{%a2, %0|%0, %a2}";
5125
5126     case TYPE_INCDEC:
5127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128       if (operands[2] == const1_rtx)
5129         return "inc{q}\t%0";
5130       else
5131         {
5132           gcc_assert (operands[2] == constm1_rtx);
5133           return "dec{q}\t%0";
5134         }
5135
5136     default:
5137       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5138
5139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5141       if (GET_CODE (operands[2]) == CONST_INT
5142           /* Avoid overflows.  */
5143           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144           && (INTVAL (operands[2]) == 128
5145               || (INTVAL (operands[2]) < 0
5146                   && INTVAL (operands[2]) != -128)))
5147         {
5148           operands[2] = GEN_INT (-INTVAL (operands[2]));
5149           return "sub{q}\t{%2, %0|%0, %2}";
5150         }
5151       return "add{q}\t{%2, %0|%0, %2}";
5152     }
5153 }
5154   [(set (attr "type")
5155      (cond [(eq_attr "alternative" "2")
5156               (const_string "lea")
5157             ; Current assemblers are broken and do not allow @GOTOFF in
5158             ; ought but a memory context.
5159             (match_operand:DI 2 "pic_symbolic_operand" "")
5160               (const_string "lea")
5161             (match_operand:DI 2 "incdec_operand" "")
5162               (const_string "incdec")
5163            ]
5164            (const_string "alu")))
5165    (set_attr "mode" "DI")])
5166
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5168 (define_split
5169   [(set (match_operand:DI 0 "register_operand" "")
5170         (plus:DI (match_operand:DI 1 "register_operand" "")
5171                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && reload_completed
5174    && true_regnum (operands[0]) != true_regnum (operands[1])"
5175   [(set (match_dup 0)
5176         (plus:DI (match_dup 1)
5177                  (match_dup 2)))]
5178   "")
5179
5180 (define_insn "*adddi_2_rex64"
5181   [(set (reg FLAGS_REG)
5182         (compare
5183           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5185           (const_int 0)))                       
5186    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187         (plus:DI (match_dup 1) (match_dup 2)))]
5188   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189    && ix86_binary_operator_ok (PLUS, DImode, operands)
5190    /* Current assemblers are broken and do not allow @GOTOFF in
5191       ought but a memory context.  */
5192    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5193 {
5194   switch (get_attr_type (insn))
5195     {
5196     case TYPE_INCDEC:
5197       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198       if (operands[2] == const1_rtx)
5199         return "inc{q}\t%0";
5200       else
5201         {
5202           gcc_assert (operands[2] == constm1_rtx);
5203           return "dec{q}\t%0";
5204         }
5205
5206     default:
5207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208       /* ???? We ought to handle there the 32bit case too
5209          - do we need new constraint?  */
5210       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5212       if (GET_CODE (operands[2]) == CONST_INT
5213           /* Avoid overflows.  */
5214           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215           && (INTVAL (operands[2]) == 128
5216               || (INTVAL (operands[2]) < 0
5217                   && INTVAL (operands[2]) != -128)))
5218         {
5219           operands[2] = GEN_INT (-INTVAL (operands[2]));
5220           return "sub{q}\t{%2, %0|%0, %2}";
5221         }
5222       return "add{q}\t{%2, %0|%0, %2}";
5223     }
5224 }
5225   [(set (attr "type")
5226      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227         (const_string "incdec")
5228         (const_string "alu")))
5229    (set_attr "mode" "DI")])
5230
5231 (define_insn "*adddi_3_rex64"
5232   [(set (reg FLAGS_REG)
5233         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235    (clobber (match_scratch:DI 0 "=r"))]
5236   "TARGET_64BIT
5237    && ix86_match_ccmode (insn, CCZmode)
5238    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239    /* Current assemblers are broken and do not allow @GOTOFF in
5240       ought but a memory context.  */
5241    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5242 {
5243   switch (get_attr_type (insn))
5244     {
5245     case TYPE_INCDEC:
5246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247       if (operands[2] == const1_rtx)
5248         return "inc{q}\t%0";
5249       else
5250         {
5251           gcc_assert (operands[2] == constm1_rtx);
5252           return "dec{q}\t%0";
5253         }
5254
5255     default:
5256       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257       /* ???? We ought to handle there the 32bit case too
5258          - do we need new constraint?  */
5259       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5261       if (GET_CODE (operands[2]) == CONST_INT
5262           /* Avoid overflows.  */
5263           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264           && (INTVAL (operands[2]) == 128
5265               || (INTVAL (operands[2]) < 0
5266                   && INTVAL (operands[2]) != -128)))
5267         {
5268           operands[2] = GEN_INT (-INTVAL (operands[2]));
5269           return "sub{q}\t{%2, %0|%0, %2}";
5270         }
5271       return "add{q}\t{%2, %0|%0, %2}";
5272     }
5273 }
5274   [(set (attr "type")
5275      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276         (const_string "incdec")
5277         (const_string "alu")))
5278    (set_attr "mode" "DI")])
5279
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5282 ; is matched then.  We can't accept general immediate, because for
5283 ; case of overflows,  the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5285 ; when negated.
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289   [(set (reg FLAGS_REG)
5290         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292    (clobber (match_scratch:DI 0 "=rm"))]
5293   "TARGET_64BIT
5294    &&  ix86_match_ccmode (insn, CCGCmode)"
5295 {
5296   switch (get_attr_type (insn))
5297     {
5298     case TYPE_INCDEC:
5299       if (operands[2] == constm1_rtx)
5300         return "inc{q}\t%0";
5301       else
5302         {
5303           gcc_assert (operands[2] == const1_rtx);
5304           return "dec{q}\t%0";
5305         }
5306
5307     default:
5308       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5311       if ((INTVAL (operands[2]) == -128
5312            || (INTVAL (operands[2]) > 0
5313                && INTVAL (operands[2]) != 128))
5314           /* Avoid overflows.  */
5315           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316         return "sub{q}\t{%2, %0|%0, %2}";
5317       operands[2] = GEN_INT (-INTVAL (operands[2]));
5318       return "add{q}\t{%2, %0|%0, %2}";
5319     }
5320 }
5321   [(set (attr "type")
5322      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323         (const_string "incdec")
5324         (const_string "alu")))
5325    (set_attr "mode" "DI")])
5326
5327 (define_insn "*adddi_5_rex64"
5328   [(set (reg FLAGS_REG)
5329         (compare
5330           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5332           (const_int 0)))                       
5333    (clobber (match_scratch:DI 0 "=r"))]
5334   "TARGET_64BIT
5335    && ix86_match_ccmode (insn, CCGOCmode)
5336    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337    /* Current assemblers are broken and do not allow @GOTOFF in
5338       ought but a memory context.  */
5339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5340 {
5341   switch (get_attr_type (insn))
5342     {
5343     case TYPE_INCDEC:
5344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345       if (operands[2] == const1_rtx)
5346         return "inc{q}\t%0";
5347       else
5348         {
5349           gcc_assert (operands[2] == constm1_rtx);
5350           return "dec{q}\t%0";
5351         }
5352
5353     default:
5354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5357       if (GET_CODE (operands[2]) == CONST_INT
5358           /* Avoid overflows.  */
5359           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360           && (INTVAL (operands[2]) == 128
5361               || (INTVAL (operands[2]) < 0
5362                   && INTVAL (operands[2]) != -128)))
5363         {
5364           operands[2] = GEN_INT (-INTVAL (operands[2]));
5365           return "sub{q}\t{%2, %0|%0, %2}";
5366         }
5367       return "add{q}\t{%2, %0|%0, %2}";
5368     }
5369 }
5370   [(set (attr "type")
5371      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372         (const_string "incdec")
5373         (const_string "alu")))
5374    (set_attr "mode" "DI")])
5375
5376
5377 (define_insn "*addsi_1"
5378   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5383 {
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_LEA:
5387       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388       return "lea{l}\t{%a2, %0|%0, %a2}";
5389
5390     case TYPE_INCDEC:
5391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392       if (operands[2] == const1_rtx)
5393         return "inc{l}\t%0";
5394       else
5395         {
5396           gcc_assert (operands[2] == constm1_rtx);
5397           return "dec{l}\t%0";
5398         }
5399
5400     default:
5401       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402
5403       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5405       if (GET_CODE (operands[2]) == CONST_INT
5406           && (INTVAL (operands[2]) == 128
5407               || (INTVAL (operands[2]) < 0
5408                   && INTVAL (operands[2]) != -128)))
5409         {
5410           operands[2] = GEN_INT (-INTVAL (operands[2]));
5411           return "sub{l}\t{%2, %0|%0, %2}";
5412         }
5413       return "add{l}\t{%2, %0|%0, %2}";
5414     }
5415 }
5416   [(set (attr "type")
5417      (cond [(eq_attr "alternative" "2")
5418               (const_string "lea")
5419             ; Current assemblers are broken and do not allow @GOTOFF in
5420             ; ought but a memory context.
5421             (match_operand:SI 2 "pic_symbolic_operand" "")
5422               (const_string "lea")
5423             (match_operand:SI 2 "incdec_operand" "")
5424               (const_string "incdec")
5425            ]
5426            (const_string "alu")))
5427    (set_attr "mode" "SI")])
5428
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5430 (define_split
5431   [(set (match_operand 0 "register_operand" "")
5432         (plus (match_operand 1 "register_operand" "")
5433               (match_operand 2 "nonmemory_operand" "")))
5434    (clobber (reg:CC FLAGS_REG))]
5435   "reload_completed
5436    && true_regnum (operands[0]) != true_regnum (operands[1])"
5437   [(const_int 0)]
5438 {
5439   rtx pat;
5440   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441      may confuse gen_lowpart.  */
5442   if (GET_MODE (operands[0]) != Pmode)
5443     {
5444       operands[1] = gen_lowpart (Pmode, operands[1]);
5445       operands[2] = gen_lowpart (Pmode, operands[2]);
5446     }
5447   operands[0] = gen_lowpart (SImode, operands[0]);
5448   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449   if (Pmode != SImode)
5450     pat = gen_rtx_SUBREG (SImode, pat, 0);
5451   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452   DONE;
5453 })
5454
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload.  This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461   [(set (match_operand:DI 0 "register_operand" "=r,r")
5462         (zero_extend:DI
5463           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465    (clobber (reg:CC FLAGS_REG))]
5466   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5467 {
5468   switch (get_attr_type (insn))
5469     {
5470     case TYPE_LEA:
5471       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5473
5474     case TYPE_INCDEC:
5475       if (operands[2] == const1_rtx)
5476         return "inc{l}\t%k0";
5477       else
5478         {
5479           gcc_assert (operands[2] == constm1_rtx);
5480           return "dec{l}\t%k0";
5481         }
5482
5483     default:
5484       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5486       if (GET_CODE (operands[2]) == CONST_INT
5487           && (INTVAL (operands[2]) == 128
5488               || (INTVAL (operands[2]) < 0
5489                   && INTVAL (operands[2]) != -128)))
5490         {
5491           operands[2] = GEN_INT (-INTVAL (operands[2]));
5492           return "sub{l}\t{%2, %k0|%k0, %2}";
5493         }
5494       return "add{l}\t{%2, %k0|%k0, %2}";
5495     }
5496 }
5497   [(set (attr "type")
5498      (cond [(eq_attr "alternative" "1")
5499               (const_string "lea")
5500             ; Current assemblers are broken and do not allow @GOTOFF in
5501             ; ought but a memory context.
5502             (match_operand:SI 2 "pic_symbolic_operand" "")
5503               (const_string "lea")
5504             (match_operand:SI 2 "incdec_operand" "")
5505               (const_string "incdec")
5506            ]
5507            (const_string "alu")))
5508    (set_attr "mode" "SI")])
5509
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5511 (define_split
5512   [(set (match_operand:DI 0 "register_operand" "")
5513         (zero_extend:DI
5514           (plus:SI (match_operand:SI 1 "register_operand" "")
5515                    (match_operand:SI 2 "nonmemory_operand" ""))))
5516    (clobber (reg:CC FLAGS_REG))]
5517   "TARGET_64BIT && reload_completed
5518    && true_regnum (operands[0]) != true_regnum (operands[1])"
5519   [(set (match_dup 0)
5520         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5521 {
5522   operands[1] = gen_lowpart (Pmode, operands[1]);
5523   operands[2] = gen_lowpart (Pmode, operands[2]);
5524 })
5525
5526 (define_insn "*addsi_2"
5527   [(set (reg FLAGS_REG)
5528         (compare
5529           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5531           (const_int 0)))                       
5532    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533         (plus:SI (match_dup 1) (match_dup 2)))]
5534   "ix86_match_ccmode (insn, CCGOCmode)
5535    && ix86_binary_operator_ok (PLUS, SImode, operands)
5536    /* Current assemblers are broken and do not allow @GOTOFF in
5537       ought but a memory context.  */
5538    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5539 {
5540   switch (get_attr_type (insn))
5541     {
5542     case TYPE_INCDEC:
5543       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544       if (operands[2] == const1_rtx)
5545         return "inc{l}\t%0";
5546       else
5547         {
5548           gcc_assert (operands[2] == constm1_rtx);
5549           return "dec{l}\t%0";
5550         }
5551
5552     default:
5553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5556       if (GET_CODE (operands[2]) == CONST_INT
5557           && (INTVAL (operands[2]) == 128
5558               || (INTVAL (operands[2]) < 0
5559                   && INTVAL (operands[2]) != -128)))
5560         {
5561           operands[2] = GEN_INT (-INTVAL (operands[2]));
5562           return "sub{l}\t{%2, %0|%0, %2}";
5563         }
5564       return "add{l}\t{%2, %0|%0, %2}";
5565     }
5566 }
5567   [(set (attr "type")
5568      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569         (const_string "incdec")
5570         (const_string "alu")))
5571    (set_attr "mode" "SI")])
5572
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575   [(set (reg FLAGS_REG)
5576         (compare
5577           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578                    (match_operand:SI 2 "general_operand" "rmni"))
5579           (const_int 0)))                       
5580    (set (match_operand:DI 0 "register_operand" "=r")
5581         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583    && ix86_binary_operator_ok (PLUS, SImode, operands)
5584    /* Current assemblers are broken and do not allow @GOTOFF in
5585       ought but a memory context.  */
5586    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587 {
5588   switch (get_attr_type (insn))
5589     {
5590     case TYPE_INCDEC:
5591       if (operands[2] == const1_rtx)
5592         return "inc{l}\t%k0";
5593       else
5594         {
5595           gcc_assert (operands[2] == constm1_rtx);
5596           return "dec{l}\t%k0";
5597         }
5598
5599     default:
5600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602       if (GET_CODE (operands[2]) == CONST_INT
5603           && (INTVAL (operands[2]) == 128
5604               || (INTVAL (operands[2]) < 0
5605                   && INTVAL (operands[2]) != -128)))
5606         {
5607           operands[2] = GEN_INT (-INTVAL (operands[2]));
5608           return "sub{l}\t{%2, %k0|%k0, %2}";
5609         }
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5612 }
5613   [(set (attr "type")
5614      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615         (const_string "incdec")
5616         (const_string "alu")))
5617    (set_attr "mode" "SI")])
5618
5619 (define_insn "*addsi_3"
5620   [(set (reg FLAGS_REG)
5621         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623    (clobber (match_scratch:SI 0 "=r"))]
5624   "ix86_match_ccmode (insn, CCZmode)
5625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626    /* Current assemblers are broken and do not allow @GOTOFF in
5627       ought but a memory context.  */
5628    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629 {
5630   switch (get_attr_type (insn))
5631     {
5632     case TYPE_INCDEC:
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (operands[2] == const1_rtx)
5635         return "inc{l}\t%0";
5636       else
5637         {
5638           gcc_assert (operands[2] == constm1_rtx);
5639           return "dec{l}\t%0";
5640         }
5641
5642     default:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5646       if (GET_CODE (operands[2]) == CONST_INT
5647           && (INTVAL (operands[2]) == 128
5648               || (INTVAL (operands[2]) < 0
5649                   && INTVAL (operands[2]) != -128)))
5650         {
5651           operands[2] = GEN_INT (-INTVAL (operands[2]));
5652           return "sub{l}\t{%2, %0|%0, %2}";
5653         }
5654       return "add{l}\t{%2, %0|%0, %2}";
5655     }
5656 }
5657   [(set (attr "type")
5658      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659         (const_string "incdec")
5660         (const_string "alu")))
5661    (set_attr "mode" "SI")])
5662
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665   [(set (reg FLAGS_REG)
5666         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668    (set (match_operand:DI 0 "register_operand" "=r")
5669         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671    && ix86_binary_operator_ok (PLUS, SImode, operands)
5672    /* Current assemblers are broken and do not allow @GOTOFF in
5673       ought but a memory context.  */
5674    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675 {
5676   switch (get_attr_type (insn))
5677     {
5678     case TYPE_INCDEC:
5679       if (operands[2] == const1_rtx)
5680         return "inc{l}\t%k0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return "dec{l}\t%k0";
5685         }
5686
5687     default:
5688       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5690       if (GET_CODE (operands[2]) == CONST_INT
5691           && (INTVAL (operands[2]) == 128
5692               || (INTVAL (operands[2]) < 0
5693                   && INTVAL (operands[2]) != -128)))
5694         {
5695           operands[2] = GEN_INT (-INTVAL (operands[2]));
5696           return "sub{l}\t{%2, %k0|%k0, %2}";
5697         }
5698       return "add{l}\t{%2, %k0|%k0, %2}";
5699     }
5700 }
5701   [(set (attr "type")
5702      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703         (const_string "incdec")
5704         (const_string "alu")))
5705    (set_attr "mode" "SI")])
5706
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5709 ; is matched then.  We can't accept general immediate, because for
5710 ; case of overflows,  the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5712 ; when negated.
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716   [(set (reg FLAGS_REG)
5717         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718                  (match_operand:SI 2 "const_int_operand" "n")))
5719    (clobber (match_scratch:SI 0 "=rm"))]
5720   "ix86_match_ccmode (insn, CCGCmode)
5721    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5722 {
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_INCDEC:
5726       if (operands[2] == constm1_rtx)
5727         return "inc{l}\t%0";
5728       else
5729         {
5730           gcc_assert (operands[2] == const1_rtx);
5731           return "dec{l}\t%0";
5732         }
5733
5734     default:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5738       if ((INTVAL (operands[2]) == -128
5739            || (INTVAL (operands[2]) > 0
5740                && INTVAL (operands[2]) != 128)))
5741         return "sub{l}\t{%2, %0|%0, %2}";
5742       operands[2] = GEN_INT (-INTVAL (operands[2]));
5743       return "add{l}\t{%2, %0|%0, %2}";
5744     }
5745 }
5746   [(set (attr "type")
5747      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748         (const_string "incdec")
5749         (const_string "alu")))
5750    (set_attr "mode" "SI")])
5751
5752 (define_insn "*addsi_5"
5753   [(set (reg FLAGS_REG)
5754         (compare
5755           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756                    (match_operand:SI 2 "general_operand" "rmni"))
5757           (const_int 0)))                       
5758    (clobber (match_scratch:SI 0 "=r"))]
5759   "ix86_match_ccmode (insn, CCGOCmode)
5760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761    /* Current assemblers are broken and do not allow @GOTOFF in
5762       ought but a memory context.  */
5763    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769       if (operands[2] == const1_rtx)
5770         return "inc{l}\t%0";
5771       else
5772         {
5773           gcc_assert (operands[2] == constm1_rtx);
5774           return "dec{l}\t%0";
5775         }
5776
5777     default:
5778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5781       if (GET_CODE (operands[2]) == CONST_INT
5782           && (INTVAL (operands[2]) == 128
5783               || (INTVAL (operands[2]) < 0
5784                   && INTVAL (operands[2]) != -128)))
5785         {
5786           operands[2] = GEN_INT (-INTVAL (operands[2]));
5787           return "sub{l}\t{%2, %0|%0, %2}";
5788         }
5789       return "add{l}\t{%2, %0|%0, %2}";
5790     }
5791 }
5792   [(set (attr "type")
5793      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794         (const_string "incdec")
5795         (const_string "alu")))
5796    (set_attr "mode" "SI")])
5797
5798 (define_expand "addhi3"
5799   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801                             (match_operand:HI 2 "general_operand" "")))
5802               (clobber (reg:CC FLAGS_REG))])]
5803   "TARGET_HIMODE_MATH"
5804   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5805
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits.  This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5809
5810 (define_insn "*addhi_1_lea"
5811   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "!TARGET_PARTIAL_REG_STALL
5816    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817 {
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_LEA:
5821       return "#";
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{w}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{w}\t%0";
5829         }
5830
5831     default:
5832       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834       if (GET_CODE (operands[2]) == CONST_INT
5835           && (INTVAL (operands[2]) == 128
5836               || (INTVAL (operands[2]) < 0
5837                   && INTVAL (operands[2]) != -128)))
5838         {
5839           operands[2] = GEN_INT (-INTVAL (operands[2]));
5840           return "sub{w}\t{%2, %0|%0, %2}";
5841         }
5842       return "add{w}\t{%2, %0|%0, %2}";
5843     }
5844 }
5845   [(set (attr "type")
5846      (if_then_else (eq_attr "alternative" "2")
5847         (const_string "lea")
5848         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849            (const_string "incdec")
5850            (const_string "alu"))))
5851    (set_attr "mode" "HI,HI,SI")])
5852
5853 (define_insn "*addhi_1"
5854   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856                  (match_operand:HI 2 "general_operand" "ri,rm")))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "TARGET_PARTIAL_REG_STALL
5859    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5860 {
5861   switch (get_attr_type (insn))
5862     {
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{w}\t%0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{w}\t%0";
5870         }
5871
5872     default:
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (GET_CODE (operands[2]) == CONST_INT
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{w}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5885 }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "HI")])
5891
5892 (define_insn "*addhi_2"
5893   [(set (reg FLAGS_REG)
5894         (compare
5895           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5897           (const_int 0)))                       
5898    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899         (plus:HI (match_dup 1) (match_dup 2)))]
5900   "ix86_match_ccmode (insn, CCGOCmode)
5901    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902 {
5903   switch (get_attr_type (insn))
5904     {
5905     case TYPE_INCDEC:
5906       if (operands[2] == const1_rtx)
5907         return "inc{w}\t%0";
5908       else
5909         {
5910           gcc_assert (operands[2] == constm1_rtx);
5911           return "dec{w}\t%0";
5912         }
5913
5914     default:
5915       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917       if (GET_CODE (operands[2]) == CONST_INT
5918           && (INTVAL (operands[2]) == 128
5919               || (INTVAL (operands[2]) < 0
5920                   && INTVAL (operands[2]) != -128)))
5921         {
5922           operands[2] = GEN_INT (-INTVAL (operands[2]));
5923           return "sub{w}\t{%2, %0|%0, %2}";
5924         }
5925       return "add{w}\t{%2, %0|%0, %2}";
5926     }
5927 }
5928   [(set (attr "type")
5929      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930         (const_string "incdec")
5931         (const_string "alu")))
5932    (set_attr "mode" "HI")])
5933
5934 (define_insn "*addhi_3"
5935   [(set (reg FLAGS_REG)
5936         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938    (clobber (match_scratch:HI 0 "=r"))]
5939   "ix86_match_ccmode (insn, CCZmode)
5940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941 {
5942   switch (get_attr_type (insn))
5943     {
5944     case TYPE_INCDEC:
5945       if (operands[2] == const1_rtx)
5946         return "inc{w}\t%0";
5947       else
5948         {
5949           gcc_assert (operands[2] == constm1_rtx);
5950           return "dec{w}\t%0";
5951         }
5952
5953     default:
5954       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5956       if (GET_CODE (operands[2]) == CONST_INT
5957           && (INTVAL (operands[2]) == 128
5958               || (INTVAL (operands[2]) < 0
5959                   && INTVAL (operands[2]) != -128)))
5960         {
5961           operands[2] = GEN_INT (-INTVAL (operands[2]));
5962           return "sub{w}\t{%2, %0|%0, %2}";
5963         }
5964       return "add{w}\t{%2, %0|%0, %2}";
5965     }
5966 }
5967   [(set (attr "type")
5968      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969         (const_string "incdec")
5970         (const_string "alu")))
5971    (set_attr "mode" "HI")])
5972
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975   [(set (reg FLAGS_REG)
5976         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977                  (match_operand:HI 2 "const_int_operand" "n")))
5978    (clobber (match_scratch:HI 0 "=rm"))]
5979   "ix86_match_ccmode (insn, CCGCmode)
5980    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5981 {
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == constm1_rtx)
5986         return "inc{w}\t%0";
5987       else
5988         {
5989           gcc_assert (operands[2] == const1_rtx);
5990           return "dec{w}\t%0";
5991         }
5992
5993     default:
5994       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if ((INTVAL (operands[2]) == -128
5998            || (INTVAL (operands[2]) > 0
5999                && INTVAL (operands[2]) != 128)))
6000         return "sub{w}\t{%2, %0|%0, %2}";
6001       operands[2] = GEN_INT (-INTVAL (operands[2]));
6002       return "add{w}\t{%2, %0|%0, %2}";
6003     }
6004 }
6005   [(set (attr "type")
6006      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007         (const_string "incdec")
6008         (const_string "alu")))
6009    (set_attr "mode" "SI")])
6010
6011
6012 (define_insn "*addhi_5"
6013   [(set (reg FLAGS_REG)
6014         (compare
6015           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016                    (match_operand:HI 2 "general_operand" "rmni"))
6017           (const_int 0)))                       
6018    (clobber (match_scratch:HI 0 "=r"))]
6019   "ix86_match_ccmode (insn, CCGOCmode)
6020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == constm1_rtx);
6030           return "dec{w}\t%0";
6031         }
6032
6033     default:
6034       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6036       if (GET_CODE (operands[2]) == CONST_INT
6037           && (INTVAL (operands[2]) == 128
6038               || (INTVAL (operands[2]) < 0
6039                   && INTVAL (operands[2]) != -128)))
6040         {
6041           operands[2] = GEN_INT (-INTVAL (operands[2]));
6042           return "sub{w}\t{%2, %0|%0, %2}";
6043         }
6044       return "add{w}\t{%2, %0|%0, %2}";
6045     }
6046 }
6047   [(set (attr "type")
6048      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049         (const_string "incdec")
6050         (const_string "alu")))
6051    (set_attr "mode" "HI")])
6052
6053 (define_expand "addqi3"
6054   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056                             (match_operand:QI 2 "general_operand" "")))
6057               (clobber (reg:CC FLAGS_REG))])]
6058   "TARGET_QIMODE_MATH"
6059   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6060
6061 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6062 (define_insn "*addqi_1_lea"
6063   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066    (clobber (reg:CC FLAGS_REG))]
6067   "!TARGET_PARTIAL_REG_STALL
6068    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6069 {
6070   int widen = (which_alternative == 2);
6071   switch (get_attr_type (insn))
6072     {
6073     case TYPE_LEA:
6074       return "#";
6075     case TYPE_INCDEC:
6076       if (operands[2] == const1_rtx)
6077         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6078       else
6079         {
6080           gcc_assert (operands[2] == constm1_rtx);
6081           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6082         }
6083
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           if (widen)
6094             return "sub{l}\t{%2, %k0|%k0, %2}";
6095           else
6096             return "sub{b}\t{%2, %0|%0, %2}";
6097         }
6098       if (widen)
6099         return "add{l}\t{%k2, %k0|%k0, %k2}";
6100       else
6101         return "add{b}\t{%2, %0|%0, %2}";
6102     }
6103 }
6104   [(set (attr "type")
6105      (if_then_else (eq_attr "alternative" "3")
6106         (const_string "lea")
6107         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108            (const_string "incdec")
6109            (const_string "alu"))))
6110    (set_attr "mode" "QI,QI,SI,SI")])
6111
6112 (define_insn "*addqi_1"
6113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116    (clobber (reg:CC FLAGS_REG))]
6117   "TARGET_PARTIAL_REG_STALL
6118    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119 {
6120   int widen = (which_alternative == 2);
6121   switch (get_attr_type (insn))
6122     {
6123     case TYPE_INCDEC:
6124       if (operands[2] == const1_rtx)
6125         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6126       else
6127         {
6128           gcc_assert (operands[2] == constm1_rtx);
6129           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6130         }
6131
6132     default:
6133       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if (GET_CODE (operands[2]) == CONST_INT
6136           && (INTVAL (operands[2]) == 128
6137               || (INTVAL (operands[2]) < 0
6138                   && INTVAL (operands[2]) != -128)))
6139         {
6140           operands[2] = GEN_INT (-INTVAL (operands[2]));
6141           if (widen)
6142             return "sub{l}\t{%2, %k0|%k0, %2}";
6143           else
6144             return "sub{b}\t{%2, %0|%0, %2}";
6145         }
6146       if (widen)
6147         return "add{l}\t{%k2, %k0|%k0, %k2}";
6148       else
6149         return "add{b}\t{%2, %0|%0, %2}";
6150     }
6151 }
6152   [(set (attr "type")
6153      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154         (const_string "incdec")
6155         (const_string "alu")))
6156    (set_attr "mode" "QI,QI,SI")])
6157
6158 (define_insn "*addqi_1_slp"
6159   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160         (plus:QI (match_dup 0)
6161                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6162    (clobber (reg:CC FLAGS_REG))]
6163   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[1] == const1_rtx)
6170         return "inc{b}\t%0";
6171       else
6172         {
6173           gcc_assert (operands[1] == constm1_rtx);
6174           return "dec{b}\t%0";
6175         }
6176
6177     default:
6178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6179       if (GET_CODE (operands[1]) == CONST_INT
6180           && INTVAL (operands[1]) < 0)
6181         {
6182           operands[1] = GEN_INT (-INTVAL (operands[1]));
6183           return "sub{b}\t{%1, %0|%0, %1}";
6184         }
6185       return "add{b}\t{%1, %0|%0, %1}";
6186     }
6187 }
6188   [(set (attr "type")
6189      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190         (const_string "incdec")
6191         (const_string "alu1")))
6192    (set (attr "memory")
6193      (if_then_else (match_operand 1 "memory_operand" "")
6194         (const_string "load")
6195         (const_string "none")))
6196    (set_attr "mode" "QI")])
6197
6198 (define_insn "*addqi_2"
6199   [(set (reg FLAGS_REG)
6200         (compare
6201           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6203           (const_int 0)))
6204    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205         (plus:QI (match_dup 1) (match_dup 2)))]
6206   "ix86_match_ccmode (insn, CCGOCmode)
6207    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == const1_rtx)
6213         return "inc{b}\t%0";
6214       else
6215         {
6216           gcc_assert (operands[2] == constm1_rtx
6217                       || (GET_CODE (operands[2]) == CONST_INT
6218                           && INTVAL (operands[2]) == 255));
6219           return "dec{b}\t%0";
6220         }
6221
6222     default:
6223       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6224       if (GET_CODE (operands[2]) == CONST_INT
6225           && INTVAL (operands[2]) < 0)
6226         {
6227           operands[2] = GEN_INT (-INTVAL (operands[2]));
6228           return "sub{b}\t{%2, %0|%0, %2}";
6229         }
6230       return "add{b}\t{%2, %0|%0, %2}";
6231     }
6232 }
6233   [(set (attr "type")
6234      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235         (const_string "incdec")
6236         (const_string "alu")))
6237    (set_attr "mode" "QI")])
6238
6239 (define_insn "*addqi_3"
6240   [(set (reg FLAGS_REG)
6241         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243    (clobber (match_scratch:QI 0 "=q"))]
6244   "ix86_match_ccmode (insn, CCZmode)
6245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6246 {
6247   switch (get_attr_type (insn))
6248     {
6249     case TYPE_INCDEC:
6250       if (operands[2] == const1_rtx)
6251         return "inc{b}\t%0";
6252       else
6253         {
6254           gcc_assert (operands[2] == constm1_rtx
6255                       || (GET_CODE (operands[2]) == CONST_INT
6256                           && INTVAL (operands[2]) == 255));
6257           return "dec{b}\t%0";
6258         }
6259
6260     default:
6261       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6262       if (GET_CODE (operands[2]) == CONST_INT
6263           && INTVAL (operands[2]) < 0)
6264         {
6265           operands[2] = GEN_INT (-INTVAL (operands[2]));
6266           return "sub{b}\t{%2, %0|%0, %2}";
6267         }
6268       return "add{b}\t{%2, %0|%0, %2}";
6269     }
6270 }
6271   [(set (attr "type")
6272      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273         (const_string "incdec")
6274         (const_string "alu")))
6275    (set_attr "mode" "QI")])
6276
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279   [(set (reg FLAGS_REG)
6280         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281                  (match_operand:QI 2 "const_int_operand" "n")))
6282    (clobber (match_scratch:QI 0 "=qm"))]
6283   "ix86_match_ccmode (insn, CCGCmode)
6284    && (INTVAL (operands[2]) & 0xff) != 0x80"
6285 {
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       if (operands[2] == constm1_rtx
6290           || (GET_CODE (operands[2]) == CONST_INT
6291               && INTVAL (operands[2]) == 255))
6292         return "inc{b}\t%0";
6293       else
6294         {
6295           gcc_assert (operands[2] == const1_rtx);
6296           return "dec{b}\t%0";
6297         }
6298
6299     default:
6300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301       if (INTVAL (operands[2]) < 0)
6302         {
6303           operands[2] = GEN_INT (-INTVAL (operands[2]));
6304           return "add{b}\t{%2, %0|%0, %2}";
6305         }
6306       return "sub{b}\t{%2, %0|%0, %2}";
6307     }
6308 }
6309   [(set (attr "type")
6310      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311         (const_string "incdec")
6312         (const_string "alu")))
6313    (set_attr "mode" "QI")])
6314
6315
6316 (define_insn "*addqi_5"
6317   [(set (reg FLAGS_REG)
6318         (compare
6319           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320                    (match_operand:QI 2 "general_operand" "qmni"))
6321           (const_int 0)))
6322    (clobber (match_scratch:QI 0 "=q"))]
6323   "ix86_match_ccmode (insn, CCGOCmode)
6324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == const1_rtx)
6330         return "inc{b}\t%0";
6331       else
6332         {
6333           gcc_assert (operands[2] == constm1_rtx
6334                       || (GET_CODE (operands[2]) == CONST_INT
6335                           && INTVAL (operands[2]) == 255));
6336           return "dec{b}\t%0";
6337         }
6338
6339     default:
6340       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6341       if (GET_CODE (operands[2]) == CONST_INT
6342           && INTVAL (operands[2]) < 0)
6343         {
6344           operands[2] = GEN_INT (-INTVAL (operands[2]));
6345           return "sub{b}\t{%2, %0|%0, %2}";
6346         }
6347       return "add{b}\t{%2, %0|%0, %2}";
6348     }
6349 }
6350   [(set (attr "type")
6351      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352         (const_string "incdec")
6353         (const_string "alu")))
6354    (set_attr "mode" "QI")])
6355
6356
6357 (define_insn "addqi_ext_1"
6358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359                          (const_int 8)
6360                          (const_int 8))
6361         (plus:SI
6362           (zero_extract:SI
6363             (match_operand 1 "ext_register_operand" "0")
6364             (const_int 8)
6365             (const_int 8))
6366           (match_operand:QI 2 "general_operand" "Qmn")))
6367    (clobber (reg:CC FLAGS_REG))]
6368   "!TARGET_64BIT"
6369 {
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{b}\t%h0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx
6378                       || (GET_CODE (operands[2]) == CONST_INT
6379                           && INTVAL (operands[2]) == 255));
6380           return "dec{b}\t%h0";
6381         }
6382
6383     default:
6384       return "add{b}\t{%2, %h0|%h0, %2}";
6385     }
6386 }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6392
6393 (define_insn "*addqi_ext_1_rex64"
6394   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395                          (const_int 8)
6396                          (const_int 8))
6397         (plus:SI
6398           (zero_extract:SI
6399             (match_operand 1 "ext_register_operand" "0")
6400             (const_int 8)
6401             (const_int 8))
6402           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "TARGET_64BIT"
6405 {
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == const1_rtx)
6410         return "inc{b}\t%h0";
6411       else
6412         {
6413           gcc_assert (operands[2] == constm1_rtx
6414                       || (GET_CODE (operands[2]) == CONST_INT
6415                           && INTVAL (operands[2]) == 255));
6416           return "dec{b}\t%h0";
6417         }
6418
6419     default:
6420       return "add{b}\t{%2, %h0|%h0, %2}";
6421     }
6422 }
6423   [(set (attr "type")
6424      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425         (const_string "incdec")
6426         (const_string "alu")))
6427    (set_attr "mode" "QI")])
6428
6429 (define_insn "*addqi_ext_2"
6430   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431                          (const_int 8)
6432                          (const_int 8))
6433         (plus:SI
6434           (zero_extract:SI
6435             (match_operand 1 "ext_register_operand" "%0")
6436             (const_int 8)
6437             (const_int 8))
6438           (zero_extract:SI
6439             (match_operand 2 "ext_register_operand" "Q")
6440             (const_int 8)
6441             (const_int 8))))
6442    (clobber (reg:CC FLAGS_REG))]
6443   ""
6444   "add{b}\t{%h2, %h0|%h0, %h2}"
6445   [(set_attr "type" "alu")
6446    (set_attr "mode" "QI")])
6447
6448 ;; The patterns that match these are at the end of this file.
6449
6450 (define_expand "addxf3"
6451   [(set (match_operand:XF 0 "register_operand" "")
6452         (plus:XF (match_operand:XF 1 "register_operand" "")
6453                  (match_operand:XF 2 "register_operand" "")))]
6454   "TARGET_80387"
6455   "")
6456
6457 (define_expand "adddf3"
6458   [(set (match_operand:DF 0 "register_operand" "")
6459         (plus:DF (match_operand:DF 1 "register_operand" "")
6460                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6462   "")
6463
6464 (define_expand "addsf3"
6465   [(set (match_operand:SF 0 "register_operand" "")
6466         (plus:SF (match_operand:SF 1 "register_operand" "")
6467                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6468   "TARGET_80387 || TARGET_SSE_MATH"
6469   "")
6470 \f
6471 ;; Subtract instructions
6472
6473 ;; %%% splits for subditi3
6474
6475 (define_expand "subti3"
6476   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478                              (match_operand:TI 2 "x86_64_general_operand" "")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   "TARGET_64BIT"
6481   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6482
6483 (define_insn "*subti3_1"
6484   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6489   "#")
6490
6491 (define_split
6492   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494                   (match_operand:TI 2 "general_operand" "")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && reload_completed"
6497   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499    (parallel [(set (match_dup 3)
6500                    (minus:DI (match_dup 4)
6501                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6502                                       (match_dup 5))))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   "split_ti (operands+0, 1, operands+0, operands+3);
6505    split_ti (operands+1, 1, operands+1, operands+4);
6506    split_ti (operands+2, 1, operands+2, operands+5);")
6507
6508 ;; %%% splits for subsidi3
6509
6510 (define_expand "subdi3"
6511   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513                              (match_operand:DI 2 "x86_64_general_operand" "")))
6514               (clobber (reg:CC FLAGS_REG))])]
6515   ""
6516   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6517
6518 (define_insn "*subdi3_1"
6519   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6522    (clobber (reg:CC FLAGS_REG))]
6523   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6524   "#")
6525
6526 (define_split
6527   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529                   (match_operand:DI 2 "general_operand" "")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "!TARGET_64BIT && reload_completed"
6532   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534    (parallel [(set (match_dup 3)
6535                    (minus:SI (match_dup 4)
6536                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6537                                       (match_dup 5))))
6538               (clobber (reg:CC FLAGS_REG))])]
6539   "split_di (operands+0, 1, operands+0, operands+3);
6540    split_di (operands+1, 1, operands+1, operands+4);
6541    split_di (operands+2, 1, operands+2, operands+5);")
6542
6543 (define_insn "subdi3_carry_rex64"
6544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550   "sbb{q}\t{%2, %0|%0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "pent_pair" "pu")
6553    (set_attr "mode" "DI")])
6554
6555 (define_insn "*subdi_1_rex64"
6556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "TARGET_64BIT && 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_2_rex64"
6566   [(set (reg FLAGS_REG)
6567         (compare
6568           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6570           (const_int 0)))
6571    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572         (minus:DI (match_dup 1) (match_dup 2)))]
6573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575   "sub{q}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "mode" "DI")])
6578
6579 (define_insn "*subdi_3_rex63"
6580   [(set (reg FLAGS_REG)
6581         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584         (minus:DI (match_dup 1) (match_dup 2)))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "DI")])
6590
6591 (define_insn "subqi3_carry"
6592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595                (match_operand:QI 2 "general_operand" "qi,qm"))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598   "sbb{b}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "pent_pair" "pu")
6601    (set_attr "mode" "QI")])
6602
6603 (define_insn "subhi3_carry"
6604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607                (match_operand:HI 2 "general_operand" "ri,rm"))))
6608    (clobber (reg:CC FLAGS_REG))]
6609   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610   "sbb{w}\t{%2, %0|%0, %2}"
6611   [(set_attr "type" "alu")
6612    (set_attr "pent_pair" "pu")
6613    (set_attr "mode" "HI")])
6614
6615 (define_insn "subsi3_carry"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619                (match_operand:SI 2 "general_operand" "ri,rm"))))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622   "sbb{l}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "pent_pair" "pu")
6625    (set_attr "mode" "SI")])
6626
6627 (define_insn "subsi3_carry_zext"
6628   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6629           (zero_extend:DI
6630             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635   "sbb{l}\t{%2, %k0|%k0, %2}"
6636   [(set_attr "type" "alu")
6637    (set_attr "pent_pair" "pu")
6638    (set_attr "mode" "SI")])
6639
6640 (define_expand "subsi3"
6641   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643                              (match_operand:SI 2 "general_operand" "")))
6644               (clobber (reg:CC FLAGS_REG))])]
6645   ""
6646   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6647
6648 (define_insn "*subsi_1"
6649   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651                   (match_operand:SI 2 "general_operand" "ri,rm")))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sub{l}\t{%2, %0|%0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "mode" "SI")])
6657
6658 (define_insn "*subsi_1_zext"
6659   [(set (match_operand:DI 0 "register_operand" "=r")
6660         (zero_extend:DI
6661           (minus:SI (match_operand:SI 1 "register_operand" "0")
6662                     (match_operand:SI 2 "general_operand" "rim"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sub{l}\t{%2, %k0|%k0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "SI")])
6668
6669 (define_insn "*subsi_2"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673                     (match_operand:SI 2 "general_operand" "ri,rm"))
6674           (const_int 0)))
6675    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676         (minus:SI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCGOCmode)
6678    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679   "sub{l}\t{%2, %0|%0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "SI")])
6682
6683 (define_insn "*subsi_2_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SI (match_operand:SI 1 "register_operand" "0")
6687                     (match_operand:SI 2 "general_operand" "rim"))
6688           (const_int 0)))
6689    (set (match_operand:DI 0 "register_operand" "=r")
6690         (zero_extend:DI
6691           (minus:SI (match_dup 1)
6692                     (match_dup 2))))]
6693   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695   "sub{l}\t{%2, %k0|%k0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "SI")])
6698
6699 (define_insn "*subsi_3"
6700   [(set (reg FLAGS_REG)
6701         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702                  (match_operand:SI 2 "general_operand" "ri,rm")))
6703    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704         (minus:SI (match_dup 1) (match_dup 2)))]
6705   "ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sub{l}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "SI")])
6710
6711 (define_insn "*subsi_3_zext"
6712   [(set (reg FLAGS_REG)
6713         (compare (match_operand:SI 1 "register_operand" "0")
6714                  (match_operand:SI 2 "general_operand" "rim")))
6715    (set (match_operand:DI 0 "register_operand" "=r")
6716         (zero_extend:DI
6717           (minus:SI (match_dup 1)
6718                     (match_dup 2))))]
6719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721   "sub{q}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "DI")])
6724
6725 (define_expand "subhi3"
6726   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728                              (match_operand:HI 2 "general_operand" "")))
6729               (clobber (reg:CC FLAGS_REG))])]
6730   "TARGET_HIMODE_MATH"
6731   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6732
6733 (define_insn "*subhi_1"
6734   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736                   (match_operand:HI 2 "general_operand" "ri,rm")))
6737    (clobber (reg:CC FLAGS_REG))]
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_2"
6744   [(set (reg FLAGS_REG)
6745         (compare
6746           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747                     (match_operand:HI 2 "general_operand" "ri,rm"))
6748           (const_int 0)))
6749    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750         (minus:HI (match_dup 1) (match_dup 2)))]
6751   "ix86_match_ccmode (insn, CCGOCmode)
6752    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6753   "sub{w}\t{%2, %0|%0, %2}"
6754   [(set_attr "type" "alu")
6755    (set_attr "mode" "HI")])
6756
6757 (define_insn "*subhi_3"
6758   [(set (reg FLAGS_REG)
6759         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760                  (match_operand:HI 2 "general_operand" "ri,rm")))
6761    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762         (minus:HI (match_dup 1) (match_dup 2)))]
6763   "ix86_match_ccmode (insn, CCmode)
6764    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765   "sub{w}\t{%2, %0|%0, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "mode" "HI")])
6768
6769 (define_expand "subqi3"
6770   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772                              (match_operand:QI 2 "general_operand" "")))
6773               (clobber (reg:CC FLAGS_REG))])]
6774   "TARGET_QIMODE_MATH"
6775   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6776
6777 (define_insn "*subqi_1"
6778   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783   "sub{b}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "QI")])
6786
6787 (define_insn "*subqi_1_slp"
6788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789         (minus:QI (match_dup 0)
6790                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794   "sub{b}\t{%1, %0|%0, %1}"
6795   [(set_attr "type" "alu1")
6796    (set_attr "mode" "QI")])
6797
6798 (define_insn "*subqi_2"
6799   [(set (reg FLAGS_REG)
6800         (compare
6801           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802                     (match_operand:QI 2 "general_operand" "qi,qm"))
6803           (const_int 0)))
6804    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805         (minus:HI (match_dup 1) (match_dup 2)))]
6806   "ix86_match_ccmode (insn, CCGOCmode)
6807    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808   "sub{b}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "QI")])
6811
6812 (define_insn "*subqi_3"
6813   [(set (reg FLAGS_REG)
6814         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815                  (match_operand:QI 2 "general_operand" "qi,qm")))
6816    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817         (minus:HI (match_dup 1) (match_dup 2)))]
6818   "ix86_match_ccmode (insn, CCmode)
6819    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820   "sub{b}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "QI")])
6823
6824 ;; The patterns that match these are at the end of this file.
6825
6826 (define_expand "subxf3"
6827   [(set (match_operand:XF 0 "register_operand" "")
6828         (minus:XF (match_operand:XF 1 "register_operand" "")
6829                   (match_operand:XF 2 "register_operand" "")))]
6830   "TARGET_80387"
6831   "")
6832
6833 (define_expand "subdf3"
6834   [(set (match_operand:DF 0 "register_operand" "")
6835         (minus:DF (match_operand:DF 1 "register_operand" "")
6836                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6837   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6838   "")
6839
6840 (define_expand "subsf3"
6841   [(set (match_operand:SF 0 "register_operand" "")
6842         (minus:SF (match_operand:SF 1 "register_operand" "")
6843                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6844   "TARGET_80387 || TARGET_SSE_MATH"
6845   "")
6846 \f
6847 ;; Multiply instructions
6848
6849 (define_expand "muldi3"
6850   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851                    (mult:DI (match_operand:DI 1 "register_operand" "")
6852                             (match_operand:DI 2 "x86_64_general_operand" "")))
6853               (clobber (reg:CC FLAGS_REG))])]
6854   "TARGET_64BIT"
6855   "")
6856
6857 (define_insn "*muldi3_1_rex64"
6858   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_64BIT
6863    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6864   "@
6865    imul{q}\t{%2, %1, %0|%0, %1, %2}
6866    imul{q}\t{%2, %1, %0|%0, %1, %2}
6867    imul{q}\t{%2, %0|%0, %2}"
6868   [(set_attr "type" "imul")
6869    (set_attr "prefix_0f" "0,0,1")
6870    (set (attr "athlon_decode")
6871         (cond [(eq_attr "cpu" "athlon")
6872                   (const_string "vector")
6873                (eq_attr "alternative" "1")
6874                   (const_string "vector")
6875                (and (eq_attr "alternative" "2")
6876                     (match_operand 1 "memory_operand" ""))
6877                   (const_string "vector")]
6878               (const_string "direct")))
6879    (set_attr "mode" "DI")])
6880
6881 (define_expand "mulsi3"
6882   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883                    (mult:SI (match_operand:SI 1 "register_operand" "")
6884                             (match_operand:SI 2 "general_operand" "")))
6885               (clobber (reg:CC FLAGS_REG))])]
6886   ""
6887   "")
6888
6889 (define_insn "*mulsi3_1"
6890   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6893    (clobber (reg:CC FLAGS_REG))]
6894   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6895   "@
6896    imul{l}\t{%2, %1, %0|%0, %1, %2}
6897    imul{l}\t{%2, %1, %0|%0, %1, %2}
6898    imul{l}\t{%2, %0|%0, %2}"
6899   [(set_attr "type" "imul")
6900    (set_attr "prefix_0f" "0,0,1")
6901    (set (attr "athlon_decode")
6902         (cond [(eq_attr "cpu" "athlon")
6903                   (const_string "vector")
6904                (eq_attr "alternative" "1")
6905                   (const_string "vector")
6906                (and (eq_attr "alternative" "2")
6907                     (match_operand 1 "memory_operand" ""))
6908                   (const_string "vector")]
6909               (const_string "direct")))
6910    (set_attr "mode" "SI")])
6911
6912 (define_insn "*mulsi3_1_zext"
6913   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914         (zero_extend:DI
6915           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "TARGET_64BIT
6919    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6920   "@
6921    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923    imul{l}\t{%2, %k0|%k0, %2}"
6924   [(set_attr "type" "imul")
6925    (set_attr "prefix_0f" "0,0,1")
6926    (set (attr "athlon_decode")
6927         (cond [(eq_attr "cpu" "athlon")
6928                   (const_string "vector")
6929                (eq_attr "alternative" "1")
6930                   (const_string "vector")
6931                (and (eq_attr "alternative" "2")
6932                     (match_operand 1 "memory_operand" ""))
6933                   (const_string "vector")]
6934               (const_string "direct")))
6935    (set_attr "mode" "SI")])
6936
6937 (define_expand "mulhi3"
6938   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939                    (mult:HI (match_operand:HI 1 "register_operand" "")
6940                             (match_operand:HI 2 "general_operand" "")))
6941               (clobber (reg:CC FLAGS_REG))])]
6942   "TARGET_HIMODE_MATH"
6943   "")
6944
6945 (define_insn "*mulhi3_1"
6946   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6951   "@
6952    imul{w}\t{%2, %1, %0|%0, %1, %2}
6953    imul{w}\t{%2, %1, %0|%0, %1, %2}
6954    imul{w}\t{%2, %0|%0, %2}"
6955   [(set_attr "type" "imul")
6956    (set_attr "prefix_0f" "0,0,1")
6957    (set (attr "athlon_decode")
6958         (cond [(eq_attr "cpu" "athlon")
6959                   (const_string "vector")
6960                (eq_attr "alternative" "1,2")
6961                   (const_string "vector")]
6962               (const_string "direct")))
6963    (set_attr "mode" "HI")])
6964
6965 (define_expand "mulqi3"
6966   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968                             (match_operand:QI 2 "register_operand" "")))
6969               (clobber (reg:CC FLAGS_REG))])]
6970   "TARGET_QIMODE_MATH"
6971   "")
6972
6973 (define_insn "*mulqi3_1"
6974   [(set (match_operand:QI 0 "register_operand" "=a")
6975         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977    (clobber (reg:CC FLAGS_REG))]
6978   "TARGET_QIMODE_MATH
6979    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6980   "mul{b}\t%2"
6981   [(set_attr "type" "imul")
6982    (set_attr "length_immediate" "0")
6983    (set (attr "athlon_decode")
6984      (if_then_else (eq_attr "cpu" "athlon")
6985         (const_string "vector")
6986         (const_string "direct")))
6987    (set_attr "mode" "QI")])
6988
6989 (define_expand "umulqihi3"
6990   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991                    (mult:HI (zero_extend:HI
6992                               (match_operand:QI 1 "nonimmediate_operand" ""))
6993                             (zero_extend:HI
6994                               (match_operand:QI 2 "register_operand" ""))))
6995               (clobber (reg:CC FLAGS_REG))])]
6996   "TARGET_QIMODE_MATH"
6997   "")
6998
6999 (define_insn "*umulqihi3_1"
7000   [(set (match_operand:HI 0 "register_operand" "=a")
7001         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "TARGET_QIMODE_MATH
7005    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006   "mul{b}\t%2"
7007   [(set_attr "type" "imul")
7008    (set_attr "length_immediate" "0")
7009    (set (attr "athlon_decode")
7010      (if_then_else (eq_attr "cpu" "athlon")
7011         (const_string "vector")
7012         (const_string "direct")))
7013    (set_attr "mode" "QI")])
7014
7015 (define_expand "mulqihi3"
7016   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019               (clobber (reg:CC FLAGS_REG))])]
7020   "TARGET_QIMODE_MATH"
7021   "")
7022
7023 (define_insn "*mulqihi3_insn"
7024   [(set (match_operand:HI 0 "register_operand" "=a")
7025         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "TARGET_QIMODE_MATH
7029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7030   "imul{b}\t%2"
7031   [(set_attr "type" "imul")
7032    (set_attr "length_immediate" "0")
7033    (set (attr "athlon_decode")
7034      (if_then_else (eq_attr "cpu" "athlon")
7035         (const_string "vector")
7036         (const_string "direct")))
7037    (set_attr "mode" "QI")])
7038
7039 (define_expand "umulditi3"
7040   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041                    (mult:TI (zero_extend:TI
7042                               (match_operand:DI 1 "nonimmediate_operand" ""))
7043                             (zero_extend:TI
7044                               (match_operand:DI 2 "register_operand" ""))))
7045               (clobber (reg:CC FLAGS_REG))])]
7046   "TARGET_64BIT"
7047   "")
7048
7049 (define_insn "*umulditi3_insn"
7050   [(set (match_operand:TI 0 "register_operand" "=A")
7051         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "TARGET_64BIT
7055    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7056   "mul{q}\t%2"
7057   [(set_attr "type" "imul")
7058    (set_attr "length_immediate" "0")
7059    (set (attr "athlon_decode")
7060      (if_then_else (eq_attr "cpu" "athlon")
7061         (const_string "vector")
7062         (const_string "double")))
7063    (set_attr "mode" "DI")])
7064
7065 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066 (define_expand "umulsidi3"
7067   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068                    (mult:DI (zero_extend:DI
7069                               (match_operand:SI 1 "nonimmediate_operand" ""))
7070                             (zero_extend:DI
7071                               (match_operand:SI 2 "register_operand" ""))))
7072               (clobber (reg:CC FLAGS_REG))])]
7073   "!TARGET_64BIT"
7074   "")
7075
7076 (define_insn "*umulsidi3_insn"
7077   [(set (match_operand:DI 0 "register_operand" "=A")
7078         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080    (clobber (reg:CC FLAGS_REG))]
7081   "!TARGET_64BIT
7082    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083   "mul{l}\t%2"
7084   [(set_attr "type" "imul")
7085    (set_attr "length_immediate" "0")
7086    (set (attr "athlon_decode")
7087      (if_then_else (eq_attr "cpu" "athlon")
7088         (const_string "vector")
7089         (const_string "double")))
7090    (set_attr "mode" "SI")])
7091
7092 (define_expand "mulditi3"
7093   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094                    (mult:TI (sign_extend:TI
7095                               (match_operand:DI 1 "nonimmediate_operand" ""))
7096                             (sign_extend:TI
7097                               (match_operand:DI 2 "register_operand" ""))))
7098               (clobber (reg:CC FLAGS_REG))])]
7099   "TARGET_64BIT"
7100   "")
7101
7102 (define_insn "*mulditi3_insn"
7103   [(set (match_operand:TI 0 "register_operand" "=A")
7104         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106    (clobber (reg:CC FLAGS_REG))]
7107   "TARGET_64BIT
7108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109   "imul{q}\t%2"
7110   [(set_attr "type" "imul")
7111    (set_attr "length_immediate" "0")
7112    (set (attr "athlon_decode")
7113      (if_then_else (eq_attr "cpu" "athlon")
7114         (const_string "vector")
7115         (const_string "double")))
7116    (set_attr "mode" "DI")])
7117
7118 (define_expand "mulsidi3"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120                    (mult:DI (sign_extend:DI
7121                               (match_operand:SI 1 "nonimmediate_operand" ""))
7122                             (sign_extend:DI
7123                               (match_operand:SI 2 "register_operand" ""))))
7124               (clobber (reg:CC FLAGS_REG))])]
7125   "!TARGET_64BIT"
7126   "")
7127
7128 (define_insn "*mulsidi3_insn"
7129   [(set (match_operand:DI 0 "register_operand" "=A")
7130         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "!TARGET_64BIT
7134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135   "imul{l}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "mode" "SI")])
7143
7144 (define_expand "umuldi3_highpart"
7145   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7146                    (truncate:DI
7147                      (lshiftrt:TI
7148                        (mult:TI (zero_extend:TI
7149                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7150                                 (zero_extend:TI
7151                                   (match_operand:DI 2 "register_operand" "")))
7152                        (const_int 64))))
7153               (clobber (match_scratch:DI 3 ""))
7154               (clobber (reg:CC FLAGS_REG))])]
7155   "TARGET_64BIT"
7156   "")
7157
7158 (define_insn "*umuldi3_highpart_rex64"
7159   [(set (match_operand:DI 0 "register_operand" "=d")
7160         (truncate:DI
7161           (lshiftrt:TI
7162             (mult:TI (zero_extend:TI
7163                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7164                      (zero_extend:TI
7165                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7166             (const_int 64))))
7167    (clobber (match_scratch:DI 3 "=1"))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "TARGET_64BIT
7170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171   "mul{q}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "DI")])
7179
7180 (define_expand "umulsi3_highpart"
7181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182                    (truncate:SI
7183                      (lshiftrt:DI
7184                        (mult:DI (zero_extend:DI
7185                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7186                                 (zero_extend:DI
7187                                   (match_operand:SI 2 "register_operand" "")))
7188                        (const_int 32))))
7189               (clobber (match_scratch:SI 3 ""))
7190               (clobber (reg:CC FLAGS_REG))])]
7191   ""
7192   "")
7193
7194 (define_insn "*umulsi3_highpart_insn"
7195   [(set (match_operand:SI 0 "register_operand" "=d")
7196         (truncate:SI
7197           (lshiftrt:DI
7198             (mult:DI (zero_extend:DI
7199                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7200                      (zero_extend:DI
7201                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7202             (const_int 32))))
7203    (clobber (match_scratch:SI 3 "=1"))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7206   "mul{l}\t%2"
7207   [(set_attr "type" "imul")
7208    (set_attr "length_immediate" "0")
7209    (set (attr "athlon_decode")
7210      (if_then_else (eq_attr "cpu" "athlon")
7211         (const_string "vector")
7212         (const_string "double")))
7213    (set_attr "mode" "SI")])
7214
7215 (define_insn "*umulsi3_highpart_zext"
7216   [(set (match_operand:DI 0 "register_operand" "=d")
7217         (zero_extend:DI (truncate:SI
7218           (lshiftrt:DI
7219             (mult:DI (zero_extend:DI
7220                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7221                      (zero_extend:DI
7222                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7223             (const_int 32)))))
7224    (clobber (match_scratch:SI 3 "=1"))
7225    (clobber (reg:CC FLAGS_REG))]
7226   "TARGET_64BIT
7227    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228   "mul{l}\t%2"
7229   [(set_attr "type" "imul")
7230    (set_attr "length_immediate" "0")
7231    (set (attr "athlon_decode")
7232      (if_then_else (eq_attr "cpu" "athlon")
7233         (const_string "vector")
7234         (const_string "double")))
7235    (set_attr "mode" "SI")])
7236
7237 (define_expand "smuldi3_highpart"
7238   [(parallel [(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" ""))
7243                                 (sign_extend:TI
7244                                   (match_operand:DI 2 "register_operand" "")))
7245                        (const_int 64))))
7246               (clobber (match_scratch:DI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   "TARGET_64BIT"
7249   "")
7250
7251 (define_insn "*smuldi3_highpart_rex64"
7252   [(set (match_operand:DI 0 "register_operand" "=d")
7253         (truncate:DI
7254           (lshiftrt:TI
7255             (mult:TI (sign_extend:TI
7256                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257                      (sign_extend:TI
7258                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259             (const_int 64))))
7260    (clobber (match_scratch:DI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "TARGET_64BIT
7263    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264   "imul{q}\t%2"
7265   [(set_attr "type" "imul")
7266    (set (attr "athlon_decode")
7267      (if_then_else (eq_attr "cpu" "athlon")
7268         (const_string "vector")
7269         (const_string "double")))
7270    (set_attr "mode" "DI")])
7271
7272 (define_expand "smulsi3_highpart"
7273   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7274                    (truncate:SI
7275                      (lshiftrt:DI
7276                        (mult:DI (sign_extend:DI
7277                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7278                                 (sign_extend:DI
7279                                   (match_operand:SI 2 "register_operand" "")))
7280                        (const_int 32))))
7281               (clobber (match_scratch:SI 3 ""))
7282               (clobber (reg:CC FLAGS_REG))])]
7283   ""
7284   "")
7285
7286 (define_insn "*smulsi3_highpart_insn"
7287   [(set (match_operand:SI 0 "register_operand" "=d")
7288         (truncate:SI
7289           (lshiftrt:DI
7290             (mult:DI (sign_extend:DI
7291                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292                      (sign_extend:DI
7293                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294             (const_int 32))))
7295    (clobber (match_scratch:SI 3 "=1"))
7296    (clobber (reg:CC FLAGS_REG))]
7297   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7298   "imul{l}\t%2"
7299   [(set_attr "type" "imul")
7300    (set (attr "athlon_decode")
7301      (if_then_else (eq_attr "cpu" "athlon")
7302         (const_string "vector")
7303         (const_string "double")))
7304    (set_attr "mode" "SI")])
7305
7306 (define_insn "*smulsi3_highpart_zext"
7307   [(set (match_operand:DI 0 "register_operand" "=d")
7308         (zero_extend:DI (truncate:SI
7309           (lshiftrt:DI
7310             (mult:DI (sign_extend:DI
7311                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7312                      (sign_extend:DI
7313                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7314             (const_int 32)))))
7315    (clobber (match_scratch:SI 3 "=1"))
7316    (clobber (reg:CC FLAGS_REG))]
7317   "TARGET_64BIT
7318    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319   "imul{l}\t%2"
7320   [(set_attr "type" "imul")
7321    (set (attr "athlon_decode")
7322      (if_then_else (eq_attr "cpu" "athlon")
7323         (const_string "vector")
7324         (const_string "double")))
7325    (set_attr "mode" "SI")])
7326
7327 ;; The patterns that match these are at the end of this file.
7328
7329 (define_expand "mulxf3"
7330   [(set (match_operand:XF 0 "register_operand" "")
7331         (mult:XF (match_operand:XF 1 "register_operand" "")
7332                  (match_operand:XF 2 "register_operand" "")))]
7333   "TARGET_80387"
7334   "")
7335
7336 (define_expand "muldf3"
7337   [(set (match_operand:DF 0 "register_operand" "")
7338         (mult:DF (match_operand:DF 1 "register_operand" "")
7339                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7340   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7341   "")
7342
7343 (define_expand "mulsf3"
7344   [(set (match_operand:SF 0 "register_operand" "")
7345         (mult:SF (match_operand:SF 1 "register_operand" "")
7346                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7347   "TARGET_80387 || TARGET_SSE_MATH"
7348   "")
7349 \f
7350 ;; Divide instructions
7351
7352 (define_insn "divqi3"
7353   [(set (match_operand:QI 0 "register_operand" "=a")
7354         (div:QI (match_operand:HI 1 "register_operand" "0")
7355                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7356    (clobber (reg:CC FLAGS_REG))]
7357   "TARGET_QIMODE_MATH"
7358   "idiv{b}\t%2"
7359   [(set_attr "type" "idiv")
7360    (set_attr "mode" "QI")])
7361
7362 (define_insn "udivqi3"
7363   [(set (match_operand:QI 0 "register_operand" "=a")
7364         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7365                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_QIMODE_MATH"
7368   "div{b}\t%2"
7369   [(set_attr "type" "idiv")
7370    (set_attr "mode" "QI")])
7371
7372 ;; The patterns that match these are at the end of this file.
7373
7374 (define_expand "divxf3"
7375   [(set (match_operand:XF 0 "register_operand" "")
7376         (div:XF (match_operand:XF 1 "register_operand" "")
7377                 (match_operand:XF 2 "register_operand" "")))]
7378   "TARGET_80387"
7379   "")
7380
7381 (define_expand "divdf3"
7382   [(set (match_operand:DF 0 "register_operand" "")
7383         (div:DF (match_operand:DF 1 "register_operand" "")
7384                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7385    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7386    "")
7387  
7388 (define_expand "divsf3"
7389   [(set (match_operand:SF 0 "register_operand" "")
7390         (div:SF (match_operand:SF 1 "register_operand" "")
7391                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7392   "TARGET_80387 || TARGET_SSE_MATH"
7393   "")
7394 \f
7395 ;; Remainder instructions.
7396
7397 (define_expand "divmoddi4"
7398   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399                    (div:DI (match_operand:DI 1 "register_operand" "")
7400                            (match_operand:DI 2 "nonimmediate_operand" "")))
7401               (set (match_operand:DI 3 "register_operand" "")
7402                    (mod:DI (match_dup 1) (match_dup 2)))
7403               (clobber (reg:CC FLAGS_REG))])]
7404   "TARGET_64BIT"
7405   "")
7406
7407 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7408 ;; Penalize eax case slightly because it results in worse scheduling
7409 ;; of code.
7410 (define_insn "*divmoddi4_nocltd_rex64"
7411   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7413                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415         (mod:DI (match_dup 2) (match_dup 3)))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7418   "#"
7419   [(set_attr "type" "multi")])
7420
7421 (define_insn "*divmoddi4_cltd_rex64"
7422   [(set (match_operand:DI 0 "register_operand" "=a")
7423         (div:DI (match_operand:DI 2 "register_operand" "a")
7424                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7425    (set (match_operand:DI 1 "register_operand" "=&d")
7426         (mod:DI (match_dup 2) (match_dup 3)))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7429   "#"
7430   [(set_attr "type" "multi")])
7431
7432 (define_insn "*divmoddi_noext_rex64"
7433   [(set (match_operand:DI 0 "register_operand" "=a")
7434         (div:DI (match_operand:DI 1 "register_operand" "0")
7435                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7436    (set (match_operand:DI 3 "register_operand" "=d")
7437         (mod:DI (match_dup 1) (match_dup 2)))
7438    (use (match_operand:DI 4 "register_operand" "3"))
7439    (clobber (reg:CC FLAGS_REG))]
7440   "TARGET_64BIT"
7441   "idiv{q}\t%2"
7442   [(set_attr "type" "idiv")
7443    (set_attr "mode" "DI")])
7444
7445 (define_split
7446   [(set (match_operand:DI 0 "register_operand" "")
7447         (div:DI (match_operand:DI 1 "register_operand" "")
7448                 (match_operand:DI 2 "nonimmediate_operand" "")))
7449    (set (match_operand:DI 3 "register_operand" "")
7450         (mod:DI (match_dup 1) (match_dup 2)))
7451    (clobber (reg:CC FLAGS_REG))]
7452   "TARGET_64BIT && reload_completed"
7453   [(parallel [(set (match_dup 3)
7454                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7455               (clobber (reg:CC FLAGS_REG))])
7456    (parallel [(set (match_dup 0)
7457                    (div:DI (reg:DI 0) (match_dup 2)))
7458               (set (match_dup 3)
7459                    (mod:DI (reg:DI 0) (match_dup 2)))
7460               (use (match_dup 3))
7461               (clobber (reg:CC FLAGS_REG))])]
7462 {
7463   /* Avoid use of cltd in favor of a mov+shift.  */
7464   if (!TARGET_USE_CLTD && !optimize_size)
7465     {
7466       if (true_regnum (operands[1]))
7467         emit_move_insn (operands[0], operands[1]);
7468       else
7469         emit_move_insn (operands[3], operands[1]);
7470       operands[4] = operands[3];
7471     }
7472   else
7473     {
7474       gcc_assert (!true_regnum (operands[1]));
7475       operands[4] = operands[1];
7476     }
7477 })
7478
7479
7480 (define_expand "divmodsi4"
7481   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482                    (div:SI (match_operand:SI 1 "register_operand" "")
7483                            (match_operand:SI 2 "nonimmediate_operand" "")))
7484               (set (match_operand:SI 3 "register_operand" "")
7485                    (mod:SI (match_dup 1) (match_dup 2)))
7486               (clobber (reg:CC FLAGS_REG))])]
7487   ""
7488   "")
7489
7490 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7491 ;; Penalize eax case slightly because it results in worse scheduling
7492 ;; of code.
7493 (define_insn "*divmodsi4_nocltd"
7494   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7496                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498         (mod:SI (match_dup 2) (match_dup 3)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "!optimize_size && !TARGET_USE_CLTD"
7501   "#"
7502   [(set_attr "type" "multi")])
7503
7504 (define_insn "*divmodsi4_cltd"
7505   [(set (match_operand:SI 0 "register_operand" "=a")
7506         (div:SI (match_operand:SI 2 "register_operand" "a")
7507                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7508    (set (match_operand:SI 1 "register_operand" "=&d")
7509         (mod:SI (match_dup 2) (match_dup 3)))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "optimize_size || TARGET_USE_CLTD"
7512   "#"
7513   [(set_attr "type" "multi")])
7514
7515 (define_insn "*divmodsi_noext"
7516   [(set (match_operand:SI 0 "register_operand" "=a")
7517         (div:SI (match_operand:SI 1 "register_operand" "0")
7518                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7519    (set (match_operand:SI 3 "register_operand" "=d")
7520         (mod:SI (match_dup 1) (match_dup 2)))
7521    (use (match_operand:SI 4 "register_operand" "3"))
7522    (clobber (reg:CC FLAGS_REG))]
7523   ""
7524   "idiv{l}\t%2"
7525   [(set_attr "type" "idiv")
7526    (set_attr "mode" "SI")])
7527
7528 (define_split
7529   [(set (match_operand:SI 0 "register_operand" "")
7530         (div:SI (match_operand:SI 1 "register_operand" "")
7531                 (match_operand:SI 2 "nonimmediate_operand" "")))
7532    (set (match_operand:SI 3 "register_operand" "")
7533         (mod:SI (match_dup 1) (match_dup 2)))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "reload_completed"
7536   [(parallel [(set (match_dup 3)
7537                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7538               (clobber (reg:CC FLAGS_REG))])
7539    (parallel [(set (match_dup 0)
7540                    (div:SI (reg:SI 0) (match_dup 2)))
7541               (set (match_dup 3)
7542                    (mod:SI (reg:SI 0) (match_dup 2)))
7543               (use (match_dup 3))
7544               (clobber (reg:CC FLAGS_REG))])]
7545 {
7546   /* Avoid use of cltd in favor of a mov+shift.  */
7547   if (!TARGET_USE_CLTD && !optimize_size)
7548     {
7549       if (true_regnum (operands[1]))
7550         emit_move_insn (operands[0], operands[1]);
7551       else
7552         emit_move_insn (operands[3], operands[1]);
7553       operands[4] = operands[3];
7554     }
7555   else
7556     {
7557       gcc_assert (!true_regnum (operands[1]));
7558       operands[4] = operands[1];
7559     }
7560 })
7561 ;; %%% Split me.
7562 (define_insn "divmodhi4"
7563   [(set (match_operand:HI 0 "register_operand" "=a")
7564         (div:HI (match_operand:HI 1 "register_operand" "0")
7565                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7566    (set (match_operand:HI 3 "register_operand" "=&d")
7567         (mod:HI (match_dup 1) (match_dup 2)))
7568    (clobber (reg:CC FLAGS_REG))]
7569   "TARGET_HIMODE_MATH"
7570   "cwtd\;idiv{w}\t%2"
7571   [(set_attr "type" "multi")
7572    (set_attr "length_immediate" "0")
7573    (set_attr "mode" "SI")])
7574
7575 (define_insn "udivmoddi4"
7576   [(set (match_operand:DI 0 "register_operand" "=a")
7577         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7578                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579    (set (match_operand:DI 3 "register_operand" "=&d")
7580         (umod:DI (match_dup 1) (match_dup 2)))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "TARGET_64BIT"
7583   "xor{q}\t%3, %3\;div{q}\t%2"
7584   [(set_attr "type" "multi")
7585    (set_attr "length_immediate" "0")
7586    (set_attr "mode" "DI")])
7587
7588 (define_insn "*udivmoddi4_noext"
7589   [(set (match_operand:DI 0 "register_operand" "=a")
7590         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7591                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592    (set (match_operand:DI 3 "register_operand" "=d")
7593         (umod:DI (match_dup 1) (match_dup 2)))
7594    (use (match_dup 3))
7595    (clobber (reg:CC FLAGS_REG))]
7596   "TARGET_64BIT"
7597   "div{q}\t%2"
7598   [(set_attr "type" "idiv")
7599    (set_attr "mode" "DI")])
7600
7601 (define_split
7602   [(set (match_operand:DI 0 "register_operand" "")
7603         (udiv:DI (match_operand:DI 1 "register_operand" "")
7604                  (match_operand:DI 2 "nonimmediate_operand" "")))
7605    (set (match_operand:DI 3 "register_operand" "")
7606         (umod:DI (match_dup 1) (match_dup 2)))
7607    (clobber (reg:CC FLAGS_REG))]
7608   "TARGET_64BIT && reload_completed"
7609   [(set (match_dup 3) (const_int 0))
7610    (parallel [(set (match_dup 0)
7611                    (udiv:DI (match_dup 1) (match_dup 2)))
7612               (set (match_dup 3)
7613                    (umod:DI (match_dup 1) (match_dup 2)))
7614               (use (match_dup 3))
7615               (clobber (reg:CC FLAGS_REG))])]
7616   "")
7617
7618 (define_insn "udivmodsi4"
7619   [(set (match_operand:SI 0 "register_operand" "=a")
7620         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7621                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622    (set (match_operand:SI 3 "register_operand" "=&d")
7623         (umod:SI (match_dup 1) (match_dup 2)))
7624    (clobber (reg:CC FLAGS_REG))]
7625   ""
7626   "xor{l}\t%3, %3\;div{l}\t%2"
7627   [(set_attr "type" "multi")
7628    (set_attr "length_immediate" "0")
7629    (set_attr "mode" "SI")])
7630
7631 (define_insn "*udivmodsi4_noext"
7632   [(set (match_operand:SI 0 "register_operand" "=a")
7633         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7634                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635    (set (match_operand:SI 3 "register_operand" "=d")
7636         (umod:SI (match_dup 1) (match_dup 2)))
7637    (use (match_dup 3))
7638    (clobber (reg:CC FLAGS_REG))]
7639   ""
7640   "div{l}\t%2"
7641   [(set_attr "type" "idiv")
7642    (set_attr "mode" "SI")])
7643
7644 (define_split
7645   [(set (match_operand:SI 0 "register_operand" "")
7646         (udiv:SI (match_operand:SI 1 "register_operand" "")
7647                  (match_operand:SI 2 "nonimmediate_operand" "")))
7648    (set (match_operand:SI 3 "register_operand" "")
7649         (umod:SI (match_dup 1) (match_dup 2)))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "reload_completed"
7652   [(set (match_dup 3) (const_int 0))
7653    (parallel [(set (match_dup 0)
7654                    (udiv:SI (match_dup 1) (match_dup 2)))
7655               (set (match_dup 3)
7656                    (umod:SI (match_dup 1) (match_dup 2)))
7657               (use (match_dup 3))
7658               (clobber (reg:CC FLAGS_REG))])]
7659   "")
7660
7661 (define_expand "udivmodhi4"
7662   [(set (match_dup 4) (const_int 0))
7663    (parallel [(set (match_operand:HI 0 "register_operand" "")
7664                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7665                             (match_operand:HI 2 "nonimmediate_operand" "")))
7666               (set (match_operand:HI 3 "register_operand" "")
7667                    (umod:HI (match_dup 1) (match_dup 2)))
7668               (use (match_dup 4))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "TARGET_HIMODE_MATH"
7671   "operands[4] = gen_reg_rtx (HImode);")
7672
7673 (define_insn "*udivmodhi_noext"
7674   [(set (match_operand:HI 0 "register_operand" "=a")
7675         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7676                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:HI 3 "register_operand" "=d")
7678         (umod:HI (match_dup 1) (match_dup 2)))
7679    (use (match_operand:HI 4 "register_operand" "3"))
7680    (clobber (reg:CC FLAGS_REG))]
7681   ""
7682   "div{w}\t%2"
7683   [(set_attr "type" "idiv")
7684    (set_attr "mode" "HI")])
7685
7686 ;; We cannot use div/idiv for double division, because it causes
7687 ;; "division by zero" on the overflow and that's not what we expect
7688 ;; from truncate.  Because true (non truncating) double division is
7689 ;; never generated, we can't create this insn anyway.
7690 ;
7691 ;(define_insn ""
7692 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7693 ;       (truncate:SI
7694 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7695 ;                  (zero_extend:DI
7696 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697 ;   (set (match_operand:SI 3 "register_operand" "=d")
7698 ;       (truncate:SI
7699 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700 ;   (clobber (reg:CC FLAGS_REG))]
7701 ;  ""
7702 ;  "div{l}\t{%2, %0|%0, %2}"
7703 ;  [(set_attr "type" "idiv")])
7704 \f
7705 ;;- Logical AND instructions
7706
7707 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708 ;; Note that this excludes ah.
7709
7710 (define_insn "*testdi_1_rex64"
7711   [(set (reg FLAGS_REG)
7712         (compare
7713           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7715           (const_int 0)))]
7716   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7718   "@
7719    test{l}\t{%k1, %k0|%k0, %k1}
7720    test{l}\t{%k1, %k0|%k0, %k1}
7721    test{q}\t{%1, %0|%0, %1}
7722    test{q}\t{%1, %0|%0, %1}
7723    test{q}\t{%1, %0|%0, %1}"
7724   [(set_attr "type" "test")
7725    (set_attr "modrm" "0,1,0,1,1")
7726    (set_attr "mode" "SI,SI,DI,DI,DI")
7727    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7728
7729 (define_insn "testsi_1"
7730   [(set (reg FLAGS_REG)
7731         (compare
7732           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7734           (const_int 0)))]
7735   "ix86_match_ccmode (insn, CCNOmode)
7736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737   "test{l}\t{%1, %0|%0, %1}"
7738   [(set_attr "type" "test")
7739    (set_attr "modrm" "0,1,1")
7740    (set_attr "mode" "SI")
7741    (set_attr "pent_pair" "uv,np,uv")])
7742
7743 (define_expand "testsi_ccno_1"
7744   [(set (reg:CCNO FLAGS_REG)
7745         (compare:CCNO
7746           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747                   (match_operand:SI 1 "nonmemory_operand" ""))
7748           (const_int 0)))]
7749   ""
7750   "")
7751
7752 (define_insn "*testhi_1"
7753   [(set (reg FLAGS_REG)
7754         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7756                  (const_int 0)))]
7757   "ix86_match_ccmode (insn, CCNOmode)
7758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759   "test{w}\t{%1, %0|%0, %1}"
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1")
7762    (set_attr "mode" "HI")
7763    (set_attr "pent_pair" "uv,np,uv")])
7764
7765 (define_expand "testqi_ccz_1"
7766   [(set (reg:CCZ FLAGS_REG)
7767         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768                              (match_operand:QI 1 "nonmemory_operand" ""))
7769                  (const_int 0)))]
7770   ""
7771   "")
7772
7773 (define_insn "*testqi_1_maybe_si"
7774   [(set (reg FLAGS_REG)
7775         (compare
7776           (and:QI
7777             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7779           (const_int 0)))]
7780    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781     && ix86_match_ccmode (insn,
7782                          GET_CODE (operands[1]) == CONST_INT
7783                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7784 {
7785   if (which_alternative == 3)
7786     {
7787       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789       return "test{l}\t{%1, %k0|%k0, %1}";
7790     }
7791   return "test{b}\t{%1, %0|%0, %1}";
7792 }
7793   [(set_attr "type" "test")
7794    (set_attr "modrm" "0,1,1,1")
7795    (set_attr "mode" "QI,QI,QI,SI")
7796    (set_attr "pent_pair" "uv,np,uv,np")])
7797
7798 (define_insn "*testqi_1"
7799   [(set (reg FLAGS_REG)
7800         (compare
7801           (and:QI
7802             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803             (match_operand:QI 1 "general_operand" "n,n,qn"))
7804           (const_int 0)))]
7805   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806    && ix86_match_ccmode (insn, CCNOmode)"
7807   "test{b}\t{%1, %0|%0, %1}"
7808   [(set_attr "type" "test")
7809    (set_attr "modrm" "0,1,1")
7810    (set_attr "mode" "QI")
7811    (set_attr "pent_pair" "uv,np,uv")])
7812
7813 (define_expand "testqi_ext_ccno_0"
7814   [(set (reg:CCNO FLAGS_REG)
7815         (compare:CCNO
7816           (and:SI
7817             (zero_extract:SI
7818               (match_operand 0 "ext_register_operand" "")
7819               (const_int 8)
7820               (const_int 8))
7821             (match_operand 1 "const_int_operand" ""))
7822           (const_int 0)))]
7823   ""
7824   "")
7825
7826 (define_insn "*testqi_ext_0"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (and:SI
7830             (zero_extract:SI
7831               (match_operand 0 "ext_register_operand" "Q")
7832               (const_int 8)
7833               (const_int 8))
7834             (match_operand 1 "const_int_operand" "n"))
7835           (const_int 0)))]
7836   "ix86_match_ccmode (insn, CCNOmode)"
7837   "test{b}\t{%1, %h0|%h0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "mode" "QI")
7840    (set_attr "length_immediate" "1")
7841    (set_attr "pent_pair" "np")])
7842
7843 (define_insn "*testqi_ext_1"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extend:SI
7852               (match_operand:QI 1 "general_operand" "Qm")))
7853           (const_int 0)))]
7854   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856   "test{b}\t{%1, %h0|%h0, %1}"
7857   [(set_attr "type" "test")
7858    (set_attr "mode" "QI")])
7859
7860 (define_insn "*testqi_ext_1_rex64"
7861   [(set (reg FLAGS_REG)
7862         (compare
7863           (and:SI
7864             (zero_extract:SI
7865               (match_operand 0 "ext_register_operand" "Q")
7866               (const_int 8)
7867               (const_int 8))
7868             (zero_extend:SI
7869               (match_operand:QI 1 "register_operand" "Q")))
7870           (const_int 0)))]
7871   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872   "test{b}\t{%1, %h0|%h0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "mode" "QI")])
7875
7876 (define_insn "*testqi_ext_2"
7877   [(set (reg FLAGS_REG)
7878         (compare
7879           (and:SI
7880             (zero_extract:SI
7881               (match_operand 0 "ext_register_operand" "Q")
7882               (const_int 8)
7883               (const_int 8))
7884             (zero_extract:SI
7885               (match_operand 1 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8)))
7888           (const_int 0)))]
7889   "ix86_match_ccmode (insn, CCNOmode)"
7890   "test{b}\t{%h1, %h0|%h0, %h1}"
7891   [(set_attr "type" "test")
7892    (set_attr "mode" "QI")])
7893
7894 ;; Combine likes to form bit extractions for some tests.  Humor it.
7895 (define_insn "*testqi_ext_3"
7896   [(set (reg FLAGS_REG)
7897         (compare (zero_extract:SI
7898                    (match_operand 0 "nonimmediate_operand" "rm")
7899                    (match_operand:SI 1 "const_int_operand" "")
7900                    (match_operand:SI 2 "const_int_operand" ""))
7901                  (const_int 0)))]
7902   "ix86_match_ccmode (insn, CCNOmode)
7903    && INTVAL (operands[1]) > 0
7904    && INTVAL (operands[2]) >= 0
7905    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906    && (GET_MODE (operands[0]) == SImode
7907        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908        || GET_MODE (operands[0]) == HImode
7909        || GET_MODE (operands[0]) == QImode)"
7910   "#")
7911
7912 (define_insn "*testqi_ext_3_rex64"
7913   [(set (reg FLAGS_REG)
7914         (compare (zero_extract:DI
7915                    (match_operand 0 "nonimmediate_operand" "rm")
7916                    (match_operand:DI 1 "const_int_operand" "")
7917                    (match_operand:DI 2 "const_int_operand" ""))
7918                  (const_int 0)))]
7919   "TARGET_64BIT
7920    && ix86_match_ccmode (insn, CCNOmode)
7921    && INTVAL (operands[1]) > 0
7922    && INTVAL (operands[2]) >= 0
7923    /* Ensure that resulting mask is zero or sign extended operand.  */
7924    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926            && INTVAL (operands[1]) > 32))
7927    && (GET_MODE (operands[0]) == SImode
7928        || GET_MODE (operands[0]) == DImode
7929        || GET_MODE (operands[0]) == HImode
7930        || GET_MODE (operands[0]) == QImode)"
7931   "#")
7932
7933 (define_split
7934   [(set (match_operand 0 "flags_reg_operand" "")
7935         (match_operator 1 "compare_operator"
7936           [(zero_extract
7937              (match_operand 2 "nonimmediate_operand" "")
7938              (match_operand 3 "const_int_operand" "")
7939              (match_operand 4 "const_int_operand" ""))
7940            (const_int 0)]))]
7941   "ix86_match_ccmode (insn, CCNOmode)"
7942   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7943 {
7944   rtx val = operands[2];
7945   HOST_WIDE_INT len = INTVAL (operands[3]);
7946   HOST_WIDE_INT pos = INTVAL (operands[4]);
7947   HOST_WIDE_INT mask;
7948   enum machine_mode mode, submode;
7949
7950   mode = GET_MODE (val);
7951   if (GET_CODE (val) == MEM)
7952     {
7953       /* ??? Combine likes to put non-volatile mem extractions in QImode
7954          no matter the size of the test.  So find a mode that works.  */
7955       if (! MEM_VOLATILE_P (val))
7956         {
7957           mode = smallest_mode_for_size (pos + len, MODE_INT);
7958           val = adjust_address (val, mode, 0);
7959         }
7960     }
7961   else if (GET_CODE (val) == SUBREG
7962            && (submode = GET_MODE (SUBREG_REG (val)),
7963                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964            && pos + len <= GET_MODE_BITSIZE (submode))
7965     {
7966       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7967       mode = submode;
7968       val = SUBREG_REG (val);
7969     }
7970   else if (mode == HImode && pos + len <= 8)
7971     {
7972       /* Small HImode tests can be converted to QImode.  */
7973       mode = QImode;
7974       val = gen_lowpart (QImode, val);
7975     }
7976
7977   if (len == HOST_BITS_PER_WIDE_INT)
7978     mask = -1;
7979   else
7980     mask = ((HOST_WIDE_INT)1 << len) - 1;
7981   mask <<= pos;
7982
7983   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7984 })
7985
7986 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988 ;; this is relatively important trick.
7989 ;; Do the conversion only post-reload to avoid limiting of the register class
7990 ;; to QI regs.
7991 (define_split
7992   [(set (match_operand 0 "flags_reg_operand" "")
7993         (match_operator 1 "compare_operator"
7994           [(and (match_operand 2 "register_operand" "")
7995                 (match_operand 3 "const_int_operand" ""))
7996            (const_int 0)]))]
7997    "reload_completed
7998     && QI_REG_P (operands[2])
7999     && GET_MODE (operands[2]) != QImode
8000     && ((ix86_match_ccmode (insn, CCZmode)
8001          && !(INTVAL (operands[3]) & ~(255 << 8)))
8002         || (ix86_match_ccmode (insn, CCNOmode)
8003             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8004   [(set (match_dup 0)
8005         (match_op_dup 1
8006           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8007                    (match_dup 3))
8008            (const_int 0)]))]
8009   "operands[2] = gen_lowpart (SImode, operands[2]);
8010    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8011
8012 (define_split
8013   [(set (match_operand 0 "flags_reg_operand" "")
8014         (match_operator 1 "compare_operator"
8015           [(and (match_operand 2 "nonimmediate_operand" "")
8016                 (match_operand 3 "const_int_operand" ""))
8017            (const_int 0)]))]
8018    "reload_completed
8019     && GET_MODE (operands[2]) != QImode
8020     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021     && ((ix86_match_ccmode (insn, CCZmode)
8022          && !(INTVAL (operands[3]) & ~255))
8023         || (ix86_match_ccmode (insn, CCNOmode)
8024             && !(INTVAL (operands[3]) & ~127)))"
8025   [(set (match_dup 0)
8026         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8027                          (const_int 0)]))]
8028   "operands[2] = gen_lowpart (QImode, operands[2]);
8029    operands[3] = gen_lowpart (QImode, operands[3]);")
8030
8031
8032 ;; %%% This used to optimize known byte-wide and operations to memory,
8033 ;; and sometimes to QImode registers.  If this is considered useful,
8034 ;; it should be done with splitters.
8035
8036 (define_expand "anddi3"
8037   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040    (clobber (reg:CC FLAGS_REG))]
8041   "TARGET_64BIT"
8042   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8043
8044 (define_insn "*anddi_1_rex64"
8045   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048    (clobber (reg:CC FLAGS_REG))]
8049   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8050 {
8051   switch (get_attr_type (insn))
8052     {
8053     case TYPE_IMOVX:
8054       {
8055         enum machine_mode mode;
8056
8057         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058         if (INTVAL (operands[2]) == 0xff)
8059           mode = QImode;
8060         else
8061           {
8062             gcc_assert (INTVAL (operands[2]) == 0xffff);
8063             mode = HImode;
8064           }
8065         
8066         operands[1] = gen_lowpart (mode, operands[1]);
8067         if (mode == QImode)
8068           return "movz{bq|x}\t{%1,%0|%0, %1}";
8069         else
8070           return "movz{wq|x}\t{%1,%0|%0, %1}";
8071       }
8072
8073     default:
8074       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075       if (get_attr_mode (insn) == MODE_SI)
8076         return "and{l}\t{%k2, %k0|%k0, %k2}";
8077       else
8078         return "and{q}\t{%2, %0|%0, %2}";
8079     }
8080 }
8081   [(set_attr "type" "alu,alu,alu,imovx")
8082    (set_attr "length_immediate" "*,*,*,0")
8083    (set_attr "mode" "SI,DI,DI,DI")])
8084
8085 (define_insn "*anddi_2"
8086   [(set (reg FLAGS_REG)
8087         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8089                  (const_int 0)))
8090    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091         (and:DI (match_dup 1) (match_dup 2)))]
8092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093    && ix86_binary_operator_ok (AND, DImode, operands)"
8094   "@
8095    and{l}\t{%k2, %k0|%k0, %k2}
8096    and{q}\t{%2, %0|%0, %2}
8097    and{q}\t{%2, %0|%0, %2}"
8098   [(set_attr "type" "alu")
8099    (set_attr "mode" "SI,DI,DI")])
8100
8101 (define_expand "andsi3"
8102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104                 (match_operand:SI 2 "general_operand" "")))
8105    (clobber (reg:CC FLAGS_REG))]
8106   ""
8107   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8108
8109 (define_insn "*andsi_1"
8110   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "ix86_binary_operator_ok (AND, SImode, operands)"
8115 {
8116   switch (get_attr_type (insn))
8117     {
8118     case TYPE_IMOVX:
8119       {
8120         enum machine_mode mode;
8121
8122         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123         if (INTVAL (operands[2]) == 0xff)
8124           mode = QImode;
8125         else
8126           {
8127             gcc_assert (INTVAL (operands[2]) == 0xffff);
8128             mode = HImode;
8129           }
8130         
8131         operands[1] = gen_lowpart (mode, operands[1]);
8132         if (mode == QImode)
8133           return "movz{bl|x}\t{%1,%0|%0, %1}";
8134         else
8135           return "movz{wl|x}\t{%1,%0|%0, %1}";
8136       }
8137
8138     default:
8139       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140       return "and{l}\t{%2, %0|%0, %2}";
8141     }
8142 }
8143   [(set_attr "type" "alu,alu,imovx")
8144    (set_attr "length_immediate" "*,*,0")
8145    (set_attr "mode" "SI")])
8146
8147 (define_split
8148   [(set (match_operand 0 "register_operand" "")
8149         (and (match_dup 0)
8150              (const_int -65536)))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154   "operands[1] = gen_lowpart (HImode, operands[0]);")
8155
8156 (define_split
8157   [(set (match_operand 0 "ext_register_operand" "")
8158         (and (match_dup 0)
8159              (const_int -256)))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163   "operands[1] = gen_lowpart (QImode, operands[0]);")
8164
8165 (define_split
8166   [(set (match_operand 0 "ext_register_operand" "")
8167         (and (match_dup 0)
8168              (const_int -65281)))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171   [(parallel [(set (zero_extract:SI (match_dup 0)
8172                                     (const_int 8)
8173                                     (const_int 8))
8174                    (xor:SI 
8175                      (zero_extract:SI (match_dup 0)
8176                                       (const_int 8)
8177                                       (const_int 8))
8178                      (zero_extract:SI (match_dup 0)
8179                                       (const_int 8)
8180                                       (const_int 8))))
8181               (clobber (reg:CC FLAGS_REG))])]
8182   "operands[0] = gen_lowpart (SImode, operands[0]);")
8183
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*andsi_1_zext"
8186   [(set (match_operand:DI 0 "register_operand" "=r")
8187         (zero_extend:DI
8188           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189                   (match_operand:SI 2 "general_operand" "rim"))))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192   "and{l}\t{%2, %k0|%k0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "mode" "SI")])
8195
8196 (define_insn "*andsi_2"
8197   [(set (reg FLAGS_REG)
8198         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199                          (match_operand:SI 2 "general_operand" "rim,ri"))
8200                  (const_int 0)))
8201    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202         (and:SI (match_dup 1) (match_dup 2)))]
8203   "ix86_match_ccmode (insn, CCNOmode)
8204    && ix86_binary_operator_ok (AND, SImode, operands)"
8205   "and{l}\t{%2, %0|%0, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "SI")])
8208
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*andsi_2_zext"
8211   [(set (reg FLAGS_REG)
8212         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213                          (match_operand:SI 2 "general_operand" "rim"))
8214                  (const_int 0)))
8215    (set (match_operand:DI 0 "register_operand" "=r")
8216         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218    && ix86_binary_operator_ok (AND, SImode, operands)"
8219   "and{l}\t{%2, %k0|%k0, %2}"
8220   [(set_attr "type" "alu")
8221    (set_attr "mode" "SI")])
8222
8223 (define_expand "andhi3"
8224   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226                 (match_operand:HI 2 "general_operand" "")))
8227    (clobber (reg:CC FLAGS_REG))]
8228   "TARGET_HIMODE_MATH"
8229   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8230
8231 (define_insn "*andhi_1"
8232   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   "ix86_binary_operator_ok (AND, HImode, operands)"
8237 {
8238   switch (get_attr_type (insn))
8239     {
8240     case TYPE_IMOVX:
8241       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242       gcc_assert (INTVAL (operands[2]) == 0xff);
8243       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8244
8245     default:
8246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8247
8248       return "and{w}\t{%2, %0|%0, %2}";
8249     }
8250 }
8251   [(set_attr "type" "alu,alu,imovx")
8252    (set_attr "length_immediate" "*,*,0")
8253    (set_attr "mode" "HI,HI,SI")])
8254
8255 (define_insn "*andhi_2"
8256   [(set (reg FLAGS_REG)
8257         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258                          (match_operand:HI 2 "general_operand" "rim,ri"))
8259                  (const_int 0)))
8260    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261         (and:HI (match_dup 1) (match_dup 2)))]
8262   "ix86_match_ccmode (insn, CCNOmode)
8263    && ix86_binary_operator_ok (AND, HImode, operands)"
8264   "and{w}\t{%2, %0|%0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "mode" "HI")])
8267
8268 (define_expand "andqi3"
8269   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271                 (match_operand:QI 2 "general_operand" "")))
8272    (clobber (reg:CC FLAGS_REG))]
8273   "TARGET_QIMODE_MATH"
8274   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8275
8276 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8277 (define_insn "*andqi_1"
8278   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "ix86_binary_operator_ok (AND, QImode, operands)"
8283   "@
8284    and{b}\t{%2, %0|%0, %2}
8285    and{b}\t{%2, %0|%0, %2}
8286    and{l}\t{%k2, %k0|%k0, %k2}"
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_1_slp"
8291   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292         (and:QI (match_dup 0)
8293                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8294    (clobber (reg:CC FLAGS_REG))]
8295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297   "and{b}\t{%1, %0|%0, %1}"
8298   [(set_attr "type" "alu1")
8299    (set_attr "mode" "QI")])
8300
8301 (define_insn "*andqi_2_maybe_si"
8302   [(set (reg FLAGS_REG)
8303         (compare (and:QI
8304                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8306                  (const_int 0)))
8307    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308         (and:QI (match_dup 1) (match_dup 2)))]
8309   "ix86_binary_operator_ok (AND, QImode, operands)
8310    && ix86_match_ccmode (insn,
8311                          GET_CODE (operands[2]) == CONST_INT
8312                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8313 {
8314   if (which_alternative == 2)
8315     {
8316       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318       return "and{l}\t{%2, %k0|%k0, %2}";
8319     }
8320   return "and{b}\t{%2, %0|%0, %2}";
8321 }
8322   [(set_attr "type" "alu")
8323    (set_attr "mode" "QI,QI,SI")])
8324
8325 (define_insn "*andqi_2"
8326   [(set (reg FLAGS_REG)
8327         (compare (and:QI
8328                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329                    (match_operand:QI 2 "general_operand" "qim,qi"))
8330                  (const_int 0)))
8331    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332         (and:QI (match_dup 1) (match_dup 2)))]
8333   "ix86_match_ccmode (insn, CCNOmode)
8334    && ix86_binary_operator_ok (AND, QImode, operands)"
8335   "and{b}\t{%2, %0|%0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "mode" "QI")])
8338
8339 (define_insn "*andqi_2_slp"
8340   [(set (reg FLAGS_REG)
8341         (compare (and:QI
8342                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8344                  (const_int 0)))
8345    (set (strict_low_part (match_dup 0))
8346         (and:QI (match_dup 0) (match_dup 1)))]
8347   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348    && ix86_match_ccmode (insn, CCNOmode)
8349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350   "and{b}\t{%1, %0|%0, %1}"
8351   [(set_attr "type" "alu1")
8352    (set_attr "mode" "QI")])
8353
8354 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8355 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8356 ;; for a QImode operand, which of course failed.
8357
8358 (define_insn "andqi_ext_0"
8359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360                          (const_int 8)
8361                          (const_int 8))
8362         (and:SI 
8363           (zero_extract:SI
8364             (match_operand 1 "ext_register_operand" "0")
8365             (const_int 8)
8366             (const_int 8))
8367           (match_operand 2 "const_int_operand" "n")))
8368    (clobber (reg:CC FLAGS_REG))]
8369   ""
8370   "and{b}\t{%2, %h0|%h0, %2}"
8371   [(set_attr "type" "alu")
8372    (set_attr "length_immediate" "1")
8373    (set_attr "mode" "QI")])
8374
8375 ;; Generated by peephole translating test to and.  This shows up
8376 ;; often in fp comparisons.
8377
8378 (define_insn "*andqi_ext_0_cc"
8379   [(set (reg FLAGS_REG)
8380         (compare
8381           (and:SI
8382             (zero_extract:SI
8383               (match_operand 1 "ext_register_operand" "0")
8384               (const_int 8)
8385               (const_int 8))
8386             (match_operand 2 "const_int_operand" "n"))
8387           (const_int 0)))
8388    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389                          (const_int 8)
8390                          (const_int 8))
8391         (and:SI 
8392           (zero_extract:SI
8393             (match_dup 1)
8394             (const_int 8)
8395             (const_int 8))
8396           (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)"
8398   "and{b}\t{%2, %h0|%h0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "length_immediate" "1")
8401    (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_ext_1"
8404   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405                          (const_int 8)
8406                          (const_int 8))
8407         (and:SI 
8408           (zero_extract:SI
8409             (match_operand 1 "ext_register_operand" "0")
8410             (const_int 8)
8411             (const_int 8))
8412           (zero_extend:SI
8413             (match_operand:QI 2 "general_operand" "Qm"))))
8414    (clobber (reg:CC FLAGS_REG))]
8415   "!TARGET_64BIT"
8416   "and{b}\t{%2, %h0|%h0, %2}"
8417   [(set_attr "type" "alu")
8418    (set_attr "length_immediate" "0")
8419    (set_attr "mode" "QI")])
8420
8421 (define_insn "*andqi_ext_1_rex64"
8422   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423                          (const_int 8)
8424                          (const_int 8))
8425         (and:SI 
8426           (zero_extract:SI
8427             (match_operand 1 "ext_register_operand" "0")
8428             (const_int 8)
8429             (const_int 8))
8430           (zero_extend:SI
8431             (match_operand 2 "ext_register_operand" "Q"))))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT"
8434   "and{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "0")
8437    (set_attr "mode" "QI")])
8438
8439 (define_insn "*andqi_ext_2"
8440   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441                          (const_int 8)
8442                          (const_int 8))
8443         (and:SI
8444           (zero_extract:SI
8445             (match_operand 1 "ext_register_operand" "%0")
8446             (const_int 8)
8447             (const_int 8))
8448           (zero_extract:SI
8449             (match_operand 2 "ext_register_operand" "Q")
8450             (const_int 8)
8451             (const_int 8))))
8452    (clobber (reg:CC FLAGS_REG))]
8453   ""
8454   "and{b}\t{%h2, %h0|%h0, %h2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "length_immediate" "0")
8457    (set_attr "mode" "QI")])
8458
8459 ;; Convert wide AND instructions with immediate operand to shorter QImode
8460 ;; equivalents when possible.
8461 ;; Don't do the splitting with memory operands, since it introduces risk
8462 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8463 ;; for size, but that can (should?) be handled by generic code instead.
8464 (define_split
8465   [(set (match_operand 0 "register_operand" "")
8466         (and (match_operand 1 "register_operand" "")
8467              (match_operand 2 "const_int_operand" "")))
8468    (clobber (reg:CC FLAGS_REG))]
8469    "reload_completed
8470     && QI_REG_P (operands[0])
8471     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472     && !(~INTVAL (operands[2]) & ~(255 << 8))
8473     && GET_MODE (operands[0]) != QImode"
8474   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475                    (and:SI (zero_extract:SI (match_dup 1)
8476                                             (const_int 8) (const_int 8))
8477                            (match_dup 2)))
8478               (clobber (reg:CC FLAGS_REG))])]
8479   "operands[0] = gen_lowpart (SImode, operands[0]);
8480    operands[1] = gen_lowpart (SImode, operands[1]);
8481    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8482
8483 ;; Since AND can be encoded with sign extended immediate, this is only
8484 ;; profitable when 7th bit is not set.
8485 (define_split
8486   [(set (match_operand 0 "register_operand" "")
8487         (and (match_operand 1 "general_operand" "")
8488              (match_operand 2 "const_int_operand" "")))
8489    (clobber (reg:CC FLAGS_REG))]
8490    "reload_completed
8491     && ANY_QI_REG_P (operands[0])
8492     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493     && !(~INTVAL (operands[2]) & ~255)
8494     && !(INTVAL (operands[2]) & 128)
8495     && GET_MODE (operands[0]) != QImode"
8496   [(parallel [(set (strict_low_part (match_dup 0))
8497                    (and:QI (match_dup 1)
8498                            (match_dup 2)))
8499               (clobber (reg:CC FLAGS_REG))])]
8500   "operands[0] = gen_lowpart (QImode, operands[0]);
8501    operands[1] = gen_lowpart (QImode, operands[1]);
8502    operands[2] = gen_lowpart (QImode, operands[2]);")
8503 \f
8504 ;; Logical inclusive OR instructions
8505
8506 ;; %%% This used to optimize known byte-wide and operations to memory.
8507 ;; If this is considered useful, it should be done with splitters.
8508
8509 (define_expand "iordi3"
8510   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512                 (match_operand:DI 2 "x86_64_general_operand" "")))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "TARGET_64BIT"
8515   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8516
8517 (define_insn "*iordi_1_rex64"
8518   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "TARGET_64BIT
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_2_rex64"
8529   [(set (reg FLAGS_REG)
8530         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8532                  (const_int 0)))
8533    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534         (ior:DI (match_dup 1) (match_dup 2)))]
8535   "TARGET_64BIT
8536    && ix86_match_ccmode (insn, CCNOmode)
8537    && ix86_binary_operator_ok (IOR, DImode, operands)"
8538   "or{q}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "DI")])
8541
8542 (define_insn "*iordi_3_rex64"
8543   [(set (reg FLAGS_REG)
8544         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8546                  (const_int 0)))
8547    (clobber (match_scratch:DI 0 "=r"))]
8548   "TARGET_64BIT
8549    && ix86_match_ccmode (insn, CCNOmode)
8550    && ix86_binary_operator_ok (IOR, DImode, operands)"
8551   "or{q}\t{%2, %0|%0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "DI")])
8554
8555
8556 (define_expand "iorsi3"
8557   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559                 (match_operand:SI 2 "general_operand" "")))
8560    (clobber (reg:CC FLAGS_REG))]
8561   ""
8562   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8563
8564 (define_insn "*iorsi_1"
8565   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "ix86_binary_operator_ok (IOR, SImode, operands)"
8570   "or{l}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*iorsi_1_zext"
8576   [(set (match_operand:DI 0 "register_operand" "=rm")
8577         (zero_extend:DI
8578           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                   (match_operand:SI 2 "general_operand" "rim"))))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582   "or{l}\t{%2, %k0|%k0, %2}"
8583   [(set_attr "type" "alu")
8584    (set_attr "mode" "SI")])
8585
8586 (define_insn "*iorsi_1_zext_imm"
8587   [(set (match_operand:DI 0 "register_operand" "=rm")
8588         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590    (clobber (reg:CC FLAGS_REG))]
8591   "TARGET_64BIT"
8592   "or{l}\t{%2, %k0|%k0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "SI")])
8595
8596 (define_insn "*iorsi_2"
8597   [(set (reg FLAGS_REG)
8598         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599                          (match_operand:SI 2 "general_operand" "rim,ri"))
8600                  (const_int 0)))
8601    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602         (ior:SI (match_dup 1) (match_dup 2)))]
8603   "ix86_match_ccmode (insn, CCNOmode)
8604    && ix86_binary_operator_ok (IOR, SImode, operands)"
8605   "or{l}\t{%2, %0|%0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "mode" "SI")])
8608
8609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610 ;; ??? Special case for immediate operand is missing - it is tricky.
8611 (define_insn "*iorsi_2_zext"
8612   [(set (reg FLAGS_REG)
8613         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614                          (match_operand:SI 2 "general_operand" "rim"))
8615                  (const_int 0)))
8616    (set (match_operand:DI 0 "register_operand" "=r")
8617         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619    && ix86_binary_operator_ok (IOR, SImode, operands)"
8620   "or{l}\t{%2, %k0|%k0, %2}"
8621   [(set_attr "type" "alu")
8622    (set_attr "mode" "SI")])
8623
8624 (define_insn "*iorsi_2_zext_imm"
8625   [(set (reg FLAGS_REG)
8626         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8628                  (const_int 0)))
8629    (set (match_operand:DI 0 "register_operand" "=r")
8630         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632    && ix86_binary_operator_ok (IOR, SImode, operands)"
8633   "or{l}\t{%2, %k0|%k0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "SI")])
8636
8637 (define_insn "*iorsi_3"
8638   [(set (reg FLAGS_REG)
8639         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640                          (match_operand:SI 2 "general_operand" "rim"))
8641                  (const_int 0)))
8642    (clobber (match_scratch:SI 0 "=r"))]
8643   "ix86_match_ccmode (insn, CCNOmode)
8644    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645   "or{l}\t{%2, %0|%0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8648
8649 (define_expand "iorhi3"
8650   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652                 (match_operand:HI 2 "general_operand" "")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_HIMODE_MATH"
8655   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8656
8657 (define_insn "*iorhi_1"
8658   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "ix86_binary_operator_ok (IOR, HImode, operands)"
8663   "or{w}\t{%2, %0|%0, %2}"
8664   [(set_attr "type" "alu")
8665    (set_attr "mode" "HI")])
8666
8667 (define_insn "*iorhi_2"
8668   [(set (reg FLAGS_REG)
8669         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670                          (match_operand:HI 2 "general_operand" "rim,ri"))
8671                  (const_int 0)))
8672    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673         (ior:HI (match_dup 1) (match_dup 2)))]
8674   "ix86_match_ccmode (insn, CCNOmode)
8675    && ix86_binary_operator_ok (IOR, HImode, operands)"
8676   "or{w}\t{%2, %0|%0, %2}"
8677   [(set_attr "type" "alu")
8678    (set_attr "mode" "HI")])
8679
8680 (define_insn "*iorhi_3"
8681   [(set (reg FLAGS_REG)
8682         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683                          (match_operand:HI 2 "general_operand" "rim"))
8684                  (const_int 0)))
8685    (clobber (match_scratch:HI 0 "=r"))]
8686   "ix86_match_ccmode (insn, CCNOmode)
8687    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688   "or{w}\t{%2, %0|%0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "HI")])
8691
8692 (define_expand "iorqi3"
8693   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695                 (match_operand:QI 2 "general_operand" "")))
8696    (clobber (reg:CC FLAGS_REG))]
8697   "TARGET_QIMODE_MATH"
8698   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8699
8700 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8701 (define_insn "*iorqi_1"
8702   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705    (clobber (reg:CC FLAGS_REG))]
8706   "ix86_binary_operator_ok (IOR, QImode, operands)"
8707   "@
8708    or{b}\t{%2, %0|%0, %2}
8709    or{b}\t{%2, %0|%0, %2}
8710    or{l}\t{%k2, %k0|%k0, %k2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "QI,QI,SI")])
8713
8714 (define_insn "*iorqi_1_slp"
8715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716         (ior:QI (match_dup 0)
8717                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8718    (clobber (reg:CC FLAGS_REG))]
8719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721   "or{b}\t{%1, %0|%0, %1}"
8722   [(set_attr "type" "alu1")
8723    (set_attr "mode" "QI")])
8724
8725 (define_insn "*iorqi_2"
8726   [(set (reg FLAGS_REG)
8727         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728                          (match_operand:QI 2 "general_operand" "qim,qi"))
8729                  (const_int 0)))
8730    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731         (ior:QI (match_dup 1) (match_dup 2)))]
8732   "ix86_match_ccmode (insn, CCNOmode)
8733    && ix86_binary_operator_ok (IOR, QImode, operands)"
8734   "or{b}\t{%2, %0|%0, %2}"
8735   [(set_attr "type" "alu")
8736    (set_attr "mode" "QI")])
8737
8738 (define_insn "*iorqi_2_slp"
8739   [(set (reg FLAGS_REG)
8740         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741                          (match_operand:QI 1 "general_operand" "qim,qi"))
8742                  (const_int 0)))
8743    (set (strict_low_part (match_dup 0))
8744         (ior:QI (match_dup 0) (match_dup 1)))]
8745   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746    && ix86_match_ccmode (insn, CCNOmode)
8747    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748   "or{b}\t{%1, %0|%0, %1}"
8749   [(set_attr "type" "alu1")
8750    (set_attr "mode" "QI")])
8751
8752 (define_insn "*iorqi_3"
8753   [(set (reg FLAGS_REG)
8754         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755                          (match_operand:QI 2 "general_operand" "qim"))
8756                  (const_int 0)))
8757    (clobber (match_scratch:QI 0 "=q"))]
8758   "ix86_match_ccmode (insn, CCNOmode)
8759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760   "or{b}\t{%2, %0|%0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "QI")])
8763
8764 (define_insn "iorqi_ext_0"
8765   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8766                          (const_int 8)
8767                          (const_int 8))
8768         (ior:SI 
8769           (zero_extract:SI
8770             (match_operand 1 "ext_register_operand" "0")
8771             (const_int 8)
8772             (const_int 8))
8773           (match_operand 2 "const_int_operand" "n")))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776   "or{b}\t{%2, %h0|%h0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "length_immediate" "1")
8779    (set_attr "mode" "QI")])
8780
8781 (define_insn "*iorqi_ext_1"
8782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783                          (const_int 8)
8784                          (const_int 8))
8785         (ior:SI 
8786           (zero_extract:SI
8787             (match_operand 1 "ext_register_operand" "0")
8788             (const_int 8)
8789             (const_int 8))
8790           (zero_extend:SI
8791             (match_operand:QI 2 "general_operand" "Qm"))))
8792    (clobber (reg:CC FLAGS_REG))]
8793   "!TARGET_64BIT
8794    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795   "or{b}\t{%2, %h0|%h0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "length_immediate" "0")
8798    (set_attr "mode" "QI")])
8799
8800 (define_insn "*iorqi_ext_1_rex64"
8801   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802                          (const_int 8)
8803                          (const_int 8))
8804         (ior:SI 
8805           (zero_extract:SI
8806             (match_operand 1 "ext_register_operand" "0")
8807             (const_int 8)
8808             (const_int 8))
8809           (zero_extend:SI
8810             (match_operand 2 "ext_register_operand" "Q"))))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "TARGET_64BIT
8813    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814   "or{b}\t{%2, %h0|%h0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "length_immediate" "0")
8817    (set_attr "mode" "QI")])
8818
8819 (define_insn "*iorqi_ext_2"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI 
8824           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8825                            (const_int 8)
8826                            (const_int 8))
8827           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8828                            (const_int 8)
8829                            (const_int 8))))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832   "ior{b}\t{%h2, %h0|%h0, %h2}"
8833   [(set_attr "type" "alu")
8834    (set_attr "length_immediate" "0")
8835    (set_attr "mode" "QI")])
8836
8837 (define_split
8838   [(set (match_operand 0 "register_operand" "")
8839         (ior (match_operand 1 "register_operand" "")
8840              (match_operand 2 "const_int_operand" "")))
8841    (clobber (reg:CC FLAGS_REG))]
8842    "reload_completed
8843     && QI_REG_P (operands[0])
8844     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845     && !(INTVAL (operands[2]) & ~(255 << 8))
8846     && GET_MODE (operands[0]) != QImode"
8847   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848                    (ior:SI (zero_extract:SI (match_dup 1)
8849                                             (const_int 8) (const_int 8))
8850                            (match_dup 2)))
8851               (clobber (reg:CC FLAGS_REG))])]
8852   "operands[0] = gen_lowpart (SImode, operands[0]);
8853    operands[1] = gen_lowpart (SImode, operands[1]);
8854    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8855
8856 ;; Since OR can be encoded with sign extended immediate, this is only
8857 ;; profitable when 7th bit is set.
8858 (define_split
8859   [(set (match_operand 0 "register_operand" "")
8860         (ior (match_operand 1 "general_operand" "")
8861              (match_operand 2 "const_int_operand" "")))
8862    (clobber (reg:CC FLAGS_REG))]
8863    "reload_completed
8864     && ANY_QI_REG_P (operands[0])
8865     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866     && !(INTVAL (operands[2]) & ~255)
8867     && (INTVAL (operands[2]) & 128)
8868     && GET_MODE (operands[0]) != QImode"
8869   [(parallel [(set (strict_low_part (match_dup 0))
8870                    (ior:QI (match_dup 1)
8871                            (match_dup 2)))
8872               (clobber (reg:CC FLAGS_REG))])]
8873   "operands[0] = gen_lowpart (QImode, operands[0]);
8874    operands[1] = gen_lowpart (QImode, operands[1]);
8875    operands[2] = gen_lowpart (QImode, operands[2]);")
8876 \f
8877 ;; Logical XOR instructions
8878
8879 ;; %%% This used to optimize known byte-wide and operations to memory.
8880 ;; If this is considered useful, it should be done with splitters.
8881
8882 (define_expand "xordi3"
8883   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885                 (match_operand:DI 2 "x86_64_general_operand" "")))
8886    (clobber (reg:CC FLAGS_REG))]
8887   "TARGET_64BIT"
8888   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8889
8890 (define_insn "*xordi_1_rex64"
8891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "TARGET_64BIT
8896    && ix86_binary_operator_ok (XOR, DImode, operands)"
8897   "@
8898    xor{q}\t{%2, %0|%0, %2}
8899    xor{q}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "DI,DI")])
8902
8903 (define_insn "*xordi_2_rex64"
8904   [(set (reg FLAGS_REG)
8905         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8907                  (const_int 0)))
8908    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909         (xor:DI (match_dup 1) (match_dup 2)))]
8910   "TARGET_64BIT
8911    && ix86_match_ccmode (insn, CCNOmode)
8912    && ix86_binary_operator_ok (XOR, DImode, operands)"
8913   "@
8914    xor{q}\t{%2, %0|%0, %2}
8915    xor{q}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "DI,DI")])
8918
8919 (define_insn "*xordi_3_rex64"
8920   [(set (reg FLAGS_REG)
8921         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8923                  (const_int 0)))
8924    (clobber (match_scratch:DI 0 "=r"))]
8925   "TARGET_64BIT
8926    && ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, DImode, operands)"
8928   "xor{q}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "DI")])
8931
8932 (define_expand "xorsi3"
8933   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935                 (match_operand:SI 2 "general_operand" "")))
8936    (clobber (reg:CC FLAGS_REG))]
8937   ""
8938   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8939
8940 (define_insn "*xorsi_1"
8941   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943                 (match_operand:SI 2 "general_operand" "ri,rm")))
8944    (clobber (reg:CC FLAGS_REG))]
8945   "ix86_binary_operator_ok (XOR, SImode, operands)"
8946   "xor{l}\t{%2, %0|%0, %2}"
8947   [(set_attr "type" "alu")
8948    (set_attr "mode" "SI")])
8949
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; Add speccase for immediates
8952 (define_insn "*xorsi_1_zext"
8953   [(set (match_operand:DI 0 "register_operand" "=r")
8954         (zero_extend:DI
8955           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                   (match_operand:SI 2 "general_operand" "rim"))))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959   "xor{l}\t{%2, %k0|%k0, %2}"
8960   [(set_attr "type" "alu")
8961    (set_attr "mode" "SI")])
8962
8963 (define_insn "*xorsi_1_zext_imm"
8964   [(set (match_operand:DI 0 "register_operand" "=r")
8965         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967    (clobber (reg:CC FLAGS_REG))]
8968   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969   "xor{l}\t{%2, %k0|%k0, %2}"
8970   [(set_attr "type" "alu")
8971    (set_attr "mode" "SI")])
8972
8973 (define_insn "*xorsi_2"
8974   [(set (reg FLAGS_REG)
8975         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976                          (match_operand:SI 2 "general_operand" "rim,ri"))
8977                  (const_int 0)))
8978    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979         (xor:SI (match_dup 1) (match_dup 2)))]
8980   "ix86_match_ccmode (insn, CCNOmode)
8981    && ix86_binary_operator_ok (XOR, SImode, operands)"
8982   "xor{l}\t{%2, %0|%0, %2}"
8983   [(set_attr "type" "alu")
8984    (set_attr "mode" "SI")])
8985
8986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987 ;; ??? Special case for immediate operand is missing - it is tricky.
8988 (define_insn "*xorsi_2_zext"
8989   [(set (reg FLAGS_REG)
8990         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991                          (match_operand:SI 2 "general_operand" "rim"))
8992                  (const_int 0)))
8993    (set (match_operand:DI 0 "register_operand" "=r")
8994         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (XOR, SImode, operands)"
8997   "xor{l}\t{%2, %k0|%k0, %2}"
8998   [(set_attr "type" "alu")
8999    (set_attr "mode" "SI")])
9000
9001 (define_insn "*xorsi_2_zext_imm"
9002   [(set (reg FLAGS_REG)
9003         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9005                  (const_int 0)))
9006    (set (match_operand:DI 0 "register_operand" "=r")
9007         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009    && ix86_binary_operator_ok (XOR, SImode, operands)"
9010   "xor{l}\t{%2, %k0|%k0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "SI")])
9013
9014 (define_insn "*xorsi_3"
9015   [(set (reg FLAGS_REG)
9016         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017                          (match_operand:SI 2 "general_operand" "rim"))
9018                  (const_int 0)))
9019    (clobber (match_scratch:SI 0 "=r"))]
9020   "ix86_match_ccmode (insn, CCNOmode)
9021    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022   "xor{l}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 (define_expand "xorhi3"
9027   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029                 (match_operand:HI 2 "general_operand" "")))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_HIMODE_MATH"
9032   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9033
9034 (define_insn "*xorhi_1"
9035   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "ix86_binary_operator_ok (XOR, HImode, operands)"
9040   "xor{w}\t{%2, %0|%0, %2}"
9041   [(set_attr "type" "alu")
9042    (set_attr "mode" "HI")])
9043
9044 (define_insn "*xorhi_2"
9045   [(set (reg FLAGS_REG)
9046         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047                          (match_operand:HI 2 "general_operand" "rim,ri"))
9048                  (const_int 0)))
9049    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050         (xor:HI (match_dup 1) (match_dup 2)))]
9051   "ix86_match_ccmode (insn, CCNOmode)
9052    && ix86_binary_operator_ok (XOR, HImode, operands)"
9053   "xor{w}\t{%2, %0|%0, %2}"
9054   [(set_attr "type" "alu")
9055    (set_attr "mode" "HI")])
9056
9057 (define_insn "*xorhi_3"
9058   [(set (reg FLAGS_REG)
9059         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060                          (match_operand:HI 2 "general_operand" "rim"))
9061                  (const_int 0)))
9062    (clobber (match_scratch:HI 0 "=r"))]
9063   "ix86_match_ccmode (insn, CCNOmode)
9064    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065   "xor{w}\t{%2, %0|%0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "HI")])
9068
9069 (define_expand "xorqi3"
9070   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072                 (match_operand:QI 2 "general_operand" "")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "TARGET_QIMODE_MATH"
9075   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9076
9077 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9078 (define_insn "*xorqi_1"
9079   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "ix86_binary_operator_ok (XOR, QImode, operands)"
9084   "@
9085    xor{b}\t{%2, %0|%0, %2}
9086    xor{b}\t{%2, %0|%0, %2}
9087    xor{l}\t{%k2, %k0|%k0, %k2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "QI,QI,SI")])
9090
9091 (define_insn "*xorqi_1_slp"
9092   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093         (xor:QI (match_dup 0)
9094                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098   "xor{b}\t{%1, %0|%0, %1}"
9099   [(set_attr "type" "alu1")
9100    (set_attr "mode" "QI")])
9101
9102 (define_insn "xorqi_ext_0"
9103   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9104                          (const_int 8)
9105                          (const_int 8))
9106         (xor:SI 
9107           (zero_extract:SI
9108             (match_operand 1 "ext_register_operand" "0")
9109             (const_int 8)
9110             (const_int 8))
9111           (match_operand 2 "const_int_operand" "n")))
9112    (clobber (reg:CC FLAGS_REG))]
9113   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114   "xor{b}\t{%2, %h0|%h0, %2}"
9115   [(set_attr "type" "alu")
9116    (set_attr "length_immediate" "1")
9117    (set_attr "mode" "QI")])
9118
9119 (define_insn "*xorqi_ext_1"
9120   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121                          (const_int 8)
9122                          (const_int 8))
9123         (xor:SI 
9124           (zero_extract:SI
9125             (match_operand 1 "ext_register_operand" "0")
9126             (const_int 8)
9127             (const_int 8))
9128           (zero_extend:SI
9129             (match_operand:QI 2 "general_operand" "Qm"))))
9130    (clobber (reg:CC FLAGS_REG))]
9131   "!TARGET_64BIT
9132    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133   "xor{b}\t{%2, %h0|%h0, %2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "length_immediate" "0")
9136    (set_attr "mode" "QI")])
9137
9138 (define_insn "*xorqi_ext_1_rex64"
9139   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140                          (const_int 8)
9141                          (const_int 8))
9142         (xor:SI 
9143           (zero_extract:SI
9144             (match_operand 1 "ext_register_operand" "0")
9145             (const_int 8)
9146             (const_int 8))
9147           (zero_extend:SI
9148             (match_operand 2 "ext_register_operand" "Q"))))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_64BIT
9151    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152   "xor{b}\t{%2, %h0|%h0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "length_immediate" "0")
9155    (set_attr "mode" "QI")])
9156
9157 (define_insn "*xorqi_ext_2"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI 
9162           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9163                            (const_int 8)
9164                            (const_int 8))
9165           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9166                            (const_int 8)
9167                            (const_int 8))))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170   "xor{b}\t{%h2, %h0|%h0, %h2}"
9171   [(set_attr "type" "alu")
9172    (set_attr "length_immediate" "0")
9173    (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_cc_1"
9176   [(set (reg FLAGS_REG)
9177         (compare
9178           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179                   (match_operand:QI 2 "general_operand" "qim,qi"))
9180           (const_int 0)))
9181    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182         (xor:QI (match_dup 1) (match_dup 2)))]
9183   "ix86_match_ccmode (insn, CCNOmode)
9184    && ix86_binary_operator_ok (XOR, QImode, operands)"
9185   "xor{b}\t{%2, %0|%0, %2}"
9186   [(set_attr "type" "alu")
9187    (set_attr "mode" "QI")])
9188
9189 (define_insn "*xorqi_2_slp"
9190   [(set (reg FLAGS_REG)
9191         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192                          (match_operand:QI 1 "general_operand" "qim,qi"))
9193                  (const_int 0)))
9194    (set (strict_low_part (match_dup 0))
9195         (xor:QI (match_dup 0) (match_dup 1)))]
9196   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197    && ix86_match_ccmode (insn, CCNOmode)
9198    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199   "xor{b}\t{%1, %0|%0, %1}"
9200   [(set_attr "type" "alu1")
9201    (set_attr "mode" "QI")])
9202
9203 (define_insn "*xorqi_cc_2"
9204   [(set (reg FLAGS_REG)
9205         (compare
9206           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207                   (match_operand:QI 2 "general_operand" "qim"))
9208           (const_int 0)))
9209    (clobber (match_scratch:QI 0 "=q"))]
9210   "ix86_match_ccmode (insn, CCNOmode)
9211    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212   "xor{b}\t{%2, %0|%0, %2}"
9213   [(set_attr "type" "alu")
9214    (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_cc_ext_1"
9217   [(set (reg FLAGS_REG)
9218         (compare
9219           (xor:SI
9220             (zero_extract:SI
9221               (match_operand 1 "ext_register_operand" "0")
9222               (const_int 8)
9223               (const_int 8))
9224             (match_operand:QI 2 "general_operand" "qmn"))
9225           (const_int 0)))
9226    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9227                          (const_int 8)
9228                          (const_int 8))
9229         (xor:SI 
9230           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9231           (match_dup 2)))]
9232   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233   "xor{b}\t{%2, %h0|%h0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "mode" "QI")])
9236
9237 (define_insn "*xorqi_cc_ext_1_rex64"
9238   [(set (reg FLAGS_REG)
9239         (compare
9240           (xor:SI
9241             (zero_extract:SI
9242               (match_operand 1 "ext_register_operand" "0")
9243               (const_int 8)
9244               (const_int 8))
9245             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9246           (const_int 0)))
9247    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248                          (const_int 8)
9249                          (const_int 8))
9250         (xor:SI 
9251           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9252           (match_dup 2)))]
9253   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254   "xor{b}\t{%2, %h0|%h0, %2}"
9255   [(set_attr "type" "alu")
9256    (set_attr "mode" "QI")])
9257
9258 (define_expand "xorqi_cc_ext_1"
9259   [(parallel [
9260      (set (reg:CCNO FLAGS_REG)
9261           (compare:CCNO
9262             (xor:SI
9263               (zero_extract:SI
9264                 (match_operand 1 "ext_register_operand" "")
9265                 (const_int 8)
9266                 (const_int 8))
9267               (match_operand:QI 2 "general_operand" ""))
9268             (const_int 0)))
9269      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9270                            (const_int 8)
9271                            (const_int 8))
9272           (xor:SI 
9273             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9274             (match_dup 2)))])]
9275   ""
9276   "")
9277
9278 (define_split
9279   [(set (match_operand 0 "register_operand" "")
9280         (xor (match_operand 1 "register_operand" "")
9281              (match_operand 2 "const_int_operand" "")))
9282    (clobber (reg:CC FLAGS_REG))]
9283    "reload_completed
9284     && QI_REG_P (operands[0])
9285     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286     && !(INTVAL (operands[2]) & ~(255 << 8))
9287     && GET_MODE (operands[0]) != QImode"
9288   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289                    (xor:SI (zero_extract:SI (match_dup 1)
9290                                             (const_int 8) (const_int 8))
9291                            (match_dup 2)))
9292               (clobber (reg:CC FLAGS_REG))])]
9293   "operands[0] = gen_lowpart (SImode, operands[0]);
9294    operands[1] = gen_lowpart (SImode, operands[1]);
9295    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296
9297 ;; Since XOR can be encoded with sign extended immediate, this is only
9298 ;; profitable when 7th bit is set.
9299 (define_split
9300   [(set (match_operand 0 "register_operand" "")
9301         (xor (match_operand 1 "general_operand" "")
9302              (match_operand 2 "const_int_operand" "")))
9303    (clobber (reg:CC FLAGS_REG))]
9304    "reload_completed
9305     && ANY_QI_REG_P (operands[0])
9306     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307     && !(INTVAL (operands[2]) & ~255)
9308     && (INTVAL (operands[2]) & 128)
9309     && GET_MODE (operands[0]) != QImode"
9310   [(parallel [(set (strict_low_part (match_dup 0))
9311                    (xor:QI (match_dup 1)
9312                            (match_dup 2)))
9313               (clobber (reg:CC FLAGS_REG))])]
9314   "operands[0] = gen_lowpart (QImode, operands[0]);
9315    operands[1] = gen_lowpart (QImode, operands[1]);
9316    operands[2] = gen_lowpart (QImode, operands[2]);")
9317 \f
9318 ;; Negation instructions
9319
9320 (define_expand "negti2"
9321   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323               (clobber (reg:CC FLAGS_REG))])]
9324   "TARGET_64BIT"
9325   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9326
9327 (define_insn "*negti2_1"
9328   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "TARGET_64BIT
9332    && ix86_unary_operator_ok (NEG, TImode, operands)"
9333   "#")
9334
9335 (define_split
9336   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337         (neg:TI (match_operand:TI 1 "general_operand" "")))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "TARGET_64BIT && reload_completed"
9340   [(parallel
9341     [(set (reg:CCZ FLAGS_REG)
9342           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343      (set (match_dup 0) (neg:DI (match_dup 2)))])
9344    (parallel
9345     [(set (match_dup 1)
9346           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9347                             (match_dup 3))
9348                    (const_int 0)))
9349      (clobber (reg:CC FLAGS_REG))])
9350    (parallel
9351     [(set (match_dup 1)
9352           (neg:DI (match_dup 1)))
9353      (clobber (reg:CC FLAGS_REG))])]
9354   "split_ti (operands+1, 1, operands+2, operands+3);
9355    split_ti (operands+0, 1, operands+0, operands+1);")
9356
9357 (define_expand "negdi2"
9358   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360               (clobber (reg:CC FLAGS_REG))])]
9361   ""
9362   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9363
9364 (define_insn "*negdi2_1"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "!TARGET_64BIT
9369    && ix86_unary_operator_ok (NEG, DImode, operands)"
9370   "#")
9371
9372 (define_split
9373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374         (neg:DI (match_operand:DI 1 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "!TARGET_64BIT && reload_completed"
9377   [(parallel
9378     [(set (reg:CCZ FLAGS_REG)
9379           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380      (set (match_dup 0) (neg:SI (match_dup 2)))])
9381    (parallel
9382     [(set (match_dup 1)
9383           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9384                             (match_dup 3))
9385                    (const_int 0)))
9386      (clobber (reg:CC FLAGS_REG))])
9387    (parallel
9388     [(set (match_dup 1)
9389           (neg:SI (match_dup 1)))
9390      (clobber (reg:CC FLAGS_REG))])]
9391   "split_di (operands+1, 1, operands+2, operands+3);
9392    split_di (operands+0, 1, operands+0, operands+1);")
9393
9394 (define_insn "*negdi2_1_rex64"
9395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9399   "neg{q}\t%0"
9400   [(set_attr "type" "negnot")
9401    (set_attr "mode" "DI")])
9402
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9406
9407 (define_insn "*negdi2_cmpz_rex64"
9408   [(set (reg:CCZ FLAGS_REG)
9409         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9410                      (const_int 0)))
9411    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412         (neg:DI (match_dup 1)))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414   "neg{q}\t%0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "DI")])
9417
9418
9419 (define_expand "negsi2"
9420   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   ""
9424   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9425
9426 (define_insn "*negsi2_1"
9427   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "ix86_unary_operator_ok (NEG, SImode, operands)"
9431   "neg{l}\t%0"
9432   [(set_attr "type" "negnot")
9433    (set_attr "mode" "SI")])
9434
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437   [(set (match_operand:DI 0 "register_operand" "=r")
9438         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9439                                         (const_int 32)))
9440                      (const_int 32)))
9441    (clobber (reg:CC FLAGS_REG))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443   "neg{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9446
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9450
9451 (define_insn "*negsi2_cmpz"
9452   [(set (reg:CCZ FLAGS_REG)
9453         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9454                      (const_int 0)))
9455    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456         (neg:SI (match_dup 1)))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 (define_insn "*negsi2_cmpz_zext"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (lshiftrt:DI
9465                        (neg:DI (ashift:DI
9466                                  (match_operand:DI 1 "register_operand" "0")
9467                                  (const_int 32)))
9468                        (const_int 32))
9469                      (const_int 0)))
9470    (set (match_operand:DI 0 "register_operand" "=r")
9471         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9472                                         (const_int 32)))
9473                      (const_int 32)))]
9474   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9475   "neg{l}\t%k0"
9476   [(set_attr "type" "negnot")
9477    (set_attr "mode" "SI")])
9478
9479 (define_expand "neghi2"
9480   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482               (clobber (reg:CC FLAGS_REG))])]
9483   "TARGET_HIMODE_MATH"
9484   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9485
9486 (define_insn "*neghi2_1"
9487   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "ix86_unary_operator_ok (NEG, HImode, operands)"
9491   "neg{w}\t%0"
9492   [(set_attr "type" "negnot")
9493    (set_attr "mode" "HI")])
9494
9495 (define_insn "*neghi2_cmpz"
9496   [(set (reg:CCZ FLAGS_REG)
9497         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9498                      (const_int 0)))
9499    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500         (neg:HI (match_dup 1)))]
9501   "ix86_unary_operator_ok (NEG, HImode, operands)"
9502   "neg{w}\t%0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "HI")])
9505
9506 (define_expand "negqi2"
9507   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_QIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9512
9513 (define_insn "*negqi2_1"
9514   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "ix86_unary_operator_ok (NEG, QImode, operands)"
9518   "neg{b}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "QI")])
9521
9522 (define_insn "*negqi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527         (neg:QI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, QImode, operands)"
9529   "neg{b}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "QI")])
9532
9533 ;; Changing of sign for FP values is doable using integer unit too.
9534
9535 (define_expand "negsf2"
9536   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538   "TARGET_80387 || TARGET_SSE_MATH"
9539   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9540
9541 (define_expand "abssf2"
9542   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544   "TARGET_80387 || TARGET_SSE_MATH"
9545   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9546
9547 (define_insn "*absnegsf2_mixed"
9548   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,f,rm")
9549         (match_operator:SF 3 "absneg_operator"
9550           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0  ,0")]))
9551    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9555   "#")
9556
9557 (define_insn "*absnegsf2_sse"
9558   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9559         (match_operator:SF 3 "absneg_operator"
9560           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "TARGET_SSE_MATH
9564    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9565   "#")
9566
9567 (define_insn "*absnegsf2_i387"
9568   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569         (match_operator:SF 3 "absneg_operator"
9570           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571    (use (match_operand 2 "" ""))
9572    (clobber (reg:CC FLAGS_REG))]
9573   "TARGET_80387 && !TARGET_SSE_MATH
9574    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9575   "#")
9576
9577 (define_expand "copysignsf3"
9578   [(match_operand:SF 0 "register_operand" "")
9579    (match_operand:SF 1 "nonmemory_operand" "")
9580    (match_operand:SF 2 "register_operand" "")]
9581   "TARGET_SSE_MATH"
9582 {
9583   ix86_expand_copysign (operands);
9584   DONE;
9585 })
9586
9587 (define_insn_and_split "copysignsf3_const"
9588   [(set (match_operand:SF 0 "register_operand"          "=x")
9589         (unspec:SF
9590           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9591            (match_operand:SF 2 "register_operand"       "0")
9592            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9593           UNSPEC_COPYSIGN))]
9594   "TARGET_SSE_MATH"
9595   "#"
9596   "&& reload_completed"
9597   [(const_int 0)]
9598 {
9599   ix86_split_copysign_const (operands);
9600   DONE;
9601 })
9602
9603 (define_insn "copysignsf3_var"
9604   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9605         (unspec:SF
9606           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9607            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9608            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9610           UNSPEC_COPYSIGN))
9611    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9612   "TARGET_SSE_MATH"
9613   "#")
9614
9615 (define_split
9616   [(set (match_operand:SF 0 "register_operand" "")
9617         (unspec:SF
9618           [(match_operand:SF 2 "register_operand" "")
9619            (match_operand:SF 3 "register_operand" "")
9620            (match_operand:V4SF 4 "" "")
9621            (match_operand:V4SF 5 "" "")]
9622           UNSPEC_COPYSIGN))
9623    (clobber (match_scratch:V4SF 1 ""))]
9624   "TARGET_SSE_MATH && reload_completed"
9625   [(const_int 0)]
9626 {
9627   ix86_split_copysign_var (operands);
9628   DONE;
9629 })
9630
9631 (define_expand "negdf2"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9636
9637 (define_expand "absdf2"
9638   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9642
9643 (define_insn "*absnegdf2_mixed"
9644   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9645         (match_operator:DF 3 "absneg_operator"
9646           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y,0  ,0")]))
9647    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9651   "#")
9652
9653 (define_insn "*absnegdf2_sse"
9654   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9655         (match_operator:DF 3 "absneg_operator"
9656           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9657    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_SSE2 && TARGET_SSE_MATH
9660    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9661   "#")
9662
9663 (define_insn "*absnegdf2_i387"
9664   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665         (match_operator:DF 3 "absneg_operator"
9666           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667    (use (match_operand 2 "" ""))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9671   "#")
9672
9673 (define_expand "copysigndf3"
9674   [(match_operand:DF 0 "register_operand" "")
9675    (match_operand:DF 1 "nonmemory_operand" "")
9676    (match_operand:DF 2 "register_operand" "")]
9677   "TARGET_SSE2 && TARGET_SSE_MATH"
9678 {
9679   ix86_expand_copysign (operands);
9680   DONE;
9681 })
9682
9683 (define_insn_and_split "copysigndf3_const"
9684   [(set (match_operand:DF 0 "register_operand"          "=x")
9685         (unspec:DF
9686           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9687            (match_operand:DF 2 "register_operand"       "0")
9688            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9689           UNSPEC_COPYSIGN))]
9690   "TARGET_SSE2 && TARGET_SSE_MATH"
9691   "#"
9692   "&& reload_completed"
9693   [(const_int 0)]
9694 {
9695   ix86_split_copysign_const (operands);
9696   DONE;
9697 })
9698
9699 (define_insn "copysigndf3_var"
9700   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9701         (unspec:DF
9702           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9703            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9704            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9706           UNSPEC_COPYSIGN))
9707    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9708   "TARGET_SSE2 && TARGET_SSE_MATH"
9709   "#")
9710
9711 (define_split
9712   [(set (match_operand:DF 0 "register_operand" "")
9713         (unspec:DF
9714           [(match_operand:DF 2 "register_operand" "")
9715            (match_operand:DF 3 "register_operand" "")
9716            (match_operand:V2DF 4 "" "")
9717            (match_operand:V2DF 5 "" "")]
9718           UNSPEC_COPYSIGN))
9719    (clobber (match_scratch:V2DF 1 ""))]
9720   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9721   [(const_int 0)]
9722 {
9723   ix86_split_copysign_var (operands);
9724   DONE;
9725 })
9726
9727 (define_expand "negxf2"
9728   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9730   "TARGET_80387"
9731   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9732
9733 (define_expand "absxf2"
9734   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736   "TARGET_80387"
9737   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9738
9739 (define_insn "*absnegxf2_i387"
9740   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741         (match_operator:XF 3 "absneg_operator"
9742           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743    (use (match_operand 2 "" ""))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "TARGET_80387
9746    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9747   "#")
9748
9749 ;; Splitters for fp abs and neg.
9750
9751 (define_split
9752   [(set (match_operand 0 "fp_register_operand" "")
9753         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754    (use (match_operand 2 "" ""))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "reload_completed"
9757   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9758
9759 (define_split
9760   [(set (match_operand 0 "register_operand" "")
9761         (match_operator 3 "absneg_operator"
9762           [(match_operand 1 "register_operand" "")]))
9763    (use (match_operand 2 "nonimmediate_operand" ""))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "reload_completed && SSE_REG_P (operands[0])"
9766   [(set (match_dup 0) (match_dup 3))]
9767 {
9768   enum machine_mode mode = GET_MODE (operands[0]);
9769   enum machine_mode vmode = GET_MODE (operands[2]);
9770   rtx tmp;
9771   
9772   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774   if (operands_match_p (operands[0], operands[2]))
9775     {
9776       tmp = operands[1];
9777       operands[1] = operands[2];
9778       operands[2] = tmp;
9779     }
9780   if (GET_CODE (operands[3]) == ABS)
9781     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9782   else
9783     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9784   operands[3] = tmp;
9785 })
9786
9787 (define_split
9788   [(set (match_operand:SF 0 "register_operand" "")
9789         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790    (use (match_operand:V4SF 2 "" ""))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "reload_completed"
9793   [(parallel [(set (match_dup 0) (match_dup 1))
9794               (clobber (reg:CC FLAGS_REG))])]
9795
9796   rtx tmp;
9797   operands[0] = gen_lowpart (SImode, operands[0]);
9798   if (GET_CODE (operands[1]) == ABS)
9799     {
9800       tmp = gen_int_mode (0x7fffffff, SImode);
9801       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9802     }
9803   else
9804     {
9805       tmp = gen_int_mode (0x80000000, SImode);
9806       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9807     }
9808   operands[1] = tmp;
9809 })
9810
9811 (define_split
9812   [(set (match_operand:DF 0 "register_operand" "")
9813         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814    (use (match_operand 2 "" ""))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "reload_completed"
9817   [(parallel [(set (match_dup 0) (match_dup 1))
9818               (clobber (reg:CC FLAGS_REG))])]
9819 {
9820   rtx tmp;
9821   if (TARGET_64BIT)
9822     {
9823       tmp = gen_lowpart (DImode, operands[0]);
9824       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9825       operands[0] = tmp;
9826
9827       if (GET_CODE (operands[1]) == ABS)
9828         tmp = const0_rtx;
9829       else
9830         tmp = gen_rtx_NOT (DImode, tmp);
9831     }
9832   else
9833     {
9834       operands[0] = gen_highpart (SImode, operands[0]);
9835       if (GET_CODE (operands[1]) == ABS)
9836         {
9837           tmp = gen_int_mode (0x7fffffff, SImode);
9838           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839         }
9840       else
9841         {
9842           tmp = gen_int_mode (0x80000000, SImode);
9843           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844         }
9845     }
9846   operands[1] = tmp;
9847 })
9848
9849 (define_split
9850   [(set (match_operand:XF 0 "register_operand" "")
9851         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852    (use (match_operand 2 "" ""))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "reload_completed"
9855   [(parallel [(set (match_dup 0) (match_dup 1))
9856               (clobber (reg:CC FLAGS_REG))])]
9857 {
9858   rtx tmp;
9859   operands[0] = gen_rtx_REG (SImode,
9860                              true_regnum (operands[0])
9861                              + (TARGET_64BIT ? 1 : 2));
9862   if (GET_CODE (operands[1]) == ABS)
9863     {
9864       tmp = GEN_INT (0x7fff);
9865       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9866     }
9867   else
9868     {
9869       tmp = GEN_INT (0x8000);
9870       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9871     }
9872   operands[1] = tmp;
9873 })
9874
9875 (define_split
9876   [(set (match_operand 0 "memory_operand" "")
9877         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878    (use (match_operand 2 "" ""))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "reload_completed"
9881   [(parallel [(set (match_dup 0) (match_dup 1))
9882               (clobber (reg:CC FLAGS_REG))])]
9883 {
9884   enum machine_mode mode = GET_MODE (operands[0]);
9885   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9886   rtx tmp;
9887
9888   operands[0] = adjust_address (operands[0], QImode, size - 1);
9889   if (GET_CODE (operands[1]) == ABS)
9890     {
9891       tmp = gen_int_mode (0x7f, QImode);
9892       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9893     }
9894   else
9895     {
9896       tmp = gen_int_mode (0x80, QImode);
9897       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9898     }
9899   operands[1] = tmp;
9900 })
9901
9902 ;; Conditionalize these after reload. If they match before reload, we 
9903 ;; lose the clobber and ability to use integer instructions.
9904
9905 (define_insn "*negsf2_1"
9906   [(set (match_operand:SF 0 "register_operand" "=f")
9907         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908   "TARGET_80387 && reload_completed"
9909   "fchs"
9910   [(set_attr "type" "fsgn")
9911    (set_attr "mode" "SF")])
9912
9913 (define_insn "*negdf2_1"
9914   [(set (match_operand:DF 0 "register_operand" "=f")
9915         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916   "TARGET_80387 && reload_completed"
9917   "fchs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "DF")])
9920
9921 (define_insn "*negxf2_1"
9922   [(set (match_operand:XF 0 "register_operand" "=f")
9923         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9924   "TARGET_80387 && reload_completed"
9925   "fchs"
9926   [(set_attr "type" "fsgn")
9927    (set_attr "mode" "XF")])
9928
9929 (define_insn "*abssf2_1"
9930   [(set (match_operand:SF 0 "register_operand" "=f")
9931         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932   "TARGET_80387 && reload_completed"
9933   "fabs"
9934   [(set_attr "type" "fsgn")
9935    (set_attr "mode" "SF")])
9936
9937 (define_insn "*absdf2_1"
9938   [(set (match_operand:DF 0 "register_operand" "=f")
9939         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940   "TARGET_80387 && reload_completed"
9941   "fabs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "DF")])
9944
9945 (define_insn "*absxf2_1"
9946   [(set (match_operand:XF 0 "register_operand" "=f")
9947         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9948   "TARGET_80387 && reload_completed"
9949   "fabs"
9950   [(set_attr "type" "fsgn")
9951    (set_attr "mode" "DF")])
9952
9953 (define_insn "*negextendsfdf2"
9954   [(set (match_operand:DF 0 "register_operand" "=f")
9955         (neg:DF (float_extend:DF
9956                   (match_operand:SF 1 "register_operand" "0"))))]
9957   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9958   "fchs"
9959   [(set_attr "type" "fsgn")
9960    (set_attr "mode" "DF")])
9961
9962 (define_insn "*negextenddfxf2"
9963   [(set (match_operand:XF 0 "register_operand" "=f")
9964         (neg:XF (float_extend:XF
9965                   (match_operand:DF 1 "register_operand" "0"))))]
9966   "TARGET_80387"
9967   "fchs"
9968   [(set_attr "type" "fsgn")
9969    (set_attr "mode" "XF")])
9970
9971 (define_insn "*negextendsfxf2"
9972   [(set (match_operand:XF 0 "register_operand" "=f")
9973         (neg:XF (float_extend:XF
9974                   (match_operand:SF 1 "register_operand" "0"))))]
9975   "TARGET_80387"
9976   "fchs"
9977   [(set_attr "type" "fsgn")
9978    (set_attr "mode" "XF")])
9979
9980 (define_insn "*absextendsfdf2"
9981   [(set (match_operand:DF 0 "register_operand" "=f")
9982         (abs:DF (float_extend:DF
9983                   (match_operand:SF 1 "register_operand" "0"))))]
9984   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9985   "fabs"
9986   [(set_attr "type" "fsgn")
9987    (set_attr "mode" "DF")])
9988
9989 (define_insn "*absextenddfxf2"
9990   [(set (match_operand:XF 0 "register_operand" "=f")
9991         (abs:XF (float_extend:XF
9992           (match_operand:DF 1 "register_operand" "0"))))]
9993   "TARGET_80387"
9994   "fabs"
9995   [(set_attr "type" "fsgn")
9996    (set_attr "mode" "XF")])
9997
9998 (define_insn "*absextendsfxf2"
9999   [(set (match_operand:XF 0 "register_operand" "=f")
10000         (abs:XF (float_extend:XF
10001           (match_operand:SF 1 "register_operand" "0"))))]
10002   "TARGET_80387"
10003   "fabs"
10004   [(set_attr "type" "fsgn")
10005    (set_attr "mode" "XF")])
10006 \f
10007 ;; One complement instructions
10008
10009 (define_expand "one_cmpldi2"
10010   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10012   "TARGET_64BIT"
10013   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10014
10015 (define_insn "*one_cmpldi2_1_rex64"
10016   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10019   "not{q}\t%0"
10020   [(set_attr "type" "negnot")
10021    (set_attr "mode" "DI")])
10022
10023 (define_insn "*one_cmpldi2_2_rex64"
10024   [(set (reg FLAGS_REG)
10025         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10026                  (const_int 0)))
10027    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028         (not:DI (match_dup 1)))]
10029   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030    && ix86_unary_operator_ok (NOT, DImode, operands)"
10031   "#"
10032   [(set_attr "type" "alu1")
10033    (set_attr "mode" "DI")])
10034
10035 (define_split
10036   [(set (match_operand 0 "flags_reg_operand" "")
10037         (match_operator 2 "compare_operator"
10038           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10039            (const_int 0)]))
10040    (set (match_operand:DI 1 "nonimmediate_operand" "")
10041         (not:DI (match_dup 3)))]
10042   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043   [(parallel [(set (match_dup 0)
10044                    (match_op_dup 2
10045                      [(xor:DI (match_dup 3) (const_int -1))
10046                       (const_int 0)]))
10047               (set (match_dup 1)
10048                    (xor:DI (match_dup 3) (const_int -1)))])]
10049   "")
10050
10051 (define_expand "one_cmplsi2"
10052   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10054   ""
10055   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10056
10057 (define_insn "*one_cmplsi2_1"
10058   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060   "ix86_unary_operator_ok (NOT, SImode, operands)"
10061   "not{l}\t%0"
10062   [(set_attr "type" "negnot")
10063    (set_attr "mode" "SI")])
10064
10065 ;; ??? Currently never generated - xor is used instead.
10066 (define_insn "*one_cmplsi2_1_zext"
10067   [(set (match_operand:DI 0 "register_operand" "=r")
10068         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10070   "not{l}\t%k0"
10071   [(set_attr "type" "negnot")
10072    (set_attr "mode" "SI")])
10073
10074 (define_insn "*one_cmplsi2_2"
10075   [(set (reg FLAGS_REG)
10076         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10077                  (const_int 0)))
10078    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079         (not:SI (match_dup 1)))]
10080   "ix86_match_ccmode (insn, CCNOmode)
10081    && ix86_unary_operator_ok (NOT, SImode, operands)"
10082   "#"
10083   [(set_attr "type" "alu1")
10084    (set_attr "mode" "SI")])
10085
10086 (define_split
10087   [(set (match_operand 0 "flags_reg_operand" "")
10088         (match_operator 2 "compare_operator"
10089           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10090            (const_int 0)]))
10091    (set (match_operand:SI 1 "nonimmediate_operand" "")
10092         (not:SI (match_dup 3)))]
10093   "ix86_match_ccmode (insn, CCNOmode)"
10094   [(parallel [(set (match_dup 0)
10095                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10096                                     (const_int 0)]))
10097               (set (match_dup 1)
10098                    (xor:SI (match_dup 3) (const_int -1)))])]
10099   "")
10100
10101 ;; ??? Currently never generated - xor is used instead.
10102 (define_insn "*one_cmplsi2_2_zext"
10103   [(set (reg FLAGS_REG)
10104         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10105                  (const_int 0)))
10106    (set (match_operand:DI 0 "register_operand" "=r")
10107         (zero_extend:DI (not:SI (match_dup 1))))]
10108   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109    && ix86_unary_operator_ok (NOT, SImode, operands)"
10110   "#"
10111   [(set_attr "type" "alu1")
10112    (set_attr "mode" "SI")])
10113
10114 (define_split
10115   [(set (match_operand 0 "flags_reg_operand" "")
10116         (match_operator 2 "compare_operator"
10117           [(not:SI (match_operand:SI 3 "register_operand" ""))
10118            (const_int 0)]))
10119    (set (match_operand:DI 1 "register_operand" "")
10120         (zero_extend:DI (not:SI (match_dup 3))))]
10121   "ix86_match_ccmode (insn, CCNOmode)"
10122   [(parallel [(set (match_dup 0)
10123                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10124                                     (const_int 0)]))
10125               (set (match_dup 1)
10126                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10127   "")
10128
10129 (define_expand "one_cmplhi2"
10130   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132   "TARGET_HIMODE_MATH"
10133   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10134
10135 (define_insn "*one_cmplhi2_1"
10136   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138   "ix86_unary_operator_ok (NOT, HImode, operands)"
10139   "not{w}\t%0"
10140   [(set_attr "type" "negnot")
10141    (set_attr "mode" "HI")])
10142
10143 (define_insn "*one_cmplhi2_2"
10144   [(set (reg FLAGS_REG)
10145         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10146                  (const_int 0)))
10147    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148         (not:HI (match_dup 1)))]
10149   "ix86_match_ccmode (insn, CCNOmode)
10150    && ix86_unary_operator_ok (NEG, HImode, operands)"
10151   "#"
10152   [(set_attr "type" "alu1")
10153    (set_attr "mode" "HI")])
10154
10155 (define_split
10156   [(set (match_operand 0 "flags_reg_operand" "")
10157         (match_operator 2 "compare_operator"
10158           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10159            (const_int 0)]))
10160    (set (match_operand:HI 1 "nonimmediate_operand" "")
10161         (not:HI (match_dup 3)))]
10162   "ix86_match_ccmode (insn, CCNOmode)"
10163   [(parallel [(set (match_dup 0)
10164                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10165                                     (const_int 0)]))
10166               (set (match_dup 1)
10167                    (xor:HI (match_dup 3) (const_int -1)))])]
10168   "")
10169
10170 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10171 (define_expand "one_cmplqi2"
10172   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174   "TARGET_QIMODE_MATH"
10175   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10176
10177 (define_insn "*one_cmplqi2_1"
10178   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180   "ix86_unary_operator_ok (NOT, QImode, operands)"
10181   "@
10182    not{b}\t%0
10183    not{l}\t%k0"
10184   [(set_attr "type" "negnot")
10185    (set_attr "mode" "QI,SI")])
10186
10187 (define_insn "*one_cmplqi2_2"
10188   [(set (reg FLAGS_REG)
10189         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10190                  (const_int 0)))
10191    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192         (not:QI (match_dup 1)))]
10193   "ix86_match_ccmode (insn, CCNOmode)
10194    && ix86_unary_operator_ok (NOT, QImode, operands)"
10195   "#"
10196   [(set_attr "type" "alu1")
10197    (set_attr "mode" "QI")])
10198
10199 (define_split
10200   [(set (match_operand 0 "flags_reg_operand" "")
10201         (match_operator 2 "compare_operator"
10202           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10203            (const_int 0)]))
10204    (set (match_operand:QI 1 "nonimmediate_operand" "")
10205         (not:QI (match_dup 3)))]
10206   "ix86_match_ccmode (insn, CCNOmode)"
10207   [(parallel [(set (match_dup 0)
10208                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10209                                     (const_int 0)]))
10210               (set (match_dup 1)
10211                    (xor:QI (match_dup 3) (const_int -1)))])]
10212   "")
10213 \f
10214 ;; Arithmetic shift instructions
10215
10216 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10217 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10218 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10219 ;; from the assembler input.
10220 ;;
10221 ;; This instruction shifts the target reg/mem as usual, but instead of
10222 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10223 ;; is a left shift double, bits are taken from the high order bits of
10224 ;; reg, else if the insn is a shift right double, bits are taken from the
10225 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10226 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10227 ;;
10228 ;; Since sh[lr]d does not change the `reg' operand, that is done
10229 ;; separately, making all shifts emit pairs of shift double and normal
10230 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10231 ;; support a 63 bit shift, each shift where the count is in a reg expands
10232 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10233 ;;
10234 ;; If the shift count is a constant, we need never emit more than one
10235 ;; shift pair, instead using moves and sign extension for counts greater
10236 ;; than 31.
10237
10238 (define_expand "ashlti3"
10239   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10241                               (match_operand:QI 2 "nonmemory_operand" "")))
10242               (clobber (reg:CC FLAGS_REG))])]
10243   "TARGET_64BIT"
10244 {
10245   if (! immediate_operand (operands[2], QImode))
10246     {
10247       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10248       DONE;
10249     }
10250   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10251   DONE;
10252 })
10253
10254 (define_insn "ashlti3_1"
10255   [(set (match_operand:TI 0 "register_operand" "=r")
10256         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10257                    (match_operand:QI 2 "register_operand" "c")))
10258    (clobber (match_scratch:DI 3 "=&r"))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_64BIT"
10261   "#"
10262   [(set_attr "type" "multi")])
10263
10264 (define_insn "*ashlti3_2"
10265   [(set (match_operand:TI 0 "register_operand" "=r")
10266         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10267                    (match_operand:QI 2 "immediate_operand" "O")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_64BIT"
10270   "#"
10271   [(set_attr "type" "multi")])
10272
10273 (define_split
10274   [(set (match_operand:TI 0 "register_operand" "")
10275         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276                    (match_operand:QI 2 "register_operand" "")))
10277    (clobber (match_scratch:DI 3 ""))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "TARGET_64BIT && reload_completed"
10280   [(const_int 0)]
10281   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10282
10283 (define_split
10284   [(set (match_operand:TI 0 "register_operand" "")
10285         (ashift:TI (match_operand:TI 1 "register_operand" "")
10286                    (match_operand:QI 2 "immediate_operand" "")))
10287    (clobber (reg:CC FLAGS_REG))]
10288   "TARGET_64BIT && reload_completed"
10289   [(const_int 0)]
10290   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10291
10292 (define_insn "x86_64_shld"
10293   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294         (ior:DI (ashift:DI (match_dup 0)
10295                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297                   (minus:QI (const_int 64) (match_dup 2)))))
10298    (clobber (reg:CC FLAGS_REG))]
10299   "TARGET_64BIT"
10300   "@
10301    shld{q}\t{%2, %1, %0|%0, %1, %2}
10302    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303   [(set_attr "type" "ishift")
10304    (set_attr "prefix_0f" "1")
10305    (set_attr "mode" "DI")
10306    (set_attr "athlon_decode" "vector")])
10307
10308 (define_expand "x86_64_shift_adj"
10309   [(set (reg:CCZ FLAGS_REG)
10310         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10311                              (const_int 64))
10312                      (const_int 0)))
10313    (set (match_operand:DI 0 "register_operand" "")
10314         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315                          (match_operand:DI 1 "register_operand" "")
10316                          (match_dup 0)))
10317    (set (match_dup 1)
10318         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319                          (match_operand:DI 3 "register_operand" "r")
10320                          (match_dup 1)))]
10321   "TARGET_64BIT"
10322   "")
10323
10324 (define_expand "ashldi3"
10325   [(set (match_operand:DI 0 "shiftdi_operand" "")
10326         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327                    (match_operand:QI 2 "nonmemory_operand" "")))]
10328   ""
10329   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10330
10331 (define_insn "*ashldi3_1_rex64"
10332   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10337 {
10338   switch (get_attr_type (insn))
10339     {
10340     case TYPE_ALU:
10341       gcc_assert (operands[2] == const1_rtx);
10342       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343       return "add{q}\t{%0, %0|%0, %0}";
10344
10345     case TYPE_LEA:
10346       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348       operands[1] = gen_rtx_MULT (DImode, operands[1],
10349                                   GEN_INT (1 << INTVAL (operands[2])));
10350       return "lea{q}\t{%a1, %0|%0, %a1}";
10351
10352     default:
10353       if (REG_P (operands[2]))
10354         return "sal{q}\t{%b2, %0|%0, %b2}";
10355       else if (operands[2] == const1_rtx
10356                && (TARGET_SHIFT1 || optimize_size))
10357         return "sal{q}\t%0";
10358       else
10359         return "sal{q}\t{%2, %0|%0, %2}";
10360     }
10361 }
10362   [(set (attr "type")
10363      (cond [(eq_attr "alternative" "1")
10364               (const_string "lea")
10365             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10366                           (const_int 0))
10367                       (match_operand 0 "register_operand" ""))
10368                  (match_operand 2 "const1_operand" ""))
10369               (const_string "alu")
10370            ]
10371            (const_string "ishift")))
10372    (set_attr "mode" "DI")])
10373
10374 ;; Convert lea to the lea pattern to avoid flags dependency.
10375 (define_split
10376   [(set (match_operand:DI 0 "register_operand" "")
10377         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378                    (match_operand:QI 2 "immediate_operand" "")))
10379    (clobber (reg:CC FLAGS_REG))]
10380   "TARGET_64BIT && reload_completed
10381    && true_regnum (operands[0]) != true_regnum (operands[1])"
10382   [(set (match_dup 0)
10383         (mult:DI (match_dup 1)
10384                  (match_dup 2)))]
10385   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10386
10387 ;; This pattern can't accept a variable shift count, since shifts by
10388 ;; zero don't affect the flags.  We assume that shifts by constant
10389 ;; zero are optimized away.
10390 (define_insn "*ashldi3_cmp_rex64"
10391   [(set (reg FLAGS_REG)
10392         (compare
10393           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394                      (match_operand:QI 2 "immediate_operand" "e"))
10395           (const_int 0)))
10396    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397         (ashift:DI (match_dup 1) (match_dup 2)))]
10398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10400 {
10401   switch (get_attr_type (insn))
10402     {
10403     case TYPE_ALU:
10404       gcc_assert (operands[2] == const1_rtx);
10405       return "add{q}\t{%0, %0|%0, %0}";
10406
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10416 }
10417   [(set (attr "type")
10418      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419                           (const_int 0))
10420                       (match_operand 0 "register_operand" ""))
10421                  (match_operand 2 "const1_operand" ""))
10422               (const_string "alu")
10423            ]
10424            (const_string "ishift")))
10425    (set_attr "mode" "DI")])
10426
10427 (define_insn "*ashldi3_1"
10428   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10429         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10430                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10431    (clobber (reg:CC FLAGS_REG))]
10432   "!TARGET_64BIT"
10433   "#"
10434   [(set_attr "type" "multi")])
10435
10436 ;; By default we don't ask for a scratch register, because when DImode
10437 ;; values are manipulated, registers are already at a premium.  But if
10438 ;; we have one handy, we won't turn it away.
10439 (define_peephole2
10440   [(match_scratch:SI 3 "r")
10441    (parallel [(set (match_operand:DI 0 "register_operand" "")
10442                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10443                               (match_operand:QI 2 "nonmemory_operand" "")))
10444               (clobber (reg:CC FLAGS_REG))])
10445    (match_dup 3)]
10446   "!TARGET_64BIT && TARGET_CMOVE"
10447   [(const_int 0)]
10448   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10449
10450 (define_split
10451   [(set (match_operand:DI 0 "register_operand" "")
10452         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10453                    (match_operand:QI 2 "nonmemory_operand" "")))
10454    (clobber (reg:CC FLAGS_REG))]
10455   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10456                      ? flow2_completed : reload_completed)"
10457   [(const_int 0)]
10458   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10459
10460 (define_insn "x86_shld_1"
10461   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10462         (ior:SI (ashift:SI (match_dup 0)
10463                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10464                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10465                   (minus:QI (const_int 32) (match_dup 2)))))
10466    (clobber (reg:CC FLAGS_REG))]
10467   ""
10468   "@
10469    shld{l}\t{%2, %1, %0|%0, %1, %2}
10470    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10471   [(set_attr "type" "ishift")
10472    (set_attr "prefix_0f" "1")
10473    (set_attr "mode" "SI")
10474    (set_attr "pent_pair" "np")
10475    (set_attr "athlon_decode" "vector")])
10476
10477 (define_expand "x86_shift_adj_1"
10478   [(set (reg:CCZ FLAGS_REG)
10479         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10480                              (const_int 32))
10481                      (const_int 0)))
10482    (set (match_operand:SI 0 "register_operand" "")
10483         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10484                          (match_operand:SI 1 "register_operand" "")
10485                          (match_dup 0)))
10486    (set (match_dup 1)
10487         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488                          (match_operand:SI 3 "register_operand" "r")
10489                          (match_dup 1)))]
10490   "TARGET_CMOVE"
10491   "")
10492
10493 (define_expand "x86_shift_adj_2"
10494   [(use (match_operand:SI 0 "register_operand" ""))
10495    (use (match_operand:SI 1 "register_operand" ""))
10496    (use (match_operand:QI 2 "register_operand" ""))]
10497   ""
10498 {
10499   rtx label = gen_label_rtx ();
10500   rtx tmp;
10501
10502   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10503
10504   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10505   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10506   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10507                               gen_rtx_LABEL_REF (VOIDmode, label),
10508                               pc_rtx);
10509   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10510   JUMP_LABEL (tmp) = label;
10511
10512   emit_move_insn (operands[0], operands[1]);
10513   ix86_expand_clear (operands[1]);
10514
10515   emit_label (label);
10516   LABEL_NUSES (label) = 1;
10517
10518   DONE;
10519 })
10520
10521 (define_expand "ashlsi3"
10522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10523         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10524                    (match_operand:QI 2 "nonmemory_operand" "")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   ""
10527   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10528
10529 (define_insn "*ashlsi3_1"
10530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10531         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10532                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10535 {
10536   switch (get_attr_type (insn))
10537     {
10538     case TYPE_ALU:
10539       gcc_assert (operands[2] == const1_rtx);
10540       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10541       return "add{l}\t{%0, %0|%0, %0}";
10542
10543     case TYPE_LEA:
10544       return "#";
10545
10546     default:
10547       if (REG_P (operands[2]))
10548         return "sal{l}\t{%b2, %0|%0, %b2}";
10549       else if (operands[2] == const1_rtx
10550                && (TARGET_SHIFT1 || optimize_size))
10551         return "sal{l}\t%0";
10552       else
10553         return "sal{l}\t{%2, %0|%0, %2}";
10554     }
10555 }
10556   [(set (attr "type")
10557      (cond [(eq_attr "alternative" "1")
10558               (const_string "lea")
10559             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10560                           (const_int 0))
10561                       (match_operand 0 "register_operand" ""))
10562                  (match_operand 2 "const1_operand" ""))
10563               (const_string "alu")
10564            ]
10565            (const_string "ishift")))
10566    (set_attr "mode" "SI")])
10567
10568 ;; Convert lea to the lea pattern to avoid flags dependency.
10569 (define_split
10570   [(set (match_operand 0 "register_operand" "")
10571         (ashift (match_operand 1 "index_register_operand" "")
10572                 (match_operand:QI 2 "const_int_operand" "")))
10573    (clobber (reg:CC FLAGS_REG))]
10574   "reload_completed
10575    && true_regnum (operands[0]) != true_regnum (operands[1])
10576    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10577   [(const_int 0)]
10578 {
10579   rtx pat;
10580   enum machine_mode mode = GET_MODE (operands[0]);
10581
10582   if (GET_MODE_SIZE (mode) < 4)
10583     operands[0] = gen_lowpart (SImode, operands[0]);
10584   if (mode != Pmode)
10585     operands[1] = gen_lowpart (Pmode, operands[1]);
10586   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10587
10588   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10589   if (Pmode != SImode)
10590     pat = gen_rtx_SUBREG (SImode, pat, 0);
10591   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10592   DONE;
10593 })
10594
10595 ;; Rare case of shifting RSP is handled by generating move and shift
10596 (define_split
10597   [(set (match_operand 0 "register_operand" "")
10598         (ashift (match_operand 1 "register_operand" "")
10599                 (match_operand:QI 2 "const_int_operand" "")))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "reload_completed
10602    && true_regnum (operands[0]) != true_regnum (operands[1])"
10603   [(const_int 0)]
10604 {
10605   rtx pat, clob;
10606   emit_move_insn (operands[0], operands[1]);
10607   pat = gen_rtx_SET (VOIDmode, operands[0],
10608                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10609                                      operands[0], operands[2]));
10610   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10611   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10612   DONE;
10613 })
10614
10615 (define_insn "*ashlsi3_1_zext"
10616   [(set (match_operand:DI 0 "register_operand" "=r,r")
10617         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10618                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10621 {
10622   switch (get_attr_type (insn))
10623     {
10624     case TYPE_ALU:
10625       gcc_assert (operands[2] == const1_rtx);
10626       return "add{l}\t{%k0, %k0|%k0, %k0}";
10627
10628     case TYPE_LEA:
10629       return "#";
10630
10631     default:
10632       if (REG_P (operands[2]))
10633         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10634       else if (operands[2] == const1_rtx
10635                && (TARGET_SHIFT1 || optimize_size))
10636         return "sal{l}\t%k0";
10637       else
10638         return "sal{l}\t{%2, %k0|%k0, %2}";
10639     }
10640 }
10641   [(set (attr "type")
10642      (cond [(eq_attr "alternative" "1")
10643               (const_string "lea")
10644             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10645                      (const_int 0))
10646                  (match_operand 2 "const1_operand" ""))
10647               (const_string "alu")
10648            ]
10649            (const_string "ishift")))
10650    (set_attr "mode" "SI")])
10651
10652 ;; Convert lea to the lea pattern to avoid flags dependency.
10653 (define_split
10654   [(set (match_operand:DI 0 "register_operand" "")
10655         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10656                                 (match_operand:QI 2 "const_int_operand" ""))))
10657    (clobber (reg:CC FLAGS_REG))]
10658   "TARGET_64BIT && reload_completed
10659    && true_regnum (operands[0]) != true_regnum (operands[1])"
10660   [(set (match_dup 0) (zero_extend:DI
10661                         (subreg:SI (mult:SI (match_dup 1)
10662                                             (match_dup 2)) 0)))]
10663 {
10664   operands[1] = gen_lowpart (Pmode, operands[1]);
10665   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10666 })
10667
10668 ;; This pattern can't accept a variable shift count, since shifts by
10669 ;; zero don't affect the flags.  We assume that shifts by constant
10670 ;; zero are optimized away.
10671 (define_insn "*ashlsi3_cmp"
10672   [(set (reg FLAGS_REG)
10673         (compare
10674           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10675                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10676           (const_int 0)))
10677    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10678         (ashift:SI (match_dup 1) (match_dup 2)))]
10679   "ix86_match_ccmode (insn, CCGOCmode)
10680    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10681 {
10682   switch (get_attr_type (insn))
10683     {
10684     case TYPE_ALU:
10685       gcc_assert (operands[2] == const1_rtx);
10686       return "add{l}\t{%0, %0|%0, %0}";
10687
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{l}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{l}\t%0";
10694       else
10695         return "sal{l}\t{%2, %0|%0, %2}";
10696     }
10697 }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "SI")])
10707
10708 (define_insn "*ashlsi3_cmp_zext"
10709   [(set (reg FLAGS_REG)
10710         (compare
10711           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10712                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10713           (const_int 0)))
10714    (set (match_operand:DI 0 "register_operand" "=r")
10715         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10717    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10718 {
10719   switch (get_attr_type (insn))
10720     {
10721     case TYPE_ALU:
10722       gcc_assert (operands[2] == const1_rtx);
10723       return "add{l}\t{%k0, %k0|%k0, %k0}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{l}\t%k0";
10731       else
10732         return "sal{l}\t{%2, %k0|%k0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737                      (const_int 0))
10738                  (match_operand 2 "const1_operand" ""))
10739               (const_string "alu")
10740            ]
10741            (const_string "ishift")))
10742    (set_attr "mode" "SI")])
10743
10744 (define_expand "ashlhi3"
10745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10746         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10747                    (match_operand:QI 2 "nonmemory_operand" "")))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "TARGET_HIMODE_MATH"
10750   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10751
10752 (define_insn "*ashlhi3_1_lea"
10753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10754         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10755                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10756    (clobber (reg:CC FLAGS_REG))]
10757   "!TARGET_PARTIAL_REG_STALL
10758    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10759 {
10760   switch (get_attr_type (insn))
10761     {
10762     case TYPE_LEA:
10763       return "#";
10764     case TYPE_ALU:
10765       gcc_assert (operands[2] == const1_rtx);
10766       return "add{w}\t{%0, %0|%0, %0}";
10767
10768     default:
10769       if (REG_P (operands[2]))
10770         return "sal{w}\t{%b2, %0|%0, %b2}";
10771       else if (operands[2] == const1_rtx
10772                && (TARGET_SHIFT1 || optimize_size))
10773         return "sal{w}\t%0";
10774       else
10775         return "sal{w}\t{%2, %0|%0, %2}";
10776     }
10777 }
10778   [(set (attr "type")
10779      (cond [(eq_attr "alternative" "1")
10780               (const_string "lea")
10781             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "HI,SI")])
10789
10790 (define_insn "*ashlhi3_1"
10791   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10793                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10794    (clobber (reg:CC FLAGS_REG))]
10795   "TARGET_PARTIAL_REG_STALL
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 {
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10803
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10813 }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10823
10824 ;; This pattern can't accept a variable shift count, since shifts by
10825 ;; zero don't affect the flags.  We assume that shifts by constant
10826 ;; zero are optimized away.
10827 (define_insn "*ashlhi3_cmp"
10828   [(set (reg FLAGS_REG)
10829         (compare
10830           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10831                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10832           (const_int 0)))
10833    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10834         (ashift:HI (match_dup 1) (match_dup 2)))]
10835   "ix86_match_ccmode (insn, CCGOCmode)
10836    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10837 {
10838   switch (get_attr_type (insn))
10839     {
10840     case TYPE_ALU:
10841       gcc_assert (operands[2] == const1_rtx);
10842       return "add{w}\t{%0, %0|%0, %0}";
10843
10844     default:
10845       if (REG_P (operands[2]))
10846         return "sal{w}\t{%b2, %0|%0, %b2}";
10847       else if (operands[2] == const1_rtx
10848                && (TARGET_SHIFT1 || optimize_size))
10849         return "sal{w}\t%0";
10850       else
10851         return "sal{w}\t{%2, %0|%0, %2}";
10852     }
10853 }
10854   [(set (attr "type")
10855      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856                           (const_int 0))
10857                       (match_operand 0 "register_operand" ""))
10858                  (match_operand 2 "const1_operand" ""))
10859               (const_string "alu")
10860            ]
10861            (const_string "ishift")))
10862    (set_attr "mode" "HI")])
10863
10864 (define_expand "ashlqi3"
10865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10866         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10867                    (match_operand:QI 2 "nonmemory_operand" "")))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "TARGET_QIMODE_MATH"
10870   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10871
10872 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10873
10874 (define_insn "*ashlqi3_1_lea"
10875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10876         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10877                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "!TARGET_PARTIAL_REG_STALL
10880    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10881 {
10882   switch (get_attr_type (insn))
10883     {
10884     case TYPE_LEA:
10885       return "#";
10886     case TYPE_ALU:
10887       gcc_assert (operands[2] == const1_rtx);
10888       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10889         return "add{l}\t{%k0, %k0|%k0, %k0}";
10890       else
10891         return "add{b}\t{%0, %0|%0, %0}";
10892
10893     default:
10894       if (REG_P (operands[2]))
10895         {
10896           if (get_attr_mode (insn) == MODE_SI)
10897             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10898           else
10899             return "sal{b}\t{%b2, %0|%0, %b2}";
10900         }
10901       else if (operands[2] == const1_rtx
10902                && (TARGET_SHIFT1 || optimize_size))
10903         {
10904           if (get_attr_mode (insn) == MODE_SI)
10905             return "sal{l}\t%0";
10906           else
10907             return "sal{b}\t%0";
10908         }
10909       else
10910         {
10911           if (get_attr_mode (insn) == MODE_SI)
10912             return "sal{l}\t{%2, %k0|%k0, %2}";
10913           else
10914             return "sal{b}\t{%2, %0|%0, %2}";
10915         }
10916     }
10917 }
10918   [(set (attr "type")
10919      (cond [(eq_attr "alternative" "2")
10920               (const_string "lea")
10921             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922                           (const_int 0))
10923                       (match_operand 0 "register_operand" ""))
10924                  (match_operand 2 "const1_operand" ""))
10925               (const_string "alu")
10926            ]
10927            (const_string "ishift")))
10928    (set_attr "mode" "QI,SI,SI")])
10929
10930 (define_insn "*ashlqi3_1"
10931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10932         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10933                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_PARTIAL_REG_STALL
10936    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10937 {
10938   switch (get_attr_type (insn))
10939     {
10940     case TYPE_ALU:
10941       gcc_assert (operands[2] == const1_rtx);
10942       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10943         return "add{l}\t{%k0, %k0|%k0, %k0}";
10944       else
10945         return "add{b}\t{%0, %0|%0, %0}";
10946
10947     default:
10948       if (REG_P (operands[2]))
10949         {
10950           if (get_attr_mode (insn) == MODE_SI)
10951             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10952           else
10953             return "sal{b}\t{%b2, %0|%0, %b2}";
10954         }
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         {
10958           if (get_attr_mode (insn) == MODE_SI)
10959             return "sal{l}\t%0";
10960           else
10961             return "sal{b}\t%0";
10962         }
10963       else
10964         {
10965           if (get_attr_mode (insn) == MODE_SI)
10966             return "sal{l}\t{%2, %k0|%k0, %2}";
10967           else
10968             return "sal{b}\t{%2, %0|%0, %2}";
10969         }
10970     }
10971 }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI,SI")])
10981
10982 ;; This pattern can't accept a variable shift count, since shifts by
10983 ;; zero don't affect the flags.  We assume that shifts by constant
10984 ;; zero are optimized away.
10985 (define_insn "*ashlqi3_cmp"
10986   [(set (reg FLAGS_REG)
10987         (compare
10988           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10989                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10990           (const_int 0)))
10991    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10992         (ashift:QI (match_dup 1) (match_dup 2)))]
10993   "ix86_match_ccmode (insn, CCGOCmode)
10994    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{b}\t{%0, %0|%0, %0}";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{b}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{b}\t%0";
11008       else
11009         return "sal{b}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "QI")])
11021
11022 ;; See comment above `ashldi3' about how this works.
11023
11024 (define_expand "ashrti3"
11025   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11026                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027                                 (match_operand:QI 2 "nonmemory_operand" "")))
11028               (clobber (reg:CC FLAGS_REG))])]
11029   "TARGET_64BIT"
11030 {
11031   if (! immediate_operand (operands[2], QImode))
11032     {
11033       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11034       DONE;
11035     }
11036   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11037   DONE;
11038 })
11039
11040 (define_insn "ashrti3_1"
11041   [(set (match_operand:TI 0 "register_operand" "=r")
11042         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11043                      (match_operand:QI 2 "register_operand" "c")))
11044    (clobber (match_scratch:DI 3 "=&r"))
11045    (clobber (reg:CC FLAGS_REG))]
11046   "TARGET_64BIT"
11047   "#"
11048   [(set_attr "type" "multi")])
11049
11050 (define_insn "*ashrti3_2"
11051   [(set (match_operand:TI 0 "register_operand" "=r")
11052         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11053                      (match_operand:QI 2 "immediate_operand" "O")))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "TARGET_64BIT"
11056   "#"
11057   [(set_attr "type" "multi")])
11058
11059 (define_split
11060   [(set (match_operand:TI 0 "register_operand" "")
11061         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11062                      (match_operand:QI 2 "register_operand" "")))
11063    (clobber (match_scratch:DI 3 ""))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "TARGET_64BIT && reload_completed"
11066   [(const_int 0)]
11067   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11068
11069 (define_split
11070   [(set (match_operand:TI 0 "register_operand" "")
11071         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11072                      (match_operand:QI 2 "immediate_operand" "")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "TARGET_64BIT && reload_completed"
11075   [(const_int 0)]
11076   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11077
11078 (define_insn "x86_64_shrd"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11080         (ior:DI (ashiftrt:DI (match_dup 0)
11081                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11082                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11083                   (minus:QI (const_int 64) (match_dup 2)))))
11084    (clobber (reg:CC FLAGS_REG))]
11085   "TARGET_64BIT"
11086   "@
11087    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11088    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11089   [(set_attr "type" "ishift")
11090    (set_attr "prefix_0f" "1")
11091    (set_attr "mode" "DI")
11092    (set_attr "athlon_decode" "vector")])
11093
11094 (define_expand "ashrdi3"
11095   [(set (match_operand:DI 0 "shiftdi_operand" "")
11096         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11097                      (match_operand:QI 2 "nonmemory_operand" "")))]
11098   ""
11099   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11100
11101 (define_insn "*ashrdi3_63_rex64"
11102   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11103         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11104                      (match_operand:DI 2 "const_int_operand" "i,i")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && INTVAL (operands[2]) == 63
11107    && (TARGET_USE_CLTD || optimize_size)
11108    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109   "@
11110    {cqto|cqo}
11111    sar{q}\t{%2, %0|%0, %2}"
11112   [(set_attr "type" "imovx,ishift")
11113    (set_attr "prefix_0f" "0,*")
11114    (set_attr "length_immediate" "0,*")
11115    (set_attr "modrm" "0,1")
11116    (set_attr "mode" "DI")])
11117
11118 (define_insn "*ashrdi3_1_one_bit_rex64"
11119   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121                      (match_operand:QI 2 "const1_operand" "")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11124    && (TARGET_SHIFT1 || optimize_size)"
11125   "sar{q}\t%0"
11126   [(set_attr "type" "ishift")
11127    (set (attr "length") 
11128      (if_then_else (match_operand:DI 0 "register_operand" "") 
11129         (const_string "2")
11130         (const_string "*")))])
11131
11132 (define_insn "*ashrdi3_1_rex64"
11133   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11134         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11135                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "@
11139    sar{q}\t{%2, %0|%0, %2}
11140    sar{q}\t{%b2, %0|%0, %b2}"
11141   [(set_attr "type" "ishift")
11142    (set_attr "mode" "DI")])
11143
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags.  We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11148   [(set (reg FLAGS_REG)
11149         (compare
11150           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11151                        (match_operand:QI 2 "const1_operand" ""))
11152           (const_int 0)))
11153    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11154         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156    && (TARGET_SHIFT1 || optimize_size)
11157    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11158   "sar{q}\t%0"
11159   [(set_attr "type" "ishift")
11160    (set (attr "length") 
11161      (if_then_else (match_operand:DI 0 "register_operand" "") 
11162         (const_string "2")
11163         (const_string "*")))])
11164
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags.  We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashrdi3_cmp_rex64"
11169   [(set (reg FLAGS_REG)
11170         (compare
11171           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11172                        (match_operand:QI 2 "const_int_operand" "n"))
11173           (const_int 0)))
11174    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11175         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11176   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11177    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178   "sar{q}\t{%2, %0|%0, %2}"
11179   [(set_attr "type" "ishift")
11180    (set_attr "mode" "DI")])
11181
11182 (define_insn "*ashrdi3_1"
11183   [(set (match_operand:DI 0 "register_operand" "=r")
11184         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11185                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11186    (clobber (reg:CC FLAGS_REG))]
11187   "!TARGET_64BIT"
11188   "#"
11189   [(set_attr "type" "multi")])
11190
11191 ;; By default we don't ask for a scratch register, because when DImode
11192 ;; values are manipulated, registers are already at a premium.  But if
11193 ;; we have one handy, we won't turn it away.
11194 (define_peephole2
11195   [(match_scratch:SI 3 "r")
11196    (parallel [(set (match_operand:DI 0 "register_operand" "")
11197                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11198                                 (match_operand:QI 2 "nonmemory_operand" "")))
11199               (clobber (reg:CC FLAGS_REG))])
11200    (match_dup 3)]
11201   "!TARGET_64BIT && TARGET_CMOVE"
11202   [(const_int 0)]
11203   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11204
11205 (define_split
11206   [(set (match_operand:DI 0 "register_operand" "")
11207         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11208                      (match_operand:QI 2 "nonmemory_operand" "")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11211                      ? flow2_completed : reload_completed)"
11212   [(const_int 0)]
11213   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11214
11215 (define_insn "x86_shrd_1"
11216   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11217         (ior:SI (ashiftrt:SI (match_dup 0)
11218                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11219                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11220                   (minus:QI (const_int 32) (match_dup 2)))))
11221    (clobber (reg:CC FLAGS_REG))]
11222   ""
11223   "@
11224    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11225    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11226   [(set_attr "type" "ishift")
11227    (set_attr "prefix_0f" "1")
11228    (set_attr "pent_pair" "np")
11229    (set_attr "mode" "SI")])
11230
11231 (define_expand "x86_shift_adj_3"
11232   [(use (match_operand:SI 0 "register_operand" ""))
11233    (use (match_operand:SI 1 "register_operand" ""))
11234    (use (match_operand:QI 2 "register_operand" ""))]
11235   ""
11236 {
11237   rtx label = gen_label_rtx ();
11238   rtx tmp;
11239
11240   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11241
11242   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11243   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11244   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11245                               gen_rtx_LABEL_REF (VOIDmode, label),
11246                               pc_rtx);
11247   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11248   JUMP_LABEL (tmp) = label;
11249
11250   emit_move_insn (operands[0], operands[1]);
11251   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11252
11253   emit_label (label);
11254   LABEL_NUSES (label) = 1;
11255
11256   DONE;
11257 })
11258
11259 (define_insn "ashrsi3_31"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11262                      (match_operand:SI 2 "const_int_operand" "i,i")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11265    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11266   "@
11267    {cltd|cdq}
11268    sar{l}\t{%2, %0|%0, %2}"
11269   [(set_attr "type" "imovx,ishift")
11270    (set_attr "prefix_0f" "0,*")
11271    (set_attr "length_immediate" "0,*")
11272    (set_attr "modrm" "0,1")
11273    (set_attr "mode" "SI")])
11274
11275 (define_insn "*ashrsi3_31_zext"
11276   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11277         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11278                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11281    && INTVAL (operands[2]) == 31
11282    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11283   "@
11284    {cltd|cdq}
11285    sar{l}\t{%2, %k0|%k0, %2}"
11286   [(set_attr "type" "imovx,ishift")
11287    (set_attr "prefix_0f" "0,*")
11288    (set_attr "length_immediate" "0,*")
11289    (set_attr "modrm" "0,1")
11290    (set_attr "mode" "SI")])
11291
11292 (define_expand "ashrsi3"
11293   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11294         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11295                      (match_operand:QI 2 "nonmemory_operand" "")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   ""
11298   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11299
11300 (define_insn "*ashrsi3_1_one_bit"
11301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11302         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11303                      (match_operand:QI 2 "const1_operand" "")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11306    && (TARGET_SHIFT1 || optimize_size)"
11307   "sar{l}\t%0"
11308   [(set_attr "type" "ishift")
11309    (set (attr "length") 
11310      (if_then_else (match_operand:SI 0 "register_operand" "") 
11311         (const_string "2")
11312         (const_string "*")))])
11313
11314 (define_insn "*ashrsi3_1_one_bit_zext"
11315   [(set (match_operand:DI 0 "register_operand" "=r")
11316         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11317                                      (match_operand:QI 2 "const1_operand" ""))))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{l}\t%k0"
11322   [(set_attr "type" "ishift")
11323    (set_attr "length" "2")])
11324
11325 (define_insn "*ashrsi3_1"
11326   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11327         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11328                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11329    (clobber (reg:CC FLAGS_REG))]
11330   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331   "@
11332    sar{l}\t{%2, %0|%0, %2}
11333    sar{l}\t{%b2, %0|%0, %b2}"
11334   [(set_attr "type" "ishift")
11335    (set_attr "mode" "SI")])
11336
11337 (define_insn "*ashrsi3_1_zext"
11338   [(set (match_operand:DI 0 "register_operand" "=r,r")
11339         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11340                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11343   "@
11344    sar{l}\t{%2, %k0|%k0, %2}
11345    sar{l}\t{%b2, %k0|%k0, %b2}"
11346   [(set_attr "type" "ishift")
11347    (set_attr "mode" "SI")])
11348
11349 ;; This pattern can't accept a variable shift count, since shifts by
11350 ;; zero don't affect the flags.  We assume that shifts by constant
11351 ;; zero are optimized away.
11352 (define_insn "*ashrsi3_one_bit_cmp"
11353   [(set (reg FLAGS_REG)
11354         (compare
11355           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11356                        (match_operand:QI 2 "const1_operand" ""))
11357           (const_int 0)))
11358    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11359         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11360   "ix86_match_ccmode (insn, CCGOCmode)
11361    && (TARGET_SHIFT1 || optimize_size)
11362    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363   "sar{l}\t%0"
11364   [(set_attr "type" "ishift")
11365    (set (attr "length") 
11366      (if_then_else (match_operand:SI 0 "register_operand" "") 
11367         (const_string "2")
11368         (const_string "*")))])
11369
11370 (define_insn "*ashrsi3_one_bit_cmp_zext"
11371   [(set (reg FLAGS_REG)
11372         (compare
11373           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374                        (match_operand:QI 2 "const1_operand" ""))
11375           (const_int 0)))
11376    (set (match_operand:DI 0 "register_operand" "=r")
11377         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11379    && (TARGET_SHIFT1 || optimize_size)
11380    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381   "sar{l}\t%k0"
11382   [(set_attr "type" "ishift")
11383    (set_attr "length" "2")])
11384
11385 ;; This pattern can't accept a variable shift count, since shifts by
11386 ;; zero don't affect the flags.  We assume that shifts by constant
11387 ;; zero are optimized away.
11388 (define_insn "*ashrsi3_cmp"
11389   [(set (reg FLAGS_REG)
11390         (compare
11391           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11393           (const_int 0)))
11394    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11395         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11396   "ix86_match_ccmode (insn, CCGOCmode)
11397    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11398   "sar{l}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "SI")])
11401
11402 (define_insn "*ashrsi3_cmp_zext"
11403   [(set (reg FLAGS_REG)
11404         (compare
11405           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11406                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11407           (const_int 0)))
11408    (set (match_operand:DI 0 "register_operand" "=r")
11409         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11410   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412   "sar{l}\t{%2, %k0|%k0, %2}"
11413   [(set_attr "type" "ishift")
11414    (set_attr "mode" "SI")])
11415
11416 (define_expand "ashrhi3"
11417   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419                      (match_operand:QI 2 "nonmemory_operand" "")))
11420    (clobber (reg:CC FLAGS_REG))]
11421   "TARGET_HIMODE_MATH"
11422   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11423
11424 (define_insn "*ashrhi3_1_one_bit"
11425   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427                      (match_operand:QI 2 "const1_operand" "")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11430    && (TARGET_SHIFT1 || optimize_size)"
11431   "sar{w}\t%0"
11432   [(set_attr "type" "ishift")
11433    (set (attr "length") 
11434      (if_then_else (match_operand 0 "register_operand" "") 
11435         (const_string "2")
11436         (const_string "*")))])
11437
11438 (define_insn "*ashrhi3_1"
11439   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11440         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11441                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11442    (clobber (reg:CC FLAGS_REG))]
11443   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11444   "@
11445    sar{w}\t{%2, %0|%0, %2}
11446    sar{w}\t{%b2, %0|%0, %b2}"
11447   [(set_attr "type" "ishift")
11448    (set_attr "mode" "HI")])
11449
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags.  We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*ashrhi3_one_bit_cmp"
11454   [(set (reg FLAGS_REG)
11455         (compare
11456           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11457                        (match_operand:QI 2 "const1_operand" ""))
11458           (const_int 0)))
11459    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11461   "ix86_match_ccmode (insn, CCGOCmode)
11462    && (TARGET_SHIFT1 || optimize_size)
11463    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11464   "sar{w}\t%0"
11465   [(set_attr "type" "ishift")
11466    (set (attr "length") 
11467      (if_then_else (match_operand 0 "register_operand" "") 
11468         (const_string "2")
11469         (const_string "*")))])
11470
11471 ;; This pattern can't accept a variable shift count, since shifts by
11472 ;; zero don't affect the flags.  We assume that shifts by constant
11473 ;; zero are optimized away.
11474 (define_insn "*ashrhi3_cmp"
11475   [(set (reg FLAGS_REG)
11476         (compare
11477           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11478                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11479           (const_int 0)))
11480    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11481         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11482   "ix86_match_ccmode (insn, CCGOCmode)
11483    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11484   "sar{w}\t{%2, %0|%0, %2}"
11485   [(set_attr "type" "ishift")
11486    (set_attr "mode" "HI")])
11487
11488 (define_expand "ashrqi3"
11489   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11490         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11491                      (match_operand:QI 2 "nonmemory_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "TARGET_QIMODE_MATH"
11494   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11495
11496 (define_insn "*ashrqi3_1_one_bit"
11497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11498         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11499                      (match_operand:QI 2 "const1_operand" "")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11502    && (TARGET_SHIFT1 || optimize_size)"
11503   "sar{b}\t%0"
11504   [(set_attr "type" "ishift")
11505    (set (attr "length") 
11506      (if_then_else (match_operand 0 "register_operand" "") 
11507         (const_string "2")
11508         (const_string "*")))])
11509
11510 (define_insn "*ashrqi3_1_one_bit_slp"
11511   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11512         (ashiftrt:QI (match_dup 0)
11513                      (match_operand:QI 1 "const1_operand" "")))
11514    (clobber (reg:CC FLAGS_REG))]
11515   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11516    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11517    && (TARGET_SHIFT1 || optimize_size)"
11518   "sar{b}\t%0"
11519   [(set_attr "type" "ishift1")
11520    (set (attr "length") 
11521      (if_then_else (match_operand 0 "register_operand" "") 
11522         (const_string "2")
11523         (const_string "*")))])
11524
11525 (define_insn "*ashrqi3_1"
11526   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11527         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11528                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11531   "@
11532    sar{b}\t{%2, %0|%0, %2}
11533    sar{b}\t{%b2, %0|%0, %b2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "QI")])
11536
11537 (define_insn "*ashrqi3_1_slp"
11538   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11539         (ashiftrt:QI (match_dup 0)
11540                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11541    (clobber (reg:CC FLAGS_REG))]
11542   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11543    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11544   "@
11545    sar{b}\t{%1, %0|%0, %1}
11546    sar{b}\t{%b1, %0|%0, %b1}"
11547   [(set_attr "type" "ishift1")
11548    (set_attr "mode" "QI")])
11549
11550 ;; This pattern can't accept a variable shift count, since shifts by
11551 ;; zero don't affect the flags.  We assume that shifts by constant
11552 ;; zero are optimized away.
11553 (define_insn "*ashrqi3_one_bit_cmp"
11554   [(set (reg FLAGS_REG)
11555         (compare
11556           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11557                        (match_operand:QI 2 "const1_operand" "I"))
11558           (const_int 0)))
11559    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11560         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11561   "ix86_match_ccmode (insn, CCGOCmode)
11562    && (TARGET_SHIFT1 || optimize_size)
11563    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11564   "sar{b}\t%0"
11565   [(set_attr "type" "ishift")
11566    (set (attr "length") 
11567      (if_then_else (match_operand 0 "register_operand" "") 
11568         (const_string "2")
11569         (const_string "*")))])
11570
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags.  We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrqi3_cmp"
11575   [(set (reg FLAGS_REG)
11576         (compare
11577           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11578                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11579           (const_int 0)))
11580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11581         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11582   "ix86_match_ccmode (insn, CCGOCmode)
11583    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584   "sar{b}\t{%2, %0|%0, %2}"
11585   [(set_attr "type" "ishift")
11586    (set_attr "mode" "QI")])
11587 \f
11588 ;; Logical shift instructions
11589
11590 ;; See comment above `ashldi3' about how this works.
11591
11592 (define_expand "lshrti3"
11593   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11594                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595                                 (match_operand:QI 2 "nonmemory_operand" "")))
11596               (clobber (reg:CC FLAGS_REG))])]
11597   "TARGET_64BIT"
11598 {
11599   if (! immediate_operand (operands[2], QImode))
11600     {
11601       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11602       DONE;
11603     }
11604   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11605   DONE;
11606 })
11607
11608 (define_insn "lshrti3_1"
11609   [(set (match_operand:TI 0 "register_operand" "=r")
11610         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11611                      (match_operand:QI 2 "register_operand" "c")))
11612    (clobber (match_scratch:DI 3 "=&r"))
11613    (clobber (reg:CC FLAGS_REG))]
11614   "TARGET_64BIT"
11615   "#"
11616   [(set_attr "type" "multi")])
11617
11618 (define_insn "*lshrti3_2"
11619   [(set (match_operand:TI 0 "register_operand" "=r")
11620         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11621                      (match_operand:QI 2 "immediate_operand" "O")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT"
11624   "#"
11625   [(set_attr "type" "multi")])
11626
11627 (define_split 
11628   [(set (match_operand:TI 0 "register_operand" "")
11629         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11630                      (match_operand:QI 2 "register_operand" "")))
11631    (clobber (match_scratch:DI 3 ""))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "TARGET_64BIT && reload_completed"
11634   [(const_int 0)]
11635   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11636
11637 (define_split 
11638   [(set (match_operand:TI 0 "register_operand" "")
11639         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11640                      (match_operand:QI 2 "immediate_operand" "")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "TARGET_64BIT && reload_completed"
11643   [(const_int 0)]
11644   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11645
11646 (define_expand "lshrdi3"
11647   [(set (match_operand:DI 0 "shiftdi_operand" "")
11648         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11649                      (match_operand:QI 2 "nonmemory_operand" "")))]
11650   ""
11651   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11652
11653 (define_insn "*lshrdi3_1_one_bit_rex64"
11654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656                      (match_operand:QI 2 "const1_operand" "")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11659    && (TARGET_SHIFT1 || optimize_size)"
11660   "shr{q}\t%0"
11661   [(set_attr "type" "ishift")
11662    (set (attr "length") 
11663      (if_then_else (match_operand:DI 0 "register_operand" "") 
11664         (const_string "2")
11665         (const_string "*")))])
11666
11667 (define_insn "*lshrdi3_1_rex64"
11668   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11669         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11670                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673   "@
11674    shr{q}\t{%2, %0|%0, %2}
11675    shr{q}\t{%b2, %0|%0, %b2}"
11676   [(set_attr "type" "ishift")
11677    (set_attr "mode" "DI")])
11678
11679 ;; This pattern can't accept a variable shift count, since shifts by
11680 ;; zero don't affect the flags.  We assume that shifts by constant
11681 ;; zero are optimized away.
11682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11683   [(set (reg FLAGS_REG)
11684         (compare
11685           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11686                        (match_operand:QI 2 "const1_operand" ""))
11687           (const_int 0)))
11688    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11690   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11691    && (TARGET_SHIFT1 || optimize_size)
11692    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11693   "shr{q}\t%0"
11694   [(set_attr "type" "ishift")
11695    (set (attr "length") 
11696      (if_then_else (match_operand:DI 0 "register_operand" "") 
11697         (const_string "2")
11698         (const_string "*")))])
11699
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags.  We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*lshrdi3_cmp_rex64"
11704   [(set (reg FLAGS_REG)
11705         (compare
11706           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707                        (match_operand:QI 2 "const_int_operand" "e"))
11708           (const_int 0)))
11709    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11710         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11711   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11713   "shr{q}\t{%2, %0|%0, %2}"
11714   [(set_attr "type" "ishift")
11715    (set_attr "mode" "DI")])
11716
11717 (define_insn "*lshrdi3_1"
11718   [(set (match_operand:DI 0 "register_operand" "=r")
11719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11720                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "!TARGET_64BIT"
11723   "#"
11724   [(set_attr "type" "multi")])
11725
11726 ;; By default we don't ask for a scratch register, because when DImode
11727 ;; values are manipulated, registers are already at a premium.  But if
11728 ;; we have one handy, we won't turn it away.
11729 (define_peephole2
11730   [(match_scratch:SI 3 "r")
11731    (parallel [(set (match_operand:DI 0 "register_operand" "")
11732                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11733                                 (match_operand:QI 2 "nonmemory_operand" "")))
11734               (clobber (reg:CC FLAGS_REG))])
11735    (match_dup 3)]
11736   "!TARGET_64BIT && TARGET_CMOVE"
11737   [(const_int 0)]
11738   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11739
11740 (define_split 
11741   [(set (match_operand:DI 0 "register_operand" "")
11742         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11743                      (match_operand:QI 2 "nonmemory_operand" "")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11746                      ? flow2_completed : reload_completed)"
11747   [(const_int 0)]
11748   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11749
11750 (define_expand "lshrsi3"
11751   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753                      (match_operand:QI 2 "nonmemory_operand" "")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   ""
11756   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757
11758 (define_insn "*lshrsi3_1_one_bit"
11759   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761                      (match_operand:QI 2 "const1_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764    && (TARGET_SHIFT1 || optimize_size)"
11765   "shr{l}\t%0"
11766   [(set_attr "type" "ishift")
11767    (set (attr "length") 
11768      (if_then_else (match_operand:SI 0 "register_operand" "") 
11769         (const_string "2")
11770         (const_string "*")))])
11771
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773   [(set (match_operand:DI 0 "register_operand" "=r")
11774         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775                      (match_operand:QI 2 "const1_operand" "")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778    && (TARGET_SHIFT1 || optimize_size)"
11779   "shr{l}\t%k0"
11780   [(set_attr "type" "ishift")
11781    (set_attr "length" "2")])
11782
11783 (define_insn "*lshrsi3_1"
11784   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789   "@
11790    shr{l}\t{%2, %0|%0, %2}
11791    shr{l}\t{%b2, %0|%0, %b2}"
11792   [(set_attr "type" "ishift")
11793    (set_attr "mode" "SI")])
11794
11795 (define_insn "*lshrsi3_1_zext"
11796   [(set (match_operand:DI 0 "register_operand" "=r,r")
11797         (zero_extend:DI
11798           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800    (clobber (reg:CC FLAGS_REG))]
11801   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802   "@
11803    shr{l}\t{%2, %k0|%k0, %2}
11804    shr{l}\t{%b2, %k0|%k0, %b2}"
11805   [(set_attr "type" "ishift")
11806    (set_attr "mode" "SI")])
11807
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags.  We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812   [(set (reg FLAGS_REG)
11813         (compare
11814           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815                        (match_operand:QI 2 "const1_operand" ""))
11816           (const_int 0)))
11817    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && (TARGET_SHIFT1 || optimize_size)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t%0"
11823   [(set_attr "type" "ishift")
11824    (set (attr "length") 
11825      (if_then_else (match_operand:SI 0 "register_operand" "") 
11826         (const_string "2")
11827         (const_string "*")))])
11828
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833                        (match_operand:QI 2 "const1_operand" ""))
11834           (const_int 0)))
11835    (set (match_operand:DI 0 "register_operand" "=r")
11836         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838    && (TARGET_SHIFT1 || optimize_size)
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{l}\t%k0"
11841   [(set_attr "type" "ishift")
11842    (set_attr "length" "2")])
11843
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags.  We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848   [(set (reg FLAGS_REG)
11849         (compare
11850           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11852           (const_int 0)))
11853    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855   "ix86_match_ccmode (insn, CCGOCmode)
11856    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857   "shr{l}\t{%2, %0|%0, %2}"
11858   [(set_attr "type" "ishift")
11859    (set_attr "mode" "SI")])
11860
11861 (define_insn "*lshrsi3_cmp_zext"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866           (const_int 0)))
11867    (set (match_operand:DI 0 "register_operand" "=r")
11868         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "shr{l}\t{%2, %k0|%k0, %2}"
11872   [(set_attr "type" "ishift")
11873    (set_attr "mode" "SI")])
11874
11875 (define_expand "lshrhi3"
11876   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878                      (match_operand:QI 2 "nonmemory_operand" "")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "TARGET_HIMODE_MATH"
11881   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882
11883 (define_insn "*lshrhi3_1_one_bit"
11884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886                      (match_operand:QI 2 "const1_operand" "")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889    && (TARGET_SHIFT1 || optimize_size)"
11890   "shr{w}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set (attr "length") 
11893      (if_then_else (match_operand 0 "register_operand" "") 
11894         (const_string "2")
11895         (const_string "*")))])
11896
11897 (define_insn "*lshrhi3_1"
11898   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11903   "@
11904    shr{w}\t{%2, %0|%0, %2}
11905    shr{w}\t{%b2, %0|%0, %b2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags.  We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913   [(set (reg FLAGS_REG)
11914         (compare
11915           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916                        (match_operand:QI 2 "const1_operand" ""))
11917           (const_int 0)))
11918    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920   "ix86_match_ccmode (insn, CCGOCmode)
11921    && (TARGET_SHIFT1 || optimize_size)
11922    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11923   "shr{w}\t%0"
11924   [(set_attr "type" "ishift")
11925    (set (attr "length") 
11926      (if_then_else (match_operand:SI 0 "register_operand" "") 
11927         (const_string "2")
11928         (const_string "*")))])
11929
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags.  We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934   [(set (reg FLAGS_REG)
11935         (compare
11936           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11938           (const_int 0)))
11939    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941   "ix86_match_ccmode (insn, CCGOCmode)
11942    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943   "shr{w}\t{%2, %0|%0, %2}"
11944   [(set_attr "type" "ishift")
11945    (set_attr "mode" "HI")])
11946
11947 (define_expand "lshrqi3"
11948   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950                      (match_operand:QI 2 "nonmemory_operand" "")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "TARGET_QIMODE_MATH"
11953   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954
11955 (define_insn "*lshrqi3_1_one_bit"
11956   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958                      (match_operand:QI 2 "const1_operand" "")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961    && (TARGET_SHIFT1 || optimize_size)"
11962   "shr{b}\t%0"
11963   [(set_attr "type" "ishift")
11964    (set (attr "length") 
11965      (if_then_else (match_operand 0 "register_operand" "") 
11966         (const_string "2")
11967         (const_string "*")))])
11968
11969 (define_insn "*lshrqi3_1_one_bit_slp"
11970   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11971         (lshiftrt:QI (match_dup 0)
11972                      (match_operand:QI 1 "const1_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11975    && (TARGET_SHIFT1 || optimize_size)"
11976   "shr{b}\t%0"
11977   [(set_attr "type" "ishift1")
11978    (set (attr "length") 
11979      (if_then_else (match_operand 0 "register_operand" "") 
11980         (const_string "2")
11981         (const_string "*")))])
11982
11983 (define_insn "*lshrqi3_1"
11984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11985         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11989   "@
11990    shr{b}\t{%2, %0|%0, %2}
11991    shr{b}\t{%b2, %0|%0, %b2}"
11992   [(set_attr "type" "ishift")
11993    (set_attr "mode" "QI")])
11994
11995 (define_insn "*lshrqi3_1_slp"
11996   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11997         (lshiftrt:QI (match_dup 0)
11998                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11999    (clobber (reg:CC FLAGS_REG))]
12000   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12002   "@
12003    shr{b}\t{%1, %0|%0, %1}
12004    shr{b}\t{%b1, %0|%0, %b1}"
12005   [(set_attr "type" "ishift1")
12006    (set_attr "mode" "QI")])
12007
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags.  We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrqi2_one_bit_cmp"
12012   [(set (reg FLAGS_REG)
12013         (compare
12014           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015                        (match_operand:QI 2 "const1_operand" ""))
12016           (const_int 0)))
12017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12019   "ix86_match_ccmode (insn, CCGOCmode)
12020    && (TARGET_SHIFT1 || optimize_size)
12021    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12022   "shr{b}\t%0"
12023   [(set_attr "type" "ishift")
12024    (set (attr "length") 
12025      (if_then_else (match_operand:SI 0 "register_operand" "") 
12026         (const_string "2")
12027         (const_string "*")))])
12028
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags.  We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*lshrqi2_cmp"
12033   [(set (reg FLAGS_REG)
12034         (compare
12035           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12036                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037           (const_int 0)))
12038    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12039         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12040   "ix86_match_ccmode (insn, CCGOCmode)
12041    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12042   "shr{b}\t{%2, %0|%0, %2}"
12043   [(set_attr "type" "ishift")
12044    (set_attr "mode" "QI")])
12045 \f
12046 ;; Rotate instructions
12047
12048 (define_expand "rotldi3"
12049   [(set (match_operand:DI 0 "shiftdi_operand" "")
12050         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12051                    (match_operand:QI 2 "nonmemory_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053  ""
12054 {
12055   if (TARGET_64BIT)
12056     {
12057       ix86_expand_binary_operator (ROTATE, DImode, operands);
12058       DONE;
12059     }
12060   if (!const_1_to_31_operand (operands[2], VOIDmode))
12061     FAIL;
12062   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063   DONE;
12064 })
12065
12066 ;; Implement rotation using two double-precision shift instructions
12067 ;; and a scratch register.   
12068 (define_insn_and_split "ix86_rotldi3"
12069  [(set (match_operand:DI 0 "register_operand" "=r")
12070        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072   (clobber (reg:CC FLAGS_REG))
12073   (clobber (match_scratch:SI 3 "=&r"))]
12074  "!TARGET_64BIT"
12075  "" 
12076  "&& reload_completed"
12077  [(set (match_dup 3) (match_dup 4))
12078   (parallel
12079    [(set (match_dup 4)
12080          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081                  (lshiftrt:SI (match_dup 5)
12082                               (minus:QI (const_int 32) (match_dup 2)))))
12083     (clobber (reg:CC FLAGS_REG))])
12084   (parallel
12085    [(set (match_dup 5)
12086          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087                  (lshiftrt:SI (match_dup 3)
12088                               (minus:QI (const_int 32) (match_dup 2)))))
12089     (clobber (reg:CC FLAGS_REG))])]
12090  "split_di (operands, 1, operands + 4, operands + 5);")
12091  
12092 (define_insn "*rotlsi3_1_one_bit_rex64"
12093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095                    (match_operand:QI 2 "const1_operand" "")))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12098    && (TARGET_SHIFT1 || optimize_size)"
12099   "rol{q}\t%0"
12100   [(set_attr "type" "rotate")
12101    (set (attr "length") 
12102      (if_then_else (match_operand:DI 0 "register_operand" "") 
12103         (const_string "2")
12104         (const_string "*")))])
12105
12106 (define_insn "*rotldi3_1_rex64"
12107   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12108         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12109                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12112   "@
12113    rol{q}\t{%2, %0|%0, %2}
12114    rol{q}\t{%b2, %0|%0, %b2}"
12115   [(set_attr "type" "rotate")
12116    (set_attr "mode" "DI")])
12117
12118 (define_expand "rotlsi3"
12119   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12120         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12121                    (match_operand:QI 2 "nonmemory_operand" "")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   ""
12124   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12125
12126 (define_insn "*rotlsi3_1_one_bit"
12127   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12128         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12129                    (match_operand:QI 2 "const1_operand" "")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12132    && (TARGET_SHIFT1 || optimize_size)"
12133   "rol{l}\t%0"
12134   [(set_attr "type" "rotate")
12135    (set (attr "length") 
12136      (if_then_else (match_operand:SI 0 "register_operand" "") 
12137         (const_string "2")
12138         (const_string "*")))])
12139
12140 (define_insn "*rotlsi3_1_one_bit_zext"
12141   [(set (match_operand:DI 0 "register_operand" "=r")
12142         (zero_extend:DI
12143           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12144                      (match_operand:QI 2 "const1_operand" ""))))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "rol{l}\t%k0"
12149   [(set_attr "type" "rotate")
12150    (set_attr "length" "2")])
12151
12152 (define_insn "*rotlsi3_1"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12154         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12155                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158   "@
12159    rol{l}\t{%2, %0|%0, %2}
12160    rol{l}\t{%b2, %0|%0, %b2}"
12161   [(set_attr "type" "rotate")
12162    (set_attr "mode" "SI")])
12163
12164 (define_insn "*rotlsi3_1_zext"
12165   [(set (match_operand:DI 0 "register_operand" "=r,r")
12166         (zero_extend:DI
12167           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12168                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12171   "@
12172    rol{l}\t{%2, %k0|%k0, %2}
12173    rol{l}\t{%b2, %k0|%k0, %b2}"
12174   [(set_attr "type" "rotate")
12175    (set_attr "mode" "SI")])
12176
12177 (define_expand "rotlhi3"
12178   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12179         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12180                    (match_operand:QI 2 "nonmemory_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_HIMODE_MATH"
12183   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12184
12185 (define_insn "*rotlhi3_1_one_bit"
12186   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12187         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12188                    (match_operand:QI 2 "const1_operand" "")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12191    && (TARGET_SHIFT1 || optimize_size)"
12192   "rol{w}\t%0"
12193   [(set_attr "type" "rotate")
12194    (set (attr "length") 
12195      (if_then_else (match_operand 0 "register_operand" "") 
12196         (const_string "2")
12197         (const_string "*")))])
12198
12199 (define_insn "*rotlhi3_1"
12200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12201         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12202                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12205   "@
12206    rol{w}\t{%2, %0|%0, %2}
12207    rol{w}\t{%b2, %0|%0, %b2}"
12208   [(set_attr "type" "rotate")
12209    (set_attr "mode" "HI")])
12210
12211 (define_expand "rotlqi3"
12212   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12213         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12214                    (match_operand:QI 2 "nonmemory_operand" "")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_QIMODE_MATH"
12217   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12218
12219 (define_insn "*rotlqi3_1_one_bit_slp"
12220   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221         (rotate:QI (match_dup 0)
12222                    (match_operand:QI 1 "const1_operand" "")))
12223    (clobber (reg:CC FLAGS_REG))]
12224   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225    && (TARGET_SHIFT1 || optimize_size)"
12226   "rol{b}\t%0"
12227   [(set_attr "type" "rotate1")
12228    (set (attr "length") 
12229      (if_then_else (match_operand 0 "register_operand" "") 
12230         (const_string "2")
12231         (const_string "*")))])
12232
12233 (define_insn "*rotlqi3_1_one_bit"
12234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236                    (match_operand:QI 2 "const1_operand" "")))
12237    (clobber (reg:CC FLAGS_REG))]
12238   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12239    && (TARGET_SHIFT1 || optimize_size)"
12240   "rol{b}\t%0"
12241   [(set_attr "type" "rotate")
12242    (set (attr "length") 
12243      (if_then_else (match_operand 0 "register_operand" "") 
12244         (const_string "2")
12245         (const_string "*")))])
12246
12247 (define_insn "*rotlqi3_1_slp"
12248   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249         (rotate:QI (match_dup 0)
12250                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251    (clobber (reg:CC FLAGS_REG))]
12252   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12253    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12254   "@
12255    rol{b}\t{%1, %0|%0, %1}
12256    rol{b}\t{%b1, %0|%0, %b1}"
12257   [(set_attr "type" "rotate1")
12258    (set_attr "mode" "QI")])
12259
12260 (define_insn "*rotlqi3_1"
12261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264    (clobber (reg:CC FLAGS_REG))]
12265   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12266   "@
12267    rol{b}\t{%2, %0|%0, %2}
12268    rol{b}\t{%b2, %0|%0, %b2}"
12269   [(set_attr "type" "rotate")
12270    (set_attr "mode" "QI")])
12271
12272 (define_expand "rotrdi3"
12273   [(set (match_operand:DI 0 "shiftdi_operand" "")
12274         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275                    (match_operand:QI 2 "nonmemory_operand" "")))
12276    (clobber (reg:CC FLAGS_REG))]
12277  ""
12278 {
12279   if (TARGET_64BIT)
12280     {
12281       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12282       DONE;
12283     }
12284   if (!const_1_to_31_operand (operands[2], VOIDmode))
12285     FAIL;
12286   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12287   DONE;
12288 })
12289   
12290 ;; Implement rotation using two double-precision shift instructions
12291 ;; and a scratch register.   
12292 (define_insn_and_split "ix86_rotrdi3"
12293  [(set (match_operand:DI 0 "register_operand" "=r")
12294        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12295                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12296   (clobber (reg:CC FLAGS_REG))
12297   (clobber (match_scratch:SI 3 "=&r"))]
12298  "!TARGET_64BIT"
12299  ""
12300  "&& reload_completed"
12301  [(set (match_dup 3) (match_dup 4))
12302   (parallel
12303    [(set (match_dup 4)
12304          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12305                  (ashift:SI (match_dup 5)
12306                             (minus:QI (const_int 32) (match_dup 2)))))
12307     (clobber (reg:CC FLAGS_REG))])
12308   (parallel
12309    [(set (match_dup 5)
12310          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12311                  (ashift:SI (match_dup 3)
12312                             (minus:QI (const_int 32) (match_dup 2)))))
12313     (clobber (reg:CC FLAGS_REG))])]
12314  "split_di (operands, 1, operands + 4, operands + 5);")
12315
12316 (define_insn "*rotrdi3_1_one_bit_rex64"
12317   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12318         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "ror{q}\t%0"
12324   [(set_attr "type" "rotate")
12325    (set (attr "length") 
12326      (if_then_else (match_operand:DI 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*rotrdi3_1_rex64"
12331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12332         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12336   "@
12337    ror{q}\t{%2, %0|%0, %2}
12338    ror{q}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "rotate")
12340    (set_attr "mode" "DI")])
12341
12342 (define_expand "rotrsi3"
12343   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12344         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12345                      (match_operand:QI 2 "nonmemory_operand" "")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   ""
12348   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12349
12350 (define_insn "*rotrsi3_1_one_bit"
12351   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12352         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353                      (match_operand:QI 2 "const1_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12356    && (TARGET_SHIFT1 || optimize_size)"
12357   "ror{l}\t%0"
12358   [(set_attr "type" "rotate")
12359    (set (attr "length") 
12360      (if_then_else (match_operand:SI 0 "register_operand" "") 
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*rotrsi3_1_one_bit_zext"
12365   [(set (match_operand:DI 0 "register_operand" "=r")
12366         (zero_extend:DI
12367           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "ror{l}\t%k0"
12373   [(set_attr "type" "rotate")
12374    (set (attr "length") 
12375      (if_then_else (match_operand:SI 0 "register_operand" "") 
12376         (const_string "2")
12377         (const_string "*")))])
12378
12379 (define_insn "*rotrsi3_1"
12380   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12381         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12385   "@
12386    ror{l}\t{%2, %0|%0, %2}
12387    ror{l}\t{%b2, %0|%0, %b2}"
12388   [(set_attr "type" "rotate")
12389    (set_attr "mode" "SI")])
12390
12391 (define_insn "*rotrsi3_1_zext"
12392   [(set (match_operand:DI 0 "register_operand" "=r,r")
12393         (zero_extend:DI
12394           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12395                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12398   "@
12399    ror{l}\t{%2, %k0|%k0, %2}
12400    ror{l}\t{%b2, %k0|%k0, %b2}"
12401   [(set_attr "type" "rotate")
12402    (set_attr "mode" "SI")])
12403
12404 (define_expand "rotrhi3"
12405   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12406         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12407                      (match_operand:QI 2 "nonmemory_operand" "")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "TARGET_HIMODE_MATH"
12410   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12411
12412 (define_insn "*rotrhi3_one_bit"
12413   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12414         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const1_operand" "")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12418    && (TARGET_SHIFT1 || optimize_size)"
12419   "ror{w}\t%0"
12420   [(set_attr "type" "rotate")
12421    (set (attr "length") 
12422      (if_then_else (match_operand 0 "register_operand" "") 
12423         (const_string "2")
12424         (const_string "*")))])
12425
12426 (define_insn "*rotrhi3"
12427   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12428         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12429                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12432   "@
12433    ror{w}\t{%2, %0|%0, %2}
12434    ror{w}\t{%b2, %0|%0, %b2}"
12435   [(set_attr "type" "rotate")
12436    (set_attr "mode" "HI")])
12437
12438 (define_expand "rotrqi3"
12439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441                      (match_operand:QI 2 "nonmemory_operand" "")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_QIMODE_MATH"
12444   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12445
12446 (define_insn "*rotrqi3_1_one_bit"
12447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449                      (match_operand:QI 2 "const1_operand" "")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12452    && (TARGET_SHIFT1 || optimize_size)"
12453   "ror{b}\t%0"
12454   [(set_attr "type" "rotate")
12455    (set (attr "length") 
12456      (if_then_else (match_operand 0 "register_operand" "") 
12457         (const_string "2")
12458         (const_string "*")))])
12459
12460 (define_insn "*rotrqi3_1_one_bit_slp"
12461   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462         (rotatert:QI (match_dup 0)
12463                      (match_operand:QI 1 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466    && (TARGET_SHIFT1 || optimize_size)"
12467   "ror{b}\t%0"
12468   [(set_attr "type" "rotate1")
12469    (set (attr "length") 
12470      (if_then_else (match_operand 0 "register_operand" "") 
12471         (const_string "2")
12472         (const_string "*")))])
12473
12474 (define_insn "*rotrqi3_1"
12475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478    (clobber (reg:CC FLAGS_REG))]
12479   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12480   "@
12481    ror{b}\t{%2, %0|%0, %2}
12482    ror{b}\t{%b2, %0|%0, %b2}"
12483   [(set_attr "type" "rotate")
12484    (set_attr "mode" "QI")])
12485
12486 (define_insn "*rotrqi3_1_slp"
12487   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12488         (rotatert:QI (match_dup 0)
12489                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12492    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12493   "@
12494    ror{b}\t{%1, %0|%0, %1}
12495    ror{b}\t{%b1, %0|%0, %b1}"
12496   [(set_attr "type" "rotate1")
12497    (set_attr "mode" "QI")])
12498 \f
12499 ;; Bit set / bit test instructions
12500
12501 (define_expand "extv"
12502   [(set (match_operand:SI 0 "register_operand" "")
12503         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12504                          (match_operand:SI 2 "immediate_operand" "")
12505                          (match_operand:SI 3 "immediate_operand" "")))]
12506   ""
12507 {
12508   /* Handle extractions from %ah et al.  */
12509   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12510     FAIL;
12511
12512   /* From mips.md: extract_bit_field doesn't verify that our source
12513      matches the predicate, so check it again here.  */
12514   if (! ext_register_operand (operands[1], VOIDmode))
12515     FAIL;
12516 })
12517
12518 (define_expand "extzv"
12519   [(set (match_operand:SI 0 "register_operand" "")
12520         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12521                          (match_operand:SI 2 "immediate_operand" "")
12522                          (match_operand:SI 3 "immediate_operand" "")))]
12523   ""
12524 {
12525   /* Handle extractions from %ah et al.  */
12526   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12527     FAIL;
12528
12529   /* From mips.md: extract_bit_field doesn't verify that our source
12530      matches the predicate, so check it again here.  */
12531   if (! ext_register_operand (operands[1], VOIDmode))
12532     FAIL;
12533 })
12534
12535 (define_expand "insv"
12536   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12537                       (match_operand 1 "immediate_operand" "")
12538                       (match_operand 2 "immediate_operand" ""))
12539         (match_operand 3 "register_operand" ""))]
12540   ""
12541 {
12542   /* Handle extractions from %ah et al.  */
12543   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12544     FAIL;
12545
12546   /* From mips.md: insert_bit_field doesn't verify that our source
12547      matches the predicate, so check it again here.  */
12548   if (! ext_register_operand (operands[0], VOIDmode))
12549     FAIL;
12550
12551   if (TARGET_64BIT)
12552     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12553   else
12554     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12555
12556   DONE;
12557 })
12558
12559 ;; %%% bts, btr, btc, bt.
12560 ;; In general these instructions are *slow* when applied to memory,
12561 ;; since they enforce atomic operation.  When applied to registers,
12562 ;; it depends on the cpu implementation.  They're never faster than
12563 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12564 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12565 ;; within the instruction itself, so operating on bits in the high
12566 ;; 32-bits of a register becomes easier.
12567 ;;
12568 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12569 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12570 ;; negdf respectively, so they can never be disabled entirely.
12571
12572 (define_insn "*btsq"
12573   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12574                          (const_int 1)
12575                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12576         (const_int 1))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12579   "bts{q} %1,%0"
12580   [(set_attr "type" "alu1")])
12581
12582 (define_insn "*btrq"
12583   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12584                          (const_int 1)
12585                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12586         (const_int 0))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12589   "btr{q} %1,%0"
12590   [(set_attr "type" "alu1")])
12591
12592 (define_insn "*btcq"
12593   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12594                          (const_int 1)
12595                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12596         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12599   "btc{q} %1,%0"
12600   [(set_attr "type" "alu1")])
12601
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12603
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 1))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12614 {
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12617
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624
12625   op1 = immed_double_const (lo, hi, DImode);
12626   if (i >= 31)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12631
12632   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633   DONE;
12634 })
12635
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642                    (const_int 0))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12646 {
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12649
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656
12657   op1 = immed_double_const (~lo, ~hi, DImode);
12658   if (i >= 32)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12663
12664   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665   DONE;
12666 })
12667
12668 (define_peephole2
12669   [(match_scratch:DI 2 "r")
12670    (parallel [(set (zero_extract:DI
12671                      (match_operand:DI 0 "register_operand" "")
12672                      (const_int 1)
12673                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12674               (not:DI (zero_extract:DI
12675                         (match_dup 0) (const_int 1) (match_dup 1))))
12676               (clobber (reg:CC FLAGS_REG))])]
12677   "TARGET_64BIT && !TARGET_USE_BT"
12678   [(const_int 0)]
12679 {
12680   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681   rtx op1;
12682
12683   if (HOST_BITS_PER_WIDE_INT >= 64)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else if (i < HOST_BITS_PER_WIDE_INT)
12686     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687   else
12688     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689
12690   op1 = immed_double_const (lo, hi, DImode);
12691   if (i >= 31)
12692     {
12693       emit_move_insn (operands[2], op1);
12694       op1 = operands[2];
12695     }
12696
12697   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698   DONE;
12699 })
12700 \f
12701 ;; Store-flag instructions.
12702
12703 ;; For all sCOND expanders, also expand the compare or test insn that
12704 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12705
12706 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12707 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12708 ;; way, which can later delete the movzx if only QImode is needed.
12709
12710 (define_expand "seq"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sne"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sgt"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sgtu"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   ""
12732   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "slt"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   ""
12738   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sltu"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   ""
12744   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sge"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   ""
12750   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sgeu"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   ""
12756   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sle"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   ""
12762   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sleu"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   ""
12768   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sunordered"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sordered"
12777   [(set (match_operand:QI 0 "register_operand" "")
12778         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779   "TARGET_80387"
12780   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "suneq"
12783   [(set (match_operand:QI 0 "register_operand" "")
12784         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785   "TARGET_80387 || TARGET_SSE"
12786   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12787
12788 (define_expand "sunge"
12789   [(set (match_operand:QI 0 "register_operand" "")
12790         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12791   "TARGET_80387 || TARGET_SSE"
12792   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12793
12794 (define_expand "sungt"
12795   [(set (match_operand:QI 0 "register_operand" "")
12796         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12797   "TARGET_80387 || TARGET_SSE"
12798   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12799
12800 (define_expand "sunle"
12801   [(set (match_operand:QI 0 "register_operand" "")
12802         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12803   "TARGET_80387 || TARGET_SSE"
12804   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12805
12806 (define_expand "sunlt"
12807   [(set (match_operand:QI 0 "register_operand" "")
12808         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12809   "TARGET_80387 || TARGET_SSE"
12810   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12811
12812 (define_expand "sltgt"
12813   [(set (match_operand:QI 0 "register_operand" "")
12814         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12815   "TARGET_80387 || TARGET_SSE"
12816   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12817
12818 (define_insn "*setcc_1"
12819   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820         (match_operator:QI 1 "ix86_comparison_operator"
12821           [(reg FLAGS_REG) (const_int 0)]))]
12822   ""
12823   "set%C1\t%0"
12824   [(set_attr "type" "setcc")
12825    (set_attr "mode" "QI")])
12826
12827 (define_insn "*setcc_2"
12828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12829         (match_operator:QI 1 "ix86_comparison_operator"
12830           [(reg FLAGS_REG) (const_int 0)]))]
12831   ""
12832   "set%C1\t%0"
12833   [(set_attr "type" "setcc")
12834    (set_attr "mode" "QI")])
12835
12836 ;; In general it is not safe to assume too much about CCmode registers,
12837 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12838 ;; conditions this is safe on x86, so help combine not create
12839 ;;
12840 ;;      seta    %al
12841 ;;      testb   %al, %al
12842 ;;      sete    %al
12843
12844 (define_split 
12845   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12846         (ne:QI (match_operator 1 "ix86_comparison_operator"
12847                  [(reg FLAGS_REG) (const_int 0)])
12848             (const_int 0)))]
12849   ""
12850   [(set (match_dup 0) (match_dup 1))]
12851 {
12852   PUT_MODE (operands[1], QImode);
12853 })
12854
12855 (define_split 
12856   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857         (ne:QI (match_operator 1 "ix86_comparison_operator"
12858                  [(reg FLAGS_REG) (const_int 0)])
12859             (const_int 0)))]
12860   ""
12861   [(set (match_dup 0) (match_dup 1))]
12862 {
12863   PUT_MODE (operands[1], QImode);
12864 })
12865
12866 (define_split 
12867   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868         (eq:QI (match_operator 1 "ix86_comparison_operator"
12869                  [(reg FLAGS_REG) (const_int 0)])
12870             (const_int 0)))]
12871   ""
12872   [(set (match_dup 0) (match_dup 1))]
12873 {
12874   rtx new_op1 = copy_rtx (operands[1]);
12875   operands[1] = new_op1;
12876   PUT_MODE (new_op1, QImode);
12877   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12878                                              GET_MODE (XEXP (new_op1, 0))));
12879
12880   /* Make sure that (a) the CCmode we have for the flags is strong
12881      enough for the reversed compare or (b) we have a valid FP compare.  */
12882   if (! ix86_comparison_operator (new_op1, VOIDmode))
12883     FAIL;
12884 })
12885
12886 (define_split 
12887   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12888         (eq:QI (match_operator 1 "ix86_comparison_operator"
12889                  [(reg FLAGS_REG) (const_int 0)])
12890             (const_int 0)))]
12891   ""
12892   [(set (match_dup 0) (match_dup 1))]
12893 {
12894   rtx new_op1 = copy_rtx (operands[1]);
12895   operands[1] = new_op1;
12896   PUT_MODE (new_op1, QImode);
12897   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12898                                              GET_MODE (XEXP (new_op1, 0))));
12899
12900   /* Make sure that (a) the CCmode we have for the flags is strong
12901      enough for the reversed compare or (b) we have a valid FP compare.  */
12902   if (! ix86_comparison_operator (new_op1, VOIDmode))
12903     FAIL;
12904 })
12905
12906 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12907 ;; subsequent logical operations are used to imitate conditional moves.
12908 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12909 ;; it directly.
12910
12911 (define_insn "*sse_setccsf"
12912   [(set (match_operand:SF 0 "register_operand" "=x")
12913         (match_operator:SF 1 "sse_comparison_operator"
12914           [(match_operand:SF 2 "register_operand" "0")
12915            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12916   "TARGET_SSE"
12917   "cmp%D1ss\t{%3, %0|%0, %3}"
12918   [(set_attr "type" "ssecmp")
12919    (set_attr "mode" "SF")])
12920
12921 (define_insn "*sse_setccdf"
12922   [(set (match_operand:DF 0 "register_operand" "=Y")
12923         (match_operator:DF 1 "sse_comparison_operator"
12924           [(match_operand:DF 2 "register_operand" "0")
12925            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12926   "TARGET_SSE2"
12927   "cmp%D1sd\t{%3, %0|%0, %3}"
12928   [(set_attr "type" "ssecmp")
12929    (set_attr "mode" "DF")])
12930 \f
12931 ;; Basic conditional jump instructions.
12932 ;; We ignore the overflow flag for signed branch instructions.
12933
12934 ;; For all bCOND expanders, also expand the compare or test insn that
12935 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12936
12937 (define_expand "beq"
12938   [(set (pc)
12939         (if_then_else (match_dup 1)
12940                       (label_ref (match_operand 0 "" ""))
12941                       (pc)))]
12942   ""
12943   "ix86_expand_branch (EQ, operands[0]); DONE;")
12944
12945 (define_expand "bne"
12946   [(set (pc)
12947         (if_then_else (match_dup 1)
12948                       (label_ref (match_operand 0 "" ""))
12949                       (pc)))]
12950   ""
12951   "ix86_expand_branch (NE, operands[0]); DONE;")
12952
12953 (define_expand "bgt"
12954   [(set (pc)
12955         (if_then_else (match_dup 1)
12956                       (label_ref (match_operand 0 "" ""))
12957                       (pc)))]
12958   ""
12959   "ix86_expand_branch (GT, operands[0]); DONE;")
12960
12961 (define_expand "bgtu"
12962   [(set (pc)
12963         (if_then_else (match_dup 1)
12964                       (label_ref (match_operand 0 "" ""))
12965                       (pc)))]
12966   ""
12967   "ix86_expand_branch (GTU, operands[0]); DONE;")
12968
12969 (define_expand "blt"
12970   [(set (pc)
12971         (if_then_else (match_dup 1)
12972                       (label_ref (match_operand 0 "" ""))
12973                       (pc)))]
12974   ""
12975   "ix86_expand_branch (LT, operands[0]); DONE;")
12976
12977 (define_expand "bltu"
12978   [(set (pc)
12979         (if_then_else (match_dup 1)
12980                       (label_ref (match_operand 0 "" ""))
12981                       (pc)))]
12982   ""
12983   "ix86_expand_branch (LTU, operands[0]); DONE;")
12984
12985 (define_expand "bge"
12986   [(set (pc)
12987         (if_then_else (match_dup 1)
12988                       (label_ref (match_operand 0 "" ""))
12989                       (pc)))]
12990   ""
12991   "ix86_expand_branch (GE, operands[0]); DONE;")
12992
12993 (define_expand "bgeu"
12994   [(set (pc)
12995         (if_then_else (match_dup 1)
12996                       (label_ref (match_operand 0 "" ""))
12997                       (pc)))]
12998   ""
12999   "ix86_expand_branch (GEU, operands[0]); DONE;")
13000
13001 (define_expand "ble"
13002   [(set (pc)
13003         (if_then_else (match_dup 1)
13004                       (label_ref (match_operand 0 "" ""))
13005                       (pc)))]
13006   ""
13007   "ix86_expand_branch (LE, operands[0]); DONE;")
13008
13009 (define_expand "bleu"
13010   [(set (pc)
13011         (if_then_else (match_dup 1)
13012                       (label_ref (match_operand 0 "" ""))
13013                       (pc)))]
13014   ""
13015   "ix86_expand_branch (LEU, operands[0]); DONE;")
13016
13017 (define_expand "bunordered"
13018   [(set (pc)
13019         (if_then_else (match_dup 1)
13020                       (label_ref (match_operand 0 "" ""))
13021                       (pc)))]
13022   "TARGET_80387 || TARGET_SSE_MATH"
13023   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13024
13025 (define_expand "bordered"
13026   [(set (pc)
13027         (if_then_else (match_dup 1)
13028                       (label_ref (match_operand 0 "" ""))
13029                       (pc)))]
13030   "TARGET_80387 || TARGET_SSE_MATH"
13031   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13032
13033 (define_expand "buneq"
13034   [(set (pc)
13035         (if_then_else (match_dup 1)
13036                       (label_ref (match_operand 0 "" ""))
13037                       (pc)))]
13038   "TARGET_80387 || TARGET_SSE_MATH"
13039   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13040
13041 (define_expand "bunge"
13042   [(set (pc)
13043         (if_then_else (match_dup 1)
13044                       (label_ref (match_operand 0 "" ""))
13045                       (pc)))]
13046   "TARGET_80387 || TARGET_SSE_MATH"
13047   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13048
13049 (define_expand "bungt"
13050   [(set (pc)
13051         (if_then_else (match_dup 1)
13052                       (label_ref (match_operand 0 "" ""))
13053                       (pc)))]
13054   "TARGET_80387 || TARGET_SSE_MATH"
13055   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13056
13057 (define_expand "bunle"
13058   [(set (pc)
13059         (if_then_else (match_dup 1)
13060                       (label_ref (match_operand 0 "" ""))
13061                       (pc)))]
13062   "TARGET_80387 || TARGET_SSE_MATH"
13063   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13064
13065 (define_expand "bunlt"
13066   [(set (pc)
13067         (if_then_else (match_dup 1)
13068                       (label_ref (match_operand 0 "" ""))
13069                       (pc)))]
13070   "TARGET_80387 || TARGET_SSE_MATH"
13071   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13072
13073 (define_expand "bltgt"
13074   [(set (pc)
13075         (if_then_else (match_dup 1)
13076                       (label_ref (match_operand 0 "" ""))
13077                       (pc)))]
13078   "TARGET_80387 || TARGET_SSE_MATH"
13079   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13080
13081 (define_insn "*jcc_1"
13082   [(set (pc)
13083         (if_then_else (match_operator 1 "ix86_comparison_operator"
13084                                       [(reg FLAGS_REG) (const_int 0)])
13085                       (label_ref (match_operand 0 "" ""))
13086                       (pc)))]
13087   ""
13088   "%+j%C1\t%l0"
13089   [(set_attr "type" "ibr")
13090    (set_attr "modrm" "0")
13091    (set (attr "length")
13092            (if_then_else (and (ge (minus (match_dup 0) (pc))
13093                                   (const_int -126))
13094                               (lt (minus (match_dup 0) (pc))
13095                                   (const_int 128)))
13096              (const_int 2)
13097              (const_int 6)))])
13098
13099 (define_insn "*jcc_2"
13100   [(set (pc)
13101         (if_then_else (match_operator 1 "ix86_comparison_operator"
13102                                       [(reg FLAGS_REG) (const_int 0)])
13103                       (pc)
13104                       (label_ref (match_operand 0 "" ""))))]
13105   ""
13106   "%+j%c1\t%l0"
13107   [(set_attr "type" "ibr")
13108    (set_attr "modrm" "0")
13109    (set (attr "length")
13110            (if_then_else (and (ge (minus (match_dup 0) (pc))
13111                                   (const_int -126))
13112                               (lt (minus (match_dup 0) (pc))
13113                                   (const_int 128)))
13114              (const_int 2)
13115              (const_int 6)))])
13116
13117 ;; In general it is not safe to assume too much about CCmode registers,
13118 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13119 ;; conditions this is safe on x86, so help combine not create
13120 ;;
13121 ;;      seta    %al
13122 ;;      testb   %al, %al
13123 ;;      je      Lfoo
13124
13125 (define_split 
13126   [(set (pc)
13127         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13128                                       [(reg FLAGS_REG) (const_int 0)])
13129                           (const_int 0))
13130                       (label_ref (match_operand 1 "" ""))
13131                       (pc)))]
13132   ""
13133   [(set (pc)
13134         (if_then_else (match_dup 0)
13135                       (label_ref (match_dup 1))
13136                       (pc)))]
13137 {
13138   PUT_MODE (operands[0], VOIDmode);
13139 })
13140   
13141 (define_split 
13142   [(set (pc)
13143         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13144                                       [(reg FLAGS_REG) (const_int 0)])
13145                           (const_int 0))
13146                       (label_ref (match_operand 1 "" ""))
13147                       (pc)))]
13148   ""
13149   [(set (pc)
13150         (if_then_else (match_dup 0)
13151                       (label_ref (match_dup 1))
13152                       (pc)))]
13153 {
13154   rtx new_op0 = copy_rtx (operands[0]);
13155   operands[0] = new_op0;
13156   PUT_MODE (new_op0, VOIDmode);
13157   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13158                                              GET_MODE (XEXP (new_op0, 0))));
13159
13160   /* Make sure that (a) the CCmode we have for the flags is strong
13161      enough for the reversed compare or (b) we have a valid FP compare.  */
13162   if (! ix86_comparison_operator (new_op0, VOIDmode))
13163     FAIL;
13164 })
13165
13166 ;; Define combination compare-and-branch fp compare instructions to use
13167 ;; during early optimization.  Splitting the operation apart early makes
13168 ;; for bad code when we want to reverse the operation.
13169
13170 (define_insn "*fp_jcc_1_mixed"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "f,x")
13174                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13175           (label_ref (match_operand 3 "" ""))
13176           (pc)))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "TARGET_MIX_SSE_I387
13180    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13183   "#")
13184
13185 (define_insn "*fp_jcc_1_sse"
13186   [(set (pc)
13187         (if_then_else (match_operator 0 "comparison_operator"
13188                         [(match_operand 1 "register_operand" "x")
13189                          (match_operand 2 "nonimmediate_operand" "xm")])
13190           (label_ref (match_operand 3 "" ""))
13191           (pc)))
13192    (clobber (reg:CCFP FPSR_REG))
13193    (clobber (reg:CCFP FLAGS_REG))]
13194   "TARGET_SSE_MATH
13195    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13199
13200 (define_insn "*fp_jcc_1_387"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "f")
13204                          (match_operand 2 "register_operand" "f")])
13205           (label_ref (match_operand 3 "" ""))
13206           (pc)))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))]
13209   "TARGET_CMOVE && TARGET_80387
13210    && FLOAT_MODE_P (GET_MODE (operands[1]))
13211    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213   "#")
13214
13215 (define_insn "*fp_jcc_2_mixed"
13216   [(set (pc)
13217         (if_then_else (match_operator 0 "comparison_operator"
13218                         [(match_operand 1 "register_operand" "f,x")
13219                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13220           (pc)
13221           (label_ref (match_operand 3 "" ""))))
13222    (clobber (reg:CCFP FPSR_REG))
13223    (clobber (reg:CCFP FLAGS_REG))]
13224   "TARGET_MIX_SSE_I387
13225    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13226    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228   "#")
13229
13230 (define_insn "*fp_jcc_2_sse"
13231   [(set (pc)
13232         (if_then_else (match_operator 0 "comparison_operator"
13233                         [(match_operand 1 "register_operand" "x")
13234                          (match_operand 2 "nonimmediate_operand" "xm")])
13235           (pc)
13236           (label_ref (match_operand 3 "" ""))))
13237    (clobber (reg:CCFP FPSR_REG))
13238    (clobber (reg:CCFP FLAGS_REG))]
13239   "TARGET_SSE_MATH
13240    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13244
13245 (define_insn "*fp_jcc_2_387"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "register_operand" "f")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))]
13254   "TARGET_CMOVE && TARGET_80387
13255    && FLOAT_MODE_P (GET_MODE (operands[1]))
13256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13258   "#")
13259
13260 (define_insn "*fp_jcc_3_387"
13261   [(set (pc)
13262         (if_then_else (match_operator 0 "comparison_operator"
13263                         [(match_operand 1 "register_operand" "f")
13264                          (match_operand 2 "nonimmediate_operand" "fm")])
13265           (label_ref (match_operand 3 "" ""))
13266           (pc)))
13267    (clobber (reg:CCFP FPSR_REG))
13268    (clobber (reg:CCFP FLAGS_REG))
13269    (clobber (match_scratch:HI 4 "=a"))]
13270   "TARGET_80387
13271    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13272    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13273    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13274    && SELECT_CC_MODE (GET_CODE (operands[0]),
13275                       operands[1], operands[2]) == CCFPmode
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13278
13279 (define_insn "*fp_jcc_4_387"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "nonimmediate_operand" "fm")])
13284           (pc)
13285           (label_ref (match_operand 3 "" ""))))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293    && SELECT_CC_MODE (GET_CODE (operands[0]),
13294                       operands[1], operands[2]) == CCFPmode
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13297
13298 (define_insn "*fp_jcc_5_387"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "register_operand" "f")])
13303           (label_ref (match_operand 3 "" ""))
13304           (pc)))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && FLOAT_MODE_P (GET_MODE (operands[1]))
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312   "#")
13313
13314 (define_insn "*fp_jcc_6_387"
13315   [(set (pc)
13316         (if_then_else (match_operator 0 "comparison_operator"
13317                         [(match_operand 1 "register_operand" "f")
13318                          (match_operand 2 "register_operand" "f")])
13319           (pc)
13320           (label_ref (match_operand 3 "" ""))))
13321    (clobber (reg:CCFP FPSR_REG))
13322    (clobber (reg:CCFP FLAGS_REG))
13323    (clobber (match_scratch:HI 4 "=a"))]
13324   "TARGET_80387
13325    && FLOAT_MODE_P (GET_MODE (operands[1]))
13326    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13327    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13328   "#")
13329
13330 (define_insn "*fp_jcc_7_387"
13331   [(set (pc)
13332         (if_then_else (match_operator 0 "comparison_operator"
13333                         [(match_operand 1 "register_operand" "f")
13334                          (match_operand 2 "const0_operand" "X")])
13335           (label_ref (match_operand 3 "" ""))
13336           (pc)))
13337    (clobber (reg:CCFP FPSR_REG))
13338    (clobber (reg:CCFP FLAGS_REG))
13339    (clobber (match_scratch:HI 4 "=a"))]
13340   "TARGET_80387
13341    && FLOAT_MODE_P (GET_MODE (operands[1]))
13342    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13343    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13344    && SELECT_CC_MODE (GET_CODE (operands[0]),
13345                       operands[1], operands[2]) == CCFPmode
13346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347   "#")
13348
13349 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13350 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13351 ;; with a precedence over other operators and is always put in the first
13352 ;; place. Swap condition and operands to match ficom instruction.
13353
13354 (define_insn "*fp_jcc_8<mode>_387"
13355   [(set (pc)
13356         (if_then_else (match_operator 0 "comparison_operator"
13357                         [(match_operator 1 "float_operator"
13358                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13359                            (match_operand 3 "register_operand" "f,f")])
13360           (label_ref (match_operand 4 "" ""))
13361           (pc)))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 5 "=a,a"))]
13365   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13366    && FLOAT_MODE_P (GET_MODE (operands[3]))
13367    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13368    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13369    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13370    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13371   "#")
13372
13373 (define_split
13374   [(set (pc)
13375         (if_then_else (match_operator 0 "comparison_operator"
13376                         [(match_operand 1 "register_operand" "")
13377                          (match_operand 2 "nonimmediate_operand" "")])
13378           (match_operand 3 "" "")
13379           (match_operand 4 "" "")))
13380    (clobber (reg:CCFP FPSR_REG))
13381    (clobber (reg:CCFP FLAGS_REG))]
13382   "reload_completed"
13383   [(const_int 0)]
13384 {
13385   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13386                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13387   DONE;
13388 })
13389
13390 (define_split
13391   [(set (pc)
13392         (if_then_else (match_operator 0 "comparison_operator"
13393                         [(match_operand 1 "register_operand" "")
13394                          (match_operand 2 "general_operand" "")])
13395           (match_operand 3 "" "")
13396           (match_operand 4 "" "")))
13397    (clobber (reg:CCFP FPSR_REG))
13398    (clobber (reg:CCFP FLAGS_REG))
13399    (clobber (match_scratch:HI 5 "=a"))]
13400   "reload_completed"
13401   [(const_int 0)]
13402 {
13403   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13404                         operands[3], operands[4], operands[5], NULL_RTX);
13405   DONE;
13406 })
13407
13408 (define_split
13409   [(set (pc)
13410         (if_then_else (match_operator 0 "comparison_operator"
13411                         [(match_operator 1 "float_operator"
13412                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13413                            (match_operand 3 "register_operand" "")])
13414           (match_operand 4 "" "")
13415           (match_operand 5 "" "")))
13416    (clobber (reg:CCFP FPSR_REG))
13417    (clobber (reg:CCFP FLAGS_REG))
13418    (clobber (match_scratch:HI 6 "=a"))]
13419   "reload_completed"
13420   [(const_int 0)]
13421 {
13422   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13423   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13424                         operands[3], operands[7],
13425                         operands[4], operands[5], operands[6], NULL_RTX);
13426   DONE;
13427 })
13428
13429 ;; %%% Kill this when reload knows how to do it.
13430 (define_split
13431   [(set (pc)
13432         (if_then_else (match_operator 0 "comparison_operator"
13433                         [(match_operator 1 "float_operator"
13434                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13435                            (match_operand 3 "register_operand" "")])
13436           (match_operand 4 "" "")
13437           (match_operand 5 "" "")))
13438    (clobber (reg:CCFP FPSR_REG))
13439    (clobber (reg:CCFP FLAGS_REG))
13440    (clobber (match_scratch:HI 6 "=a"))]
13441   "reload_completed"
13442   [(const_int 0)]
13443 {
13444   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13445   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13446   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13447                         operands[3], operands[7],
13448                         operands[4], operands[5], operands[6], operands[2]);
13449   DONE;
13450 })
13451 \f
13452 ;; Unconditional and other jump instructions
13453
13454 (define_insn "jump"
13455   [(set (pc)
13456         (label_ref (match_operand 0 "" "")))]
13457   ""
13458   "jmp\t%l0"
13459   [(set_attr "type" "ibr")
13460    (set (attr "length")
13461            (if_then_else (and (ge (minus (match_dup 0) (pc))
13462                                   (const_int -126))
13463                               (lt (minus (match_dup 0) (pc))
13464                                   (const_int 128)))
13465              (const_int 2)
13466              (const_int 5)))
13467    (set_attr "modrm" "0")])
13468
13469 (define_expand "indirect_jump"
13470   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13471   ""
13472   "")
13473
13474 (define_insn "*indirect_jump"
13475   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13476   "!TARGET_64BIT"
13477   "jmp\t%A0"
13478   [(set_attr "type" "ibr")
13479    (set_attr "length_immediate" "0")])
13480
13481 (define_insn "*indirect_jump_rtx64"
13482   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13483   "TARGET_64BIT"
13484   "jmp\t%A0"
13485   [(set_attr "type" "ibr")
13486    (set_attr "length_immediate" "0")])
13487
13488 (define_expand "tablejump"
13489   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13490               (use (label_ref (match_operand 1 "" "")))])]
13491   ""
13492 {
13493   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13494      relative.  Convert the relative address to an absolute address.  */
13495   if (flag_pic)
13496     {
13497       rtx op0, op1;
13498       enum rtx_code code;
13499
13500       if (TARGET_64BIT)
13501         {
13502           code = PLUS;
13503           op0 = operands[0];
13504           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13505         }
13506       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13507         {
13508           code = PLUS;
13509           op0 = operands[0];
13510           op1 = pic_offset_table_rtx;
13511         }
13512       else
13513         {
13514           code = MINUS;
13515           op0 = pic_offset_table_rtx;
13516           op1 = operands[0];
13517         }
13518
13519       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13520                                          OPTAB_DIRECT);
13521     }
13522 })
13523
13524 (define_insn "*tablejump_1"
13525   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13526    (use (label_ref (match_operand 1 "" "")))]
13527   "!TARGET_64BIT"
13528   "jmp\t%A0"
13529   [(set_attr "type" "ibr")
13530    (set_attr "length_immediate" "0")])
13531
13532 (define_insn "*tablejump_1_rtx64"
13533   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13534    (use (label_ref (match_operand 1 "" "")))]
13535   "TARGET_64BIT"
13536   "jmp\t%A0"
13537   [(set_attr "type" "ibr")
13538    (set_attr "length_immediate" "0")])
13539 \f
13540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13541
13542 (define_peephole2
13543   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13544    (set (match_operand:QI 1 "register_operand" "")
13545         (match_operator:QI 2 "ix86_comparison_operator"
13546           [(reg FLAGS_REG) (const_int 0)]))
13547    (set (match_operand 3 "q_regs_operand" "")
13548         (zero_extend (match_dup 1)))]
13549   "(peep2_reg_dead_p (3, operands[1])
13550     || operands_match_p (operands[1], operands[3]))
13551    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552   [(set (match_dup 4) (match_dup 0))
13553    (set (strict_low_part (match_dup 5))
13554         (match_dup 2))]
13555 {
13556   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13557   operands[5] = gen_lowpart (QImode, operands[3]);
13558   ix86_expand_clear (operands[3]);
13559 })
13560
13561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13562
13563 (define_peephole2
13564   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13565    (set (match_operand:QI 1 "register_operand" "")
13566         (match_operator:QI 2 "ix86_comparison_operator"
13567           [(reg FLAGS_REG) (const_int 0)]))
13568    (parallel [(set (match_operand 3 "q_regs_operand" "")
13569                    (zero_extend (match_dup 1)))
13570               (clobber (reg:CC FLAGS_REG))])]
13571   "(peep2_reg_dead_p (3, operands[1])
13572     || operands_match_p (operands[1], operands[3]))
13573    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13574   [(set (match_dup 4) (match_dup 0))
13575    (set (strict_low_part (match_dup 5))
13576         (match_dup 2))]
13577 {
13578   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13579   operands[5] = gen_lowpart (QImode, operands[3]);
13580   ix86_expand_clear (operands[3]);
13581 })
13582 \f
13583 ;; Call instructions.
13584
13585 ;; The predicates normally associated with named expanders are not properly
13586 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13587 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13588
13589 ;; Call subroutine returning no value.
13590
13591 (define_expand "call_pop"
13592   [(parallel [(call (match_operand:QI 0 "" "")
13593                     (match_operand:SI 1 "" ""))
13594               (set (reg:SI SP_REG)
13595                    (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 3 "" "")))])]
13597   "!TARGET_64BIT"
13598 {
13599   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13600   DONE;
13601 })
13602
13603 (define_insn "*call_pop_0"
13604   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13605          (match_operand:SI 1 "" ""))
13606    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13607                             (match_operand:SI 2 "immediate_operand" "")))]
13608   "!TARGET_64BIT"
13609 {
13610   if (SIBLING_CALL_P (insn))
13611     return "jmp\t%P0";
13612   else
13613     return "call\t%P0";
13614 }
13615   [(set_attr "type" "call")])
13616   
13617 (define_insn "*call_pop_1"
13618   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13619          (match_operand:SI 1 "" ""))
13620    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13621                             (match_operand:SI 2 "immediate_operand" "i")))]
13622   "!TARGET_64BIT"
13623 {
13624   if (constant_call_address_operand (operands[0], Pmode))
13625     {
13626       if (SIBLING_CALL_P (insn))
13627         return "jmp\t%P0";
13628       else
13629         return "call\t%P0";
13630     }
13631   if (SIBLING_CALL_P (insn))
13632     return "jmp\t%A0";
13633   else
13634     return "call\t%A0";
13635 }
13636   [(set_attr "type" "call")])
13637
13638 (define_expand "call"
13639   [(call (match_operand:QI 0 "" "")
13640          (match_operand 1 "" ""))
13641    (use (match_operand 2 "" ""))]
13642   ""
13643 {
13644   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13645   DONE;
13646 })
13647
13648 (define_expand "sibcall"
13649   [(call (match_operand:QI 0 "" "")
13650          (match_operand 1 "" ""))
13651    (use (match_operand 2 "" ""))]
13652   ""
13653 {
13654   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13655   DONE;
13656 })
13657
13658 (define_insn "*call_0"
13659   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13660          (match_operand 1 "" ""))]
13661   ""
13662 {
13663   if (SIBLING_CALL_P (insn))
13664     return "jmp\t%P0";
13665   else
13666     return "call\t%P0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*call_1"
13671   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13672          (match_operand 1 "" ""))]
13673   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674 {
13675   if (constant_call_address_operand (operands[0], Pmode))
13676     return "call\t%P0";
13677   return "call\t%A0";
13678 }
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1"
13682   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13683          (match_operand 1 "" ""))]
13684   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13685 {
13686   if (constant_call_address_operand (operands[0], Pmode))
13687     return "jmp\t%P0";
13688   return "jmp\t%A0";
13689 }
13690   [(set_attr "type" "call")])
13691
13692 (define_insn "*call_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13694          (match_operand 1 "" ""))]
13695   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13696 {
13697   if (constant_call_address_operand (operands[0], Pmode))
13698     return "call\t%P0";
13699   return "call\t%A0";
13700 }
13701   [(set_attr "type" "call")])
13702
13703 (define_insn "*sibcall_1_rex64"
13704   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13705          (match_operand 1 "" ""))]
13706   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13707   "jmp\t%P0"
13708   [(set_attr "type" "call")])
13709
13710 (define_insn "*sibcall_1_rex64_v"
13711   [(call (mem:QI (reg:DI 40))
13712          (match_operand 0 "" ""))]
13713   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13714   "jmp\t*%%r11"
13715   [(set_attr "type" "call")])
13716
13717
13718 ;; Call subroutine, returning value in operand 0
13719
13720 (define_expand "call_value_pop"
13721   [(parallel [(set (match_operand 0 "" "")
13722                    (call (match_operand:QI 1 "" "")
13723                          (match_operand:SI 2 "" "")))
13724               (set (reg:SI SP_REG)
13725                    (plus:SI (reg:SI SP_REG)
13726                             (match_operand:SI 4 "" "")))])]
13727   "!TARGET_64BIT"
13728 {
13729   ix86_expand_call (operands[0], operands[1], operands[2],
13730                     operands[3], operands[4], 0);
13731   DONE;
13732 })
13733
13734 (define_expand "call_value"
13735   [(set (match_operand 0 "" "")
13736         (call (match_operand:QI 1 "" "")
13737               (match_operand:SI 2 "" "")))
13738    (use (match_operand:SI 3 "" ""))]
13739   ;; Operand 2 not used on the i386.
13740   ""
13741 {
13742   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13743   DONE;
13744 })
13745
13746 (define_expand "sibcall_value"
13747   [(set (match_operand 0 "" "")
13748         (call (match_operand:QI 1 "" "")
13749               (match_operand:SI 2 "" "")))
13750    (use (match_operand:SI 3 "" ""))]
13751   ;; Operand 2 not used on the i386.
13752   ""
13753 {
13754   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13755   DONE;
13756 })
13757
13758 ;; Call subroutine returning any type.
13759
13760 (define_expand "untyped_call"
13761   [(parallel [(call (match_operand 0 "" "")
13762                     (const_int 0))
13763               (match_operand 1 "" "")
13764               (match_operand 2 "" "")])]
13765   ""
13766 {
13767   int i;
13768
13769   /* In order to give reg-stack an easier job in validating two
13770      coprocessor registers as containing a possible return value,
13771      simply pretend the untyped call returns a complex long double
13772      value.  */
13773
13774   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13775                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13776                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13777                     NULL, 0);
13778
13779   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13780     {
13781       rtx set = XVECEXP (operands[2], 0, i);
13782       emit_move_insn (SET_DEST (set), SET_SRC (set));
13783     }
13784
13785   /* The optimizer does not know that the call sets the function value
13786      registers we stored in the result block.  We avoid problems by
13787      claiming that all hard registers are used and clobbered at this
13788      point.  */
13789   emit_insn (gen_blockage (const0_rtx));
13790
13791   DONE;
13792 })
13793 \f
13794 ;; Prologue and epilogue instructions
13795
13796 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13797 ;; all of memory.  This blocks insns from being moved across this point.
13798
13799 (define_insn "blockage"
13800   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13801   ""
13802   ""
13803   [(set_attr "length" "0")])
13804
13805 ;; Insn emitted into the body of a function to return from a function.
13806 ;; This is only done if the function's epilogue is known to be simple.
13807 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13808
13809 (define_expand "return"
13810   [(return)]
13811   "ix86_can_use_return_insn_p ()"
13812 {
13813   if (current_function_pops_args)
13814     {
13815       rtx popc = GEN_INT (current_function_pops_args);
13816       emit_jump_insn (gen_return_pop_internal (popc));
13817       DONE;
13818     }
13819 })
13820
13821 (define_insn "return_internal"
13822   [(return)]
13823   "reload_completed"
13824   "ret"
13825   [(set_attr "length" "1")
13826    (set_attr "length_immediate" "0")
13827    (set_attr "modrm" "0")])
13828
13829 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13830 ;; instruction Athlon and K8 have.
13831
13832 (define_insn "return_internal_long"
13833   [(return)
13834    (unspec [(const_int 0)] UNSPEC_REP)]
13835   "reload_completed"
13836   "rep {;} ret"
13837   [(set_attr "length" "1")
13838    (set_attr "length_immediate" "0")
13839    (set_attr "prefix_rep" "1")
13840    (set_attr "modrm" "0")])
13841
13842 (define_insn "return_pop_internal"
13843   [(return)
13844    (use (match_operand:SI 0 "const_int_operand" ""))]
13845   "reload_completed"
13846   "ret\t%0"
13847   [(set_attr "length" "3")
13848    (set_attr "length_immediate" "2")
13849    (set_attr "modrm" "0")])
13850
13851 (define_insn "return_indirect_internal"
13852   [(return)
13853    (use (match_operand:SI 0 "register_operand" "r"))]
13854   "reload_completed"
13855   "jmp\t%A0"
13856   [(set_attr "type" "ibr")
13857    (set_attr "length_immediate" "0")])
13858
13859 (define_insn "nop"
13860   [(const_int 0)]
13861   ""
13862   "nop"
13863   [(set_attr "length" "1")
13864    (set_attr "length_immediate" "0")
13865    (set_attr "modrm" "0")])
13866
13867 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13868 ;; branch prediction penalty for the third jump in a 16-byte
13869 ;; block on K8.
13870
13871 (define_insn "align"
13872   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13873   ""
13874 {
13875 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13876   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13877 #else
13878   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13879      The align insn is used to avoid 3 jump instructions in the row to improve
13880      branch prediction and the benefits hardly outweight the cost of extra 8
13881      nops on the average inserted by full alignment pseudo operation.  */
13882 #endif
13883   return "";
13884 }
13885   [(set_attr "length" "16")])
13886
13887 (define_expand "prologue"
13888   [(const_int 1)]
13889   ""
13890   "ix86_expand_prologue (); DONE;")
13891
13892 (define_insn "set_got"
13893   [(set (match_operand:SI 0 "register_operand" "=r")
13894         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13895    (clobber (reg:CC FLAGS_REG))]
13896   "!TARGET_64BIT"
13897   { return output_set_got (operands[0], NULL_RTX); }
13898   [(set_attr "type" "multi")
13899    (set_attr "length" "12")])
13900
13901 (define_insn "set_got_labelled"
13902   [(set (match_operand:SI 0 "register_operand" "=r")
13903         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13904          UNSPEC_SET_GOT))
13905    (clobber (reg:CC FLAGS_REG))]
13906   "!TARGET_64BIT"
13907   { return output_set_got (operands[0], operands[1]); }
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "12")])
13910
13911 (define_insn "set_got_rex64"
13912   [(set (match_operand:DI 0 "register_operand" "=r")
13913         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13914   "TARGET_64BIT"
13915   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13916   [(set_attr "type" "lea")
13917    (set_attr "length" "6")])
13918
13919 (define_expand "epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (1); DONE;")
13923
13924 (define_expand "sibcall_epilogue"
13925   [(const_int 1)]
13926   ""
13927   "ix86_expand_epilogue (0); DONE;")
13928
13929 (define_expand "eh_return"
13930   [(use (match_operand 0 "register_operand" ""))]
13931   ""
13932 {
13933   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13934
13935   /* Tricky bit: we write the address of the handler to which we will
13936      be returning into someone else's stack frame, one word below the
13937      stack address we wish to restore.  */
13938   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940   tmp = gen_rtx_MEM (Pmode, tmp);
13941   emit_move_insn (tmp, ra);
13942
13943   if (Pmode == SImode)
13944     emit_jump_insn (gen_eh_return_si (sa));
13945   else
13946     emit_jump_insn (gen_eh_return_di (sa));
13947   emit_barrier ();
13948   DONE;
13949 })
13950
13951 (define_insn_and_split "eh_return_si"
13952   [(set (pc) 
13953         (unspec [(match_operand:SI 0 "register_operand" "c")]
13954                  UNSPEC_EH_RETURN))]
13955   "!TARGET_64BIT"
13956   "#"
13957   "reload_completed"
13958   [(const_int 1)]
13959   "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn_and_split "eh_return_di"
13962   [(set (pc) 
13963         (unspec [(match_operand:DI 0 "register_operand" "c")]
13964                  UNSPEC_EH_RETURN))]
13965   "TARGET_64BIT"
13966   "#"
13967   "reload_completed"
13968   [(const_int 1)]
13969   "ix86_expand_epilogue (2); DONE;")
13970
13971 (define_insn "leave"
13972   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974    (clobber (mem:BLK (scratch)))]
13975   "!TARGET_64BIT"
13976   "leave"
13977   [(set_attr "type" "leave")])
13978
13979 (define_insn "leave_rex64"
13980   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982    (clobber (mem:BLK (scratch)))]
13983   "TARGET_64BIT"
13984   "leave"
13985   [(set_attr "type" "leave")])
13986 \f
13987 (define_expand "ffssi2"
13988   [(parallel
13989      [(set (match_operand:SI 0 "register_operand" "") 
13990            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991       (clobber (match_scratch:SI 2 ""))
13992       (clobber (reg:CC FLAGS_REG))])]
13993   ""
13994   "")
13995
13996 (define_insn_and_split "*ffs_cmove"
13997   [(set (match_operand:SI 0 "register_operand" "=r") 
13998         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999    (clobber (match_scratch:SI 2 "=&r"))
14000    (clobber (reg:CC FLAGS_REG))]
14001   "TARGET_CMOVE"
14002   "#"
14003   "&& reload_completed"
14004   [(set (match_dup 2) (const_int -1))
14005    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007    (set (match_dup 0) (if_then_else:SI
14008                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009                         (match_dup 2)
14010                         (match_dup 0)))
14011    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012               (clobber (reg:CC FLAGS_REG))])]
14013   "")
14014
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   ""
14021   "#"
14022   "reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025    (set (strict_low_part (match_dup 3))
14026         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030               (clobber (reg:CC FLAGS_REG))])
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033 {
14034   operands[3] = gen_lowpart (QImode, operands[2]);
14035   ix86_expand_clear (operands[2]);
14036 })
14037
14038 (define_insn "*ffssi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:SI 0 "register_operand" "=r")
14043         (ctz:SI (match_dup 1)))]
14044   ""
14045   "bsf{l}\t{%1, %0|%0, %1}"
14046   [(set_attr "prefix_0f" "1")])
14047
14048 (define_expand "ffsdi2"
14049   [(parallel
14050      [(set (match_operand:DI 0 "register_operand" "") 
14051            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052       (clobber (match_scratch:DI 2 ""))
14053       (clobber (reg:CC FLAGS_REG))])]
14054   "TARGET_64BIT && TARGET_CMOVE"
14055   "")
14056
14057 (define_insn_and_split "*ffs_rex64"
14058   [(set (match_operand:DI 0 "register_operand" "=r") 
14059         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060    (clobber (match_scratch:DI 2 "=&r"))
14061    (clobber (reg:CC FLAGS_REG))]
14062   "TARGET_64BIT && TARGET_CMOVE"
14063   "#"
14064   "&& reload_completed"
14065   [(set (match_dup 2) (const_int -1))
14066    (parallel [(set (reg:CCZ FLAGS_REG)
14067                    (compare:CCZ (match_dup 1) (const_int 0)))
14068               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14069    (set (match_dup 0) (if_then_else:DI
14070                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14071                         (match_dup 2)
14072                         (match_dup 0)))
14073    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14074               (clobber (reg:CC FLAGS_REG))])]
14075   "")
14076
14077 (define_insn "*ffsdi_1"
14078   [(set (reg:CCZ FLAGS_REG)
14079         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14080                      (const_int 0)))
14081    (set (match_operand:DI 0 "register_operand" "=r")
14082         (ctz:DI (match_dup 1)))]
14083   "TARGET_64BIT"
14084   "bsf{q}\t{%1, %0|%0, %1}"
14085   [(set_attr "prefix_0f" "1")])
14086
14087 (define_insn "ctzsi2"
14088   [(set (match_operand:SI 0 "register_operand" "=r")
14089         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14090    (clobber (reg:CC FLAGS_REG))]
14091   ""
14092   "bsf{l}\t{%1, %0|%0, %1}"
14093   [(set_attr "prefix_0f" "1")])
14094
14095 (define_insn "ctzdi2"
14096   [(set (match_operand:DI 0 "register_operand" "=r")
14097         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14098    (clobber (reg:CC FLAGS_REG))]
14099   "TARGET_64BIT"
14100   "bsf{q}\t{%1, %0|%0, %1}"
14101   [(set_attr "prefix_0f" "1")])
14102
14103 (define_expand "clzsi2"
14104   [(parallel
14105      [(set (match_operand:SI 0 "register_operand" "")
14106            (minus:SI (const_int 31)
14107                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14108       (clobber (reg:CC FLAGS_REG))])
14109    (parallel
14110      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14111       (clobber (reg:CC FLAGS_REG))])]
14112   ""
14113   "")
14114
14115 (define_insn "*bsr"
14116   [(set (match_operand:SI 0 "register_operand" "=r")
14117         (minus:SI (const_int 31)
14118                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14119    (clobber (reg:CC FLAGS_REG))]
14120   ""
14121   "bsr{l}\t{%1, %0|%0, %1}"
14122   [(set_attr "prefix_0f" "1")])
14123
14124 (define_expand "clzdi2"
14125   [(parallel
14126      [(set (match_operand:DI 0 "register_operand" "")
14127            (minus:DI (const_int 63)
14128                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14129       (clobber (reg:CC FLAGS_REG))])
14130    (parallel
14131      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14132       (clobber (reg:CC FLAGS_REG))])]
14133   "TARGET_64BIT"
14134   "")
14135
14136 (define_insn "*bsr_rex64"
14137   [(set (match_operand:DI 0 "register_operand" "=r")
14138         (minus:DI (const_int 63)
14139                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14140    (clobber (reg:CC FLAGS_REG))]
14141   "TARGET_64BIT"
14142   "bsr{q}\t{%1, %0|%0, %1}"
14143   [(set_attr "prefix_0f" "1")])
14144 \f
14145 ;; Thread-local storage patterns for ELF.
14146 ;;
14147 ;; Note that these code sequences must appear exactly as shown
14148 ;; in order to allow linker relaxation.
14149
14150 (define_insn "*tls_global_dynamic_32_gnu"
14151   [(set (match_operand:SI 0 "register_operand" "=a")
14152         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153                     (match_operand:SI 2 "tls_symbolic_operand" "")
14154                     (match_operand:SI 3 "call_insn_operand" "")]
14155                     UNSPEC_TLS_GD))
14156    (clobber (match_scratch:SI 4 "=d"))
14157    (clobber (match_scratch:SI 5 "=c"))
14158    (clobber (reg:CC FLAGS_REG))]
14159   "!TARGET_64BIT && TARGET_GNU_TLS"
14160   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14161   [(set_attr "type" "multi")
14162    (set_attr "length" "12")])
14163
14164 (define_insn "*tls_global_dynamic_32_sun"
14165   [(set (match_operand:SI 0 "register_operand" "=a")
14166         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14167                     (match_operand:SI 2 "tls_symbolic_operand" "")
14168                     (match_operand:SI 3 "call_insn_operand" "")]
14169                     UNSPEC_TLS_GD))
14170    (clobber (match_scratch:SI 4 "=d"))
14171    (clobber (match_scratch:SI 5 "=c"))
14172    (clobber (reg:CC FLAGS_REG))]
14173   "!TARGET_64BIT && TARGET_SUN_TLS"
14174   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14175         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14176   [(set_attr "type" "multi")
14177    (set_attr "length" "14")])
14178
14179 (define_expand "tls_global_dynamic_32"
14180   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14181                    (unspec:SI
14182                     [(match_dup 2)
14183                      (match_operand:SI 1 "tls_symbolic_operand" "")
14184                      (match_dup 3)]
14185                     UNSPEC_TLS_GD))
14186               (clobber (match_scratch:SI 4 ""))
14187               (clobber (match_scratch:SI 5 ""))
14188               (clobber (reg:CC FLAGS_REG))])]
14189   ""
14190 {
14191   if (flag_pic)
14192     operands[2] = pic_offset_table_rtx;
14193   else
14194     {
14195       operands[2] = gen_reg_rtx (Pmode);
14196       emit_insn (gen_set_got (operands[2]));
14197     }
14198   if (TARGET_GNU2_TLS)
14199     {
14200        emit_insn (gen_tls_dynamic_gnu2_32
14201                   (operands[0], operands[1], operands[2]));
14202        DONE;
14203     }
14204   operands[3] = ix86_tls_get_addr ();
14205 })
14206
14207 (define_insn "*tls_global_dynamic_64"
14208   [(set (match_operand:DI 0 "register_operand" "=a")
14209         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14210                  (match_operand:DI 3 "" "")))
14211    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14212               UNSPEC_TLS_GD)]
14213   "TARGET_64BIT"
14214   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14215   [(set_attr "type" "multi")
14216    (set_attr "length" "16")])
14217
14218 (define_expand "tls_global_dynamic_64"
14219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14220                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14221               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14222                          UNSPEC_TLS_GD)])]
14223   ""
14224 {
14225   if (TARGET_GNU2_TLS)
14226     {
14227        emit_insn (gen_tls_dynamic_gnu2_64
14228                   (operands[0], operands[1]));
14229        DONE;
14230     }
14231   operands[2] = ix86_tls_get_addr ();
14232 })
14233
14234 (define_insn "*tls_local_dynamic_base_32_gnu"
14235   [(set (match_operand:SI 0 "register_operand" "=a")
14236         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237                     (match_operand:SI 2 "call_insn_operand" "")]
14238                    UNSPEC_TLS_LD_BASE))
14239    (clobber (match_scratch:SI 3 "=d"))
14240    (clobber (match_scratch:SI 4 "=c"))
14241    (clobber (reg:CC FLAGS_REG))]
14242   "!TARGET_64BIT && TARGET_GNU_TLS"
14243   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14244   [(set_attr "type" "multi")
14245    (set_attr "length" "11")])
14246
14247 (define_insn "*tls_local_dynamic_base_32_sun"
14248   [(set (match_operand:SI 0 "register_operand" "=a")
14249         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14250                     (match_operand:SI 2 "call_insn_operand" "")]
14251                    UNSPEC_TLS_LD_BASE))
14252    (clobber (match_scratch:SI 3 "=d"))
14253    (clobber (match_scratch:SI 4 "=c"))
14254    (clobber (reg:CC FLAGS_REG))]
14255   "!TARGET_64BIT && TARGET_SUN_TLS"
14256   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14257         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14258   [(set_attr "type" "multi")
14259    (set_attr "length" "13")])
14260
14261 (define_expand "tls_local_dynamic_base_32"
14262   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14263                    (unspec:SI [(match_dup 1) (match_dup 2)]
14264                               UNSPEC_TLS_LD_BASE))
14265               (clobber (match_scratch:SI 3 ""))
14266               (clobber (match_scratch:SI 4 ""))
14267               (clobber (reg:CC FLAGS_REG))])]
14268   ""
14269 {
14270   if (flag_pic)
14271     operands[1] = pic_offset_table_rtx;
14272   else
14273     {
14274       operands[1] = gen_reg_rtx (Pmode);
14275       emit_insn (gen_set_got (operands[1]));
14276     }
14277   if (TARGET_GNU2_TLS)
14278     {
14279        emit_insn (gen_tls_dynamic_gnu2_32
14280                   (operands[0], ix86_tls_module_base (), operands[1]));
14281        DONE;
14282     }
14283   operands[2] = ix86_tls_get_addr ();
14284 })
14285
14286 (define_insn "*tls_local_dynamic_base_64"
14287   [(set (match_operand:DI 0 "register_operand" "=a")
14288         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14289                  (match_operand:DI 2 "" "")))
14290    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14291   "TARGET_64BIT"
14292   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14293   [(set_attr "type" "multi")
14294    (set_attr "length" "12")])
14295
14296 (define_expand "tls_local_dynamic_base_64"
14297   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14298                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14299               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14300   ""
14301 {
14302   if (TARGET_GNU2_TLS)
14303     {
14304        emit_insn (gen_tls_dynamic_gnu2_64
14305                   (operands[0], ix86_tls_module_base ()));
14306        DONE;
14307     }
14308   operands[1] = ix86_tls_get_addr ();
14309 })
14310
14311 ;; Local dynamic of a single variable is a lose.  Show combine how
14312 ;; to convert that back to global dynamic.
14313
14314 (define_insn_and_split "*tls_local_dynamic_32_once"
14315   [(set (match_operand:SI 0 "register_operand" "=a")
14316         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14317                              (match_operand:SI 2 "call_insn_operand" "")]
14318                             UNSPEC_TLS_LD_BASE)
14319                  (const:SI (unspec:SI
14320                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14321                             UNSPEC_DTPOFF))))
14322    (clobber (match_scratch:SI 4 "=d"))
14323    (clobber (match_scratch:SI 5 "=c"))
14324    (clobber (reg:CC FLAGS_REG))]
14325   ""
14326   "#"
14327   ""
14328   [(parallel [(set (match_dup 0)
14329                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14330                               UNSPEC_TLS_GD))
14331               (clobber (match_dup 4))
14332               (clobber (match_dup 5))
14333               (clobber (reg:CC FLAGS_REG))])]
14334   "")
14335
14336 ;; Load and add the thread base pointer from %gs:0.
14337
14338 (define_insn "*load_tp_si"
14339   [(set (match_operand:SI 0 "register_operand" "=r")
14340         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14341   "!TARGET_64BIT"
14342   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14343   [(set_attr "type" "imov")
14344    (set_attr "modrm" "0")
14345    (set_attr "length" "7")
14346    (set_attr "memory" "load")
14347    (set_attr "imm_disp" "false")])
14348
14349 (define_insn "*add_tp_si"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14352                  (match_operand:SI 1 "register_operand" "0")))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "!TARGET_64BIT"
14355   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14356   [(set_attr "type" "alu")
14357    (set_attr "modrm" "0")
14358    (set_attr "length" "7")
14359    (set_attr "memory" "load")
14360    (set_attr "imm_disp" "false")])
14361
14362 (define_insn "*load_tp_di"
14363   [(set (match_operand:DI 0 "register_operand" "=r")
14364         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14365   "TARGET_64BIT"
14366   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14367   [(set_attr "type" "imov")
14368    (set_attr "modrm" "0")
14369    (set_attr "length" "7")
14370    (set_attr "memory" "load")
14371    (set_attr "imm_disp" "false")])
14372
14373 (define_insn "*add_tp_di"
14374   [(set (match_operand:DI 0 "register_operand" "=r")
14375         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14376                  (match_operand:DI 1 "register_operand" "0")))
14377    (clobber (reg:CC FLAGS_REG))]
14378   "TARGET_64BIT"
14379   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14380   [(set_attr "type" "alu")
14381    (set_attr "modrm" "0")
14382    (set_attr "length" "7")
14383    (set_attr "memory" "load")
14384    (set_attr "imm_disp" "false")])
14385
14386 ;; GNU2 TLS patterns can be split.
14387
14388 (define_expand "tls_dynamic_gnu2_32"
14389   [(set (match_dup 3)
14390         (plus:SI (match_operand:SI 2 "register_operand" "")
14391                  (const:SI
14392                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14393                              UNSPEC_TLSDESC))))
14394    (parallel
14395     [(set (match_operand:SI 0 "register_operand" "")
14396           (unspec:SI [(match_dup 1) (match_dup 3)
14397                       (match_dup 2) (reg:SI SP_REG)]
14398                       UNSPEC_TLSDESC))
14399      (clobber (reg:CC FLAGS_REG))])]
14400   "!TARGET_64BIT && TARGET_GNU2_TLS"
14401 {
14402   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14403   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14404 })
14405
14406 (define_insn "*tls_dynamic_lea_32"
14407   [(set (match_operand:SI 0 "register_operand" "=r")
14408         (plus:SI (match_operand:SI 1 "register_operand" "b")
14409                  (const:SI
14410                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14411                               UNSPEC_TLSDESC))))]
14412   "!TARGET_64BIT && TARGET_GNU2_TLS"
14413   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14414   [(set_attr "type" "lea")
14415    (set_attr "mode" "SI")
14416    (set_attr "length" "6")
14417    (set_attr "length_address" "4")])
14418
14419 (define_insn "*tls_dynamic_call_32"
14420   [(set (match_operand:SI 0 "register_operand" "=a")
14421         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14422                     (match_operand:SI 2 "register_operand" "0")
14423                     ;; we have to make sure %ebx still points to the GOT
14424                     (match_operand:SI 3 "register_operand" "b")
14425                     (reg:SI SP_REG)]
14426                    UNSPEC_TLSDESC))
14427    (clobber (reg:CC FLAGS_REG))]
14428   "!TARGET_64BIT && TARGET_GNU2_TLS"
14429   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14430   [(set_attr "type" "call")
14431    (set_attr "length" "2")
14432    (set_attr "length_address" "0")])
14433
14434 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14435   [(set (match_operand:SI 0 "register_operand" "=&a")
14436         (plus:SI
14437          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14438                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14439                               (match_operand:SI 5 "" "")
14440                               (match_operand:SI 2 "register_operand" "b")
14441                               (reg:SI SP_REG)]
14442                              UNSPEC_TLSDESC))
14443          (const:SI (unspec:SI
14444                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14445                     UNSPEC_DTPOFF))))
14446    (clobber (reg:CC FLAGS_REG))]
14447   "!TARGET_64BIT && TARGET_GNU2_TLS"
14448   "#"
14449   ""
14450   [(parallel
14451     [(set (match_dup 0)
14452           (plus:SI (match_dup 3)
14453                    (match_dup 5)))
14454      (clobber (reg:CC FLAGS_REG))])]
14455 {
14456   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14457   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14458 })
14459
14460 (define_expand "tls_dynamic_gnu2_64"
14461   [(set (match_dup 2)
14462         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14463                    UNSPEC_TLSDESC))
14464    (parallel
14465     [(set (match_operand:DI 0 "register_operand" "")
14466           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14467                      UNSPEC_TLSDESC))
14468      (clobber (reg:CC FLAGS_REG))])]
14469   "TARGET_64BIT && TARGET_GNU2_TLS"
14470 {
14471   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14472   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14473 })
14474
14475 (define_insn "*tls_dynamic_lea_64"
14476   [(set (match_operand:DI 0 "register_operand" "=r")
14477         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14478                    UNSPEC_TLSDESC))]
14479   "TARGET_64BIT && TARGET_GNU2_TLS"
14480   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14481   [(set_attr "type" "lea")
14482    (set_attr "mode" "DI")
14483    (set_attr "length" "7")
14484    (set_attr "length_address" "4")])
14485
14486 (define_insn "*tls_dynamic_call_64"
14487   [(set (match_operand:DI 0 "register_operand" "=a")
14488         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14489                     (match_operand:DI 2 "register_operand" "0")
14490                     (reg:DI SP_REG)]
14491                    UNSPEC_TLSDESC))
14492    (clobber (reg:CC FLAGS_REG))]
14493   "TARGET_64BIT && TARGET_GNU2_TLS"
14494   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14495   [(set_attr "type" "call")
14496    (set_attr "length" "2")
14497    (set_attr "length_address" "0")])
14498
14499 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14500   [(set (match_operand:DI 0 "register_operand" "=&a")
14501         (plus:DI
14502          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14503                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14504                               (match_operand:DI 4 "" "")
14505                               (reg:DI SP_REG)]
14506                               UNSPEC_TLSDESC))
14507          (const:DI (unspec:DI
14508                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14509                     UNSPEC_DTPOFF))))
14510    (clobber (reg:CC FLAGS_REG))]
14511   "TARGET_64BIT && TARGET_GNU2_TLS"
14512   "#"
14513   ""
14514   [(parallel
14515     [(set (match_dup 0)
14516           (plus:DI (match_dup 2)
14517                    (match_dup 4)))
14518      (clobber (reg:CC FLAGS_REG))])]
14519 {
14520   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14521   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14522 })
14523
14524 ;;
14525 \f
14526 ;; These patterns match the binary 387 instructions for addM3, subM3,
14527 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14528 ;; SFmode.  The first is the normal insn, the second the same insn but
14529 ;; with one operand a conversion, and the third the same insn but with
14530 ;; the other operand a conversion.  The conversion may be SFmode or
14531 ;; SImode if the target mode DFmode, but only SImode if the target mode
14532 ;; is SFmode.
14533
14534 ;; Gcc is slightly more smart about handling normal two address instructions
14535 ;; so use special patterns for add and mull.
14536
14537 (define_insn "*fop_sf_comm_mixed"
14538   [(set (match_operand:SF 0 "register_operand" "=f,x")
14539         (match_operator:SF 3 "binary_fp_operator"
14540                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14541                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14542   "TARGET_MIX_SSE_I387
14543    && COMMUTATIVE_ARITH_P (operands[3])
14544    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14545   "* return output_387_binary_op (insn, operands);"
14546   [(set (attr "type") 
14547         (if_then_else (eq_attr "alternative" "1")
14548            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14549               (const_string "ssemul")
14550               (const_string "sseadd"))
14551            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14552               (const_string "fmul")
14553               (const_string "fop"))))
14554    (set_attr "mode" "SF")])
14555
14556 (define_insn "*fop_sf_comm_sse"
14557   [(set (match_operand:SF 0 "register_operand" "=x")
14558         (match_operator:SF 3 "binary_fp_operator"
14559                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14560                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14561   "TARGET_SSE_MATH
14562    && COMMUTATIVE_ARITH_P (operands[3])
14563    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14564   "* return output_387_binary_op (insn, operands);"
14565   [(set (attr "type") 
14566         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14567            (const_string "ssemul")
14568            (const_string "sseadd")))
14569    (set_attr "mode" "SF")])
14570
14571 (define_insn "*fop_sf_comm_i387"
14572   [(set (match_operand:SF 0 "register_operand" "=f")
14573         (match_operator:SF 3 "binary_fp_operator"
14574                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14575                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14576   "TARGET_80387
14577    && COMMUTATIVE_ARITH_P (operands[3])
14578    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579   "* return output_387_binary_op (insn, operands);"
14580   [(set (attr "type") 
14581         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14582            (const_string "fmul")
14583            (const_string "fop")))
14584    (set_attr "mode" "SF")])
14585
14586 (define_insn "*fop_sf_1_mixed"
14587   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14588         (match_operator:SF 3 "binary_fp_operator"
14589                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14590                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14591   "TARGET_MIX_SSE_I387
14592    && !COMMUTATIVE_ARITH_P (operands[3])
14593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14594   "* return output_387_binary_op (insn, operands);"
14595   [(set (attr "type") 
14596         (cond [(and (eq_attr "alternative" "2")
14597                     (match_operand:SF 3 "mult_operator" ""))
14598                  (const_string "ssemul")
14599                (and (eq_attr "alternative" "2")
14600                     (match_operand:SF 3 "div_operator" ""))
14601                  (const_string "ssediv")
14602                (eq_attr "alternative" "2")
14603                  (const_string "sseadd")
14604                (match_operand:SF 3 "mult_operator" "") 
14605                  (const_string "fmul")
14606                (match_operand:SF 3 "div_operator" "") 
14607                  (const_string "fdiv")
14608               ]
14609               (const_string "fop")))
14610    (set_attr "mode" "SF")])
14611
14612 (define_insn "*fop_sf_1_sse"
14613   [(set (match_operand:SF 0 "register_operand" "=x")
14614         (match_operator:SF 3 "binary_fp_operator"
14615                         [(match_operand:SF 1 "register_operand" "0")
14616                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14617   "TARGET_SSE_MATH
14618    && !COMMUTATIVE_ARITH_P (operands[3])"
14619   "* return output_387_binary_op (insn, operands);"
14620   [(set (attr "type") 
14621         (cond [(match_operand:SF 3 "mult_operator" "")
14622                  (const_string "ssemul")
14623                (match_operand:SF 3 "div_operator" "")
14624                  (const_string "ssediv")
14625               ]
14626               (const_string "sseadd")))
14627    (set_attr "mode" "SF")])
14628
14629 ;; This pattern is not fully shadowed by the pattern above.
14630 (define_insn "*fop_sf_1_i387"
14631   [(set (match_operand:SF 0 "register_operand" "=f,f")
14632         (match_operator:SF 3 "binary_fp_operator"
14633                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14634                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14635   "TARGET_80387 && !TARGET_SSE_MATH
14636    && !COMMUTATIVE_ARITH_P (operands[3])
14637    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14638   "* return output_387_binary_op (insn, operands);"
14639   [(set (attr "type") 
14640         (cond [(match_operand:SF 3 "mult_operator" "") 
14641                  (const_string "fmul")
14642                (match_operand:SF 3 "div_operator" "") 
14643                  (const_string "fdiv")
14644               ]
14645               (const_string "fop")))
14646    (set_attr "mode" "SF")])
14647
14648 ;; ??? Add SSE splitters for these!
14649 (define_insn "*fop_sf_2<mode>_i387"
14650   [(set (match_operand:SF 0 "register_operand" "=f,f")
14651         (match_operator:SF 3 "binary_fp_operator"
14652           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14653            (match_operand:SF 2 "register_operand" "0,0")]))]
14654   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14655   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14656   [(set (attr "type") 
14657         (cond [(match_operand:SF 3 "mult_operator" "") 
14658                  (const_string "fmul")
14659                (match_operand:SF 3 "div_operator" "") 
14660                  (const_string "fdiv")
14661               ]
14662               (const_string "fop")))
14663    (set_attr "fp_int_src" "true")
14664    (set_attr "mode" "<MODE>")])
14665
14666 (define_insn "*fop_sf_3<mode>_i387"
14667   [(set (match_operand:SF 0 "register_operand" "=f,f")
14668         (match_operator:SF 3 "binary_fp_operator"
14669           [(match_operand:SF 1 "register_operand" "0,0")
14670            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14671   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14672   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14673   [(set (attr "type") 
14674         (cond [(match_operand:SF 3 "mult_operator" "") 
14675                  (const_string "fmul")
14676                (match_operand:SF 3 "div_operator" "") 
14677                  (const_string "fdiv")
14678               ]
14679               (const_string "fop")))
14680    (set_attr "fp_int_src" "true")
14681    (set_attr "mode" "<MODE>")])
14682
14683 (define_insn "*fop_df_comm_mixed"
14684   [(set (match_operand:DF 0 "register_operand" "=f,Y")
14685         (match_operator:DF 3 "binary_fp_operator"
14686                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14687                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14688   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14689    && COMMUTATIVE_ARITH_P (operands[3])
14690    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14691   "* return output_387_binary_op (insn, operands);"
14692   [(set (attr "type") 
14693         (if_then_else (eq_attr "alternative" "1")
14694            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14695               (const_string "ssemul")
14696               (const_string "sseadd"))
14697            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14698               (const_string "fmul")
14699               (const_string "fop"))))
14700    (set_attr "mode" "DF")])
14701
14702 (define_insn "*fop_df_comm_sse"
14703   [(set (match_operand:DF 0 "register_operand" "=Y")
14704         (match_operator:DF 3 "binary_fp_operator"
14705                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14706                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14707   "TARGET_SSE2 && TARGET_SSE_MATH
14708    && COMMUTATIVE_ARITH_P (operands[3])
14709    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14710   "* return output_387_binary_op (insn, operands);"
14711   [(set (attr "type") 
14712         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14713            (const_string "ssemul")
14714            (const_string "sseadd")))
14715    (set_attr "mode" "DF")])
14716
14717 (define_insn "*fop_df_comm_i387"
14718   [(set (match_operand:DF 0 "register_operand" "=f")
14719         (match_operator:DF 3 "binary_fp_operator"
14720                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14721                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14722   "TARGET_80387
14723    && COMMUTATIVE_ARITH_P (operands[3])
14724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14725   "* return output_387_binary_op (insn, operands);"
14726   [(set (attr "type") 
14727         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14728            (const_string "fmul")
14729            (const_string "fop")))
14730    (set_attr "mode" "DF")])
14731
14732 (define_insn "*fop_df_1_mixed"
14733   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14734         (match_operator:DF 3 "binary_fp_operator"
14735                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14736                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14737   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14738    && !COMMUTATIVE_ARITH_P (operands[3])
14739    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14740   "* return output_387_binary_op (insn, operands);"
14741   [(set (attr "type") 
14742         (cond [(and (eq_attr "alternative" "2")
14743                     (match_operand:SF 3 "mult_operator" ""))
14744                  (const_string "ssemul")
14745                (and (eq_attr "alternative" "2")
14746                     (match_operand:SF 3 "div_operator" ""))
14747                  (const_string "ssediv")
14748                (eq_attr "alternative" "2")
14749                  (const_string "sseadd")
14750                (match_operand:DF 3 "mult_operator" "") 
14751                  (const_string "fmul")
14752                (match_operand:DF 3 "div_operator" "") 
14753                  (const_string "fdiv")
14754               ]
14755               (const_string "fop")))
14756    (set_attr "mode" "DF")])
14757
14758 (define_insn "*fop_df_1_sse"
14759   [(set (match_operand:DF 0 "register_operand" "=Y")
14760         (match_operator:DF 3 "binary_fp_operator"
14761                         [(match_operand:DF 1 "register_operand" "0")
14762                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14763   "TARGET_SSE2 && TARGET_SSE_MATH
14764    && !COMMUTATIVE_ARITH_P (operands[3])"
14765   "* return output_387_binary_op (insn, operands);"
14766   [(set_attr "mode" "DF")
14767    (set (attr "type") 
14768         (cond [(match_operand:SF 3 "mult_operator" "")
14769                  (const_string "ssemul")
14770                (match_operand:SF 3 "div_operator" "")
14771                  (const_string "ssediv")
14772               ]
14773               (const_string "sseadd")))])
14774
14775 ;; This pattern is not fully shadowed by the pattern above.
14776 (define_insn "*fop_df_1_i387"
14777   [(set (match_operand:DF 0 "register_operand" "=f,f")
14778         (match_operator:DF 3 "binary_fp_operator"
14779                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14780                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14781   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14782    && !COMMUTATIVE_ARITH_P (operands[3])
14783    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14784   "* return output_387_binary_op (insn, operands);"
14785   [(set (attr "type") 
14786         (cond [(match_operand:DF 3 "mult_operator" "") 
14787                  (const_string "fmul")
14788                (match_operand:DF 3 "div_operator" "")
14789                  (const_string "fdiv")
14790               ]
14791               (const_string "fop")))
14792    (set_attr "mode" "DF")])
14793
14794 ;; ??? Add SSE splitters for these!
14795 (define_insn "*fop_df_2<mode>_i387"
14796   [(set (match_operand:DF 0 "register_operand" "=f,f")
14797         (match_operator:DF 3 "binary_fp_operator"
14798            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14799             (match_operand:DF 2 "register_operand" "0,0")]))]
14800   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14801    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14802   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14803   [(set (attr "type") 
14804         (cond [(match_operand:DF 3 "mult_operator" "") 
14805                  (const_string "fmul")
14806                (match_operand:DF 3 "div_operator" "") 
14807                  (const_string "fdiv")
14808               ]
14809               (const_string "fop")))
14810    (set_attr "fp_int_src" "true")
14811    (set_attr "mode" "<MODE>")])
14812
14813 (define_insn "*fop_df_3<mode>_i387"
14814   [(set (match_operand:DF 0 "register_operand" "=f,f")
14815         (match_operator:DF 3 "binary_fp_operator"
14816            [(match_operand:DF 1 "register_operand" "0,0")
14817             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14818   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14819    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14820   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14821   [(set (attr "type") 
14822         (cond [(match_operand:DF 3 "mult_operator" "") 
14823                  (const_string "fmul")
14824                (match_operand:DF 3 "div_operator" "") 
14825                  (const_string "fdiv")
14826               ]
14827               (const_string "fop")))
14828    (set_attr "fp_int_src" "true")
14829    (set_attr "mode" "<MODE>")])
14830
14831 (define_insn "*fop_df_4_i387"
14832   [(set (match_operand:DF 0 "register_operand" "=f,f")
14833         (match_operator:DF 3 "binary_fp_operator"
14834            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14835             (match_operand:DF 2 "register_operand" "0,f")]))]
14836   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14837    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14838   "* return output_387_binary_op (insn, operands);"
14839   [(set (attr "type") 
14840         (cond [(match_operand:DF 3 "mult_operator" "") 
14841                  (const_string "fmul")
14842                (match_operand:DF 3 "div_operator" "") 
14843                  (const_string "fdiv")
14844               ]
14845               (const_string "fop")))
14846    (set_attr "mode" "SF")])
14847
14848 (define_insn "*fop_df_5_i387"
14849   [(set (match_operand:DF 0 "register_operand" "=f,f")
14850         (match_operator:DF 3 "binary_fp_operator"
14851           [(match_operand:DF 1 "register_operand" "0,f")
14852            (float_extend:DF
14853             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14854   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14855   "* return output_387_binary_op (insn, operands);"
14856   [(set (attr "type") 
14857         (cond [(match_operand:DF 3 "mult_operator" "") 
14858                  (const_string "fmul")
14859                (match_operand:DF 3 "div_operator" "") 
14860                  (const_string "fdiv")
14861               ]
14862               (const_string "fop")))
14863    (set_attr "mode" "SF")])
14864
14865 (define_insn "*fop_df_6_i387"
14866   [(set (match_operand:DF 0 "register_operand" "=f,f")
14867         (match_operator:DF 3 "binary_fp_operator"
14868           [(float_extend:DF
14869             (match_operand:SF 1 "register_operand" "0,f"))
14870            (float_extend:DF
14871             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14872   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14873   "* return output_387_binary_op (insn, operands);"
14874   [(set (attr "type") 
14875         (cond [(match_operand:DF 3 "mult_operator" "") 
14876                  (const_string "fmul")
14877                (match_operand:DF 3 "div_operator" "") 
14878                  (const_string "fdiv")
14879               ]
14880               (const_string "fop")))
14881    (set_attr "mode" "SF")])
14882
14883 (define_insn "*fop_xf_comm_i387"
14884   [(set (match_operand:XF 0 "register_operand" "=f")
14885         (match_operator:XF 3 "binary_fp_operator"
14886                         [(match_operand:XF 1 "register_operand" "%0")
14887                          (match_operand:XF 2 "register_operand" "f")]))]
14888   "TARGET_80387
14889    && COMMUTATIVE_ARITH_P (operands[3])"
14890   "* return output_387_binary_op (insn, operands);"
14891   [(set (attr "type") 
14892         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14893            (const_string "fmul")
14894            (const_string "fop")))
14895    (set_attr "mode" "XF")])
14896
14897 (define_insn "*fop_xf_1_i387"
14898   [(set (match_operand:XF 0 "register_operand" "=f,f")
14899         (match_operator:XF 3 "binary_fp_operator"
14900                         [(match_operand:XF 1 "register_operand" "0,f")
14901                          (match_operand:XF 2 "register_operand" "f,0")]))]
14902   "TARGET_80387
14903    && !COMMUTATIVE_ARITH_P (operands[3])"
14904   "* return output_387_binary_op (insn, operands);"
14905   [(set (attr "type") 
14906         (cond [(match_operand:XF 3 "mult_operator" "") 
14907                  (const_string "fmul")
14908                (match_operand:XF 3 "div_operator" "") 
14909                  (const_string "fdiv")
14910               ]
14911               (const_string "fop")))
14912    (set_attr "mode" "XF")])
14913
14914 (define_insn "*fop_xf_2<mode>_i387"
14915   [(set (match_operand:XF 0 "register_operand" "=f,f")
14916         (match_operator:XF 3 "binary_fp_operator"
14917            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14918             (match_operand:XF 2 "register_operand" "0,0")]))]
14919   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14920   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14921   [(set (attr "type") 
14922         (cond [(match_operand:XF 3 "mult_operator" "") 
14923                  (const_string "fmul")
14924                (match_operand:XF 3 "div_operator" "") 
14925                  (const_string "fdiv")
14926               ]
14927               (const_string "fop")))
14928    (set_attr "fp_int_src" "true")
14929    (set_attr "mode" "<MODE>")])
14930
14931 (define_insn "*fop_xf_3<mode>_i387"
14932   [(set (match_operand:XF 0 "register_operand" "=f,f")
14933         (match_operator:XF 3 "binary_fp_operator"
14934           [(match_operand:XF 1 "register_operand" "0,0")
14935            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14936   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14937   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14938   [(set (attr "type") 
14939         (cond [(match_operand:XF 3 "mult_operator" "") 
14940                  (const_string "fmul")
14941                (match_operand:XF 3 "div_operator" "") 
14942                  (const_string "fdiv")
14943               ]
14944               (const_string "fop")))
14945    (set_attr "fp_int_src" "true")
14946    (set_attr "mode" "<MODE>")])
14947
14948 (define_insn "*fop_xf_4_i387"
14949   [(set (match_operand:XF 0 "register_operand" "=f,f")
14950         (match_operator:XF 3 "binary_fp_operator"
14951            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14952             (match_operand:XF 2 "register_operand" "0,f")]))]
14953   "TARGET_80387"
14954   "* return output_387_binary_op (insn, operands);"
14955   [(set (attr "type") 
14956         (cond [(match_operand:XF 3 "mult_operator" "") 
14957                  (const_string "fmul")
14958                (match_operand:XF 3 "div_operator" "") 
14959                  (const_string "fdiv")
14960               ]
14961               (const_string "fop")))
14962    (set_attr "mode" "SF")])
14963
14964 (define_insn "*fop_xf_5_i387"
14965   [(set (match_operand:XF 0 "register_operand" "=f,f")
14966         (match_operator:XF 3 "binary_fp_operator"
14967           [(match_operand:XF 1 "register_operand" "0,f")
14968            (float_extend:XF
14969             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14970   "TARGET_80387"
14971   "* return output_387_binary_op (insn, operands);"
14972   [(set (attr "type") 
14973         (cond [(match_operand:XF 3 "mult_operator" "") 
14974                  (const_string "fmul")
14975                (match_operand:XF 3 "div_operator" "") 
14976                  (const_string "fdiv")
14977               ]
14978               (const_string "fop")))
14979    (set_attr "mode" "SF")])
14980
14981 (define_insn "*fop_xf_6_i387"
14982   [(set (match_operand:XF 0 "register_operand" "=f,f")
14983         (match_operator:XF 3 "binary_fp_operator"
14984           [(float_extend:XF
14985             (match_operand 1 "register_operand" "0,f"))
14986            (float_extend:XF
14987             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14988   "TARGET_80387"
14989   "* return output_387_binary_op (insn, operands);"
14990   [(set (attr "type") 
14991         (cond [(match_operand:XF 3 "mult_operator" "") 
14992                  (const_string "fmul")
14993                (match_operand:XF 3 "div_operator" "") 
14994                  (const_string "fdiv")
14995               ]
14996               (const_string "fop")))
14997    (set_attr "mode" "SF")])
14998
14999 (define_split
15000   [(set (match_operand 0 "register_operand" "")
15001         (match_operator 3 "binary_fp_operator"
15002            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15003             (match_operand 2 "register_operand" "")]))]
15004   "TARGET_80387 && reload_completed
15005    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15006   [(const_int 0)]
15007
15008   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15009   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15010   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15011                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15012                                           GET_MODE (operands[3]),
15013                                           operands[4],
15014                                           operands[2])));
15015   ix86_free_from_memory (GET_MODE (operands[1]));
15016   DONE;
15017 })
15018
15019 (define_split
15020   [(set (match_operand 0 "register_operand" "")
15021         (match_operator 3 "binary_fp_operator"
15022            [(match_operand 1 "register_operand" "")
15023             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15024   "TARGET_80387 && reload_completed
15025    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15026   [(const_int 0)]
15027 {
15028   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15029   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15030   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15031                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15032                                           GET_MODE (operands[3]),
15033                                           operands[1],
15034                                           operands[4])));
15035   ix86_free_from_memory (GET_MODE (operands[2]));
15036   DONE;
15037 })
15038 \f
15039 ;; FPU special functions.
15040
15041 (define_expand "sqrtsf2"
15042   [(set (match_operand:SF 0 "register_operand" "")
15043         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15044   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15045 {
15046   if (!TARGET_SSE_MATH)
15047     operands[1] = force_reg (SFmode, operands[1]);
15048 })
15049
15050 (define_insn "*sqrtsf2_mixed"
15051   [(set (match_operand:SF 0 "register_operand" "=f,x")
15052         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15053   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15054   "@
15055    fsqrt
15056    sqrtss\t{%1, %0|%0, %1}"
15057   [(set_attr "type" "fpspc,sse")
15058    (set_attr "mode" "SF,SF")
15059    (set_attr "athlon_decode" "direct,*")])
15060
15061 (define_insn "*sqrtsf2_sse"
15062   [(set (match_operand:SF 0 "register_operand" "=x")
15063         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15064   "TARGET_SSE_MATH"
15065   "sqrtss\t{%1, %0|%0, %1}"
15066   [(set_attr "type" "sse")
15067    (set_attr "mode" "SF")
15068    (set_attr "athlon_decode" "*")])
15069
15070 (define_insn "*sqrtsf2_i387"
15071   [(set (match_operand:SF 0 "register_operand" "=f")
15072         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15073   "TARGET_USE_FANCY_MATH_387"
15074   "fsqrt"
15075   [(set_attr "type" "fpspc")
15076    (set_attr "mode" "SF")
15077    (set_attr "athlon_decode" "direct")])
15078
15079 (define_expand "sqrtdf2"
15080   [(set (match_operand:DF 0 "register_operand" "")
15081         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15082   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15083 {
15084   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15085     operands[1] = force_reg (DFmode, operands[1]);
15086 })
15087
15088 (define_insn "*sqrtdf2_mixed"
15089   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15090         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15091   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15092   "@
15093    fsqrt
15094    sqrtsd\t{%1, %0|%0, %1}"
15095   [(set_attr "type" "fpspc,sse")
15096    (set_attr "mode" "DF,DF")
15097    (set_attr "athlon_decode" "direct,*")])
15098
15099 (define_insn "*sqrtdf2_sse"
15100   [(set (match_operand:DF 0 "register_operand" "=Y")
15101         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15102   "TARGET_SSE2 && TARGET_SSE_MATH"
15103   "sqrtsd\t{%1, %0|%0, %1}"
15104   [(set_attr "type" "sse")
15105    (set_attr "mode" "DF")
15106    (set_attr "athlon_decode" "*")])
15107
15108 (define_insn "*sqrtdf2_i387"
15109   [(set (match_operand:DF 0 "register_operand" "=f")
15110         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15111   "TARGET_USE_FANCY_MATH_387"
15112   "fsqrt"
15113   [(set_attr "type" "fpspc")
15114    (set_attr "mode" "DF")
15115    (set_attr "athlon_decode" "direct")])
15116
15117 (define_insn "*sqrtextendsfdf2_i387"
15118   [(set (match_operand:DF 0 "register_operand" "=f")
15119         (sqrt:DF (float_extend:DF
15120                   (match_operand:SF 1 "register_operand" "0"))))]
15121   "TARGET_USE_FANCY_MATH_387
15122    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15123   "fsqrt"
15124   [(set_attr "type" "fpspc")
15125    (set_attr "mode" "DF")
15126    (set_attr "athlon_decode" "direct")])
15127
15128 (define_insn "sqrtxf2"
15129   [(set (match_operand:XF 0 "register_operand" "=f")
15130         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15131   "TARGET_USE_FANCY_MATH_387 
15132    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15133   "fsqrt"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "XF")
15136    (set_attr "athlon_decode" "direct")])
15137
15138 (define_insn "*sqrtextendsfxf2_i387"
15139   [(set (match_operand:XF 0 "register_operand" "=f")
15140         (sqrt:XF (float_extend:XF
15141                   (match_operand:SF 1 "register_operand" "0"))))]
15142   "TARGET_USE_FANCY_MATH_387"
15143   "fsqrt"
15144   [(set_attr "type" "fpspc")
15145    (set_attr "mode" "XF")
15146    (set_attr "athlon_decode" "direct")])
15147
15148 (define_insn "*sqrtextenddfxf2_i387"
15149   [(set (match_operand:XF 0 "register_operand" "=f")
15150         (sqrt:XF (float_extend:XF
15151                   (match_operand:DF 1 "register_operand" "0"))))]
15152   "TARGET_USE_FANCY_MATH_387"
15153   "fsqrt"
15154   [(set_attr "type" "fpspc")
15155    (set_attr "mode" "XF")
15156    (set_attr "athlon_decode" "direct")])
15157
15158 (define_insn "fpremxf4"
15159   [(set (match_operand:XF 0 "register_operand" "=f")
15160         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15161                     (match_operand:XF 3 "register_operand" "1")]
15162                    UNSPEC_FPREM_F))
15163    (set (match_operand:XF 1 "register_operand" "=u")
15164         (unspec:XF [(match_dup 2) (match_dup 3)]
15165                    UNSPEC_FPREM_U))
15166    (set (reg:CCFP FPSR_REG)
15167         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_unsafe_math_optimizations"
15170   "fprem"
15171   [(set_attr "type" "fpspc")
15172    (set_attr "mode" "XF")])
15173
15174 (define_expand "fmodsf3"
15175   [(use (match_operand:SF 0 "register_operand" ""))
15176    (use (match_operand:SF 1 "register_operand" ""))
15177    (use (match_operand:SF 2 "register_operand" ""))]
15178   "TARGET_USE_FANCY_MATH_387
15179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180    && flag_unsafe_math_optimizations"
15181 {
15182   rtx label = gen_label_rtx ();
15183
15184   rtx op1 = gen_reg_rtx (XFmode);
15185   rtx op2 = gen_reg_rtx (XFmode);
15186
15187   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15188   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15189
15190   emit_label (label);
15191
15192   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15193   ix86_emit_fp_unordered_jump (label);
15194
15195   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15196   DONE;
15197 })
15198
15199 (define_expand "fmoddf3"
15200   [(use (match_operand:DF 0 "register_operand" ""))
15201    (use (match_operand:DF 1 "register_operand" ""))
15202    (use (match_operand:DF 2 "register_operand" ""))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15205    && flag_unsafe_math_optimizations"
15206 {
15207   rtx label = gen_label_rtx ();
15208
15209   rtx op1 = gen_reg_rtx (XFmode);
15210   rtx op2 = gen_reg_rtx (XFmode);
15211
15212   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15213   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15214
15215   emit_label (label);
15216
15217   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15218   ix86_emit_fp_unordered_jump (label);
15219
15220   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15221   DONE;
15222 })
15223
15224 (define_expand "fmodxf3"
15225   [(use (match_operand:XF 0 "register_operand" ""))
15226    (use (match_operand:XF 1 "register_operand" ""))
15227    (use (match_operand:XF 2 "register_operand" ""))]
15228   "TARGET_USE_FANCY_MATH_387
15229    && flag_unsafe_math_optimizations"
15230 {
15231   rtx label = gen_label_rtx ();
15232
15233   emit_label (label);
15234
15235   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15236                            operands[1], operands[2]));
15237   ix86_emit_fp_unordered_jump (label);
15238
15239   emit_move_insn (operands[0], operands[1]);
15240   DONE;
15241 })
15242
15243 (define_insn "fprem1xf4"
15244   [(set (match_operand:XF 0 "register_operand" "=f")
15245         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15246                     (match_operand:XF 3 "register_operand" "1")]
15247                    UNSPEC_FPREM1_F))
15248    (set (match_operand:XF 1 "register_operand" "=u")
15249         (unspec:XF [(match_dup 2) (match_dup 3)]
15250                    UNSPEC_FPREM1_U))
15251    (set (reg:CCFP FPSR_REG)
15252         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15253   "TARGET_USE_FANCY_MATH_387
15254    && flag_unsafe_math_optimizations"
15255   "fprem1"
15256   [(set_attr "type" "fpspc")
15257    (set_attr "mode" "XF")])
15258
15259 (define_expand "dremsf3"
15260   [(use (match_operand:SF 0 "register_operand" ""))
15261    (use (match_operand:SF 1 "register_operand" ""))
15262    (use (match_operand:SF 2 "register_operand" ""))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15265    && flag_unsafe_math_optimizations"
15266 {
15267   rtx label = gen_label_rtx ();
15268
15269   rtx op1 = gen_reg_rtx (XFmode);
15270   rtx op2 = gen_reg_rtx (XFmode);
15271
15272   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15273   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15274
15275   emit_label (label);
15276
15277   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15278   ix86_emit_fp_unordered_jump (label);
15279
15280   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15281   DONE;
15282 })
15283
15284 (define_expand "dremdf3"
15285   [(use (match_operand:DF 0 "register_operand" ""))
15286    (use (match_operand:DF 1 "register_operand" ""))
15287    (use (match_operand:DF 2 "register_operand" ""))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15290    && flag_unsafe_math_optimizations"
15291 {
15292   rtx label = gen_label_rtx ();
15293
15294   rtx op1 = gen_reg_rtx (XFmode);
15295   rtx op2 = gen_reg_rtx (XFmode);
15296
15297   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15298   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15299
15300   emit_label (label);
15301
15302   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15303   ix86_emit_fp_unordered_jump (label);
15304
15305   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15306   DONE;
15307 })
15308
15309 (define_expand "dremxf3"
15310   [(use (match_operand:XF 0 "register_operand" ""))
15311    (use (match_operand:XF 1 "register_operand" ""))
15312    (use (match_operand:XF 2 "register_operand" ""))]
15313   "TARGET_USE_FANCY_MATH_387
15314    && flag_unsafe_math_optimizations"
15315 {
15316   rtx label = gen_label_rtx ();
15317
15318   emit_label (label);
15319
15320   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15321                             operands[1], operands[2]));
15322   ix86_emit_fp_unordered_jump (label);
15323
15324   emit_move_insn (operands[0], operands[1]);
15325   DONE;
15326 })
15327
15328 (define_insn "*sindf2"
15329   [(set (match_operand:DF 0 "register_operand" "=f")
15330         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15333    && flag_unsafe_math_optimizations"
15334   "fsin"
15335   [(set_attr "type" "fpspc")
15336    (set_attr "mode" "DF")])
15337
15338 (define_insn "*sinsf2"
15339   [(set (match_operand:SF 0 "register_operand" "=f")
15340         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15341   "TARGET_USE_FANCY_MATH_387
15342    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15343    && flag_unsafe_math_optimizations"
15344   "fsin"
15345   [(set_attr "type" "fpspc")
15346    (set_attr "mode" "SF")])
15347
15348 (define_insn "*sinextendsfdf2"
15349   [(set (match_operand:DF 0 "register_operand" "=f")
15350         (unspec:DF [(float_extend:DF
15351                      (match_operand:SF 1 "register_operand" "0"))]
15352                    UNSPEC_SIN))]
15353   "TARGET_USE_FANCY_MATH_387
15354    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15355    && flag_unsafe_math_optimizations"
15356   "fsin"
15357   [(set_attr "type" "fpspc")
15358    (set_attr "mode" "DF")])
15359
15360 (define_insn "*sinxf2"
15361   [(set (match_operand:XF 0 "register_operand" "=f")
15362         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && flag_unsafe_math_optimizations"
15365   "fsin"
15366   [(set_attr "type" "fpspc")
15367    (set_attr "mode" "XF")])
15368
15369 (define_insn "*cosdf2"
15370   [(set (match_operand:DF 0 "register_operand" "=f")
15371         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374    && flag_unsafe_math_optimizations"
15375   "fcos"
15376   [(set_attr "type" "fpspc")
15377    (set_attr "mode" "DF")])
15378
15379 (define_insn "*cossf2"
15380   [(set (match_operand:SF 0 "register_operand" "=f")
15381         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15382   "TARGET_USE_FANCY_MATH_387
15383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15384    && flag_unsafe_math_optimizations"
15385   "fcos"
15386   [(set_attr "type" "fpspc")
15387    (set_attr "mode" "SF")])
15388
15389 (define_insn "*cosextendsfdf2"
15390   [(set (match_operand:DF 0 "register_operand" "=f")
15391         (unspec:DF [(float_extend:DF
15392                      (match_operand:SF 1 "register_operand" "0"))]
15393                    UNSPEC_COS))]
15394   "TARGET_USE_FANCY_MATH_387
15395    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15396    && flag_unsafe_math_optimizations"
15397   "fcos"
15398   [(set_attr "type" "fpspc")
15399    (set_attr "mode" "DF")])
15400
15401 (define_insn "*cosxf2"
15402   [(set (match_operand:XF 0 "register_operand" "=f")
15403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && flag_unsafe_math_optimizations"
15406   "fcos"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "XF")])
15409
15410 ;; With sincos pattern defined, sin and cos builtin function will be
15411 ;; expanded to sincos pattern with one of its outputs left unused. 
15412 ;; Cse pass  will detected, if two sincos patterns can be combined,
15413 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15414 ;; depending on the unused output.
15415
15416 (define_insn "sincosdf3"
15417   [(set (match_operand:DF 0 "register_operand" "=f")
15418         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15419                    UNSPEC_SINCOS_COS))
15420    (set (match_operand:DF 1 "register_operand" "=u")
15421         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424    && flag_unsafe_math_optimizations"
15425   "fsincos"
15426   [(set_attr "type" "fpspc")
15427    (set_attr "mode" "DF")])
15428
15429 (define_split
15430   [(set (match_operand:DF 0 "register_operand" "")
15431         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15432                    UNSPEC_SINCOS_COS))
15433    (set (match_operand:DF 1 "register_operand" "")
15434         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15436    && !reload_completed && !reload_in_progress"
15437   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15438   "")
15439
15440 (define_split
15441   [(set (match_operand:DF 0 "register_operand" "")
15442         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15443                    UNSPEC_SINCOS_COS))
15444    (set (match_operand:DF 1 "register_operand" "")
15445         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15446   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15447    && !reload_completed && !reload_in_progress"
15448   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15449   "")
15450
15451 (define_insn "sincossf3"
15452   [(set (match_operand:SF 0 "register_operand" "=f")
15453         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15454                    UNSPEC_SINCOS_COS))
15455    (set (match_operand:SF 1 "register_operand" "=u")
15456         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459    && flag_unsafe_math_optimizations"
15460   "fsincos"
15461   [(set_attr "type" "fpspc")
15462    (set_attr "mode" "SF")])
15463
15464 (define_split
15465   [(set (match_operand:SF 0 "register_operand" "")
15466         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15467                    UNSPEC_SINCOS_COS))
15468    (set (match_operand:SF 1 "register_operand" "")
15469         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15470   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15471    && !reload_completed && !reload_in_progress"
15472   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15473   "")
15474
15475 (define_split
15476   [(set (match_operand:SF 0 "register_operand" "")
15477         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15478                    UNSPEC_SINCOS_COS))
15479    (set (match_operand:SF 1 "register_operand" "")
15480         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15481   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15482    && !reload_completed && !reload_in_progress"
15483   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15484   "")
15485
15486 (define_insn "*sincosextendsfdf3"
15487   [(set (match_operand:DF 0 "register_operand" "=f")
15488         (unspec:DF [(float_extend:DF
15489                      (match_operand:SF 2 "register_operand" "0"))]
15490                    UNSPEC_SINCOS_COS))
15491    (set (match_operand:DF 1 "register_operand" "=u")
15492         (unspec:DF [(float_extend:DF
15493                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496    && flag_unsafe_math_optimizations"
15497   "fsincos"
15498   [(set_attr "type" "fpspc")
15499    (set_attr "mode" "DF")])
15500
15501 (define_split
15502   [(set (match_operand:DF 0 "register_operand" "")
15503         (unspec:DF [(float_extend:DF
15504                      (match_operand:SF 2 "register_operand" ""))]
15505                    UNSPEC_SINCOS_COS))
15506    (set (match_operand:DF 1 "register_operand" "")
15507         (unspec:DF [(float_extend:DF
15508                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15509   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15510    && !reload_completed && !reload_in_progress"
15511   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15512                                    (match_dup 2))] UNSPEC_SIN))]
15513   "")
15514
15515 (define_split
15516   [(set (match_operand:DF 0 "register_operand" "")
15517         (unspec:DF [(float_extend:DF
15518                      (match_operand:SF 2 "register_operand" ""))]
15519                    UNSPEC_SINCOS_COS))
15520    (set (match_operand:DF 1 "register_operand" "")
15521         (unspec:DF [(float_extend:DF
15522                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15523   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15524    && !reload_completed && !reload_in_progress"
15525   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15526                                    (match_dup 2))] UNSPEC_COS))]
15527   "")
15528
15529 (define_insn "sincosxf3"
15530   [(set (match_operand:XF 0 "register_operand" "=f")
15531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15532                    UNSPEC_SINCOS_COS))
15533    (set (match_operand:XF 1 "register_operand" "=u")
15534         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15535   "TARGET_USE_FANCY_MATH_387
15536    && flag_unsafe_math_optimizations"
15537   "fsincos"
15538   [(set_attr "type" "fpspc")
15539    (set_attr "mode" "XF")])
15540
15541 (define_split
15542   [(set (match_operand:XF 0 "register_operand" "")
15543         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15544                    UNSPEC_SINCOS_COS))
15545    (set (match_operand:XF 1 "register_operand" "")
15546         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15547   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15548    && !reload_completed && !reload_in_progress"
15549   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15550   "")
15551
15552 (define_split
15553   [(set (match_operand:XF 0 "register_operand" "")
15554         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15555                    UNSPEC_SINCOS_COS))
15556    (set (match_operand:XF 1 "register_operand" "")
15557         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15558   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15559    && !reload_completed && !reload_in_progress"
15560   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15561   "")
15562
15563 (define_insn "*tandf3_1"
15564   [(set (match_operand:DF 0 "register_operand" "=f")
15565         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15566                    UNSPEC_TAN_ONE))
15567    (set (match_operand:DF 1 "register_operand" "=u")
15568         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15569   "TARGET_USE_FANCY_MATH_387
15570    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15571    && flag_unsafe_math_optimizations"
15572   "fptan"
15573   [(set_attr "type" "fpspc")
15574    (set_attr "mode" "DF")])
15575
15576 ;; optimize sequence: fptan
15577 ;;                    fstp    %st(0)
15578 ;;                    fld1
15579 ;; into fptan insn.
15580
15581 (define_peephole2
15582   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15583                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15584                              UNSPEC_TAN_ONE))
15585              (set (match_operand:DF 1 "register_operand" "")
15586                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15587    (set (match_dup 0)
15588         (match_operand:DF 3 "immediate_operand" ""))]
15589   "standard_80387_constant_p (operands[3]) == 2"
15590   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15591              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15592   "")
15593
15594 (define_expand "tandf2"
15595   [(parallel [(set (match_dup 2)
15596                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15597                               UNSPEC_TAN_ONE))
15598               (set (match_operand:DF 0 "register_operand" "")
15599                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15600   "TARGET_USE_FANCY_MATH_387
15601    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15602    && flag_unsafe_math_optimizations"
15603 {
15604   operands[2] = gen_reg_rtx (DFmode);
15605 })
15606
15607 (define_insn "*tansf3_1"
15608   [(set (match_operand:SF 0 "register_operand" "=f")
15609         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15610                    UNSPEC_TAN_ONE))
15611    (set (match_operand:SF 1 "register_operand" "=u")
15612         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15615    && flag_unsafe_math_optimizations"
15616   "fptan"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "SF")])
15619
15620 ;; optimize sequence: fptan
15621 ;;                    fstp    %st(0)
15622 ;;                    fld1
15623 ;; into fptan insn.
15624
15625 (define_peephole2
15626   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15627                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15628                              UNSPEC_TAN_ONE))
15629              (set (match_operand:SF 1 "register_operand" "")
15630                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15631    (set (match_dup 0)
15632         (match_operand:SF 3 "immediate_operand" ""))]
15633   "standard_80387_constant_p (operands[3]) == 2"
15634   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15635              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15636   "")
15637
15638 (define_expand "tansf2"
15639   [(parallel [(set (match_dup 2)
15640                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15641                               UNSPEC_TAN_ONE))
15642               (set (match_operand:SF 0 "register_operand" "")
15643                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15644   "TARGET_USE_FANCY_MATH_387
15645    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646    && flag_unsafe_math_optimizations"
15647 {
15648   operands[2] = gen_reg_rtx (SFmode);
15649 })
15650
15651 (define_insn "*tanxf3_1"
15652   [(set (match_operand:XF 0 "register_operand" "=f")
15653         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15654                    UNSPEC_TAN_ONE))
15655    (set (match_operand:XF 1 "register_operand" "=u")
15656         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15657   "TARGET_USE_FANCY_MATH_387
15658    && flag_unsafe_math_optimizations"
15659   "fptan"
15660   [(set_attr "type" "fpspc")
15661    (set_attr "mode" "XF")])
15662
15663 ;; optimize sequence: fptan
15664 ;;                    fstp    %st(0)
15665 ;;                    fld1
15666 ;; into fptan insn.
15667
15668 (define_peephole2
15669   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15670                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15671                              UNSPEC_TAN_ONE))
15672              (set (match_operand:XF 1 "register_operand" "")
15673                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15674    (set (match_dup 0)
15675         (match_operand:XF 3 "immediate_operand" ""))]
15676   "standard_80387_constant_p (operands[3]) == 2"
15677   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15678              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15679   "")
15680
15681 (define_expand "tanxf2"
15682   [(parallel [(set (match_dup 2)
15683                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15684                               UNSPEC_TAN_ONE))
15685               (set (match_operand:XF 0 "register_operand" "")
15686                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15687   "TARGET_USE_FANCY_MATH_387
15688    && flag_unsafe_math_optimizations"
15689 {
15690   operands[2] = gen_reg_rtx (XFmode);
15691 })
15692
15693 (define_insn "atan2df3_1"
15694   [(set (match_operand:DF 0 "register_operand" "=f")
15695         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15696                     (match_operand:DF 1 "register_operand" "u")]
15697                    UNSPEC_FPATAN))
15698    (clobber (match_scratch:DF 3 "=1"))]
15699   "TARGET_USE_FANCY_MATH_387
15700    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15701    && flag_unsafe_math_optimizations"
15702   "fpatan"
15703   [(set_attr "type" "fpspc")
15704    (set_attr "mode" "DF")])
15705
15706 (define_expand "atan2df3"
15707   [(use (match_operand:DF 0 "register_operand" ""))
15708    (use (match_operand:DF 2 "register_operand" ""))
15709    (use (match_operand:DF 1 "register_operand" ""))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15712    && flag_unsafe_math_optimizations"
15713 {
15714   rtx copy = gen_reg_rtx (DFmode);
15715   emit_move_insn (copy, operands[1]);
15716   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15717   DONE;
15718 })
15719
15720 (define_expand "atandf2"
15721   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15722                    (unspec:DF [(match_dup 2)
15723                                (match_operand:DF 1 "register_operand" "")]
15724                     UNSPEC_FPATAN))
15725               (clobber (match_scratch:DF 3 ""))])]
15726   "TARGET_USE_FANCY_MATH_387
15727    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728    && flag_unsafe_math_optimizations"
15729 {
15730   operands[2] = gen_reg_rtx (DFmode);
15731   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15732 })
15733
15734 (define_insn "atan2sf3_1"
15735   [(set (match_operand:SF 0 "register_operand" "=f")
15736         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15737                     (match_operand:SF 1 "register_operand" "u")]
15738                    UNSPEC_FPATAN))
15739    (clobber (match_scratch:SF 3 "=1"))]
15740   "TARGET_USE_FANCY_MATH_387
15741    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15742    && flag_unsafe_math_optimizations"
15743   "fpatan"
15744   [(set_attr "type" "fpspc")
15745    (set_attr "mode" "SF")])
15746
15747 (define_expand "atan2sf3"
15748   [(use (match_operand:SF 0 "register_operand" ""))
15749    (use (match_operand:SF 2 "register_operand" ""))
15750    (use (match_operand:SF 1 "register_operand" ""))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations"
15754 {
15755   rtx copy = gen_reg_rtx (SFmode);
15756   emit_move_insn (copy, operands[1]);
15757   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15758   DONE;
15759 })
15760
15761 (define_expand "atansf2"
15762   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15763                    (unspec:SF [(match_dup 2)
15764                                (match_operand:SF 1 "register_operand" "")]
15765                     UNSPEC_FPATAN))
15766               (clobber (match_scratch:SF 3 ""))])]
15767   "TARGET_USE_FANCY_MATH_387
15768    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769    && flag_unsafe_math_optimizations"
15770 {
15771   operands[2] = gen_reg_rtx (SFmode);
15772   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15773 })
15774
15775 (define_insn "atan2xf3_1"
15776   [(set (match_operand:XF 0 "register_operand" "=f")
15777         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15778                     (match_operand:XF 1 "register_operand" "u")]
15779                    UNSPEC_FPATAN))
15780    (clobber (match_scratch:XF 3 "=1"))]
15781   "TARGET_USE_FANCY_MATH_387
15782    && flag_unsafe_math_optimizations"
15783   "fpatan"
15784   [(set_attr "type" "fpspc")
15785    (set_attr "mode" "XF")])
15786
15787 (define_expand "atan2xf3"
15788   [(use (match_operand:XF 0 "register_operand" ""))
15789    (use (match_operand:XF 2 "register_operand" ""))
15790    (use (match_operand:XF 1 "register_operand" ""))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15793 {
15794   rtx copy = gen_reg_rtx (XFmode);
15795   emit_move_insn (copy, operands[1]);
15796   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15797   DONE;
15798 })
15799
15800 (define_expand "atanxf2"
15801   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802                    (unspec:XF [(match_dup 2)
15803                                (match_operand:XF 1 "register_operand" "")]
15804                     UNSPEC_FPATAN))
15805               (clobber (match_scratch:XF 3 ""))])]
15806   "TARGET_USE_FANCY_MATH_387
15807    && flag_unsafe_math_optimizations"
15808 {
15809   operands[2] = gen_reg_rtx (XFmode);
15810   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15811 })
15812
15813 (define_expand "asindf2"
15814   [(set (match_dup 2)
15815         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15816    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15817    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15818    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15819    (parallel [(set (match_dup 7)
15820                    (unspec:XF [(match_dup 6) (match_dup 2)]
15821                               UNSPEC_FPATAN))
15822               (clobber (match_scratch:XF 8 ""))])
15823    (set (match_operand:DF 0 "register_operand" "")
15824         (float_truncate:DF (match_dup 7)))]
15825   "TARGET_USE_FANCY_MATH_387
15826    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827    && flag_unsafe_math_optimizations"
15828 {
15829   int i;
15830
15831   for (i=2; i<8; i++)
15832     operands[i] = gen_reg_rtx (XFmode);
15833
15834   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15835 })
15836
15837 (define_expand "asinsf2"
15838   [(set (match_dup 2)
15839         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15840    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15841    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15842    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15843    (parallel [(set (match_dup 7)
15844                    (unspec:XF [(match_dup 6) (match_dup 2)]
15845                               UNSPEC_FPATAN))
15846               (clobber (match_scratch:XF 8 ""))])
15847    (set (match_operand:SF 0 "register_operand" "")
15848         (float_truncate:SF (match_dup 7)))]
15849   "TARGET_USE_FANCY_MATH_387
15850    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15851    && flag_unsafe_math_optimizations"
15852 {
15853   int i;
15854
15855   for (i=2; i<8; i++)
15856     operands[i] = gen_reg_rtx (XFmode);
15857
15858   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15859 })
15860
15861 (define_expand "asinxf2"
15862   [(set (match_dup 2)
15863         (mult:XF (match_operand:XF 1 "register_operand" "")
15864                  (match_dup 1)))
15865    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15866    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15867    (parallel [(set (match_operand:XF 0 "register_operand" "")
15868                    (unspec:XF [(match_dup 5) (match_dup 1)]
15869                               UNSPEC_FPATAN))
15870               (clobber (match_scratch:XF 6 ""))])]
15871   "TARGET_USE_FANCY_MATH_387
15872    && flag_unsafe_math_optimizations"
15873 {
15874   int i;
15875
15876   for (i=2; i<6; i++)
15877     operands[i] = gen_reg_rtx (XFmode);
15878
15879   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15880 })
15881
15882 (define_expand "acosdf2"
15883   [(set (match_dup 2)
15884         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15885    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15886    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15887    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15888    (parallel [(set (match_dup 7)
15889                    (unspec:XF [(match_dup 2) (match_dup 6)]
15890                               UNSPEC_FPATAN))
15891               (clobber (match_scratch:XF 8 ""))])
15892    (set (match_operand:DF 0 "register_operand" "")
15893         (float_truncate:DF (match_dup 7)))]
15894   "TARGET_USE_FANCY_MATH_387
15895    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15896    && flag_unsafe_math_optimizations"
15897 {
15898   int i;
15899
15900   for (i=2; i<8; i++)
15901     operands[i] = gen_reg_rtx (XFmode);
15902
15903   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15904 })
15905
15906 (define_expand "acossf2"
15907   [(set (match_dup 2)
15908         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15909    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15910    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15911    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15912    (parallel [(set (match_dup 7)
15913                    (unspec:XF [(match_dup 2) (match_dup 6)]
15914                               UNSPEC_FPATAN))
15915               (clobber (match_scratch:XF 8 ""))])
15916    (set (match_operand:SF 0 "register_operand" "")
15917         (float_truncate:SF (match_dup 7)))]
15918   "TARGET_USE_FANCY_MATH_387
15919    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15920    && flag_unsafe_math_optimizations"
15921 {
15922   int i;
15923
15924   for (i=2; i<8; i++)
15925     operands[i] = gen_reg_rtx (XFmode);
15926
15927   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15928 })
15929
15930 (define_expand "acosxf2"
15931   [(set (match_dup 2)
15932         (mult:XF (match_operand:XF 1 "register_operand" "")
15933                  (match_dup 1)))
15934    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15935    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15936    (parallel [(set (match_operand:XF 0 "register_operand" "")
15937                    (unspec:XF [(match_dup 1) (match_dup 5)]
15938                               UNSPEC_FPATAN))
15939               (clobber (match_scratch:XF 6 ""))])]
15940   "TARGET_USE_FANCY_MATH_387
15941    && flag_unsafe_math_optimizations"
15942 {
15943   int i;
15944
15945   for (i=2; i<6; i++)
15946     operands[i] = gen_reg_rtx (XFmode);
15947
15948   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15949 })
15950
15951 (define_insn "fyl2x_xf3"
15952   [(set (match_operand:XF 0 "register_operand" "=f")
15953         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954                     (match_operand:XF 1 "register_operand" "u")]
15955                    UNSPEC_FYL2X))
15956    (clobber (match_scratch:XF 3 "=1"))]
15957   "TARGET_USE_FANCY_MATH_387
15958    && flag_unsafe_math_optimizations"
15959   "fyl2x"
15960   [(set_attr "type" "fpspc")
15961    (set_attr "mode" "XF")])
15962
15963 (define_expand "logsf2"
15964   [(set (match_dup 2)
15965         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15966    (parallel [(set (match_dup 4)
15967                    (unspec:XF [(match_dup 2)
15968                                (match_dup 3)] UNSPEC_FYL2X))
15969               (clobber (match_scratch:XF 5 ""))])
15970    (set (match_operand:SF 0 "register_operand" "")
15971         (float_truncate:SF (match_dup 4)))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974    && flag_unsafe_math_optimizations"
15975 {
15976   rtx temp;
15977
15978   operands[2] = gen_reg_rtx (XFmode);
15979   operands[3] = gen_reg_rtx (XFmode);
15980   operands[4] = gen_reg_rtx (XFmode);
15981
15982   temp = standard_80387_constant_rtx (4); /* fldln2 */
15983   emit_move_insn (operands[3], temp);
15984 })
15985
15986 (define_expand "logdf2"
15987   [(set (match_dup 2)
15988         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15989    (parallel [(set (match_dup 4)
15990                    (unspec:XF [(match_dup 2)
15991                                (match_dup 3)] UNSPEC_FYL2X))
15992               (clobber (match_scratch:XF 5 ""))])
15993    (set (match_operand:DF 0 "register_operand" "")
15994         (float_truncate:DF (match_dup 4)))]
15995   "TARGET_USE_FANCY_MATH_387
15996    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15997    && flag_unsafe_math_optimizations"
15998 {
15999   rtx temp;
16000
16001   operands[2] = gen_reg_rtx (XFmode);
16002   operands[3] = gen_reg_rtx (XFmode);
16003   operands[4] = gen_reg_rtx (XFmode);
16004
16005   temp = standard_80387_constant_rtx (4); /* fldln2 */
16006   emit_move_insn (operands[3], temp);
16007 })
16008
16009 (define_expand "logxf2"
16010   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16011                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16012                                (match_dup 2)] UNSPEC_FYL2X))
16013               (clobber (match_scratch:XF 3 ""))])]
16014   "TARGET_USE_FANCY_MATH_387
16015    && flag_unsafe_math_optimizations"
16016 {
16017   rtx temp;
16018
16019   operands[2] = gen_reg_rtx (XFmode);
16020   temp = standard_80387_constant_rtx (4); /* fldln2 */
16021   emit_move_insn (operands[2], temp);
16022 })
16023
16024 (define_expand "log10sf2"
16025   [(set (match_dup 2)
16026         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16027    (parallel [(set (match_dup 4)
16028                    (unspec:XF [(match_dup 2)
16029                                (match_dup 3)] UNSPEC_FYL2X))
16030               (clobber (match_scratch:XF 5 ""))])
16031    (set (match_operand:SF 0 "register_operand" "")
16032         (float_truncate:SF (match_dup 4)))]
16033   "TARGET_USE_FANCY_MATH_387
16034    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16035    && flag_unsafe_math_optimizations"
16036 {
16037   rtx temp;
16038
16039   operands[2] = gen_reg_rtx (XFmode);
16040   operands[3] = gen_reg_rtx (XFmode);
16041   operands[4] = gen_reg_rtx (XFmode);
16042
16043   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16044   emit_move_insn (operands[3], temp);
16045 })
16046
16047 (define_expand "log10df2"
16048   [(set (match_dup 2)
16049         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16050    (parallel [(set (match_dup 4)
16051                    (unspec:XF [(match_dup 2)
16052                                (match_dup 3)] UNSPEC_FYL2X))
16053               (clobber (match_scratch:XF 5 ""))])
16054    (set (match_operand:DF 0 "register_operand" "")
16055         (float_truncate:DF (match_dup 4)))]
16056   "TARGET_USE_FANCY_MATH_387
16057    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16058    && flag_unsafe_math_optimizations"
16059 {
16060   rtx temp;
16061
16062   operands[2] = gen_reg_rtx (XFmode);
16063   operands[3] = gen_reg_rtx (XFmode);
16064   operands[4] = gen_reg_rtx (XFmode);
16065
16066   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16067   emit_move_insn (operands[3], temp);
16068 })
16069
16070 (define_expand "log10xf2"
16071   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16072                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16073                                (match_dup 2)] UNSPEC_FYL2X))
16074               (clobber (match_scratch:XF 3 ""))])]
16075   "TARGET_USE_FANCY_MATH_387
16076    && flag_unsafe_math_optimizations"
16077 {
16078   rtx temp;
16079
16080   operands[2] = gen_reg_rtx (XFmode);
16081   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16082   emit_move_insn (operands[2], temp);
16083 })
16084
16085 (define_expand "log2sf2"
16086   [(set (match_dup 2)
16087         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16088    (parallel [(set (match_dup 4)
16089                    (unspec:XF [(match_dup 2)
16090                                (match_dup 3)] UNSPEC_FYL2X))
16091               (clobber (match_scratch:XF 5 ""))])
16092    (set (match_operand:SF 0 "register_operand" "")
16093         (float_truncate:SF (match_dup 4)))]
16094   "TARGET_USE_FANCY_MATH_387
16095    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16096    && flag_unsafe_math_optimizations"
16097 {
16098   operands[2] = gen_reg_rtx (XFmode);
16099   operands[3] = gen_reg_rtx (XFmode);
16100   operands[4] = gen_reg_rtx (XFmode);
16101
16102   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16103 })
16104
16105 (define_expand "log2df2"
16106   [(set (match_dup 2)
16107         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16108    (parallel [(set (match_dup 4)
16109                    (unspec:XF [(match_dup 2)
16110                                (match_dup 3)] UNSPEC_FYL2X))
16111               (clobber (match_scratch:XF 5 ""))])
16112    (set (match_operand:DF 0 "register_operand" "")
16113         (float_truncate:DF (match_dup 4)))]
16114   "TARGET_USE_FANCY_MATH_387
16115    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16116    && flag_unsafe_math_optimizations"
16117 {
16118   operands[2] = gen_reg_rtx (XFmode);
16119   operands[3] = gen_reg_rtx (XFmode);
16120   operands[4] = gen_reg_rtx (XFmode);
16121
16122   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16123 })
16124
16125 (define_expand "log2xf2"
16126   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16127                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16128                                (match_dup 2)] UNSPEC_FYL2X))
16129               (clobber (match_scratch:XF 3 ""))])]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16132 {
16133   operands[2] = gen_reg_rtx (XFmode);
16134   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16135 })
16136
16137 (define_insn "fyl2xp1_xf3"
16138   [(set (match_operand:XF 0 "register_operand" "=f")
16139         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140                     (match_operand:XF 1 "register_operand" "u")]
16141                    UNSPEC_FYL2XP1))
16142    (clobber (match_scratch:XF 3 "=1"))]
16143   "TARGET_USE_FANCY_MATH_387
16144    && flag_unsafe_math_optimizations"
16145   "fyl2xp1"
16146   [(set_attr "type" "fpspc")
16147    (set_attr "mode" "XF")])
16148
16149 (define_expand "log1psf2"
16150   [(use (match_operand:SF 0 "register_operand" ""))
16151    (use (match_operand:SF 1 "register_operand" ""))]
16152   "TARGET_USE_FANCY_MATH_387
16153    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154    && flag_unsafe_math_optimizations"
16155 {
16156   rtx op0 = gen_reg_rtx (XFmode);
16157   rtx op1 = gen_reg_rtx (XFmode);
16158
16159   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16160   ix86_emit_i387_log1p (op0, op1);
16161   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16162   DONE;
16163 })
16164
16165 (define_expand "log1pdf2"
16166   [(use (match_operand:DF 0 "register_operand" ""))
16167    (use (match_operand:DF 1 "register_operand" ""))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16170    && flag_unsafe_math_optimizations"
16171 {
16172   rtx op0 = gen_reg_rtx (XFmode);
16173   rtx op1 = gen_reg_rtx (XFmode);
16174
16175   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16176   ix86_emit_i387_log1p (op0, op1);
16177   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16178   DONE;
16179 })
16180
16181 (define_expand "log1pxf2"
16182   [(use (match_operand:XF 0 "register_operand" ""))
16183    (use (match_operand:XF 1 "register_operand" ""))]
16184   "TARGET_USE_FANCY_MATH_387
16185    && flag_unsafe_math_optimizations"
16186 {
16187   ix86_emit_i387_log1p (operands[0], operands[1]);
16188   DONE;
16189 })
16190
16191 (define_insn "*fxtractxf3"
16192   [(set (match_operand:XF 0 "register_operand" "=f")
16193         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16194                    UNSPEC_XTRACT_FRACT))
16195    (set (match_operand:XF 1 "register_operand" "=u")
16196         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16197   "TARGET_USE_FANCY_MATH_387
16198    && flag_unsafe_math_optimizations"
16199   "fxtract"
16200   [(set_attr "type" "fpspc")
16201    (set_attr "mode" "XF")])
16202
16203 (define_expand "logbsf2"
16204   [(set (match_dup 2)
16205         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16206    (parallel [(set (match_dup 3)
16207                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16208               (set (match_dup 4)
16209                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16210    (set (match_operand:SF 0 "register_operand" "")
16211         (float_truncate:SF (match_dup 4)))]
16212   "TARGET_USE_FANCY_MATH_387
16213    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16214    && flag_unsafe_math_optimizations"
16215 {
16216   operands[2] = gen_reg_rtx (XFmode);
16217   operands[3] = gen_reg_rtx (XFmode);
16218   operands[4] = gen_reg_rtx (XFmode);
16219 })
16220
16221 (define_expand "logbdf2"
16222   [(set (match_dup 2)
16223         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16224    (parallel [(set (match_dup 3)
16225                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16226               (set (match_dup 4)
16227                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16228    (set (match_operand:DF 0 "register_operand" "")
16229         (float_truncate:DF (match_dup 4)))]
16230   "TARGET_USE_FANCY_MATH_387
16231    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16232    && flag_unsafe_math_optimizations"
16233 {
16234   operands[2] = gen_reg_rtx (XFmode);
16235   operands[3] = gen_reg_rtx (XFmode);
16236   operands[4] = gen_reg_rtx (XFmode);
16237 })
16238
16239 (define_expand "logbxf2"
16240   [(parallel [(set (match_dup 2)
16241                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16242                               UNSPEC_XTRACT_FRACT))
16243               (set (match_operand:XF 0 "register_operand" "")
16244                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16245   "TARGET_USE_FANCY_MATH_387
16246    && flag_unsafe_math_optimizations"
16247 {
16248   operands[2] = gen_reg_rtx (XFmode);
16249 })
16250
16251 (define_expand "ilogbsi2"
16252   [(parallel [(set (match_dup 2)
16253                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16254                               UNSPEC_XTRACT_FRACT))
16255               (set (match_operand:XF 3 "register_operand" "")
16256                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16257    (parallel [(set (match_operand:SI 0 "register_operand" "")
16258                    (fix:SI (match_dup 3)))
16259               (clobber (reg:CC FLAGS_REG))])]
16260   "TARGET_USE_FANCY_MATH_387
16261    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16262    && flag_unsafe_math_optimizations"
16263 {
16264   operands[2] = gen_reg_rtx (XFmode);
16265   operands[3] = gen_reg_rtx (XFmode);
16266 })
16267
16268 (define_insn "*f2xm1xf2"
16269   [(set (match_operand:XF 0 "register_operand" "=f")
16270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16271          UNSPEC_F2XM1))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16274   "f2xm1"
16275   [(set_attr "type" "fpspc")
16276    (set_attr "mode" "XF")])
16277
16278 (define_insn "*fscalexf4"
16279   [(set (match_operand:XF 0 "register_operand" "=f")
16280         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16281                     (match_operand:XF 3 "register_operand" "1")]
16282                    UNSPEC_FSCALE_FRACT))
16283    (set (match_operand:XF 1 "register_operand" "=u")
16284         (unspec:XF [(match_dup 2) (match_dup 3)]
16285                    UNSPEC_FSCALE_EXP))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16288   "fscale"
16289   [(set_attr "type" "fpspc")
16290    (set_attr "mode" "XF")])
16291
16292 (define_expand "expsf2"
16293   [(set (match_dup 2)
16294         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16295    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16296    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16297    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16298    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16299    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16300    (parallel [(set (match_dup 10)
16301                    (unspec:XF [(match_dup 9) (match_dup 5)]
16302                               UNSPEC_FSCALE_FRACT))
16303               (set (match_dup 11)
16304                    (unspec:XF [(match_dup 9) (match_dup 5)]
16305                               UNSPEC_FSCALE_EXP))])
16306    (set (match_operand:SF 0 "register_operand" "")
16307         (float_truncate:SF (match_dup 10)))]
16308   "TARGET_USE_FANCY_MATH_387
16309    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16310    && flag_unsafe_math_optimizations"
16311 {
16312   rtx temp;
16313   int i;
16314
16315   for (i=2; i<12; i++)
16316     operands[i] = gen_reg_rtx (XFmode);
16317   temp = standard_80387_constant_rtx (5); /* fldl2e */
16318   emit_move_insn (operands[3], temp);
16319   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16320 })
16321
16322 (define_expand "expdf2"
16323   [(set (match_dup 2)
16324         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16326    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16327    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16328    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16329    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16330    (parallel [(set (match_dup 10)
16331                    (unspec:XF [(match_dup 9) (match_dup 5)]
16332                               UNSPEC_FSCALE_FRACT))
16333               (set (match_dup 11)
16334                    (unspec:XF [(match_dup 9) (match_dup 5)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (set (match_operand:DF 0 "register_operand" "")
16337         (float_truncate:DF (match_dup 10)))]
16338   "TARGET_USE_FANCY_MATH_387
16339    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16340    && flag_unsafe_math_optimizations"
16341 {
16342   rtx temp;
16343   int i;
16344
16345   for (i=2; i<12; i++)
16346     operands[i] = gen_reg_rtx (XFmode);
16347   temp = standard_80387_constant_rtx (5); /* fldl2e */
16348   emit_move_insn (operands[3], temp);
16349   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16350 })
16351
16352 (define_expand "expxf2"
16353   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16354                                (match_dup 2)))
16355    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16356    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16357    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16358    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16359    (parallel [(set (match_operand:XF 0 "register_operand" "")
16360                    (unspec:XF [(match_dup 8) (match_dup 4)]
16361                               UNSPEC_FSCALE_FRACT))
16362               (set (match_dup 9)
16363                    (unspec:XF [(match_dup 8) (match_dup 4)]
16364                               UNSPEC_FSCALE_EXP))])]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations"
16367 {
16368   rtx temp;
16369   int i;
16370
16371   for (i=2; i<10; i++)
16372     operands[i] = gen_reg_rtx (XFmode);
16373   temp = standard_80387_constant_rtx (5); /* fldl2e */
16374   emit_move_insn (operands[2], temp);
16375   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16376 })
16377
16378 (define_expand "exp10sf2"
16379   [(set (match_dup 2)
16380         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16381    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16382    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16383    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16384    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16385    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16386    (parallel [(set (match_dup 10)
16387                    (unspec:XF [(match_dup 9) (match_dup 5)]
16388                               UNSPEC_FSCALE_FRACT))
16389               (set (match_dup 11)
16390                    (unspec:XF [(match_dup 9) (match_dup 5)]
16391                               UNSPEC_FSCALE_EXP))])
16392    (set (match_operand:SF 0 "register_operand" "")
16393         (float_truncate:SF (match_dup 10)))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16397 {
16398   rtx temp;
16399   int i;
16400
16401   for (i=2; i<12; i++)
16402     operands[i] = gen_reg_rtx (XFmode);
16403   temp = standard_80387_constant_rtx (6); /* fldl2t */
16404   emit_move_insn (operands[3], temp);
16405   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16406 })
16407
16408 (define_expand "exp10df2"
16409   [(set (match_dup 2)
16410         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16411    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16412    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16413    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16414    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16415    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16416    (parallel [(set (match_dup 10)
16417                    (unspec:XF [(match_dup 9) (match_dup 5)]
16418                               UNSPEC_FSCALE_FRACT))
16419               (set (match_dup 11)
16420                    (unspec:XF [(match_dup 9) (match_dup 5)]
16421                               UNSPEC_FSCALE_EXP))])
16422    (set (match_operand:DF 0 "register_operand" "")
16423         (float_truncate:DF (match_dup 10)))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16426    && flag_unsafe_math_optimizations"
16427 {
16428   rtx temp;
16429   int i;
16430
16431   for (i=2; i<12; i++)
16432     operands[i] = gen_reg_rtx (XFmode);
16433   temp = standard_80387_constant_rtx (6); /* fldl2t */
16434   emit_move_insn (operands[3], temp);
16435   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16436 })
16437
16438 (define_expand "exp10xf2"
16439   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16440                                (match_dup 2)))
16441    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16442    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16443    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16444    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16445    (parallel [(set (match_operand:XF 0 "register_operand" "")
16446                    (unspec:XF [(match_dup 8) (match_dup 4)]
16447                               UNSPEC_FSCALE_FRACT))
16448               (set (match_dup 9)
16449                    (unspec:XF [(match_dup 8) (match_dup 4)]
16450                               UNSPEC_FSCALE_EXP))])]
16451   "TARGET_USE_FANCY_MATH_387
16452    && flag_unsafe_math_optimizations"
16453 {
16454   rtx temp;
16455   int i;
16456
16457   for (i=2; i<10; i++)
16458     operands[i] = gen_reg_rtx (XFmode);
16459   temp = standard_80387_constant_rtx (6); /* fldl2t */
16460   emit_move_insn (operands[2], temp);
16461   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16462 })
16463
16464 (define_expand "exp2sf2"
16465   [(set (match_dup 2)
16466         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16467    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16468    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16469    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16470    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16471    (parallel [(set (match_dup 8)
16472                    (unspec:XF [(match_dup 7) (match_dup 3)]
16473                               UNSPEC_FSCALE_FRACT))
16474               (set (match_dup 9)
16475                    (unspec:XF [(match_dup 7) (match_dup 3)]
16476                               UNSPEC_FSCALE_EXP))])
16477    (set (match_operand:SF 0 "register_operand" "")
16478         (float_truncate:SF (match_dup 8)))]
16479   "TARGET_USE_FANCY_MATH_387
16480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16482 {
16483   int i;
16484
16485   for (i=2; i<10; i++)
16486     operands[i] = gen_reg_rtx (XFmode);
16487   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16488 })
16489
16490 (define_expand "exp2df2"
16491   [(set (match_dup 2)
16492         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16493    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16494    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16495    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16496    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16497    (parallel [(set (match_dup 8)
16498                    (unspec:XF [(match_dup 7) (match_dup 3)]
16499                               UNSPEC_FSCALE_FRACT))
16500               (set (match_dup 9)
16501                    (unspec:XF [(match_dup 7) (match_dup 3)]
16502                               UNSPEC_FSCALE_EXP))])
16503    (set (match_operand:DF 0 "register_operand" "")
16504         (float_truncate:DF (match_dup 8)))]
16505   "TARGET_USE_FANCY_MATH_387
16506    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16507    && flag_unsafe_math_optimizations"
16508 {
16509   int i;
16510
16511   for (i=2; i<10; i++)
16512     operands[i] = gen_reg_rtx (XFmode);
16513   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16514 })
16515
16516 (define_expand "exp2xf2"
16517   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16518    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16519    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16520    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16521    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16522    (parallel [(set (match_operand:XF 0 "register_operand" "")
16523                    (unspec:XF [(match_dup 7) (match_dup 3)]
16524                               UNSPEC_FSCALE_FRACT))
16525               (set (match_dup 8)
16526                    (unspec:XF [(match_dup 7) (match_dup 3)]
16527                               UNSPEC_FSCALE_EXP))])]
16528   "TARGET_USE_FANCY_MATH_387
16529    && flag_unsafe_math_optimizations"
16530 {
16531   int i;
16532
16533   for (i=2; i<9; i++)
16534     operands[i] = gen_reg_rtx (XFmode);
16535   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16536 })
16537
16538 (define_expand "expm1df2"
16539   [(set (match_dup 2)
16540         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16541    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16542    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16543    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16544    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16545    (parallel [(set (match_dup 8)
16546                    (unspec:XF [(match_dup 7) (match_dup 5)]
16547                               UNSPEC_FSCALE_FRACT))
16548                    (set (match_dup 9)
16549                    (unspec:XF [(match_dup 7) (match_dup 5)]
16550                               UNSPEC_FSCALE_EXP))])
16551    (parallel [(set (match_dup 11)
16552                    (unspec:XF [(match_dup 10) (match_dup 9)]
16553                               UNSPEC_FSCALE_FRACT))
16554               (set (match_dup 12)
16555                    (unspec:XF [(match_dup 10) (match_dup 9)]
16556                               UNSPEC_FSCALE_EXP))])
16557    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16558    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16559    (set (match_operand:DF 0 "register_operand" "")
16560         (float_truncate:DF (match_dup 14)))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16563    && flag_unsafe_math_optimizations"
16564 {
16565   rtx temp;
16566   int i;
16567
16568   for (i=2; i<15; i++)
16569     operands[i] = gen_reg_rtx (XFmode);
16570   temp = standard_80387_constant_rtx (5); /* fldl2e */
16571   emit_move_insn (operands[3], temp);
16572   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16573 })
16574
16575 (define_expand "expm1sf2"
16576   [(set (match_dup 2)
16577         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16578    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16579    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16580    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16581    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16582    (parallel [(set (match_dup 8)
16583                    (unspec:XF [(match_dup 7) (match_dup 5)]
16584                               UNSPEC_FSCALE_FRACT))
16585                    (set (match_dup 9)
16586                    (unspec:XF [(match_dup 7) (match_dup 5)]
16587                               UNSPEC_FSCALE_EXP))])
16588    (parallel [(set (match_dup 11)
16589                    (unspec:XF [(match_dup 10) (match_dup 9)]
16590                               UNSPEC_FSCALE_FRACT))
16591               (set (match_dup 12)
16592                    (unspec:XF [(match_dup 10) (match_dup 9)]
16593                               UNSPEC_FSCALE_EXP))])
16594    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16595    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16596    (set (match_operand:SF 0 "register_operand" "")
16597         (float_truncate:SF (match_dup 14)))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16600    && flag_unsafe_math_optimizations"
16601 {
16602   rtx temp;
16603   int i;
16604
16605   for (i=2; i<15; i++)
16606     operands[i] = gen_reg_rtx (XFmode);
16607   temp = standard_80387_constant_rtx (5); /* fldl2e */
16608   emit_move_insn (operands[3], temp);
16609   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16610 })
16611
16612 (define_expand "expm1xf2"
16613   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16614                                (match_dup 2)))
16615    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16616    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16617    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16618    (parallel [(set (match_dup 7)
16619                    (unspec:XF [(match_dup 6) (match_dup 4)]
16620                               UNSPEC_FSCALE_FRACT))
16621                    (set (match_dup 8)
16622                    (unspec:XF [(match_dup 6) (match_dup 4)]
16623                               UNSPEC_FSCALE_EXP))])
16624    (parallel [(set (match_dup 10)
16625                    (unspec:XF [(match_dup 9) (match_dup 8)]
16626                               UNSPEC_FSCALE_FRACT))
16627               (set (match_dup 11)
16628                    (unspec:XF [(match_dup 9) (match_dup 8)]
16629                               UNSPEC_FSCALE_EXP))])
16630    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16631    (set (match_operand:XF 0 "register_operand" "")
16632         (plus:XF (match_dup 12) (match_dup 7)))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations"
16635 {
16636   rtx temp;
16637   int i;
16638
16639   for (i=2; i<13; i++)
16640     operands[i] = gen_reg_rtx (XFmode);
16641   temp = standard_80387_constant_rtx (5); /* fldl2e */
16642   emit_move_insn (operands[2], temp);
16643   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16644 })
16645
16646 (define_expand "ldexpdf3"
16647   [(set (match_dup 3)
16648         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16649    (set (match_dup 4)
16650         (float:XF (match_operand:SI 2 "register_operand" "")))
16651    (parallel [(set (match_dup 5)
16652                    (unspec:XF [(match_dup 3) (match_dup 4)]
16653                               UNSPEC_FSCALE_FRACT))
16654               (set (match_dup 6)
16655                    (unspec:XF [(match_dup 3) (match_dup 4)]
16656                               UNSPEC_FSCALE_EXP))])
16657    (set (match_operand:DF 0 "register_operand" "")
16658         (float_truncate:DF (match_dup 5)))]
16659   "TARGET_USE_FANCY_MATH_387
16660    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16661    && flag_unsafe_math_optimizations"
16662 {
16663   int i;
16664
16665   for (i=3; i<7; i++)
16666     operands[i] = gen_reg_rtx (XFmode);
16667 })
16668
16669 (define_expand "ldexpsf3"
16670   [(set (match_dup 3)
16671         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16672    (set (match_dup 4)
16673         (float:XF (match_operand:SI 2 "register_operand" "")))
16674    (parallel [(set (match_dup 5)
16675                    (unspec:XF [(match_dup 3) (match_dup 4)]
16676                               UNSPEC_FSCALE_FRACT))
16677               (set (match_dup 6)
16678                    (unspec:XF [(match_dup 3) (match_dup 4)]
16679                               UNSPEC_FSCALE_EXP))])
16680    (set (match_operand:SF 0 "register_operand" "")
16681         (float_truncate:SF (match_dup 5)))]
16682   "TARGET_USE_FANCY_MATH_387
16683    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16684    && flag_unsafe_math_optimizations"
16685 {
16686   int i;
16687
16688   for (i=3; i<7; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16690 })
16691
16692 (define_expand "ldexpxf3"
16693   [(set (match_dup 3)
16694         (float:XF (match_operand:SI 2 "register_operand" "")))
16695    (parallel [(set (match_operand:XF 0 " register_operand" "")
16696                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16697                                (match_dup 3)]
16698                               UNSPEC_FSCALE_FRACT))
16699               (set (match_dup 4)
16700                    (unspec:XF [(match_dup 1) (match_dup 3)]
16701                               UNSPEC_FSCALE_EXP))])]
16702   "TARGET_USE_FANCY_MATH_387
16703    && flag_unsafe_math_optimizations"
16704 {
16705   int i;
16706
16707   for (i=3; i<5; i++)
16708     operands[i] = gen_reg_rtx (XFmode);
16709 })
16710 \f
16711
16712 (define_insn "frndintxf2"
16713   [(set (match_operand:XF 0 "register_operand" "=f")
16714         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16715          UNSPEC_FRNDINT))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && flag_unsafe_math_optimizations"
16718   "frndint"
16719   [(set_attr "type" "fpspc")
16720    (set_attr "mode" "XF")])
16721
16722 (define_expand "rintdf2"
16723   [(use (match_operand:DF 0 "register_operand" ""))
16724    (use (match_operand:DF 1 "register_operand" ""))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16727    && flag_unsafe_math_optimizations"
16728 {
16729   rtx op0 = gen_reg_rtx (XFmode);
16730   rtx op1 = gen_reg_rtx (XFmode);
16731
16732   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16733   emit_insn (gen_frndintxf2 (op0, op1));
16734
16735   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16736   DONE;
16737 })
16738
16739 (define_expand "rintsf2"
16740   [(use (match_operand:SF 0 "register_operand" ""))
16741    (use (match_operand:SF 1 "register_operand" ""))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16744    && flag_unsafe_math_optimizations"
16745 {
16746   rtx op0 = gen_reg_rtx (XFmode);
16747   rtx op1 = gen_reg_rtx (XFmode);
16748
16749   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16750   emit_insn (gen_frndintxf2 (op0, op1));
16751
16752   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16753   DONE;
16754 })
16755
16756 (define_expand "rintxf2"
16757   [(use (match_operand:XF 0 "register_operand" ""))
16758    (use (match_operand:XF 1 "register_operand" ""))]
16759   "TARGET_USE_FANCY_MATH_387
16760    && flag_unsafe_math_optimizations"
16761 {
16762   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16763   DONE;
16764 })
16765
16766 (define_insn_and_split "*fistdi2_1"
16767   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16768         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16769          UNSPEC_FIST))]
16770   "TARGET_USE_FANCY_MATH_387
16771    && flag_unsafe_math_optimizations
16772    && !(reload_completed || reload_in_progress)"
16773   "#"
16774   "&& 1"
16775   [(const_int 0)]
16776 {
16777   if (memory_operand (operands[0], VOIDmode))
16778     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16779   else
16780     {
16781       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16782       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16783                                          operands[2]));
16784     }
16785   DONE;
16786 }
16787   [(set_attr "type" "fpspc")
16788    (set_attr "mode" "DI")])
16789
16790 (define_insn "fistdi2"
16791   [(set (match_operand:DI 0 "memory_operand" "=m")
16792         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16793          UNSPEC_FIST))
16794    (clobber (match_scratch:XF 2 "=&1f"))]
16795   "TARGET_USE_FANCY_MATH_387
16796    && flag_unsafe_math_optimizations"
16797   "* return output_fix_trunc (insn, operands, 0);"
16798   [(set_attr "type" "fpspc")
16799    (set_attr "mode" "DI")])
16800
16801 (define_insn "fistdi2_with_temp"
16802   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16803         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16804          UNSPEC_FIST))
16805    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16806    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16807   "TARGET_USE_FANCY_MATH_387
16808    && flag_unsafe_math_optimizations"
16809   "#"
16810   [(set_attr "type" "fpspc")
16811    (set_attr "mode" "DI")])
16812
16813 (define_split 
16814   [(set (match_operand:DI 0 "register_operand" "")
16815         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16816          UNSPEC_FIST))
16817    (clobber (match_operand:DI 2 "memory_operand" ""))
16818    (clobber (match_scratch 3 ""))]
16819   "reload_completed"
16820   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16821               (clobber (match_dup 3))])
16822    (set (match_dup 0) (match_dup 2))]
16823   "")
16824
16825 (define_split 
16826   [(set (match_operand:DI 0 "memory_operand" "")
16827         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16828          UNSPEC_FIST))
16829    (clobber (match_operand:DI 2 "memory_operand" ""))
16830    (clobber (match_scratch 3 ""))]
16831   "reload_completed"
16832   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16833               (clobber (match_dup 3))])]
16834   "")
16835
16836 (define_insn_and_split "*fist<mode>2_1"
16837   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16839          UNSPEC_FIST))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations
16842    && !(reload_completed || reload_in_progress)"
16843   "#"
16844   "&& 1"
16845   [(const_int 0)]
16846 {
16847   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16848   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16849                                         operands[2]));
16850   DONE;
16851 }
16852   [(set_attr "type" "fpspc")
16853    (set_attr "mode" "<MODE>")])
16854
16855 (define_insn "fist<mode>2"
16856   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16857         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16858          UNSPEC_FIST))]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861   "* return output_fix_trunc (insn, operands, 0);"
16862   [(set_attr "type" "fpspc")
16863    (set_attr "mode" "<MODE>")])
16864
16865 (define_insn "fist<mode>2_with_temp"
16866   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16867         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16868          UNSPEC_FIST))
16869    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16870   "TARGET_USE_FANCY_MATH_387
16871    && flag_unsafe_math_optimizations"
16872   "#"
16873   [(set_attr "type" "fpspc")
16874    (set_attr "mode" "<MODE>")])
16875
16876 (define_split 
16877   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16878         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16879          UNSPEC_FIST))
16880    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16881   "reload_completed"
16882   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16883                        UNSPEC_FIST))
16884    (set (match_dup 0) (match_dup 2))]
16885   "")
16886
16887 (define_split 
16888   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16889         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16890          UNSPEC_FIST))
16891    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16892   "reload_completed"
16893   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16894                        UNSPEC_FIST))]
16895   "")
16896
16897 (define_expand "lrint<mode>2"
16898   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16899         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16900          UNSPEC_FIST))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16903    && flag_unsafe_math_optimizations"
16904   "")
16905
16906 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16907 (define_insn_and_split "frndintxf2_floor"
16908   [(set (match_operand:XF 0 "register_operand" "=f")
16909         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16910          UNSPEC_FRNDINT_FLOOR))
16911    (clobber (reg:CC FLAGS_REG))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations
16914    && !(reload_completed || reload_in_progress)"
16915   "#"
16916   "&& 1"
16917   [(const_int 0)]
16918 {
16919   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16920
16921   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16922   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16923
16924   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16925                                         operands[2], operands[3]));
16926   DONE;
16927 }
16928   [(set_attr "type" "frndint")
16929    (set_attr "i387_cw" "floor")
16930    (set_attr "mode" "XF")])
16931
16932 (define_insn "frndintxf2_floor_i387"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16935          UNSPEC_FRNDINT_FLOOR))
16936    (use (match_operand:HI 2 "memory_operand" "m"))
16937    (use (match_operand:HI 3 "memory_operand" "m"))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16940   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16941   [(set_attr "type" "frndint")
16942    (set_attr "i387_cw" "floor")
16943    (set_attr "mode" "XF")])
16944
16945 (define_expand "floorxf2"
16946   [(use (match_operand:XF 0 "register_operand" ""))
16947    (use (match_operand:XF 1 "register_operand" ""))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && flag_unsafe_math_optimizations"
16950 {
16951   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16952   DONE;
16953 })
16954
16955 (define_expand "floordf2"
16956   [(use (match_operand:DF 0 "register_operand" ""))
16957    (use (match_operand:DF 1 "register_operand" ""))]
16958   "TARGET_USE_FANCY_MATH_387
16959    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16960    && flag_unsafe_math_optimizations"
16961 {
16962   rtx op0 = gen_reg_rtx (XFmode);
16963   rtx op1 = gen_reg_rtx (XFmode);
16964
16965   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16966   emit_insn (gen_frndintxf2_floor (op0, op1));
16967
16968   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16969   DONE;
16970 })
16971
16972 (define_expand "floorsf2"
16973   [(use (match_operand:SF 0 "register_operand" ""))
16974    (use (match_operand:SF 1 "register_operand" ""))]
16975   "TARGET_USE_FANCY_MATH_387
16976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977    && flag_unsafe_math_optimizations"
16978 {
16979   rtx op0 = gen_reg_rtx (XFmode);
16980   rtx op1 = gen_reg_rtx (XFmode);
16981
16982   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16983   emit_insn (gen_frndintxf2_floor (op0, op1));
16984
16985   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16986   DONE;
16987 })
16988
16989 (define_insn_and_split "*fist<mode>2_floor_1"
16990   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16991         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16992          UNSPEC_FIST_FLOOR))
16993    (clobber (reg:CC FLAGS_REG))]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations
16996    && !(reload_completed || reload_in_progress)"
16997   "#"
16998   "&& 1"
16999   [(const_int 0)]
17000 {
17001   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17002
17003   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17004   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17005   if (memory_operand (operands[0], VOIDmode))
17006     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17007                                       operands[2], operands[3]));
17008   else
17009     {
17010       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17011       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17012                                                   operands[2], operands[3],
17013                                                   operands[4]));
17014     }
17015   DONE;
17016 }
17017   [(set_attr "type" "fistp")
17018    (set_attr "i387_cw" "floor")
17019    (set_attr "mode" "<MODE>")])
17020
17021 (define_insn "fistdi2_floor"
17022   [(set (match_operand:DI 0 "memory_operand" "=m")
17023         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17024          UNSPEC_FIST_FLOOR))
17025    (use (match_operand:HI 2 "memory_operand" "m"))
17026    (use (match_operand:HI 3 "memory_operand" "m"))
17027    (clobber (match_scratch:XF 4 "=&1f"))]
17028   "TARGET_USE_FANCY_MATH_387
17029    && flag_unsafe_math_optimizations"
17030   "* return output_fix_trunc (insn, operands, 0);"
17031   [(set_attr "type" "fistp")
17032    (set_attr "i387_cw" "floor")
17033    (set_attr "mode" "DI")])
17034
17035 (define_insn "fistdi2_floor_with_temp"
17036   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17037         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17038          UNSPEC_FIST_FLOOR))
17039    (use (match_operand:HI 2 "memory_operand" "m,m"))
17040    (use (match_operand:HI 3 "memory_operand" "m,m"))
17041    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17042    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17043   "TARGET_USE_FANCY_MATH_387
17044    && flag_unsafe_math_optimizations"
17045   "#"
17046   [(set_attr "type" "fistp")
17047    (set_attr "i387_cw" "floor")
17048    (set_attr "mode" "DI")])
17049
17050 (define_split 
17051   [(set (match_operand:DI 0 "register_operand" "")
17052         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17053          UNSPEC_FIST_FLOOR))
17054    (use (match_operand:HI 2 "memory_operand" ""))
17055    (use (match_operand:HI 3 "memory_operand" ""))
17056    (clobber (match_operand:DI 4 "memory_operand" ""))
17057    (clobber (match_scratch 5 ""))]
17058   "reload_completed"
17059   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17060               (use (match_dup 2))
17061               (use (match_dup 3))
17062               (clobber (match_dup 5))])
17063    (set (match_dup 0) (match_dup 4))]
17064   "")
17065
17066 (define_split 
17067   [(set (match_operand:DI 0 "memory_operand" "")
17068         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17069          UNSPEC_FIST_FLOOR))
17070    (use (match_operand:HI 2 "memory_operand" ""))
17071    (use (match_operand:HI 3 "memory_operand" ""))
17072    (clobber (match_operand:DI 4 "memory_operand" ""))
17073    (clobber (match_scratch 5 ""))]
17074   "reload_completed"
17075   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17076               (use (match_dup 2))
17077               (use (match_dup 3))
17078               (clobber (match_dup 5))])]
17079   "")
17080
17081 (define_insn "fist<mode>2_floor"
17082   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17083         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17084          UNSPEC_FIST_FLOOR))
17085    (use (match_operand:HI 2 "memory_operand" "m"))
17086    (use (match_operand:HI 3 "memory_operand" "m"))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations"
17089   "* return output_fix_trunc (insn, operands, 0);"
17090   [(set_attr "type" "fistp")
17091    (set_attr "i387_cw" "floor")
17092    (set_attr "mode" "<MODE>")])
17093
17094 (define_insn "fist<mode>2_floor_with_temp"
17095   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17096         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17097          UNSPEC_FIST_FLOOR))
17098    (use (match_operand:HI 2 "memory_operand" "m,m"))
17099    (use (match_operand:HI 3 "memory_operand" "m,m"))
17100    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17101   "TARGET_USE_FANCY_MATH_387
17102    && flag_unsafe_math_optimizations"
17103   "#"
17104   [(set_attr "type" "fistp")
17105    (set_attr "i387_cw" "floor")
17106    (set_attr "mode" "<MODE>")])
17107
17108 (define_split 
17109   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17110         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17111          UNSPEC_FIST_FLOOR))
17112    (use (match_operand:HI 2 "memory_operand" ""))
17113    (use (match_operand:HI 3 "memory_operand" ""))
17114    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17115   "reload_completed"
17116   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17117                                   UNSPEC_FIST_FLOOR))
17118               (use (match_dup 2))
17119               (use (match_dup 3))])
17120    (set (match_dup 0) (match_dup 4))]
17121   "")
17122
17123 (define_split 
17124   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17125         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17126          UNSPEC_FIST_FLOOR))
17127    (use (match_operand:HI 2 "memory_operand" ""))
17128    (use (match_operand:HI 3 "memory_operand" ""))
17129    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17130   "reload_completed"
17131   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17132                                   UNSPEC_FIST_FLOOR))
17133               (use (match_dup 2))
17134               (use (match_dup 3))])]
17135   "")
17136
17137 (define_expand "lfloor<mode>2"
17138   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17139                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17140                     UNSPEC_FIST_FLOOR))
17141               (clobber (reg:CC FLAGS_REG))])]
17142   "TARGET_USE_FANCY_MATH_387
17143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17144    && flag_unsafe_math_optimizations"
17145   "")
17146
17147 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17148 (define_insn_and_split "frndintxf2_ceil"
17149   [(set (match_operand:XF 0 "register_operand" "=f")
17150         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17151          UNSPEC_FRNDINT_CEIL))
17152    (clobber (reg:CC FLAGS_REG))]
17153   "TARGET_USE_FANCY_MATH_387
17154    && flag_unsafe_math_optimizations
17155    && !(reload_completed || reload_in_progress)"
17156   "#"
17157   "&& 1"
17158   [(const_int 0)]
17159 {
17160   ix86_optimize_mode_switching[I387_CEIL] = 1;
17161
17162   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17163   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17164
17165   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17166                                        operands[2], operands[3]));
17167   DONE;
17168 }
17169   [(set_attr "type" "frndint")
17170    (set_attr "i387_cw" "ceil")
17171    (set_attr "mode" "XF")])
17172
17173 (define_insn "frndintxf2_ceil_i387"
17174   [(set (match_operand:XF 0 "register_operand" "=f")
17175         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17176          UNSPEC_FRNDINT_CEIL))
17177    (use (match_operand:HI 2 "memory_operand" "m"))
17178    (use (match_operand:HI 3 "memory_operand" "m"))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && flag_unsafe_math_optimizations"
17181   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17182   [(set_attr "type" "frndint")
17183    (set_attr "i387_cw" "ceil")
17184    (set_attr "mode" "XF")])
17185
17186 (define_expand "ceilxf2"
17187   [(use (match_operand:XF 0 "register_operand" ""))
17188    (use (match_operand:XF 1 "register_operand" ""))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations"
17191 {
17192   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17193   DONE;
17194 })
17195
17196 (define_expand "ceildf2"
17197   [(use (match_operand:DF 0 "register_operand" ""))
17198    (use (match_operand:DF 1 "register_operand" ""))]
17199   "TARGET_USE_FANCY_MATH_387
17200    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17201    && flag_unsafe_math_optimizations"
17202 {
17203   rtx op0 = gen_reg_rtx (XFmode);
17204   rtx op1 = gen_reg_rtx (XFmode);
17205
17206   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17207   emit_insn (gen_frndintxf2_ceil (op0, op1));
17208
17209   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17210   DONE;
17211 })
17212
17213 (define_expand "ceilsf2"
17214   [(use (match_operand:SF 0 "register_operand" ""))
17215    (use (match_operand:SF 1 "register_operand" ""))]
17216   "TARGET_USE_FANCY_MATH_387
17217    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17218    && flag_unsafe_math_optimizations"
17219 {
17220   rtx op0 = gen_reg_rtx (XFmode);
17221   rtx op1 = gen_reg_rtx (XFmode);
17222
17223   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17224   emit_insn (gen_frndintxf2_ceil (op0, op1));
17225
17226   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17227   DONE;
17228 })
17229
17230 (define_insn_and_split "*fist<mode>2_ceil_1"
17231   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17232         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17233          UNSPEC_FIST_CEIL))
17234    (clobber (reg:CC FLAGS_REG))]
17235   "TARGET_USE_FANCY_MATH_387
17236    && flag_unsafe_math_optimizations
17237    && !(reload_completed || reload_in_progress)"
17238   "#"
17239   "&& 1"
17240   [(const_int 0)]
17241 {
17242   ix86_optimize_mode_switching[I387_CEIL] = 1;
17243
17244   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17245   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17246   if (memory_operand (operands[0], VOIDmode))
17247     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17248                                      operands[2], operands[3]));
17249   else
17250     {
17251       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17252       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17253                                                  operands[2], operands[3],
17254                                                  operands[4]));
17255     }
17256   DONE;
17257 }
17258   [(set_attr "type" "fistp")
17259    (set_attr "i387_cw" "ceil")
17260    (set_attr "mode" "<MODE>")])
17261
17262 (define_insn "fistdi2_ceil"
17263   [(set (match_operand:DI 0 "memory_operand" "=m")
17264         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17265          UNSPEC_FIST_CEIL))
17266    (use (match_operand:HI 2 "memory_operand" "m"))
17267    (use (match_operand:HI 3 "memory_operand" "m"))
17268    (clobber (match_scratch:XF 4 "=&1f"))]
17269   "TARGET_USE_FANCY_MATH_387
17270    && flag_unsafe_math_optimizations"
17271   "* return output_fix_trunc (insn, operands, 0);"
17272   [(set_attr "type" "fistp")
17273    (set_attr "i387_cw" "ceil")
17274    (set_attr "mode" "DI")])
17275
17276 (define_insn "fistdi2_ceil_with_temp"
17277   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17278         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17279          UNSPEC_FIST_CEIL))
17280    (use (match_operand:HI 2 "memory_operand" "m,m"))
17281    (use (match_operand:HI 3 "memory_operand" "m,m"))
17282    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17283    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17284   "TARGET_USE_FANCY_MATH_387
17285    && flag_unsafe_math_optimizations"
17286   "#"
17287   [(set_attr "type" "fistp")
17288    (set_attr "i387_cw" "ceil")
17289    (set_attr "mode" "DI")])
17290
17291 (define_split 
17292   [(set (match_operand:DI 0 "register_operand" "")
17293         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17294          UNSPEC_FIST_CEIL))
17295    (use (match_operand:HI 2 "memory_operand" ""))
17296    (use (match_operand:HI 3 "memory_operand" ""))
17297    (clobber (match_operand:DI 4 "memory_operand" ""))
17298    (clobber (match_scratch 5 ""))]
17299   "reload_completed"
17300   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17301               (use (match_dup 2))
17302               (use (match_dup 3))
17303               (clobber (match_dup 5))])
17304    (set (match_dup 0) (match_dup 4))]
17305   "")
17306
17307 (define_split 
17308   [(set (match_operand:DI 0 "memory_operand" "")
17309         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17310          UNSPEC_FIST_CEIL))
17311    (use (match_operand:HI 2 "memory_operand" ""))
17312    (use (match_operand:HI 3 "memory_operand" ""))
17313    (clobber (match_operand:DI 4 "memory_operand" ""))
17314    (clobber (match_scratch 5 ""))]
17315   "reload_completed"
17316   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17317               (use (match_dup 2))
17318               (use (match_dup 3))
17319               (clobber (match_dup 5))])]
17320   "")
17321
17322 (define_insn "fist<mode>2_ceil"
17323   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17324         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17325          UNSPEC_FIST_CEIL))
17326    (use (match_operand:HI 2 "memory_operand" "m"))
17327    (use (match_operand:HI 3 "memory_operand" "m"))]
17328   "TARGET_USE_FANCY_MATH_387
17329    && flag_unsafe_math_optimizations"
17330   "* return output_fix_trunc (insn, operands, 0);"
17331   [(set_attr "type" "fistp")
17332    (set_attr "i387_cw" "ceil")
17333    (set_attr "mode" "<MODE>")])
17334
17335 (define_insn "fist<mode>2_ceil_with_temp"
17336   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17337         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17338          UNSPEC_FIST_CEIL))
17339    (use (match_operand:HI 2 "memory_operand" "m,m"))
17340    (use (match_operand:HI 3 "memory_operand" "m,m"))
17341    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17342   "TARGET_USE_FANCY_MATH_387
17343    && flag_unsafe_math_optimizations"
17344   "#"
17345   [(set_attr "type" "fistp")
17346    (set_attr "i387_cw" "ceil")
17347    (set_attr "mode" "<MODE>")])
17348
17349 (define_split 
17350   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17351         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17352          UNSPEC_FIST_CEIL))
17353    (use (match_operand:HI 2 "memory_operand" ""))
17354    (use (match_operand:HI 3 "memory_operand" ""))
17355    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17356   "reload_completed"
17357   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17358                                   UNSPEC_FIST_CEIL))
17359               (use (match_dup 2))
17360               (use (match_dup 3))])
17361    (set (match_dup 0) (match_dup 4))]
17362   "")
17363
17364 (define_split 
17365   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17366         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17367          UNSPEC_FIST_CEIL))
17368    (use (match_operand:HI 2 "memory_operand" ""))
17369    (use (match_operand:HI 3 "memory_operand" ""))
17370    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17371   "reload_completed"
17372   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17373                                   UNSPEC_FIST_CEIL))
17374               (use (match_dup 2))
17375               (use (match_dup 3))])]
17376   "")
17377
17378 (define_expand "lceil<mode>2"
17379   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17380                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17381                     UNSPEC_FIST_CEIL))
17382               (clobber (reg:CC FLAGS_REG))])]
17383   "TARGET_USE_FANCY_MATH_387
17384    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17385    && flag_unsafe_math_optimizations"
17386   "")
17387
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_trunc"
17390   [(set (match_operand:XF 0 "register_operand" "=f")
17391         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17392          UNSPEC_FRNDINT_TRUNC))
17393    (clobber (reg:CC FLAGS_REG))]
17394   "TARGET_USE_FANCY_MATH_387
17395    && flag_unsafe_math_optimizations
17396    && !(reload_completed || reload_in_progress)"
17397   "#"
17398   "&& 1"
17399   [(const_int 0)]
17400 {
17401   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17402
17403   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17405
17406   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17407                                         operands[2], operands[3]));
17408   DONE;
17409 }
17410   [(set_attr "type" "frndint")
17411    (set_attr "i387_cw" "trunc")
17412    (set_attr "mode" "XF")])
17413
17414 (define_insn "frndintxf2_trunc_i387"
17415   [(set (match_operand:XF 0 "register_operand" "=f")
17416         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417          UNSPEC_FRNDINT_TRUNC))
17418    (use (match_operand:HI 2 "memory_operand" "m"))
17419    (use (match_operand:HI 3 "memory_operand" "m"))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations"
17422   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17423   [(set_attr "type" "frndint")
17424    (set_attr "i387_cw" "trunc")
17425    (set_attr "mode" "XF")])
17426
17427 (define_expand "btruncxf2"
17428   [(use (match_operand:XF 0 "register_operand" ""))
17429    (use (match_operand:XF 1 "register_operand" ""))]
17430   "TARGET_USE_FANCY_MATH_387
17431    && flag_unsafe_math_optimizations"
17432 {
17433   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17434   DONE;
17435 })
17436
17437 (define_expand "btruncdf2"
17438   [(use (match_operand:DF 0 "register_operand" ""))
17439    (use (match_operand:DF 1 "register_operand" ""))]
17440   "TARGET_USE_FANCY_MATH_387
17441    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442    && flag_unsafe_math_optimizations"
17443 {
17444   rtx op0 = gen_reg_rtx (XFmode);
17445   rtx op1 = gen_reg_rtx (XFmode);
17446
17447   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448   emit_insn (gen_frndintxf2_trunc (op0, op1));
17449
17450   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17451   DONE;
17452 })
17453
17454 (define_expand "btruncsf2"
17455   [(use (match_operand:SF 0 "register_operand" ""))
17456    (use (match_operand:SF 1 "register_operand" ""))]
17457   "TARGET_USE_FANCY_MATH_387
17458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459    && flag_unsafe_math_optimizations"
17460 {
17461   rtx op0 = gen_reg_rtx (XFmode);
17462   rtx op1 = gen_reg_rtx (XFmode);
17463
17464   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465   emit_insn (gen_frndintxf2_trunc (op0, op1));
17466
17467   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17468   DONE;
17469 })
17470
17471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17472 (define_insn_and_split "frndintxf2_mask_pm"
17473   [(set (match_operand:XF 0 "register_operand" "=f")
17474         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17475          UNSPEC_FRNDINT_MASK_PM))
17476    (clobber (reg:CC FLAGS_REG))]
17477   "TARGET_USE_FANCY_MATH_387
17478    && flag_unsafe_math_optimizations
17479    && !(reload_completed || reload_in_progress)"
17480   "#"
17481   "&& 1"
17482   [(const_int 0)]
17483 {
17484   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17485
17486   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17487   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17488
17489   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17490                                           operands[2], operands[3]));
17491   DONE;
17492 }
17493   [(set_attr "type" "frndint")
17494    (set_attr "i387_cw" "mask_pm")
17495    (set_attr "mode" "XF")])
17496
17497 (define_insn "frndintxf2_mask_pm_i387"
17498   [(set (match_operand:XF 0 "register_operand" "=f")
17499         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17500          UNSPEC_FRNDINT_MASK_PM))
17501    (use (match_operand:HI 2 "memory_operand" "m"))
17502    (use (match_operand:HI 3 "memory_operand" "m"))]
17503   "TARGET_USE_FANCY_MATH_387
17504    && flag_unsafe_math_optimizations"
17505   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17506   [(set_attr "type" "frndint")
17507    (set_attr "i387_cw" "mask_pm")
17508    (set_attr "mode" "XF")])
17509
17510 (define_expand "nearbyintxf2"
17511   [(use (match_operand:XF 0 "register_operand" ""))
17512    (use (match_operand:XF 1 "register_operand" ""))]
17513   "TARGET_USE_FANCY_MATH_387
17514    && flag_unsafe_math_optimizations"
17515 {
17516   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17517
17518   DONE;
17519 })
17520
17521 (define_expand "nearbyintdf2"
17522   [(use (match_operand:DF 0 "register_operand" ""))
17523    (use (match_operand:DF 1 "register_operand" ""))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17526    && flag_unsafe_math_optimizations"
17527 {
17528   rtx op0 = gen_reg_rtx (XFmode);
17529   rtx op1 = gen_reg_rtx (XFmode);
17530
17531   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17532   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17533
17534   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17535   DONE;
17536 })
17537
17538 (define_expand "nearbyintsf2"
17539   [(use (match_operand:SF 0 "register_operand" ""))
17540    (use (match_operand:SF 1 "register_operand" ""))]
17541   "TARGET_USE_FANCY_MATH_387
17542    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17543    && flag_unsafe_math_optimizations"
17544 {
17545   rtx op0 = gen_reg_rtx (XFmode);
17546   rtx op1 = gen_reg_rtx (XFmode);
17547
17548   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17549   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17550
17551   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17552   DONE;
17553 })
17554
17555 \f
17556 ;; Block operation instructions
17557
17558 (define_insn "cld"
17559  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17560  ""
17561  "cld"
17562   [(set_attr "type" "cld")])
17563
17564 (define_expand "movmemsi"
17565   [(use (match_operand:BLK 0 "memory_operand" ""))
17566    (use (match_operand:BLK 1 "memory_operand" ""))
17567    (use (match_operand:SI 2 "nonmemory_operand" ""))
17568    (use (match_operand:SI 3 "const_int_operand" ""))]
17569   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17570 {
17571  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17572    DONE;
17573  else
17574    FAIL;
17575 })
17576
17577 (define_expand "movmemdi"
17578   [(use (match_operand:BLK 0 "memory_operand" ""))
17579    (use (match_operand:BLK 1 "memory_operand" ""))
17580    (use (match_operand:DI 2 "nonmemory_operand" ""))
17581    (use (match_operand:DI 3 "const_int_operand" ""))]
17582   "TARGET_64BIT"
17583 {
17584  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17585    DONE;
17586  else
17587    FAIL;
17588 })
17589
17590 ;; Most CPUs don't like single string operations
17591 ;; Handle this case here to simplify previous expander.
17592
17593 (define_expand "strmov"
17594   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17595    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17596    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17597               (clobber (reg:CC FLAGS_REG))])
17598    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17599               (clobber (reg:CC FLAGS_REG))])]
17600   ""
17601 {
17602   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17603
17604   /* If .md ever supports :P for Pmode, these can be directly
17605      in the pattern above.  */
17606   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17607   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17608
17609   if (TARGET_SINGLE_STRINGOP || optimize_size)
17610     {
17611       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17612                                       operands[2], operands[3],
17613                                       operands[5], operands[6]));
17614       DONE;
17615     }
17616
17617   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17618 })
17619
17620 (define_expand "strmov_singleop"
17621   [(parallel [(set (match_operand 1 "memory_operand" "")
17622                    (match_operand 3 "memory_operand" ""))
17623               (set (match_operand 0 "register_operand" "")
17624                    (match_operand 4 "" ""))
17625               (set (match_operand 2 "register_operand" "")
17626                    (match_operand 5 "" ""))
17627               (use (reg:SI DIRFLAG_REG))])]
17628   "TARGET_SINGLE_STRINGOP || optimize_size"
17629   "")
17630
17631 (define_insn "*strmovdi_rex_1"
17632   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17633         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17634    (set (match_operand:DI 0 "register_operand" "=D")
17635         (plus:DI (match_dup 2)
17636                  (const_int 8)))
17637    (set (match_operand:DI 1 "register_operand" "=S")
17638         (plus:DI (match_dup 3)
17639                  (const_int 8)))
17640    (use (reg:SI DIRFLAG_REG))]
17641   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17642   "movsq"
17643   [(set_attr "type" "str")
17644    (set_attr "mode" "DI")
17645    (set_attr "memory" "both")])
17646
17647 (define_insn "*strmovsi_1"
17648   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17649         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17650    (set (match_operand:SI 0 "register_operand" "=D")
17651         (plus:SI (match_dup 2)
17652                  (const_int 4)))
17653    (set (match_operand:SI 1 "register_operand" "=S")
17654         (plus:SI (match_dup 3)
17655                  (const_int 4)))
17656    (use (reg:SI DIRFLAG_REG))]
17657   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17658   "{movsl|movsd}"
17659   [(set_attr "type" "str")
17660    (set_attr "mode" "SI")
17661    (set_attr "memory" "both")])
17662
17663 (define_insn "*strmovsi_rex_1"
17664   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17665         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17666    (set (match_operand:DI 0 "register_operand" "=D")
17667         (plus:DI (match_dup 2)
17668                  (const_int 4)))
17669    (set (match_operand:DI 1 "register_operand" "=S")
17670         (plus:DI (match_dup 3)
17671                  (const_int 4)))
17672    (use (reg:SI DIRFLAG_REG))]
17673   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17674   "{movsl|movsd}"
17675   [(set_attr "type" "str")
17676    (set_attr "mode" "SI")
17677    (set_attr "memory" "both")])
17678
17679 (define_insn "*strmovhi_1"
17680   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17681         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17682    (set (match_operand:SI 0 "register_operand" "=D")
17683         (plus:SI (match_dup 2)
17684                  (const_int 2)))
17685    (set (match_operand:SI 1 "register_operand" "=S")
17686         (plus:SI (match_dup 3)
17687                  (const_int 2)))
17688    (use (reg:SI DIRFLAG_REG))]
17689   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17690   "movsw"
17691   [(set_attr "type" "str")
17692    (set_attr "memory" "both")
17693    (set_attr "mode" "HI")])
17694
17695 (define_insn "*strmovhi_rex_1"
17696   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17697         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17698    (set (match_operand:DI 0 "register_operand" "=D")
17699         (plus:DI (match_dup 2)
17700                  (const_int 2)))
17701    (set (match_operand:DI 1 "register_operand" "=S")
17702         (plus:DI (match_dup 3)
17703                  (const_int 2)))
17704    (use (reg:SI DIRFLAG_REG))]
17705   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17706   "movsw"
17707   [(set_attr "type" "str")
17708    (set_attr "memory" "both")
17709    (set_attr "mode" "HI")])
17710
17711 (define_insn "*strmovqi_1"
17712   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17713         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17714    (set (match_operand:SI 0 "register_operand" "=D")
17715         (plus:SI (match_dup 2)
17716                  (const_int 1)))
17717    (set (match_operand:SI 1 "register_operand" "=S")
17718         (plus:SI (match_dup 3)
17719                  (const_int 1)))
17720    (use (reg:SI DIRFLAG_REG))]
17721   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17722   "movsb"
17723   [(set_attr "type" "str")
17724    (set_attr "memory" "both")
17725    (set_attr "mode" "QI")])
17726
17727 (define_insn "*strmovqi_rex_1"
17728   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17729         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17730    (set (match_operand:DI 0 "register_operand" "=D")
17731         (plus:DI (match_dup 2)
17732                  (const_int 1)))
17733    (set (match_operand:DI 1 "register_operand" "=S")
17734         (plus:DI (match_dup 3)
17735                  (const_int 1)))
17736    (use (reg:SI DIRFLAG_REG))]
17737   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17738   "movsb"
17739   [(set_attr "type" "str")
17740    (set_attr "memory" "both")
17741    (set_attr "mode" "QI")])
17742
17743 (define_expand "rep_mov"
17744   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17745               (set (match_operand 0 "register_operand" "")
17746                    (match_operand 5 "" ""))
17747               (set (match_operand 2 "register_operand" "")
17748                    (match_operand 6 "" ""))
17749               (set (match_operand 1 "memory_operand" "")
17750                    (match_operand 3 "memory_operand" ""))
17751               (use (match_dup 4))
17752               (use (reg:SI DIRFLAG_REG))])]
17753   ""
17754   "")
17755
17756 (define_insn "*rep_movdi_rex64"
17757   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17758    (set (match_operand:DI 0 "register_operand" "=D") 
17759         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17760                             (const_int 3))
17761                  (match_operand:DI 3 "register_operand" "0")))
17762    (set (match_operand:DI 1 "register_operand" "=S") 
17763         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17764                  (match_operand:DI 4 "register_operand" "1")))
17765    (set (mem:BLK (match_dup 3))
17766         (mem:BLK (match_dup 4)))
17767    (use (match_dup 5))
17768    (use (reg:SI DIRFLAG_REG))]
17769   "TARGET_64BIT"
17770   "{rep\;movsq|rep movsq}"
17771   [(set_attr "type" "str")
17772    (set_attr "prefix_rep" "1")
17773    (set_attr "memory" "both")
17774    (set_attr "mode" "DI")])
17775
17776 (define_insn "*rep_movsi"
17777   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17778    (set (match_operand:SI 0 "register_operand" "=D") 
17779         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17780                             (const_int 2))
17781                  (match_operand:SI 3 "register_operand" "0")))
17782    (set (match_operand:SI 1 "register_operand" "=S") 
17783         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17784                  (match_operand:SI 4 "register_operand" "1")))
17785    (set (mem:BLK (match_dup 3))
17786         (mem:BLK (match_dup 4)))
17787    (use (match_dup 5))
17788    (use (reg:SI DIRFLAG_REG))]
17789   "!TARGET_64BIT"
17790   "{rep\;movsl|rep movsd}"
17791   [(set_attr "type" "str")
17792    (set_attr "prefix_rep" "1")
17793    (set_attr "memory" "both")
17794    (set_attr "mode" "SI")])
17795
17796 (define_insn "*rep_movsi_rex64"
17797   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17798    (set (match_operand:DI 0 "register_operand" "=D") 
17799         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17800                             (const_int 2))
17801                  (match_operand:DI 3 "register_operand" "0")))
17802    (set (match_operand:DI 1 "register_operand" "=S") 
17803         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17804                  (match_operand:DI 4 "register_operand" "1")))
17805    (set (mem:BLK (match_dup 3))
17806         (mem:BLK (match_dup 4)))
17807    (use (match_dup 5))
17808    (use (reg:SI DIRFLAG_REG))]
17809   "TARGET_64BIT"
17810   "{rep\;movsl|rep movsd}"
17811   [(set_attr "type" "str")
17812    (set_attr "prefix_rep" "1")
17813    (set_attr "memory" "both")
17814    (set_attr "mode" "SI")])
17815
17816 (define_insn "*rep_movqi"
17817   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17818    (set (match_operand:SI 0 "register_operand" "=D") 
17819         (plus:SI (match_operand:SI 3 "register_operand" "0")
17820                  (match_operand:SI 5 "register_operand" "2")))
17821    (set (match_operand:SI 1 "register_operand" "=S") 
17822         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17823    (set (mem:BLK (match_dup 3))
17824         (mem:BLK (match_dup 4)))
17825    (use (match_dup 5))
17826    (use (reg:SI DIRFLAG_REG))]
17827   "!TARGET_64BIT"
17828   "{rep\;movsb|rep movsb}"
17829   [(set_attr "type" "str")
17830    (set_attr "prefix_rep" "1")
17831    (set_attr "memory" "both")
17832    (set_attr "mode" "SI")])
17833
17834 (define_insn "*rep_movqi_rex64"
17835   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17836    (set (match_operand:DI 0 "register_operand" "=D") 
17837         (plus:DI (match_operand:DI 3 "register_operand" "0")
17838                  (match_operand:DI 5 "register_operand" "2")))
17839    (set (match_operand:DI 1 "register_operand" "=S") 
17840         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17841    (set (mem:BLK (match_dup 3))
17842         (mem:BLK (match_dup 4)))
17843    (use (match_dup 5))
17844    (use (reg:SI DIRFLAG_REG))]
17845   "TARGET_64BIT"
17846   "{rep\;movsb|rep movsb}"
17847   [(set_attr "type" "str")
17848    (set_attr "prefix_rep" "1")
17849    (set_attr "memory" "both")
17850    (set_attr "mode" "SI")])
17851
17852 (define_expand "setmemsi"
17853    [(use (match_operand:BLK 0 "memory_operand" ""))
17854     (use (match_operand:SI 1 "nonmemory_operand" ""))
17855     (use (match_operand 2 "const_int_operand" ""))
17856     (use (match_operand 3 "const_int_operand" ""))]
17857   ""
17858 {
17859  /* If value to set is not zero, use the library routine.  */
17860  if (operands[2] != const0_rtx)
17861    FAIL;
17862
17863  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17864    DONE;
17865  else
17866    FAIL;
17867 })
17868
17869 (define_expand "setmemdi"
17870    [(use (match_operand:BLK 0 "memory_operand" ""))
17871     (use (match_operand:DI 1 "nonmemory_operand" ""))
17872     (use (match_operand 2 "const_int_operand" ""))
17873     (use (match_operand 3 "const_int_operand" ""))]
17874   "TARGET_64BIT"
17875 {
17876  /* If value to set is not zero, use the library routine.  */
17877  if (operands[2] != const0_rtx)
17878    FAIL;
17879
17880  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17881    DONE;
17882  else
17883    FAIL;
17884 })
17885
17886 ;; Most CPUs don't like single string operations
17887 ;; Handle this case here to simplify previous expander.
17888
17889 (define_expand "strset"
17890   [(set (match_operand 1 "memory_operand" "")
17891         (match_operand 2 "register_operand" ""))
17892    (parallel [(set (match_operand 0 "register_operand" "")
17893                    (match_dup 3))
17894               (clobber (reg:CC FLAGS_REG))])]
17895   ""
17896 {
17897   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17898     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17899
17900   /* If .md ever supports :P for Pmode, this can be directly
17901      in the pattern above.  */
17902   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17903                               GEN_INT (GET_MODE_SIZE (GET_MODE
17904                                                       (operands[2]))));
17905   if (TARGET_SINGLE_STRINGOP || optimize_size)
17906     {
17907       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17908                                       operands[3]));
17909       DONE;
17910     }
17911 })
17912
17913 (define_expand "strset_singleop"
17914   [(parallel [(set (match_operand 1 "memory_operand" "")
17915                    (match_operand 2 "register_operand" ""))
17916               (set (match_operand 0 "register_operand" "")
17917                    (match_operand 3 "" ""))
17918               (use (reg:SI DIRFLAG_REG))])]
17919   "TARGET_SINGLE_STRINGOP || optimize_size"
17920   "")
17921
17922 (define_insn "*strsetdi_rex_1"
17923   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17924         (match_operand:DI 2 "register_operand" "a"))
17925    (set (match_operand:DI 0 "register_operand" "=D")
17926         (plus:DI (match_dup 1)
17927                  (const_int 8)))
17928    (use (reg:SI DIRFLAG_REG))]
17929   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17930   "stosq"
17931   [(set_attr "type" "str")
17932    (set_attr "memory" "store")
17933    (set_attr "mode" "DI")])
17934
17935 (define_insn "*strsetsi_1"
17936   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17937         (match_operand:SI 2 "register_operand" "a"))
17938    (set (match_operand:SI 0 "register_operand" "=D")
17939         (plus:SI (match_dup 1)
17940                  (const_int 4)))
17941    (use (reg:SI DIRFLAG_REG))]
17942   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17943   "{stosl|stosd}"
17944   [(set_attr "type" "str")
17945    (set_attr "memory" "store")
17946    (set_attr "mode" "SI")])
17947
17948 (define_insn "*strsetsi_rex_1"
17949   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17950         (match_operand:SI 2 "register_operand" "a"))
17951    (set (match_operand:DI 0 "register_operand" "=D")
17952         (plus:DI (match_dup 1)
17953                  (const_int 4)))
17954    (use (reg:SI DIRFLAG_REG))]
17955   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17956   "{stosl|stosd}"
17957   [(set_attr "type" "str")
17958    (set_attr "memory" "store")
17959    (set_attr "mode" "SI")])
17960
17961 (define_insn "*strsethi_1"
17962   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17963         (match_operand:HI 2 "register_operand" "a"))
17964    (set (match_operand:SI 0 "register_operand" "=D")
17965         (plus:SI (match_dup 1)
17966                  (const_int 2)))
17967    (use (reg:SI DIRFLAG_REG))]
17968   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17969   "stosw"
17970   [(set_attr "type" "str")
17971    (set_attr "memory" "store")
17972    (set_attr "mode" "HI")])
17973
17974 (define_insn "*strsethi_rex_1"
17975   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17976         (match_operand:HI 2 "register_operand" "a"))
17977    (set (match_operand:DI 0 "register_operand" "=D")
17978         (plus:DI (match_dup 1)
17979                  (const_int 2)))
17980    (use (reg:SI DIRFLAG_REG))]
17981   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17982   "stosw"
17983   [(set_attr "type" "str")
17984    (set_attr "memory" "store")
17985    (set_attr "mode" "HI")])
17986
17987 (define_insn "*strsetqi_1"
17988   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17989         (match_operand:QI 2 "register_operand" "a"))
17990    (set (match_operand:SI 0 "register_operand" "=D")
17991         (plus:SI (match_dup 1)
17992                  (const_int 1)))
17993    (use (reg:SI DIRFLAG_REG))]
17994   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17995   "stosb"
17996   [(set_attr "type" "str")
17997    (set_attr "memory" "store")
17998    (set_attr "mode" "QI")])
17999
18000 (define_insn "*strsetqi_rex_1"
18001   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18002         (match_operand:QI 2 "register_operand" "a"))
18003    (set (match_operand:DI 0 "register_operand" "=D")
18004         (plus:DI (match_dup 1)
18005                  (const_int 1)))
18006    (use (reg:SI DIRFLAG_REG))]
18007   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18008   "stosb"
18009   [(set_attr "type" "str")
18010    (set_attr "memory" "store")
18011    (set_attr "mode" "QI")])
18012
18013 (define_expand "rep_stos"
18014   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18015               (set (match_operand 0 "register_operand" "")
18016                    (match_operand 4 "" ""))
18017               (set (match_operand 2 "memory_operand" "") (const_int 0))
18018               (use (match_operand 3 "register_operand" ""))
18019               (use (match_dup 1))
18020               (use (reg:SI DIRFLAG_REG))])]
18021   ""
18022   "")
18023
18024 (define_insn "*rep_stosdi_rex64"
18025   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18026    (set (match_operand:DI 0 "register_operand" "=D") 
18027         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18028                             (const_int 3))
18029                  (match_operand:DI 3 "register_operand" "0")))
18030    (set (mem:BLK (match_dup 3))
18031         (const_int 0))
18032    (use (match_operand:DI 2 "register_operand" "a"))
18033    (use (match_dup 4))
18034    (use (reg:SI DIRFLAG_REG))]
18035   "TARGET_64BIT"
18036   "{rep\;stosq|rep stosq}"
18037   [(set_attr "type" "str")
18038    (set_attr "prefix_rep" "1")
18039    (set_attr "memory" "store")
18040    (set_attr "mode" "DI")])
18041
18042 (define_insn "*rep_stossi"
18043   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18044    (set (match_operand:SI 0 "register_operand" "=D") 
18045         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18046                             (const_int 2))
18047                  (match_operand:SI 3 "register_operand" "0")))
18048    (set (mem:BLK (match_dup 3))
18049         (const_int 0))
18050    (use (match_operand:SI 2 "register_operand" "a"))
18051    (use (match_dup 4))
18052    (use (reg:SI DIRFLAG_REG))]
18053   "!TARGET_64BIT"
18054   "{rep\;stosl|rep stosd}"
18055   [(set_attr "type" "str")
18056    (set_attr "prefix_rep" "1")
18057    (set_attr "memory" "store")
18058    (set_attr "mode" "SI")])
18059
18060 (define_insn "*rep_stossi_rex64"
18061   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062    (set (match_operand:DI 0 "register_operand" "=D") 
18063         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18064                             (const_int 2))
18065                  (match_operand:DI 3 "register_operand" "0")))
18066    (set (mem:BLK (match_dup 3))
18067         (const_int 0))
18068    (use (match_operand:SI 2 "register_operand" "a"))
18069    (use (match_dup 4))
18070    (use (reg:SI DIRFLAG_REG))]
18071   "TARGET_64BIT"
18072   "{rep\;stosl|rep stosd}"
18073   [(set_attr "type" "str")
18074    (set_attr "prefix_rep" "1")
18075    (set_attr "memory" "store")
18076    (set_attr "mode" "SI")])
18077
18078 (define_insn "*rep_stosqi"
18079   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080    (set (match_operand:SI 0 "register_operand" "=D") 
18081         (plus:SI (match_operand:SI 3 "register_operand" "0")
18082                  (match_operand:SI 4 "register_operand" "1")))
18083    (set (mem:BLK (match_dup 3))
18084         (const_int 0))
18085    (use (match_operand:QI 2 "register_operand" "a"))
18086    (use (match_dup 4))
18087    (use (reg:SI DIRFLAG_REG))]
18088   "!TARGET_64BIT"
18089   "{rep\;stosb|rep stosb}"
18090   [(set_attr "type" "str")
18091    (set_attr "prefix_rep" "1")
18092    (set_attr "memory" "store")
18093    (set_attr "mode" "QI")])
18094
18095 (define_insn "*rep_stosqi_rex64"
18096   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18097    (set (match_operand:DI 0 "register_operand" "=D") 
18098         (plus:DI (match_operand:DI 3 "register_operand" "0")
18099                  (match_operand:DI 4 "register_operand" "1")))
18100    (set (mem:BLK (match_dup 3))
18101         (const_int 0))
18102    (use (match_operand:QI 2 "register_operand" "a"))
18103    (use (match_dup 4))
18104    (use (reg:SI DIRFLAG_REG))]
18105   "TARGET_64BIT"
18106   "{rep\;stosb|rep stosb}"
18107   [(set_attr "type" "str")
18108    (set_attr "prefix_rep" "1")
18109    (set_attr "memory" "store")
18110    (set_attr "mode" "QI")])
18111
18112 (define_expand "cmpstrnsi"
18113   [(set (match_operand:SI 0 "register_operand" "")
18114         (compare:SI (match_operand:BLK 1 "general_operand" "")
18115                     (match_operand:BLK 2 "general_operand" "")))
18116    (use (match_operand 3 "general_operand" ""))
18117    (use (match_operand 4 "immediate_operand" ""))]
18118   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18119 {
18120   rtx addr1, addr2, out, outlow, count, countreg, align;
18121
18122   /* Can't use this if the user has appropriated esi or edi.  */
18123   if (global_regs[4] || global_regs[5])
18124     FAIL;
18125
18126   out = operands[0];
18127   if (GET_CODE (out) != REG)
18128     out = gen_reg_rtx (SImode);
18129
18130   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18131   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18132   if (addr1 != XEXP (operands[1], 0))
18133     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18134   if (addr2 != XEXP (operands[2], 0))
18135     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18136
18137   count = operands[3];
18138   countreg = ix86_zero_extend_to_Pmode (count);
18139
18140   /* %%% Iff we are testing strict equality, we can use known alignment
18141      to good advantage.  This may be possible with combine, particularly
18142      once cc0 is dead.  */
18143   align = operands[4];
18144
18145   emit_insn (gen_cld ());
18146   if (GET_CODE (count) == CONST_INT)
18147     {
18148       if (INTVAL (count) == 0)
18149         {
18150           emit_move_insn (operands[0], const0_rtx);
18151           DONE;
18152         }
18153       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154                                      operands[1], operands[2]));
18155     }
18156   else
18157     {
18158       if (TARGET_64BIT)
18159         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18160       else
18161         emit_insn (gen_cmpsi_1 (countreg, countreg));
18162       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18163                                   operands[1], operands[2]));
18164     }
18165
18166   outlow = gen_lowpart (QImode, out);
18167   emit_insn (gen_cmpintqi (outlow));
18168   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18169
18170   if (operands[0] != out)
18171     emit_move_insn (operands[0], out);
18172
18173   DONE;
18174 })
18175
18176 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18177
18178 (define_expand "cmpintqi"
18179   [(set (match_dup 1)
18180         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181    (set (match_dup 2)
18182         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183    (parallel [(set (match_operand:QI 0 "register_operand" "")
18184                    (minus:QI (match_dup 1)
18185                              (match_dup 2)))
18186               (clobber (reg:CC FLAGS_REG))])]
18187   ""
18188   "operands[1] = gen_reg_rtx (QImode);
18189    operands[2] = gen_reg_rtx (QImode);")
18190
18191 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18192 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18193
18194 (define_expand "cmpstrnqi_nz_1"
18195   [(parallel [(set (reg:CC FLAGS_REG)
18196                    (compare:CC (match_operand 4 "memory_operand" "")
18197                                (match_operand 5 "memory_operand" "")))
18198               (use (match_operand 2 "register_operand" ""))
18199               (use (match_operand:SI 3 "immediate_operand" ""))
18200               (use (reg:SI DIRFLAG_REG))
18201               (clobber (match_operand 0 "register_operand" ""))
18202               (clobber (match_operand 1 "register_operand" ""))
18203               (clobber (match_dup 2))])]
18204   ""
18205   "")
18206
18207 (define_insn "*cmpstrnqi_nz_1"
18208   [(set (reg:CC FLAGS_REG)
18209         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18210                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18211    (use (match_operand:SI 6 "register_operand" "2"))
18212    (use (match_operand:SI 3 "immediate_operand" "i"))
18213    (use (reg:SI DIRFLAG_REG))
18214    (clobber (match_operand:SI 0 "register_operand" "=S"))
18215    (clobber (match_operand:SI 1 "register_operand" "=D"))
18216    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18217   "!TARGET_64BIT"
18218   "repz{\;| }cmpsb"
18219   [(set_attr "type" "str")
18220    (set_attr "mode" "QI")
18221    (set_attr "prefix_rep" "1")])
18222
18223 (define_insn "*cmpstrnqi_nz_rex_1"
18224   [(set (reg:CC FLAGS_REG)
18225         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18226                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18227    (use (match_operand:DI 6 "register_operand" "2"))
18228    (use (match_operand:SI 3 "immediate_operand" "i"))
18229    (use (reg:SI DIRFLAG_REG))
18230    (clobber (match_operand:DI 0 "register_operand" "=S"))
18231    (clobber (match_operand:DI 1 "register_operand" "=D"))
18232    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18233   "TARGET_64BIT"
18234   "repz{\;| }cmpsb"
18235   [(set_attr "type" "str")
18236    (set_attr "mode" "QI")
18237    (set_attr "prefix_rep" "1")])
18238
18239 ;; The same, but the count is not known to not be zero.
18240
18241 (define_expand "cmpstrnqi_1"
18242   [(parallel [(set (reg:CC FLAGS_REG)
18243                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18244                                      (const_int 0))
18245                   (compare:CC (match_operand 4 "memory_operand" "")
18246                               (match_operand 5 "memory_operand" ""))
18247                   (const_int 0)))
18248               (use (match_operand:SI 3 "immediate_operand" ""))
18249               (use (reg:CC FLAGS_REG))
18250               (use (reg:SI DIRFLAG_REG))
18251               (clobber (match_operand 0 "register_operand" ""))
18252               (clobber (match_operand 1 "register_operand" ""))
18253               (clobber (match_dup 2))])]
18254   ""
18255   "")
18256
18257 (define_insn "*cmpstrnqi_1"
18258   [(set (reg:CC FLAGS_REG)
18259         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18260                              (const_int 0))
18261           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18263           (const_int 0)))
18264    (use (match_operand:SI 3 "immediate_operand" "i"))
18265    (use (reg:CC FLAGS_REG))
18266    (use (reg:SI DIRFLAG_REG))
18267    (clobber (match_operand:SI 0 "register_operand" "=S"))
18268    (clobber (match_operand:SI 1 "register_operand" "=D"))
18269    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18270   "!TARGET_64BIT"
18271   "repz{\;| }cmpsb"
18272   [(set_attr "type" "str")
18273    (set_attr "mode" "QI")
18274    (set_attr "prefix_rep" "1")])
18275
18276 (define_insn "*cmpstrnqi_rex_1"
18277   [(set (reg:CC FLAGS_REG)
18278         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18279                              (const_int 0))
18280           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18282           (const_int 0)))
18283    (use (match_operand:SI 3 "immediate_operand" "i"))
18284    (use (reg:CC FLAGS_REG))
18285    (use (reg:SI DIRFLAG_REG))
18286    (clobber (match_operand:DI 0 "register_operand" "=S"))
18287    (clobber (match_operand:DI 1 "register_operand" "=D"))
18288    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18289   "TARGET_64BIT"
18290   "repz{\;| }cmpsb"
18291   [(set_attr "type" "str")
18292    (set_attr "mode" "QI")
18293    (set_attr "prefix_rep" "1")])
18294
18295 (define_expand "strlensi"
18296   [(set (match_operand:SI 0 "register_operand" "")
18297         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298                     (match_operand:QI 2 "immediate_operand" "")
18299                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18300   ""
18301 {
18302  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18303    DONE;
18304  else
18305    FAIL;
18306 })
18307
18308 (define_expand "strlendi"
18309   [(set (match_operand:DI 0 "register_operand" "")
18310         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311                     (match_operand:QI 2 "immediate_operand" "")
18312                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18313   ""
18314 {
18315  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18316    DONE;
18317  else
18318    FAIL;
18319 })
18320
18321 (define_expand "strlenqi_1"
18322   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323               (use (reg:SI DIRFLAG_REG))
18324               (clobber (match_operand 1 "register_operand" ""))
18325               (clobber (reg:CC FLAGS_REG))])]
18326   ""
18327   "")
18328
18329 (define_insn "*strlenqi_1"
18330   [(set (match_operand:SI 0 "register_operand" "=&c")
18331         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18332                     (match_operand:QI 2 "register_operand" "a")
18333                     (match_operand:SI 3 "immediate_operand" "i")
18334                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18335    (use (reg:SI DIRFLAG_REG))
18336    (clobber (match_operand:SI 1 "register_operand" "=D"))
18337    (clobber (reg:CC FLAGS_REG))]
18338   "!TARGET_64BIT"
18339   "repnz{\;| }scasb"
18340   [(set_attr "type" "str")
18341    (set_attr "mode" "QI")
18342    (set_attr "prefix_rep" "1")])
18343
18344 (define_insn "*strlenqi_rex_1"
18345   [(set (match_operand:DI 0 "register_operand" "=&c")
18346         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18347                     (match_operand:QI 2 "register_operand" "a")
18348                     (match_operand:DI 3 "immediate_operand" "i")
18349                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18350    (use (reg:SI DIRFLAG_REG))
18351    (clobber (match_operand:DI 1 "register_operand" "=D"))
18352    (clobber (reg:CC FLAGS_REG))]
18353   "TARGET_64BIT"
18354   "repnz{\;| }scasb"
18355   [(set_attr "type" "str")
18356    (set_attr "mode" "QI")
18357    (set_attr "prefix_rep" "1")])
18358
18359 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18360 ;; handled in combine, but it is not currently up to the task.
18361 ;; When used for their truth value, the cmpstrn* expanders generate
18362 ;; code like this:
18363 ;;
18364 ;;   repz cmpsb
18365 ;;   seta       %al
18366 ;;   setb       %dl
18367 ;;   cmpb       %al, %dl
18368 ;;   jcc        label
18369 ;;
18370 ;; The intermediate three instructions are unnecessary.
18371
18372 ;; This one handles cmpstrn*_nz_1...
18373 (define_peephole2
18374   [(parallel[
18375      (set (reg:CC FLAGS_REG)
18376           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18377                       (mem:BLK (match_operand 5 "register_operand" ""))))
18378      (use (match_operand 6 "register_operand" ""))
18379      (use (match_operand:SI 3 "immediate_operand" ""))
18380      (use (reg:SI DIRFLAG_REG))
18381      (clobber (match_operand 0 "register_operand" ""))
18382      (clobber (match_operand 1 "register_operand" ""))
18383      (clobber (match_operand 2 "register_operand" ""))])
18384    (set (match_operand:QI 7 "register_operand" "")
18385         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18386    (set (match_operand:QI 8 "register_operand" "")
18387         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388    (set (reg FLAGS_REG)
18389         (compare (match_dup 7) (match_dup 8)))
18390   ]
18391   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18392   [(parallel[
18393      (set (reg:CC FLAGS_REG)
18394           (compare:CC (mem:BLK (match_dup 4))
18395                       (mem:BLK (match_dup 5))))
18396      (use (match_dup 6))
18397      (use (match_dup 3))
18398      (use (reg:SI DIRFLAG_REG))
18399      (clobber (match_dup 0))
18400      (clobber (match_dup 1))
18401      (clobber (match_dup 2))])]
18402   "")
18403
18404 ;; ...and this one handles cmpstrn*_1.
18405 (define_peephole2
18406   [(parallel[
18407      (set (reg:CC FLAGS_REG)
18408           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18409                                (const_int 0))
18410             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18411                         (mem:BLK (match_operand 5 "register_operand" "")))
18412             (const_int 0)))
18413      (use (match_operand:SI 3 "immediate_operand" ""))
18414      (use (reg:CC FLAGS_REG))
18415      (use (reg:SI DIRFLAG_REG))
18416      (clobber (match_operand 0 "register_operand" ""))
18417      (clobber (match_operand 1 "register_operand" ""))
18418      (clobber (match_operand 2 "register_operand" ""))])
18419    (set (match_operand:QI 7 "register_operand" "")
18420         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18421    (set (match_operand:QI 8 "register_operand" "")
18422         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18423    (set (reg FLAGS_REG)
18424         (compare (match_dup 7) (match_dup 8)))
18425   ]
18426   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18427   [(parallel[
18428      (set (reg:CC FLAGS_REG)
18429           (if_then_else:CC (ne (match_dup 6)
18430                                (const_int 0))
18431             (compare:CC (mem:BLK (match_dup 4))
18432                         (mem:BLK (match_dup 5)))
18433             (const_int 0)))
18434      (use (match_dup 3))
18435      (use (reg:CC FLAGS_REG))
18436      (use (reg:SI DIRFLAG_REG))
18437      (clobber (match_dup 0))
18438      (clobber (match_dup 1))
18439      (clobber (match_dup 2))])]
18440   "")
18441
18442
18443 \f
18444 ;; Conditional move instructions.
18445
18446 (define_expand "movdicc"
18447   [(set (match_operand:DI 0 "register_operand" "")
18448         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18449                          (match_operand:DI 2 "general_operand" "")
18450                          (match_operand:DI 3 "general_operand" "")))]
18451   "TARGET_64BIT"
18452   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18453
18454 (define_insn "x86_movdicc_0_m1_rex64"
18455   [(set (match_operand:DI 0 "register_operand" "=r")
18456         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18457           (const_int -1)
18458           (const_int 0)))
18459    (clobber (reg:CC FLAGS_REG))]
18460   "TARGET_64BIT"
18461   "sbb{q}\t%0, %0"
18462   ; Since we don't have the proper number of operands for an alu insn,
18463   ; fill in all the blanks.
18464   [(set_attr "type" "alu")
18465    (set_attr "pent_pair" "pu")
18466    (set_attr "memory" "none")
18467    (set_attr "imm_disp" "false")
18468    (set_attr "mode" "DI")
18469    (set_attr "length_immediate" "0")])
18470
18471 (define_insn "*movdicc_c_rex64"
18472   [(set (match_operand:DI 0 "register_operand" "=r,r")
18473         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18474                                 [(reg FLAGS_REG) (const_int 0)])
18475                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18476                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18477   "TARGET_64BIT && TARGET_CMOVE
18478    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18479   "@
18480    cmov%O2%C1\t{%2, %0|%0, %2}
18481    cmov%O2%c1\t{%3, %0|%0, %3}"
18482   [(set_attr "type" "icmov")
18483    (set_attr "mode" "DI")])
18484
18485 (define_expand "movsicc"
18486   [(set (match_operand:SI 0 "register_operand" "")
18487         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18488                          (match_operand:SI 2 "general_operand" "")
18489                          (match_operand:SI 3 "general_operand" "")))]
18490   ""
18491   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18492
18493 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18494 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18495 ;; So just document what we're doing explicitly.
18496
18497 (define_insn "x86_movsicc_0_m1"
18498   [(set (match_operand:SI 0 "register_operand" "=r")
18499         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18500           (const_int -1)
18501           (const_int 0)))
18502    (clobber (reg:CC FLAGS_REG))]
18503   ""
18504   "sbb{l}\t%0, %0"
18505   ; Since we don't have the proper number of operands for an alu insn,
18506   ; fill in all the blanks.
18507   [(set_attr "type" "alu")
18508    (set_attr "pent_pair" "pu")
18509    (set_attr "memory" "none")
18510    (set_attr "imm_disp" "false")
18511    (set_attr "mode" "SI")
18512    (set_attr "length_immediate" "0")])
18513
18514 (define_insn "*movsicc_noc"
18515   [(set (match_operand:SI 0 "register_operand" "=r,r")
18516         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18517                                 [(reg FLAGS_REG) (const_int 0)])
18518                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18519                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18520   "TARGET_CMOVE
18521    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18522   "@
18523    cmov%O2%C1\t{%2, %0|%0, %2}
18524    cmov%O2%c1\t{%3, %0|%0, %3}"
18525   [(set_attr "type" "icmov")
18526    (set_attr "mode" "SI")])
18527
18528 (define_expand "movhicc"
18529   [(set (match_operand:HI 0 "register_operand" "")
18530         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18531                          (match_operand:HI 2 "general_operand" "")
18532                          (match_operand:HI 3 "general_operand" "")))]
18533   "TARGET_HIMODE_MATH"
18534   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18535
18536 (define_insn "*movhicc_noc"
18537   [(set (match_operand:HI 0 "register_operand" "=r,r")
18538         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18539                                 [(reg FLAGS_REG) (const_int 0)])
18540                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18541                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18542   "TARGET_CMOVE
18543    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18544   "@
18545    cmov%O2%C1\t{%2, %0|%0, %2}
18546    cmov%O2%c1\t{%3, %0|%0, %3}"
18547   [(set_attr "type" "icmov")
18548    (set_attr "mode" "HI")])
18549
18550 (define_expand "movqicc"
18551   [(set (match_operand:QI 0 "register_operand" "")
18552         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18553                          (match_operand:QI 2 "general_operand" "")
18554                          (match_operand:QI 3 "general_operand" "")))]
18555   "TARGET_QIMODE_MATH"
18556   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18557
18558 (define_insn_and_split "*movqicc_noc"
18559   [(set (match_operand:QI 0 "register_operand" "=r,r")
18560         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18561                                 [(match_operand 4 "flags_reg_operand" "")
18562                                  (const_int 0)])
18563                       (match_operand:QI 2 "register_operand" "r,0")
18564                       (match_operand:QI 3 "register_operand" "0,r")))]
18565   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18566   "#"
18567   "&& reload_completed"
18568   [(set (match_dup 0)
18569         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18570                       (match_dup 2)
18571                       (match_dup 3)))]
18572   "operands[0] = gen_lowpart (SImode, operands[0]);
18573    operands[2] = gen_lowpart (SImode, operands[2]);
18574    operands[3] = gen_lowpart (SImode, operands[3]);"
18575   [(set_attr "type" "icmov")
18576    (set_attr "mode" "SI")])
18577
18578 (define_expand "movsfcc"
18579   [(set (match_operand:SF 0 "register_operand" "")
18580         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18581                          (match_operand:SF 2 "register_operand" "")
18582                          (match_operand:SF 3 "register_operand" "")))]
18583   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18584   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18585
18586 (define_insn "*movsfcc_1_387"
18587   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18588         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18589                                 [(reg FLAGS_REG) (const_int 0)])
18590                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18591                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18592   "TARGET_80387 && TARGET_CMOVE
18593    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18594   "@
18595    fcmov%F1\t{%2, %0|%0, %2}
18596    fcmov%f1\t{%3, %0|%0, %3}
18597    cmov%O2%C1\t{%2, %0|%0, %2}
18598    cmov%O2%c1\t{%3, %0|%0, %3}"
18599   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18600    (set_attr "mode" "SF,SF,SI,SI")])
18601
18602 (define_expand "movdfcc"
18603   [(set (match_operand:DF 0 "register_operand" "")
18604         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18605                          (match_operand:DF 2 "register_operand" "")
18606                          (match_operand:DF 3 "register_operand" "")))]
18607   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18608   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18609
18610 (define_insn "*movdfcc_1"
18611   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18612         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18613                                 [(reg FLAGS_REG) (const_int 0)])
18614                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18615                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18616   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18617    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18618   "@
18619    fcmov%F1\t{%2, %0|%0, %2}
18620    fcmov%f1\t{%3, %0|%0, %3}
18621    #
18622    #"
18623   [(set_attr "type" "fcmov,fcmov,multi,multi")
18624    (set_attr "mode" "DF")])
18625
18626 (define_insn "*movdfcc_1_rex64"
18627   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18628         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18629                                 [(reg FLAGS_REG) (const_int 0)])
18630                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18631                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18632   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18633    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18634   "@
18635    fcmov%F1\t{%2, %0|%0, %2}
18636    fcmov%f1\t{%3, %0|%0, %3}
18637    cmov%O2%C1\t{%2, %0|%0, %2}
18638    cmov%O2%c1\t{%3, %0|%0, %3}"
18639   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18640    (set_attr "mode" "DF")])
18641
18642 (define_split
18643   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18644         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18645                                 [(match_operand 4 "flags_reg_operand" "")
18646                                  (const_int 0)])
18647                       (match_operand:DF 2 "nonimmediate_operand" "")
18648                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18649   "!TARGET_64BIT && reload_completed"
18650   [(set (match_dup 2)
18651         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18652                       (match_dup 5)
18653                       (match_dup 7)))
18654    (set (match_dup 3)
18655         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18656                       (match_dup 6)
18657                       (match_dup 8)))]
18658   "split_di (operands+2, 1, operands+5, operands+6);
18659    split_di (operands+3, 1, operands+7, operands+8);
18660    split_di (operands, 1, operands+2, operands+3);")
18661
18662 (define_expand "movxfcc"
18663   [(set (match_operand:XF 0 "register_operand" "")
18664         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18665                          (match_operand:XF 2 "register_operand" "")
18666                          (match_operand:XF 3 "register_operand" "")))]
18667   "TARGET_80387 && TARGET_CMOVE"
18668   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18669
18670 (define_insn "*movxfcc_1"
18671   [(set (match_operand:XF 0 "register_operand" "=f,f")
18672         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18673                                 [(reg FLAGS_REG) (const_int 0)])
18674                       (match_operand:XF 2 "register_operand" "f,0")
18675                       (match_operand:XF 3 "register_operand" "0,f")))]
18676   "TARGET_80387 && TARGET_CMOVE"
18677   "@
18678    fcmov%F1\t{%2, %0|%0, %2}
18679    fcmov%f1\t{%3, %0|%0, %3}"
18680   [(set_attr "type" "fcmov")
18681    (set_attr "mode" "XF")])
18682
18683 ;; These versions of the min/max patterns are intentionally ignorant of
18684 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18685 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18686 ;; are undefined in this condition, we're certain this is correct.
18687
18688 (define_insn "sminsf3"
18689   [(set (match_operand:SF 0 "register_operand" "=x")
18690         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18691                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18692   "TARGET_SSE_MATH"
18693   "minss\t{%2, %0|%0, %2}"
18694   [(set_attr "type" "sseadd")
18695    (set_attr "mode" "SF")])
18696
18697 (define_insn "smaxsf3"
18698   [(set (match_operand:SF 0 "register_operand" "=x")
18699         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18700                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18701   "TARGET_SSE_MATH"
18702   "maxss\t{%2, %0|%0, %2}"
18703   [(set_attr "type" "sseadd")
18704    (set_attr "mode" "SF")])
18705
18706 (define_insn "smindf3"
18707   [(set (match_operand:DF 0 "register_operand" "=x")
18708         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18709                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18710   "TARGET_SSE2 && TARGET_SSE_MATH"
18711   "minsd\t{%2, %0|%0, %2}"
18712   [(set_attr "type" "sseadd")
18713    (set_attr "mode" "DF")])
18714
18715 (define_insn "smaxdf3"
18716   [(set (match_operand:DF 0 "register_operand" "=x")
18717         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18718                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18719   "TARGET_SSE2 && TARGET_SSE_MATH"
18720   "maxsd\t{%2, %0|%0, %2}"
18721   [(set_attr "type" "sseadd")
18722    (set_attr "mode" "DF")])
18723
18724 ;; These versions of the min/max patterns implement exactly the operations
18725 ;;   min = (op1 < op2 ? op1 : op2)
18726 ;;   max = (!(op1 < op2) ? op1 : op2)
18727 ;; Their operands are not commutative, and thus they may be used in the
18728 ;; presence of -0.0 and NaN.
18729
18730 (define_insn "*ieee_sminsf3"
18731   [(set (match_operand:SF 0 "register_operand" "=x")
18732         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18734                    UNSPEC_IEEE_MIN))]
18735   "TARGET_SSE_MATH"
18736   "minss\t{%2, %0|%0, %2}"
18737   [(set_attr "type" "sseadd")
18738    (set_attr "mode" "SF")])
18739
18740 (define_insn "*ieee_smaxsf3"
18741   [(set (match_operand:SF 0 "register_operand" "=x")
18742         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18743                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18744                    UNSPEC_IEEE_MAX))]
18745   "TARGET_SSE_MATH"
18746   "maxss\t{%2, %0|%0, %2}"
18747   [(set_attr "type" "sseadd")
18748    (set_attr "mode" "SF")])
18749
18750 (define_insn "*ieee_smindf3"
18751   [(set (match_operand:DF 0 "register_operand" "=x")
18752         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18754                    UNSPEC_IEEE_MIN))]
18755   "TARGET_SSE2 && TARGET_SSE_MATH"
18756   "minsd\t{%2, %0|%0, %2}"
18757   [(set_attr "type" "sseadd")
18758    (set_attr "mode" "DF")])
18759
18760 (define_insn "*ieee_smaxdf3"
18761   [(set (match_operand:DF 0 "register_operand" "=x")
18762         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18763                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18764                    UNSPEC_IEEE_MAX))]
18765   "TARGET_SSE2 && TARGET_SSE_MATH"
18766   "maxsd\t{%2, %0|%0, %2}"
18767   [(set_attr "type" "sseadd")
18768    (set_attr "mode" "DF")])
18769
18770 ;; Conditional addition patterns
18771 (define_expand "addqicc"
18772   [(match_operand:QI 0 "register_operand" "")
18773    (match_operand 1 "comparison_operator" "")
18774    (match_operand:QI 2 "register_operand" "")
18775    (match_operand:QI 3 "const_int_operand" "")]
18776   ""
18777   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18778
18779 (define_expand "addhicc"
18780   [(match_operand:HI 0 "register_operand" "")
18781    (match_operand 1 "comparison_operator" "")
18782    (match_operand:HI 2 "register_operand" "")
18783    (match_operand:HI 3 "const_int_operand" "")]
18784   ""
18785   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18786
18787 (define_expand "addsicc"
18788   [(match_operand:SI 0 "register_operand" "")
18789    (match_operand 1 "comparison_operator" "")
18790    (match_operand:SI 2 "register_operand" "")
18791    (match_operand:SI 3 "const_int_operand" "")]
18792   ""
18793   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18794
18795 (define_expand "adddicc"
18796   [(match_operand:DI 0 "register_operand" "")
18797    (match_operand 1 "comparison_operator" "")
18798    (match_operand:DI 2 "register_operand" "")
18799    (match_operand:DI 3 "const_int_operand" "")]
18800   "TARGET_64BIT"
18801   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18802
18803 \f
18804 ;; Misc patterns (?)
18805
18806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18807 ;; Otherwise there will be nothing to keep
18808 ;; 
18809 ;; [(set (reg ebp) (reg esp))]
18810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18811 ;;  (clobber (eflags)]
18812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18813 ;;
18814 ;; in proper program order.
18815 (define_insn "pro_epilogue_adjust_stack_1"
18816   [(set (match_operand:SI 0 "register_operand" "=r,r")
18817         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18818                  (match_operand:SI 2 "immediate_operand" "i,i")))
18819    (clobber (reg:CC FLAGS_REG))
18820    (clobber (mem:BLK (scratch)))]
18821   "!TARGET_64BIT"
18822 {
18823   switch (get_attr_type (insn))
18824     {
18825     case TYPE_IMOV:
18826       return "mov{l}\t{%1, %0|%0, %1}";
18827
18828     case TYPE_ALU:
18829       if (GET_CODE (operands[2]) == CONST_INT
18830           && (INTVAL (operands[2]) == 128
18831               || (INTVAL (operands[2]) < 0
18832                   && INTVAL (operands[2]) != -128)))
18833         {
18834           operands[2] = GEN_INT (-INTVAL (operands[2]));
18835           return "sub{l}\t{%2, %0|%0, %2}";
18836         }
18837       return "add{l}\t{%2, %0|%0, %2}";
18838
18839     case TYPE_LEA:
18840       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18841       return "lea{l}\t{%a2, %0|%0, %a2}";
18842
18843     default:
18844       gcc_unreachable ();
18845     }
18846 }
18847   [(set (attr "type")
18848         (cond [(eq_attr "alternative" "0")
18849                  (const_string "alu")
18850                (match_operand:SI 2 "const0_operand" "")
18851                  (const_string "imov")
18852               ]
18853               (const_string "lea")))
18854    (set_attr "mode" "SI")])
18855
18856 (define_insn "pro_epilogue_adjust_stack_rex64"
18857   [(set (match_operand:DI 0 "register_operand" "=r,r")
18858         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18859                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18860    (clobber (reg:CC FLAGS_REG))
18861    (clobber (mem:BLK (scratch)))]
18862   "TARGET_64BIT"
18863 {
18864   switch (get_attr_type (insn))
18865     {
18866     case TYPE_IMOV:
18867       return "mov{q}\t{%1, %0|%0, %1}";
18868
18869     case TYPE_ALU:
18870       if (GET_CODE (operands[2]) == CONST_INT
18871           /* Avoid overflows.  */
18872           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18873           && (INTVAL (operands[2]) == 128
18874               || (INTVAL (operands[2]) < 0
18875                   && INTVAL (operands[2]) != -128)))
18876         {
18877           operands[2] = GEN_INT (-INTVAL (operands[2]));
18878           return "sub{q}\t{%2, %0|%0, %2}";
18879         }
18880       return "add{q}\t{%2, %0|%0, %2}";
18881
18882     case TYPE_LEA:
18883       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18884       return "lea{q}\t{%a2, %0|%0, %a2}";
18885
18886     default:
18887       gcc_unreachable ();
18888     }
18889 }
18890   [(set (attr "type")
18891         (cond [(eq_attr "alternative" "0")
18892                  (const_string "alu")
18893                (match_operand:DI 2 "const0_operand" "")
18894                  (const_string "imov")
18895               ]
18896               (const_string "lea")))
18897    (set_attr "mode" "DI")])
18898
18899 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18900   [(set (match_operand:DI 0 "register_operand" "=r,r")
18901         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18902                  (match_operand:DI 3 "immediate_operand" "i,i")))
18903    (use (match_operand:DI 2 "register_operand" "r,r"))
18904    (clobber (reg:CC FLAGS_REG))
18905    (clobber (mem:BLK (scratch)))]
18906   "TARGET_64BIT"
18907 {
18908   switch (get_attr_type (insn))
18909     {
18910     case TYPE_ALU:
18911       return "add{q}\t{%2, %0|%0, %2}";
18912
18913     case TYPE_LEA:
18914       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18915       return "lea{q}\t{%a2, %0|%0, %a2}";
18916
18917     default:
18918       gcc_unreachable ();
18919     }
18920 }
18921   [(set_attr "type" "alu,lea")
18922    (set_attr "mode" "DI")])
18923
18924 (define_expand "allocate_stack_worker"
18925   [(match_operand:SI 0 "register_operand" "")]
18926   "TARGET_STACK_PROBE"
18927 {
18928   if (reload_completed)
18929     {
18930       if (TARGET_64BIT)
18931         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18932       else
18933         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18934     }
18935   else
18936     {
18937       if (TARGET_64BIT)
18938         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18939       else
18940         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18941     }
18942   DONE;
18943 })
18944
18945 (define_insn "allocate_stack_worker_1"
18946   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18947     UNSPECV_STACK_PROBE)
18948    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18949    (clobber (match_scratch:SI 1 "=0"))
18950    (clobber (reg:CC FLAGS_REG))]
18951   "!TARGET_64BIT && TARGET_STACK_PROBE"
18952   "call\t__alloca"
18953   [(set_attr "type" "multi")
18954    (set_attr "length" "5")])
18955
18956 (define_expand "allocate_stack_worker_postreload"
18957   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18958                                     UNSPECV_STACK_PROBE)
18959               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18960               (clobber (match_dup 0))
18961               (clobber (reg:CC FLAGS_REG))])]
18962   ""
18963   "")
18964
18965 (define_insn "allocate_stack_worker_rex64"
18966   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18967     UNSPECV_STACK_PROBE)
18968    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18969    (clobber (match_scratch:DI 1 "=0"))
18970    (clobber (reg:CC FLAGS_REG))]
18971   "TARGET_64BIT && TARGET_STACK_PROBE"
18972   "call\t__alloca"
18973   [(set_attr "type" "multi")
18974    (set_attr "length" "5")])
18975
18976 (define_expand "allocate_stack_worker_rex64_postreload"
18977   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18978                                     UNSPECV_STACK_PROBE)
18979               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18980               (clobber (match_dup 0))
18981               (clobber (reg:CC FLAGS_REG))])]
18982   ""
18983   "")
18984
18985 (define_expand "allocate_stack"
18986   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18987                    (minus:SI (reg:SI SP_REG)
18988                              (match_operand:SI 1 "general_operand" "")))
18989               (clobber (reg:CC FLAGS_REG))])
18990    (parallel [(set (reg:SI SP_REG)
18991                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18992               (clobber (reg:CC FLAGS_REG))])]
18993   "TARGET_STACK_PROBE"
18994 {
18995 #ifdef CHECK_STACK_LIMIT
18996   if (GET_CODE (operands[1]) == CONST_INT
18997       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18998     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18999                            operands[1]));
19000   else 
19001 #endif
19002     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19003                                                             operands[1])));
19004
19005   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19006   DONE;
19007 })
19008
19009 (define_expand "builtin_setjmp_receiver"
19010   [(label_ref (match_operand 0 "" ""))]
19011   "!TARGET_64BIT && flag_pic"
19012 {
19013   if (TARGET_MACHO)
19014     {
19015       rtx xops[3];
19016       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19017       rtx label_rtx = gen_label_rtx ();
19018       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19019       xops[0] = xops[1] = picreg;
19020       xops[2] = gen_rtx_CONST (SImode,
19021                   gen_rtx_MINUS (SImode,
19022                     gen_rtx_LABEL_REF (SImode, label_rtx),
19023                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19024       ix86_expand_binary_operator (MINUS, SImode, xops);
19025     }
19026   else
19027     emit_insn (gen_set_got (pic_offset_table_rtx));
19028   DONE;
19029 })
19030 \f
19031 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19032
19033 (define_split
19034   [(set (match_operand 0 "register_operand" "")
19035         (match_operator 3 "promotable_binary_operator"
19036            [(match_operand 1 "register_operand" "")
19037             (match_operand 2 "aligned_operand" "")]))
19038    (clobber (reg:CC FLAGS_REG))]
19039   "! TARGET_PARTIAL_REG_STALL && reload_completed
19040    && ((GET_MODE (operands[0]) == HImode 
19041         && ((!optimize_size && !TARGET_FAST_PREFIX)
19042             /* ??? next two lines just !satisfies_constraint_K (...) */
19043             || GET_CODE (operands[2]) != CONST_INT
19044             || satisfies_constraint_K (operands[2])))
19045        || (GET_MODE (operands[0]) == QImode 
19046            && (TARGET_PROMOTE_QImode || optimize_size)))"
19047   [(parallel [(set (match_dup 0)
19048                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19049               (clobber (reg:CC FLAGS_REG))])]
19050   "operands[0] = gen_lowpart (SImode, operands[0]);
19051    operands[1] = gen_lowpart (SImode, operands[1]);
19052    if (GET_CODE (operands[3]) != ASHIFT)
19053      operands[2] = gen_lowpart (SImode, operands[2]);
19054    PUT_MODE (operands[3], SImode);")
19055
19056 ; Promote the QImode tests, as i386 has encoding of the AND
19057 ; instruction with 32-bit sign-extended immediate and thus the
19058 ; instruction size is unchanged, except in the %eax case for
19059 ; which it is increased by one byte, hence the ! optimize_size.
19060 (define_split
19061   [(set (match_operand 0 "flags_reg_operand" "")
19062         (match_operator 2 "compare_operator"
19063           [(and (match_operand 3 "aligned_operand" "")
19064                 (match_operand 4 "const_int_operand" ""))
19065            (const_int 0)]))
19066    (set (match_operand 1 "register_operand" "")
19067         (and (match_dup 3) (match_dup 4)))]
19068   "! TARGET_PARTIAL_REG_STALL && reload_completed
19069    /* Ensure that the operand will remain sign-extended immediate.  */
19070    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19071    && ! optimize_size
19072    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19073        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19074   [(parallel [(set (match_dup 0)
19075                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19076                                     (const_int 0)]))
19077               (set (match_dup 1)
19078                    (and:SI (match_dup 3) (match_dup 4)))])]
19079 {
19080   operands[4]
19081     = gen_int_mode (INTVAL (operands[4])
19082                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19083   operands[1] = gen_lowpart (SImode, operands[1]);
19084   operands[3] = gen_lowpart (SImode, operands[3]);
19085 })
19086
19087 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19088 ; the TEST instruction with 32-bit sign-extended immediate and thus
19089 ; the instruction size would at least double, which is not what we
19090 ; want even with ! optimize_size.
19091 (define_split
19092   [(set (match_operand 0 "flags_reg_operand" "")
19093         (match_operator 1 "compare_operator"
19094           [(and (match_operand:HI 2 "aligned_operand" "")
19095                 (match_operand:HI 3 "const_int_operand" ""))
19096            (const_int 0)]))]
19097   "! TARGET_PARTIAL_REG_STALL && reload_completed
19098    /* Ensure that the operand will remain sign-extended immediate.  */
19099    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19100    && ! TARGET_FAST_PREFIX
19101    && ! optimize_size"
19102   [(set (match_dup 0)
19103         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19104                          (const_int 0)]))]
19105 {
19106   operands[3]
19107     = gen_int_mode (INTVAL (operands[3])
19108                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19109   operands[2] = gen_lowpart (SImode, operands[2]);
19110 })
19111
19112 (define_split
19113   [(set (match_operand 0 "register_operand" "")
19114         (neg (match_operand 1 "register_operand" "")))
19115    (clobber (reg:CC FLAGS_REG))]
19116   "! TARGET_PARTIAL_REG_STALL && reload_completed
19117    && (GET_MODE (operands[0]) == HImode
19118        || (GET_MODE (operands[0]) == QImode 
19119            && (TARGET_PROMOTE_QImode || optimize_size)))"
19120   [(parallel [(set (match_dup 0)
19121                    (neg:SI (match_dup 1)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   "operands[0] = gen_lowpart (SImode, operands[0]);
19124    operands[1] = gen_lowpart (SImode, operands[1]);")
19125
19126 (define_split
19127   [(set (match_operand 0 "register_operand" "")
19128         (not (match_operand 1 "register_operand" "")))]
19129   "! TARGET_PARTIAL_REG_STALL && reload_completed
19130    && (GET_MODE (operands[0]) == HImode
19131        || (GET_MODE (operands[0]) == QImode 
19132            && (TARGET_PROMOTE_QImode || optimize_size)))"
19133   [(set (match_dup 0)
19134         (not:SI (match_dup 1)))]
19135   "operands[0] = gen_lowpart (SImode, operands[0]);
19136    operands[1] = gen_lowpart (SImode, operands[1]);")
19137
19138 (define_split 
19139   [(set (match_operand 0 "register_operand" "")
19140         (if_then_else (match_operator 1 "comparison_operator" 
19141                                 [(reg FLAGS_REG) (const_int 0)])
19142                       (match_operand 2 "register_operand" "")
19143                       (match_operand 3 "register_operand" "")))]
19144   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19145    && (GET_MODE (operands[0]) == HImode
19146        || (GET_MODE (operands[0]) == QImode 
19147            && (TARGET_PROMOTE_QImode || optimize_size)))"
19148   [(set (match_dup 0)
19149         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19150   "operands[0] = gen_lowpart (SImode, operands[0]);
19151    operands[2] = gen_lowpart (SImode, operands[2]);
19152    operands[3] = gen_lowpart (SImode, operands[3]);")
19153                         
19154 \f
19155 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19156 ;; transform a complex memory operation into two memory to register operations.
19157
19158 ;; Don't push memory operands
19159 (define_peephole2
19160   [(set (match_operand:SI 0 "push_operand" "")
19161         (match_operand:SI 1 "memory_operand" ""))
19162    (match_scratch:SI 2 "r")]
19163   "!optimize_size && !TARGET_PUSH_MEMORY
19164    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19165   [(set (match_dup 2) (match_dup 1))
19166    (set (match_dup 0) (match_dup 2))]
19167   "")
19168
19169 (define_peephole2
19170   [(set (match_operand:DI 0 "push_operand" "")
19171         (match_operand:DI 1 "memory_operand" ""))
19172    (match_scratch:DI 2 "r")]
19173   "!optimize_size && !TARGET_PUSH_MEMORY
19174    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19175   [(set (match_dup 2) (match_dup 1))
19176    (set (match_dup 0) (match_dup 2))]
19177   "")
19178
19179 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19180 ;; SImode pushes.
19181 (define_peephole2
19182   [(set (match_operand:SF 0 "push_operand" "")
19183         (match_operand:SF 1 "memory_operand" ""))
19184    (match_scratch:SF 2 "r")]
19185   "!optimize_size && !TARGET_PUSH_MEMORY
19186    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19187   [(set (match_dup 2) (match_dup 1))
19188    (set (match_dup 0) (match_dup 2))]
19189   "")
19190
19191 (define_peephole2
19192   [(set (match_operand:HI 0 "push_operand" "")
19193         (match_operand:HI 1 "memory_operand" ""))
19194    (match_scratch:HI 2 "r")]
19195   "!optimize_size && !TARGET_PUSH_MEMORY
19196    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19197   [(set (match_dup 2) (match_dup 1))
19198    (set (match_dup 0) (match_dup 2))]
19199   "")
19200
19201 (define_peephole2
19202   [(set (match_operand:QI 0 "push_operand" "")
19203         (match_operand:QI 1 "memory_operand" ""))
19204    (match_scratch:QI 2 "q")]
19205   "!optimize_size && !TARGET_PUSH_MEMORY
19206    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19207   [(set (match_dup 2) (match_dup 1))
19208    (set (match_dup 0) (match_dup 2))]
19209   "")
19210
19211 ;; Don't move an immediate directly to memory when the instruction
19212 ;; gets too big.
19213 (define_peephole2
19214   [(match_scratch:SI 1 "r")
19215    (set (match_operand:SI 0 "memory_operand" "")
19216         (const_int 0))]
19217   "! optimize_size
19218    && ! TARGET_USE_MOV0
19219    && TARGET_SPLIT_LONG_MOVES
19220    && get_attr_length (insn) >= ix86_cost->large_insn
19221    && peep2_regno_dead_p (0, FLAGS_REG)"
19222   [(parallel [(set (match_dup 1) (const_int 0))
19223               (clobber (reg:CC FLAGS_REG))])
19224    (set (match_dup 0) (match_dup 1))]
19225   "")
19226
19227 (define_peephole2
19228   [(match_scratch:HI 1 "r")
19229    (set (match_operand:HI 0 "memory_operand" "")
19230         (const_int 0))]
19231   "! optimize_size
19232    && ! TARGET_USE_MOV0
19233    && TARGET_SPLIT_LONG_MOVES
19234    && get_attr_length (insn) >= ix86_cost->large_insn
19235    && peep2_regno_dead_p (0, FLAGS_REG)"
19236   [(parallel [(set (match_dup 2) (const_int 0))
19237               (clobber (reg:CC FLAGS_REG))])
19238    (set (match_dup 0) (match_dup 1))]
19239   "operands[2] = gen_lowpart (SImode, operands[1]);")
19240
19241 (define_peephole2
19242   [(match_scratch:QI 1 "q")
19243    (set (match_operand:QI 0 "memory_operand" "")
19244         (const_int 0))]
19245   "! optimize_size
19246    && ! TARGET_USE_MOV0
19247    && TARGET_SPLIT_LONG_MOVES
19248    && get_attr_length (insn) >= ix86_cost->large_insn
19249    && peep2_regno_dead_p (0, FLAGS_REG)"
19250   [(parallel [(set (match_dup 2) (const_int 0))
19251               (clobber (reg:CC FLAGS_REG))])
19252    (set (match_dup 0) (match_dup 1))]
19253   "operands[2] = gen_lowpart (SImode, operands[1]);")
19254
19255 (define_peephole2
19256   [(match_scratch:SI 2 "r")
19257    (set (match_operand:SI 0 "memory_operand" "")
19258         (match_operand:SI 1 "immediate_operand" ""))]
19259   "! optimize_size
19260    && get_attr_length (insn) >= ix86_cost->large_insn
19261    && TARGET_SPLIT_LONG_MOVES"
19262   [(set (match_dup 2) (match_dup 1))
19263    (set (match_dup 0) (match_dup 2))]
19264   "")
19265
19266 (define_peephole2
19267   [(match_scratch:HI 2 "r")
19268    (set (match_operand:HI 0 "memory_operand" "")
19269         (match_operand:HI 1 "immediate_operand" ""))]
19270   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19271   && TARGET_SPLIT_LONG_MOVES"
19272   [(set (match_dup 2) (match_dup 1))
19273    (set (match_dup 0) (match_dup 2))]
19274   "")
19275
19276 (define_peephole2
19277   [(match_scratch:QI 2 "q")
19278    (set (match_operand:QI 0 "memory_operand" "")
19279         (match_operand:QI 1 "immediate_operand" ""))]
19280   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19281   && TARGET_SPLIT_LONG_MOVES"
19282   [(set (match_dup 2) (match_dup 1))
19283    (set (match_dup 0) (match_dup 2))]
19284   "")
19285
19286 ;; Don't compare memory with zero, load and use a test instead.
19287 (define_peephole2
19288   [(set (match_operand 0 "flags_reg_operand" "")
19289         (match_operator 1 "compare_operator"
19290           [(match_operand:SI 2 "memory_operand" "")
19291            (const_int 0)]))
19292    (match_scratch:SI 3 "r")]
19293   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19294   [(set (match_dup 3) (match_dup 2))
19295    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19296   "")
19297
19298 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19299 ;; Don't split NOTs with a displacement operand, because resulting XOR
19300 ;; will not be pairable anyway.
19301 ;;
19302 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19303 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19304 ;; so this split helps here as well.
19305 ;;
19306 ;; Note: Can't do this as a regular split because we can't get proper
19307 ;; lifetime information then.
19308
19309 (define_peephole2
19310   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19311         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19312   "!optimize_size
19313    && peep2_regno_dead_p (0, FLAGS_REG)
19314    && ((TARGET_PENTIUM 
19315         && (GET_CODE (operands[0]) != MEM
19316             || !memory_displacement_operand (operands[0], SImode)))
19317        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19318   [(parallel [(set (match_dup 0)
19319                    (xor:SI (match_dup 1) (const_int -1)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "")
19322
19323 (define_peephole2
19324   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19325         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19326   "!optimize_size
19327    && peep2_regno_dead_p (0, FLAGS_REG)
19328    && ((TARGET_PENTIUM 
19329         && (GET_CODE (operands[0]) != MEM
19330             || !memory_displacement_operand (operands[0], HImode)))
19331        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19332   [(parallel [(set (match_dup 0)
19333                    (xor:HI (match_dup 1) (const_int -1)))
19334               (clobber (reg:CC FLAGS_REG))])]
19335   "")
19336
19337 (define_peephole2
19338   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19339         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19340   "!optimize_size
19341    && peep2_regno_dead_p (0, FLAGS_REG)
19342    && ((TARGET_PENTIUM 
19343         && (GET_CODE (operands[0]) != MEM
19344             || !memory_displacement_operand (operands[0], QImode)))
19345        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19346   [(parallel [(set (match_dup 0)
19347                    (xor:QI (match_dup 1) (const_int -1)))
19348               (clobber (reg:CC FLAGS_REG))])]
19349   "")
19350
19351 ;; Non pairable "test imm, reg" instructions can be translated to
19352 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19353 ;; byte opcode instead of two, have a short form for byte operands),
19354 ;; so do it for other CPUs as well.  Given that the value was dead,
19355 ;; this should not create any new dependencies.  Pass on the sub-word
19356 ;; versions if we're concerned about partial register stalls.
19357
19358 (define_peephole2
19359   [(set (match_operand 0 "flags_reg_operand" "")
19360         (match_operator 1 "compare_operator"
19361           [(and:SI (match_operand:SI 2 "register_operand" "")
19362                    (match_operand:SI 3 "immediate_operand" ""))
19363            (const_int 0)]))]
19364   "ix86_match_ccmode (insn, CCNOmode)
19365    && (true_regnum (operands[2]) != 0
19366        || satisfies_constraint_K (operands[3]))
19367    && peep2_reg_dead_p (1, operands[2])"
19368   [(parallel
19369      [(set (match_dup 0)
19370            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19371                             (const_int 0)]))
19372       (set (match_dup 2)
19373            (and:SI (match_dup 2) (match_dup 3)))])]
19374   "")
19375
19376 ;; We don't need to handle HImode case, because it will be promoted to SImode
19377 ;; on ! TARGET_PARTIAL_REG_STALL
19378
19379 (define_peephole2
19380   [(set (match_operand 0 "flags_reg_operand" "")
19381         (match_operator 1 "compare_operator"
19382           [(and:QI (match_operand:QI 2 "register_operand" "")
19383                    (match_operand:QI 3 "immediate_operand" ""))
19384            (const_int 0)]))]
19385   "! TARGET_PARTIAL_REG_STALL
19386    && ix86_match_ccmode (insn, CCNOmode)
19387    && true_regnum (operands[2]) != 0
19388    && peep2_reg_dead_p (1, operands[2])"
19389   [(parallel
19390      [(set (match_dup 0)
19391            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19392                             (const_int 0)]))
19393       (set (match_dup 2)
19394            (and:QI (match_dup 2) (match_dup 3)))])]
19395   "")
19396
19397 (define_peephole2
19398   [(set (match_operand 0 "flags_reg_operand" "")
19399         (match_operator 1 "compare_operator"
19400           [(and:SI
19401              (zero_extract:SI
19402                (match_operand 2 "ext_register_operand" "")
19403                (const_int 8)
19404                (const_int 8))
19405              (match_operand 3 "const_int_operand" ""))
19406            (const_int 0)]))]
19407   "! TARGET_PARTIAL_REG_STALL
19408    && ix86_match_ccmode (insn, CCNOmode)
19409    && true_regnum (operands[2]) != 0
19410    && peep2_reg_dead_p (1, operands[2])"
19411   [(parallel [(set (match_dup 0)
19412                    (match_op_dup 1
19413                      [(and:SI
19414                         (zero_extract:SI
19415                           (match_dup 2)
19416                           (const_int 8)
19417                           (const_int 8))
19418                         (match_dup 3))
19419                       (const_int 0)]))
19420               (set (zero_extract:SI (match_dup 2)
19421                                     (const_int 8)
19422                                     (const_int 8))
19423                    (and:SI 
19424                      (zero_extract:SI
19425                        (match_dup 2)
19426                        (const_int 8)
19427                        (const_int 8))
19428                      (match_dup 3)))])]
19429   "")
19430
19431 ;; Don't do logical operations with memory inputs.
19432 (define_peephole2
19433   [(match_scratch:SI 2 "r")
19434    (parallel [(set (match_operand:SI 0 "register_operand" "")
19435                    (match_operator:SI 3 "arith_or_logical_operator"
19436                      [(match_dup 0)
19437                       (match_operand:SI 1 "memory_operand" "")]))
19438               (clobber (reg:CC FLAGS_REG))])]
19439   "! optimize_size && ! TARGET_READ_MODIFY"
19440   [(set (match_dup 2) (match_dup 1))
19441    (parallel [(set (match_dup 0)
19442                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19443               (clobber (reg:CC FLAGS_REG))])]
19444   "")
19445
19446 (define_peephole2
19447   [(match_scratch:SI 2 "r")
19448    (parallel [(set (match_operand:SI 0 "register_operand" "")
19449                    (match_operator:SI 3 "arith_or_logical_operator"
19450                      [(match_operand:SI 1 "memory_operand" "")
19451                       (match_dup 0)]))
19452               (clobber (reg:CC FLAGS_REG))])]
19453   "! optimize_size && ! TARGET_READ_MODIFY"
19454   [(set (match_dup 2) (match_dup 1))
19455    (parallel [(set (match_dup 0)
19456                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19457               (clobber (reg:CC FLAGS_REG))])]
19458   "")
19459
19460 ; Don't do logical operations with memory outputs
19461 ;
19462 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19463 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19464 ; the same decoder scheduling characteristics as the original.
19465
19466 (define_peephole2
19467   [(match_scratch:SI 2 "r")
19468    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19469                    (match_operator:SI 3 "arith_or_logical_operator"
19470                      [(match_dup 0)
19471                       (match_operand:SI 1 "nonmemory_operand" "")]))
19472               (clobber (reg:CC FLAGS_REG))])]
19473   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19474   [(set (match_dup 2) (match_dup 0))
19475    (parallel [(set (match_dup 2)
19476                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19477               (clobber (reg:CC FLAGS_REG))])
19478    (set (match_dup 0) (match_dup 2))]
19479   "")
19480
19481 (define_peephole2
19482   [(match_scratch:SI 2 "r")
19483    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19484                    (match_operator:SI 3 "arith_or_logical_operator"
19485                      [(match_operand:SI 1 "nonmemory_operand" "")
19486                       (match_dup 0)]))
19487               (clobber (reg:CC FLAGS_REG))])]
19488   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19489   [(set (match_dup 2) (match_dup 0))
19490    (parallel [(set (match_dup 2)
19491                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492               (clobber (reg:CC FLAGS_REG))])
19493    (set (match_dup 0) (match_dup 2))]
19494   "")
19495
19496 ;; Attempt to always use XOR for zeroing registers.
19497 (define_peephole2
19498   [(set (match_operand 0 "register_operand" "")
19499         (match_operand 1 "const0_operand" ""))]
19500   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19501    && (! TARGET_USE_MOV0 || optimize_size)
19502    && GENERAL_REG_P (operands[0])
19503    && peep2_regno_dead_p (0, FLAGS_REG)"
19504   [(parallel [(set (match_dup 0) (const_int 0))
19505               (clobber (reg:CC FLAGS_REG))])]
19506 {
19507   operands[0] = gen_lowpart (word_mode, operands[0]);
19508 })
19509
19510 (define_peephole2
19511   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19512         (const_int 0))]
19513   "(GET_MODE (operands[0]) == QImode
19514     || GET_MODE (operands[0]) == HImode)
19515    && (! TARGET_USE_MOV0 || optimize_size)
19516    && peep2_regno_dead_p (0, FLAGS_REG)"
19517   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19518               (clobber (reg:CC FLAGS_REG))])])
19519
19520 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19521 (define_peephole2
19522   [(set (match_operand 0 "register_operand" "")
19523         (const_int -1))]
19524   "(GET_MODE (operands[0]) == HImode
19525     || GET_MODE (operands[0]) == SImode 
19526     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19527    && (optimize_size || TARGET_PENTIUM)
19528    && peep2_regno_dead_p (0, FLAGS_REG)"
19529   [(parallel [(set (match_dup 0) (const_int -1))
19530               (clobber (reg:CC FLAGS_REG))])]
19531   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19532                               operands[0]);")
19533
19534 ;; Attempt to convert simple leas to adds. These can be created by
19535 ;; move expanders.
19536 (define_peephole2
19537   [(set (match_operand:SI 0 "register_operand" "")
19538         (plus:SI (match_dup 0)
19539                  (match_operand:SI 1 "nonmemory_operand" "")))]
19540   "peep2_regno_dead_p (0, FLAGS_REG)"
19541   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19542               (clobber (reg:CC FLAGS_REG))])]
19543   "")
19544
19545 (define_peephole2
19546   [(set (match_operand:SI 0 "register_operand" "")
19547         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19548                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19549   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19550   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19551               (clobber (reg:CC FLAGS_REG))])]
19552   "operands[2] = gen_lowpart (SImode, operands[2]);")
19553
19554 (define_peephole2
19555   [(set (match_operand:DI 0 "register_operand" "")
19556         (plus:DI (match_dup 0)
19557                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19558   "peep2_regno_dead_p (0, FLAGS_REG)"
19559   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19560               (clobber (reg:CC FLAGS_REG))])]
19561   "")
19562
19563 (define_peephole2
19564   [(set (match_operand:SI 0 "register_operand" "")
19565         (mult:SI (match_dup 0)
19566                  (match_operand:SI 1 "const_int_operand" "")))]
19567   "exact_log2 (INTVAL (operands[1])) >= 0
19568    && peep2_regno_dead_p (0, FLAGS_REG)"
19569   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19570               (clobber (reg:CC FLAGS_REG))])]
19571   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19572
19573 (define_peephole2
19574   [(set (match_operand:DI 0 "register_operand" "")
19575         (mult:DI (match_dup 0)
19576                  (match_operand:DI 1 "const_int_operand" "")))]
19577   "exact_log2 (INTVAL (operands[1])) >= 0
19578    && peep2_regno_dead_p (0, FLAGS_REG)"
19579   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19582
19583 (define_peephole2
19584   [(set (match_operand:SI 0 "register_operand" "")
19585         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19586                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19587   "exact_log2 (INTVAL (operands[2])) >= 0
19588    && REGNO (operands[0]) == REGNO (operands[1])
19589    && peep2_regno_dead_p (0, FLAGS_REG)"
19590   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19591               (clobber (reg:CC FLAGS_REG))])]
19592   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19593
19594 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19595 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19596 ;; many CPUs it is also faster, since special hardware to avoid esp
19597 ;; dependencies is present.
19598
19599 ;; While some of these conversions may be done using splitters, we use peepholes
19600 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19601
19602 ;; Convert prologue esp subtractions to push.
19603 ;; We need register to push.  In order to keep verify_flow_info happy we have
19604 ;; two choices
19605 ;; - use scratch and clobber it in order to avoid dependencies
19606 ;; - use already live register
19607 ;; We can't use the second way right now, since there is no reliable way how to
19608 ;; verify that given register is live.  First choice will also most likely in
19609 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19610 ;; call clobbered registers are dead.  We may want to use base pointer as an
19611 ;; alternative when no register is available later.
19612
19613 (define_peephole2
19614   [(match_scratch:SI 0 "r")
19615    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616               (clobber (reg:CC FLAGS_REG))
19617               (clobber (mem:BLK (scratch)))])]
19618   "optimize_size || !TARGET_SUB_ESP_4"
19619   [(clobber (match_dup 0))
19620    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19621               (clobber (mem:BLK (scratch)))])])
19622
19623 (define_peephole2
19624   [(match_scratch:SI 0 "r")
19625    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19626               (clobber (reg:CC FLAGS_REG))
19627               (clobber (mem:BLK (scratch)))])]
19628   "optimize_size || !TARGET_SUB_ESP_8"
19629   [(clobber (match_dup 0))
19630    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19632               (clobber (mem:BLK (scratch)))])])
19633
19634 ;; Convert esp subtractions to push.
19635 (define_peephole2
19636   [(match_scratch:SI 0 "r")
19637    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "optimize_size || !TARGET_SUB_ESP_4"
19640   [(clobber (match_dup 0))
19641    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19642
19643 (define_peephole2
19644   [(match_scratch:SI 0 "r")
19645    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19646               (clobber (reg:CC FLAGS_REG))])]
19647   "optimize_size || !TARGET_SUB_ESP_8"
19648   [(clobber (match_dup 0))
19649    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19650    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19651
19652 ;; Convert epilogue deallocator to pop.
19653 (define_peephole2
19654   [(match_scratch:SI 0 "r")
19655    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656               (clobber (reg:CC FLAGS_REG))
19657               (clobber (mem:BLK (scratch)))])]
19658   "optimize_size || !TARGET_ADD_ESP_4"
19659   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19660               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19661               (clobber (mem:BLK (scratch)))])]
19662   "")
19663
19664 ;; Two pops case is tricky, since pop causes dependency on destination register.
19665 ;; We use two registers if available.
19666 (define_peephole2
19667   [(match_scratch:SI 0 "r")
19668    (match_scratch:SI 1 "r")
19669    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19670               (clobber (reg:CC FLAGS_REG))
19671               (clobber (mem:BLK (scratch)))])]
19672   "optimize_size || !TARGET_ADD_ESP_8"
19673   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19674               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675               (clobber (mem:BLK (scratch)))])
19676    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19677               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19678   "")
19679
19680 (define_peephole2
19681   [(match_scratch:SI 0 "r")
19682    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19683               (clobber (reg:CC FLAGS_REG))
19684               (clobber (mem:BLK (scratch)))])]
19685   "optimize_size"
19686   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19687               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19688               (clobber (mem:BLK (scratch)))])
19689    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19691   "")
19692
19693 ;; Convert esp additions to pop.
19694 (define_peephole2
19695   [(match_scratch:SI 0 "r")
19696    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19697               (clobber (reg:CC FLAGS_REG))])]
19698   ""
19699   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19700               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19701   "")
19702
19703 ;; Two pops case is tricky, since pop causes dependency on destination register.
19704 ;; We use two registers if available.
19705 (define_peephole2
19706   [(match_scratch:SI 0 "r")
19707    (match_scratch:SI 1 "r")
19708    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19709               (clobber (reg:CC FLAGS_REG))])]
19710   ""
19711   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19712               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19713    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19714               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19715   "")
19716
19717 (define_peephole2
19718   [(match_scratch:SI 0 "r")
19719    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19720               (clobber (reg:CC FLAGS_REG))])]
19721   "optimize_size"
19722   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19723               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19724    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19725               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19726   "")
19727 \f
19728 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19729 ;; required and register dies.  Similarly for 128 to plus -128.
19730 (define_peephole2
19731   [(set (match_operand 0 "flags_reg_operand" "")
19732         (match_operator 1 "compare_operator"
19733           [(match_operand 2 "register_operand" "")
19734            (match_operand 3 "const_int_operand" "")]))]
19735   "(INTVAL (operands[3]) == -1
19736     || INTVAL (operands[3]) == 1
19737     || INTVAL (operands[3]) == 128)
19738    && ix86_match_ccmode (insn, CCGCmode)
19739    && peep2_reg_dead_p (1, operands[2])"
19740   [(parallel [(set (match_dup 0)
19741                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19742               (clobber (match_dup 2))])]
19743   "")
19744 \f
19745 (define_peephole2
19746   [(match_scratch:DI 0 "r")
19747    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19748               (clobber (reg:CC FLAGS_REG))
19749               (clobber (mem:BLK (scratch)))])]
19750   "optimize_size || !TARGET_SUB_ESP_4"
19751   [(clobber (match_dup 0))
19752    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19753               (clobber (mem:BLK (scratch)))])])
19754
19755 (define_peephole2
19756   [(match_scratch:DI 0 "r")
19757    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19758               (clobber (reg:CC FLAGS_REG))
19759               (clobber (mem:BLK (scratch)))])]
19760   "optimize_size || !TARGET_SUB_ESP_8"
19761   [(clobber (match_dup 0))
19762    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19764               (clobber (mem:BLK (scratch)))])])
19765
19766 ;; Convert esp subtractions to push.
19767 (define_peephole2
19768   [(match_scratch:DI 0 "r")
19769    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19770               (clobber (reg:CC FLAGS_REG))])]
19771   "optimize_size || !TARGET_SUB_ESP_4"
19772   [(clobber (match_dup 0))
19773    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19774
19775 (define_peephole2
19776   [(match_scratch:DI 0 "r")
19777    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779   "optimize_size || !TARGET_SUB_ESP_8"
19780   [(clobber (match_dup 0))
19781    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19782    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19783
19784 ;; Convert epilogue deallocator to pop.
19785 (define_peephole2
19786   [(match_scratch:DI 0 "r")
19787    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788               (clobber (reg:CC FLAGS_REG))
19789               (clobber (mem:BLK (scratch)))])]
19790   "optimize_size || !TARGET_ADD_ESP_4"
19791   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19792               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19793               (clobber (mem:BLK (scratch)))])]
19794   "")
19795
19796 ;; Two pops case is tricky, since pop causes dependency on destination register.
19797 ;; We use two registers if available.
19798 (define_peephole2
19799   [(match_scratch:DI 0 "r")
19800    (match_scratch:DI 1 "r")
19801    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19802               (clobber (reg:CC FLAGS_REG))
19803               (clobber (mem:BLK (scratch)))])]
19804   "optimize_size || !TARGET_ADD_ESP_8"
19805   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19806               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19807               (clobber (mem:BLK (scratch)))])
19808    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19809               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19810   "")
19811
19812 (define_peephole2
19813   [(match_scratch:DI 0 "r")
19814    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19815               (clobber (reg:CC FLAGS_REG))
19816               (clobber (mem:BLK (scratch)))])]
19817   "optimize_size"
19818   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19819               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19820               (clobber (mem:BLK (scratch)))])
19821    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19823   "")
19824
19825 ;; Convert esp additions to pop.
19826 (define_peephole2
19827   [(match_scratch:DI 0 "r")
19828    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19829               (clobber (reg:CC FLAGS_REG))])]
19830   ""
19831   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19832               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833   "")
19834
19835 ;; Two pops case is tricky, since pop causes dependency on destination register.
19836 ;; We use two registers if available.
19837 (define_peephole2
19838   [(match_scratch:DI 0 "r")
19839    (match_scratch:DI 1 "r")
19840    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19841               (clobber (reg:CC FLAGS_REG))])]
19842   ""
19843   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19844               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19845    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19846               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19847   "")
19848
19849 (define_peephole2
19850   [(match_scratch:DI 0 "r")
19851    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19852               (clobber (reg:CC FLAGS_REG))])]
19853   "optimize_size"
19854   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19855               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19856    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19857               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19858   "")
19859 \f
19860 ;; Convert imul by three, five and nine into lea
19861 (define_peephole2
19862   [(parallel
19863     [(set (match_operand:SI 0 "register_operand" "")
19864           (mult:SI (match_operand:SI 1 "register_operand" "")
19865                    (match_operand:SI 2 "const_int_operand" "")))
19866      (clobber (reg:CC FLAGS_REG))])]
19867   "INTVAL (operands[2]) == 3
19868    || INTVAL (operands[2]) == 5
19869    || INTVAL (operands[2]) == 9"
19870   [(set (match_dup 0)
19871         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19872                  (match_dup 1)))]
19873   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19874
19875 (define_peephole2
19876   [(parallel
19877     [(set (match_operand:SI 0 "register_operand" "")
19878           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19879                    (match_operand:SI 2 "const_int_operand" "")))
19880      (clobber (reg:CC FLAGS_REG))])]
19881   "!optimize_size 
19882    && (INTVAL (operands[2]) == 3
19883        || INTVAL (operands[2]) == 5
19884        || INTVAL (operands[2]) == 9)"
19885   [(set (match_dup 0) (match_dup 1))
19886    (set (match_dup 0)
19887         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19888                  (match_dup 0)))]
19889   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19890
19891 (define_peephole2
19892   [(parallel
19893     [(set (match_operand:DI 0 "register_operand" "")
19894           (mult:DI (match_operand:DI 1 "register_operand" "")
19895                    (match_operand:DI 2 "const_int_operand" "")))
19896      (clobber (reg:CC FLAGS_REG))])]
19897   "TARGET_64BIT
19898    && (INTVAL (operands[2]) == 3
19899        || INTVAL (operands[2]) == 5
19900        || INTVAL (operands[2]) == 9)"
19901   [(set (match_dup 0)
19902         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19903                  (match_dup 1)))]
19904   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19905
19906 (define_peephole2
19907   [(parallel
19908     [(set (match_operand:DI 0 "register_operand" "")
19909           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19910                    (match_operand:DI 2 "const_int_operand" "")))
19911      (clobber (reg:CC FLAGS_REG))])]
19912   "TARGET_64BIT
19913    && !optimize_size 
19914    && (INTVAL (operands[2]) == 3
19915        || INTVAL (operands[2]) == 5
19916        || INTVAL (operands[2]) == 9)"
19917   [(set (match_dup 0) (match_dup 1))
19918    (set (match_dup 0)
19919         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19920                  (match_dup 0)))]
19921   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19922
19923 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19924 ;; imul $32bit_imm, reg, reg is direct decoded.
19925 (define_peephole2
19926   [(match_scratch:DI 3 "r")
19927    (parallel [(set (match_operand:DI 0 "register_operand" "")
19928                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19929                             (match_operand:DI 2 "immediate_operand" "")))
19930               (clobber (reg:CC FLAGS_REG))])]
19931   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19932    && !satisfies_constraint_K (operands[2])"
19933   [(set (match_dup 3) (match_dup 1))
19934    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19935               (clobber (reg:CC FLAGS_REG))])]
19936 "")
19937
19938 (define_peephole2
19939   [(match_scratch:SI 3 "r")
19940    (parallel [(set (match_operand:SI 0 "register_operand" "")
19941                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19942                             (match_operand:SI 2 "immediate_operand" "")))
19943               (clobber (reg:CC FLAGS_REG))])]
19944   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19945    && !satisfies_constraint_K (operands[2])"
19946   [(set (match_dup 3) (match_dup 1))
19947    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19948               (clobber (reg:CC FLAGS_REG))])]
19949 "")
19950
19951 (define_peephole2
19952   [(match_scratch:SI 3 "r")
19953    (parallel [(set (match_operand:DI 0 "register_operand" "")
19954                    (zero_extend:DI
19955                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19956                               (match_operand:SI 2 "immediate_operand" ""))))
19957               (clobber (reg:CC FLAGS_REG))])]
19958   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19959    && !satisfies_constraint_K (operands[2])"
19960   [(set (match_dup 3) (match_dup 1))
19961    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19962               (clobber (reg:CC FLAGS_REG))])]
19963 "")
19964
19965 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19966 ;; Convert it into imul reg, reg
19967 ;; It would be better to force assembler to encode instruction using long
19968 ;; immediate, but there is apparently no way to do so.
19969 (define_peephole2
19970   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19971                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19972                             (match_operand:DI 2 "const_int_operand" "")))
19973               (clobber (reg:CC FLAGS_REG))])
19974    (match_scratch:DI 3 "r")]
19975   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19976    && satisfies_constraint_K (operands[2])"
19977   [(set (match_dup 3) (match_dup 2))
19978    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19979               (clobber (reg:CC FLAGS_REG))])]
19980 {
19981   if (!rtx_equal_p (operands[0], operands[1]))
19982     emit_move_insn (operands[0], operands[1]);
19983 })
19984
19985 (define_peephole2
19986   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19987                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19988                             (match_operand:SI 2 "const_int_operand" "")))
19989               (clobber (reg:CC FLAGS_REG))])
19990    (match_scratch:SI 3 "r")]
19991   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992    && satisfies_constraint_K (operands[2])"
19993   [(set (match_dup 3) (match_dup 2))
19994    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19995               (clobber (reg:CC FLAGS_REG))])]
19996 {
19997   if (!rtx_equal_p (operands[0], operands[1]))
19998     emit_move_insn (operands[0], operands[1]);
19999 })
20000
20001 (define_peephole2
20002   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20003                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20004                             (match_operand:HI 2 "immediate_operand" "")))
20005               (clobber (reg:CC FLAGS_REG))])
20006    (match_scratch:HI 3 "r")]
20007   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20008   [(set (match_dup 3) (match_dup 2))
20009    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20010               (clobber (reg:CC FLAGS_REG))])]
20011 {
20012   if (!rtx_equal_p (operands[0], operands[1]))
20013     emit_move_insn (operands[0], operands[1]);
20014 })
20015
20016 ;; After splitting up read-modify operations, array accesses with memory
20017 ;; operands might end up in form:
20018 ;;  sall    $2, %eax
20019 ;;  movl    4(%esp), %edx
20020 ;;  addl    %edx, %eax
20021 ;; instead of pre-splitting:
20022 ;;  sall    $2, %eax
20023 ;;  addl    4(%esp), %eax
20024 ;; Turn it into:
20025 ;;  movl    4(%esp), %edx
20026 ;;  leal    (%edx,%eax,4), %eax
20027
20028 (define_peephole2
20029   [(parallel [(set (match_operand 0 "register_operand" "")
20030                    (ashift (match_operand 1 "register_operand" "")
20031                            (match_operand 2 "const_int_operand" "")))
20032                (clobber (reg:CC FLAGS_REG))])
20033    (set (match_operand 3 "register_operand")
20034         (match_operand 4 "x86_64_general_operand" ""))
20035    (parallel [(set (match_operand 5 "register_operand" "")
20036                    (plus (match_operand 6 "register_operand" "")
20037                          (match_operand 7 "register_operand" "")))
20038                    (clobber (reg:CC FLAGS_REG))])]
20039   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20040    /* Validate MODE for lea.  */
20041    && ((!TARGET_PARTIAL_REG_STALL
20042         && (GET_MODE (operands[0]) == QImode
20043             || GET_MODE (operands[0]) == HImode))
20044        || GET_MODE (operands[0]) == SImode 
20045        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20046    /* We reorder load and the shift.  */
20047    && !rtx_equal_p (operands[1], operands[3])
20048    && !reg_overlap_mentioned_p (operands[0], operands[4])
20049    /* Last PLUS must consist of operand 0 and 3.  */
20050    && !rtx_equal_p (operands[0], operands[3])
20051    && (rtx_equal_p (operands[3], operands[6])
20052        || rtx_equal_p (operands[3], operands[7]))
20053    && (rtx_equal_p (operands[0], operands[6])
20054        || rtx_equal_p (operands[0], operands[7]))
20055    /* The intermediate operand 0 must die or be same as output.  */
20056    && (rtx_equal_p (operands[0], operands[5])
20057        || peep2_reg_dead_p (3, operands[0]))"
20058   [(set (match_dup 3) (match_dup 4))
20059    (set (match_dup 0) (match_dup 1))]
20060 {
20061   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20062   int scale = 1 << INTVAL (operands[2]);
20063   rtx index = gen_lowpart (Pmode, operands[1]);
20064   rtx base = gen_lowpart (Pmode, operands[3]);
20065   rtx dest = gen_lowpart (mode, operands[5]);
20066
20067   operands[1] = gen_rtx_PLUS (Pmode, base,
20068                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20069   if (mode != Pmode)
20070     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20071   operands[0] = dest;
20072 })
20073 \f
20074 ;; Call-value patterns last so that the wildcard operand does not
20075 ;; disrupt insn-recog's switch tables.
20076
20077 (define_insn "*call_value_pop_0"
20078   [(set (match_operand 0 "" "")
20079         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20080               (match_operand:SI 2 "" "")))
20081    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20082                             (match_operand:SI 3 "immediate_operand" "")))]
20083   "!TARGET_64BIT"
20084 {
20085   if (SIBLING_CALL_P (insn))
20086     return "jmp\t%P1";
20087   else
20088     return "call\t%P1";
20089 }
20090   [(set_attr "type" "callv")])
20091
20092 (define_insn "*call_value_pop_1"
20093   [(set (match_operand 0 "" "")
20094         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20095               (match_operand:SI 2 "" "")))
20096    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20097                             (match_operand:SI 3 "immediate_operand" "i")))]
20098   "!TARGET_64BIT"
20099 {
20100   if (constant_call_address_operand (operands[1], Pmode))
20101     {
20102       if (SIBLING_CALL_P (insn))
20103         return "jmp\t%P1";
20104       else
20105         return "call\t%P1";
20106     }
20107   if (SIBLING_CALL_P (insn))
20108     return "jmp\t%A1";
20109   else
20110     return "call\t%A1";
20111 }
20112   [(set_attr "type" "callv")])
20113
20114 (define_insn "*call_value_0"
20115   [(set (match_operand 0 "" "")
20116         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20117               (match_operand:SI 2 "" "")))]
20118   "!TARGET_64BIT"
20119 {
20120   if (SIBLING_CALL_P (insn))
20121     return "jmp\t%P1";
20122   else
20123     return "call\t%P1";
20124 }
20125   [(set_attr "type" "callv")])
20126
20127 (define_insn "*call_value_0_rex64"
20128   [(set (match_operand 0 "" "")
20129         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20130               (match_operand:DI 2 "const_int_operand" "")))]
20131   "TARGET_64BIT"
20132 {
20133   if (SIBLING_CALL_P (insn))
20134     return "jmp\t%P1";
20135   else
20136     return "call\t%P1";
20137 }
20138   [(set_attr "type" "callv")])
20139
20140 (define_insn "*call_value_1"
20141   [(set (match_operand 0 "" "")
20142         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20143               (match_operand:SI 2 "" "")))]
20144   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20145 {
20146   if (constant_call_address_operand (operands[1], Pmode))
20147     return "call\t%P1";
20148   return "call\t%A1";
20149 }
20150   [(set_attr "type" "callv")])
20151
20152 (define_insn "*sibcall_value_1"
20153   [(set (match_operand 0 "" "")
20154         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20155               (match_operand:SI 2 "" "")))]
20156   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20157 {
20158   if (constant_call_address_operand (operands[1], Pmode))
20159     return "jmp\t%P1";
20160   return "jmp\t%A1";
20161 }
20162   [(set_attr "type" "callv")])
20163
20164 (define_insn "*call_value_1_rex64"
20165   [(set (match_operand 0 "" "")
20166         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20167               (match_operand:DI 2 "" "")))]
20168   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20169 {
20170   if (constant_call_address_operand (operands[1], Pmode))
20171     return "call\t%P1";
20172   return "call\t%A1";
20173 }
20174   [(set_attr "type" "callv")])
20175
20176 (define_insn "*sibcall_value_1_rex64"
20177   [(set (match_operand 0 "" "")
20178         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20179               (match_operand:DI 2 "" "")))]
20180   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20181   "jmp\t%P1"
20182   [(set_attr "type" "callv")])
20183
20184 (define_insn "*sibcall_value_1_rex64_v"
20185   [(set (match_operand 0 "" "")
20186         (call (mem:QI (reg:DI 40))
20187               (match_operand:DI 1 "" "")))]
20188   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20189   "jmp\t*%%r11"
20190   [(set_attr "type" "callv")])
20191 \f
20192 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20193 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20194 ;; caught for use by garbage collectors and the like.  Using an insn that
20195 ;; maps to SIGILL makes it more likely the program will rightfully die.
20196 ;; Keeping with tradition, "6" is in honor of #UD.
20197 (define_insn "trap"
20198   [(trap_if (const_int 1) (const_int 6))]
20199   ""
20200   { return ASM_SHORT "0x0b0f"; }
20201   [(set_attr "length" "2")])
20202
20203 (define_expand "sse_prologue_save"
20204   [(parallel [(set (match_operand:BLK 0 "" "")
20205                    (unspec:BLK [(reg:DI 21)
20206                                 (reg:DI 22)
20207                                 (reg:DI 23)
20208                                 (reg:DI 24)
20209                                 (reg:DI 25)
20210                                 (reg:DI 26)
20211                                 (reg:DI 27)
20212                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20213               (use (match_operand:DI 1 "register_operand" ""))
20214               (use (match_operand:DI 2 "immediate_operand" ""))
20215               (use (label_ref:DI (match_operand 3 "" "")))])]
20216   "TARGET_64BIT"
20217   "")
20218
20219 (define_insn "*sse_prologue_save_insn"
20220   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20221                           (match_operand:DI 4 "const_int_operand" "n")))
20222         (unspec:BLK [(reg:DI 21)
20223                      (reg:DI 22)
20224                      (reg:DI 23)
20225                      (reg:DI 24)
20226                      (reg:DI 25)
20227                      (reg:DI 26)
20228                      (reg:DI 27)
20229                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20230    (use (match_operand:DI 1 "register_operand" "r"))
20231    (use (match_operand:DI 2 "const_int_operand" "i"))
20232    (use (label_ref:DI (match_operand 3 "" "X")))]
20233   "TARGET_64BIT
20234    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20235    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20236   "*
20237 {
20238   int i;
20239   operands[0] = gen_rtx_MEM (Pmode,
20240                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20241   output_asm_insn (\"jmp\\t%A1\", operands);
20242   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20243     {
20244       operands[4] = adjust_address (operands[0], DImode, i*16);
20245       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20246       PUT_MODE (operands[4], TImode);
20247       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20248         output_asm_insn (\"rex\", operands);
20249       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20250     }
20251   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20252                              CODE_LABEL_NUMBER (operands[3]));
20253   RET;
20254 }
20255   "
20256   [(set_attr "type" "other")
20257    (set_attr "length_immediate" "0")
20258    (set_attr "length_address" "0")
20259    (set_attr "length" "135")
20260    (set_attr "memory" "store")
20261    (set_attr "modrm" "0")
20262    (set_attr "mode" "DI")])
20263
20264 (define_expand "prefetch"
20265   [(prefetch (match_operand 0 "address_operand" "")
20266              (match_operand:SI 1 "const_int_operand" "")
20267              (match_operand:SI 2 "const_int_operand" ""))]
20268   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20269 {
20270   int rw = INTVAL (operands[1]);
20271   int locality = INTVAL (operands[2]);
20272
20273   gcc_assert (rw == 0 || rw == 1);
20274   gcc_assert (locality >= 0 && locality <= 3);
20275   gcc_assert (GET_MODE (operands[0]) == Pmode
20276               || GET_MODE (operands[0]) == VOIDmode);
20277
20278   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20279      supported by SSE counterpart or the SSE prefetch is not available
20280      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20281      of locality.  */
20282   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20283     operands[2] = GEN_INT (3);
20284   else
20285     operands[1] = const0_rtx;
20286 })
20287
20288 (define_insn "*prefetch_sse"
20289   [(prefetch (match_operand:SI 0 "address_operand" "p")
20290              (const_int 0)
20291              (match_operand:SI 1 "const_int_operand" ""))]
20292   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20293 {
20294   static const char * const patterns[4] = {
20295    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20296   };
20297
20298   int locality = INTVAL (operands[1]);
20299   gcc_assert (locality >= 0 && locality <= 3);
20300
20301   return patterns[locality];  
20302 }
20303   [(set_attr "type" "sse")
20304    (set_attr "memory" "none")])
20305
20306 (define_insn "*prefetch_sse_rex"
20307   [(prefetch (match_operand:DI 0 "address_operand" "p")
20308              (const_int 0)
20309              (match_operand:SI 1 "const_int_operand" ""))]
20310   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20311 {
20312   static const char * const patterns[4] = {
20313    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20314   };
20315
20316   int locality = INTVAL (operands[1]);
20317   gcc_assert (locality >= 0 && locality <= 3);
20318
20319   return patterns[locality];  
20320 }
20321   [(set_attr "type" "sse")
20322    (set_attr "memory" "none")])
20323
20324 (define_insn "*prefetch_3dnow"
20325   [(prefetch (match_operand:SI 0 "address_operand" "p")
20326              (match_operand:SI 1 "const_int_operand" "n")
20327              (const_int 3))]
20328   "TARGET_3DNOW && !TARGET_64BIT"
20329 {
20330   if (INTVAL (operands[1]) == 0)
20331     return "prefetch\t%a0";
20332   else
20333     return "prefetchw\t%a0";
20334 }
20335   [(set_attr "type" "mmx")
20336    (set_attr "memory" "none")])
20337
20338 (define_insn "*prefetch_3dnow_rex"
20339   [(prefetch (match_operand:DI 0 "address_operand" "p")
20340              (match_operand:SI 1 "const_int_operand" "n")
20341              (const_int 3))]
20342   "TARGET_3DNOW && TARGET_64BIT"
20343 {
20344   if (INTVAL (operands[1]) == 0)
20345     return "prefetch\t%a0";
20346   else
20347     return "prefetchw\t%a0";
20348 }
20349   [(set_attr "type" "mmx")
20350    (set_attr "memory" "none")])
20351
20352 (define_expand "stack_protect_set"
20353   [(match_operand 0 "memory_operand" "")
20354    (match_operand 1 "memory_operand" "")]
20355   ""
20356 {
20357 #ifdef TARGET_THREAD_SSP_OFFSET
20358   if (TARGET_64BIT)
20359     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20360                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20361   else
20362     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20363                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20364 #else
20365   if (TARGET_64BIT)
20366     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20367   else
20368     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20369 #endif
20370   DONE;
20371 })
20372
20373 (define_insn "stack_protect_set_si"
20374   [(set (match_operand:SI 0 "memory_operand" "=m")
20375         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20376    (set (match_scratch:SI 2 "=&r") (const_int 0))
20377    (clobber (reg:CC FLAGS_REG))]
20378   ""
20379   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20380   [(set_attr "type" "multi")])
20381
20382 (define_insn "stack_protect_set_di"
20383   [(set (match_operand:DI 0 "memory_operand" "=m")
20384         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20385    (set (match_scratch:DI 2 "=&r") (const_int 0))
20386    (clobber (reg:CC FLAGS_REG))]
20387   "TARGET_64BIT"
20388   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20389   [(set_attr "type" "multi")])
20390
20391 (define_insn "stack_tls_protect_set_si"
20392   [(set (match_operand:SI 0 "memory_operand" "=m")
20393         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20394    (set (match_scratch:SI 2 "=&r") (const_int 0))
20395    (clobber (reg:CC FLAGS_REG))]
20396   ""
20397   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20398   [(set_attr "type" "multi")])
20399
20400 (define_insn "stack_tls_protect_set_di"
20401   [(set (match_operand:DI 0 "memory_operand" "=m")
20402         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20403    (set (match_scratch:DI 2 "=&r") (const_int 0))
20404    (clobber (reg:CC FLAGS_REG))]
20405   "TARGET_64BIT"
20406   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20407   [(set_attr "type" "multi")])
20408
20409 (define_expand "stack_protect_test"
20410   [(match_operand 0 "memory_operand" "")
20411    (match_operand 1 "memory_operand" "")
20412    (match_operand 2 "" "")]
20413   ""
20414 {
20415   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20416   ix86_compare_op0 = operands[0];
20417   ix86_compare_op1 = operands[1];
20418   ix86_compare_emitted = flags;
20419
20420 #ifdef TARGET_THREAD_SSP_OFFSET
20421   if (TARGET_64BIT)
20422     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20423                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20424   else
20425     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20426                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20427 #else
20428   if (TARGET_64BIT)
20429     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20430   else
20431     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20432 #endif
20433   emit_jump_insn (gen_beq (operands[2]));
20434   DONE;
20435 })
20436
20437 (define_insn "stack_protect_test_si"
20438   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20439         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20440                      (match_operand:SI 2 "memory_operand" "m")]
20441                     UNSPEC_SP_TEST))
20442    (clobber (match_scratch:SI 3 "=&r"))]
20443   ""
20444   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20445   [(set_attr "type" "multi")])
20446
20447 (define_insn "stack_protect_test_di"
20448   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20449         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20450                      (match_operand:DI 2 "memory_operand" "m")]
20451                     UNSPEC_SP_TEST))
20452    (clobber (match_scratch:DI 3 "=&r"))]
20453   "TARGET_64BIT"
20454   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20455   [(set_attr "type" "multi")])
20456
20457 (define_insn "stack_tls_protect_test_si"
20458   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20459         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20460                      (match_operand:SI 2 "const_int_operand" "i")]
20461                     UNSPEC_SP_TLS_TEST))
20462    (clobber (match_scratch:SI 3 "=r"))]
20463   ""
20464   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20465   [(set_attr "type" "multi")])
20466
20467 (define_insn "stack_tls_protect_test_di"
20468   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20469         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20470                      (match_operand:DI 2 "const_int_operand" "i")]
20471                     UNSPEC_SP_TLS_TEST))
20472    (clobber (match_scratch:DI 3 "=r"))]
20473   "TARGET_64BIT"
20474   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20475   [(set_attr "type" "multi")])
20476
20477 (include "sse.md")
20478 (include "mmx.md")
20479 (include "sync.md")