]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - contrib/gcc/config/i386/i386.md
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / contrib / 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_VIRTUAL);
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_VIRTUAL);
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_VIRTUAL);
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 "x86_64_general_operand" "roe,re")))
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 "x86_64_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 "x86_64_general_operand" "roe,re")))
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 "x86_64_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{l}\t{%2, %1|%1, %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 "nonimmediate_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 "nonimmediate_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 || !TARGET_SSE_MATH)"
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 || !(TARGET_SSE2 && TARGET_SSE_MATH))"
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"
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 || !TARGET_SSE_MATH)"
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 || !(TARGET_SSE2 && TARGET_SSE_MATH))"
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"
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    && (optimize_size
10401        || !TARGET_PARTIAL_FLAG_REG_STALL
10402        || (operands[2] == const1_rtx
10403            && (TARGET_SHIFT1
10404                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10405 {
10406   switch (get_attr_type (insn))
10407     {
10408     case TYPE_ALU:
10409       gcc_assert (operands[2] == const1_rtx);
10410       return "add{q}\t{%0, %0|%0, %0}";
10411
10412     default:
10413       if (REG_P (operands[2]))
10414         return "sal{q}\t{%b2, %0|%0, %b2}";
10415       else if (operands[2] == const1_rtx
10416                && (TARGET_SHIFT1 || optimize_size))
10417         return "sal{q}\t%0";
10418       else
10419         return "sal{q}\t{%2, %0|%0, %2}";
10420     }
10421 }
10422   [(set (attr "type")
10423      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424                           (const_int 0))
10425                       (match_operand 0 "register_operand" ""))
10426                  (match_operand 2 "const1_operand" ""))
10427               (const_string "alu")
10428            ]
10429            (const_string "ishift")))
10430    (set_attr "mode" "DI")])
10431
10432 (define_insn "*ashldi3_cconly_rex64"
10433   [(set (reg FLAGS_REG)
10434         (compare
10435           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10436                      (match_operand:QI 2 "immediate_operand" "e"))
10437           (const_int 0)))
10438    (clobber (match_scratch:DI 0 "=r"))]
10439   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10440    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10441    && (optimize_size
10442        || !TARGET_PARTIAL_FLAG_REG_STALL
10443        || (operands[2] == const1_rtx
10444            && (TARGET_SHIFT1
10445                || TARGET_DOUBLE_WITH_ADD)))"
10446 {
10447   switch (get_attr_type (insn))
10448     {
10449     case TYPE_ALU:
10450       gcc_assert (operands[2] == const1_rtx);
10451       return "add{q}\t{%0, %0|%0, %0}";
10452
10453     default:
10454       if (REG_P (operands[2]))
10455         return "sal{q}\t{%b2, %0|%0, %b2}";
10456       else if (operands[2] == const1_rtx
10457                && (TARGET_SHIFT1 || optimize_size))
10458         return "sal{q}\t%0";
10459       else
10460         return "sal{q}\t{%2, %0|%0, %2}";
10461     }
10462 }
10463   [(set (attr "type")
10464      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10465                           (const_int 0))
10466                       (match_operand 0 "register_operand" ""))
10467                  (match_operand 2 "const1_operand" ""))
10468               (const_string "alu")
10469            ]
10470            (const_string "ishift")))
10471    (set_attr "mode" "DI")])
10472
10473 (define_insn "*ashldi3_1"
10474   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10475         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10476                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10477    (clobber (reg:CC FLAGS_REG))]
10478   "!TARGET_64BIT"
10479   "#"
10480   [(set_attr "type" "multi")])
10481
10482 ;; By default we don't ask for a scratch register, because when DImode
10483 ;; values are manipulated, registers are already at a premium.  But if
10484 ;; we have one handy, we won't turn it away.
10485 (define_peephole2
10486   [(match_scratch:SI 3 "r")
10487    (parallel [(set (match_operand:DI 0 "register_operand" "")
10488                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10489                               (match_operand:QI 2 "nonmemory_operand" "")))
10490               (clobber (reg:CC FLAGS_REG))])
10491    (match_dup 3)]
10492   "!TARGET_64BIT && TARGET_CMOVE"
10493   [(const_int 0)]
10494   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10495
10496 (define_split
10497   [(set (match_operand:DI 0 "register_operand" "")
10498         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10499                    (match_operand:QI 2 "nonmemory_operand" "")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10502                      ? flow2_completed : reload_completed)"
10503   [(const_int 0)]
10504   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10505
10506 (define_insn "x86_shld_1"
10507   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10508         (ior:SI (ashift:SI (match_dup 0)
10509                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10510                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10511                   (minus:QI (const_int 32) (match_dup 2)))))
10512    (clobber (reg:CC FLAGS_REG))]
10513   ""
10514   "@
10515    shld{l}\t{%2, %1, %0|%0, %1, %2}
10516    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10517   [(set_attr "type" "ishift")
10518    (set_attr "prefix_0f" "1")
10519    (set_attr "mode" "SI")
10520    (set_attr "pent_pair" "np")
10521    (set_attr "athlon_decode" "vector")])
10522
10523 (define_expand "x86_shift_adj_1"
10524   [(set (reg:CCZ FLAGS_REG)
10525         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10526                              (const_int 32))
10527                      (const_int 0)))
10528    (set (match_operand:SI 0 "register_operand" "")
10529         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10530                          (match_operand:SI 1 "register_operand" "")
10531                          (match_dup 0)))
10532    (set (match_dup 1)
10533         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10534                          (match_operand:SI 3 "register_operand" "r")
10535                          (match_dup 1)))]
10536   "TARGET_CMOVE"
10537   "")
10538
10539 (define_expand "x86_shift_adj_2"
10540   [(use (match_operand:SI 0 "register_operand" ""))
10541    (use (match_operand:SI 1 "register_operand" ""))
10542    (use (match_operand:QI 2 "register_operand" ""))]
10543   ""
10544 {
10545   rtx label = gen_label_rtx ();
10546   rtx tmp;
10547
10548   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10549
10550   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10551   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10552   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10553                               gen_rtx_LABEL_REF (VOIDmode, label),
10554                               pc_rtx);
10555   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10556   JUMP_LABEL (tmp) = label;
10557
10558   emit_move_insn (operands[0], operands[1]);
10559   ix86_expand_clear (operands[1]);
10560
10561   emit_label (label);
10562   LABEL_NUSES (label) = 1;
10563
10564   DONE;
10565 })
10566
10567 (define_expand "ashlsi3"
10568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10569         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10570                    (match_operand:QI 2 "nonmemory_operand" "")))
10571    (clobber (reg:CC FLAGS_REG))]
10572   ""
10573   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10574
10575 (define_insn "*ashlsi3_1"
10576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10577         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10578                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10581 {
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587       return "add{l}\t{%0, %0|%0, %0}";
10588
10589     case TYPE_LEA:
10590       return "#";
10591
10592     default:
10593       if (REG_P (operands[2]))
10594         return "sal{l}\t{%b2, %0|%0, %b2}";
10595       else if (operands[2] == const1_rtx
10596                && (TARGET_SHIFT1 || optimize_size))
10597         return "sal{l}\t%0";
10598       else
10599         return "sal{l}\t{%2, %0|%0, %2}";
10600     }
10601 }
10602   [(set (attr "type")
10603      (cond [(eq_attr "alternative" "1")
10604               (const_string "lea")
10605             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10606                           (const_int 0))
10607                       (match_operand 0 "register_operand" ""))
10608                  (match_operand 2 "const1_operand" ""))
10609               (const_string "alu")
10610            ]
10611            (const_string "ishift")))
10612    (set_attr "mode" "SI")])
10613
10614 ;; Convert lea to the lea pattern to avoid flags dependency.
10615 (define_split
10616   [(set (match_operand 0 "register_operand" "")
10617         (ashift (match_operand 1 "index_register_operand" "")
10618                 (match_operand:QI 2 "const_int_operand" "")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "reload_completed
10621    && true_regnum (operands[0]) != true_regnum (operands[1])
10622    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10623   [(const_int 0)]
10624 {
10625   rtx pat;
10626   enum machine_mode mode = GET_MODE (operands[0]);
10627
10628   if (GET_MODE_SIZE (mode) < 4)
10629     operands[0] = gen_lowpart (SImode, operands[0]);
10630   if (mode != Pmode)
10631     operands[1] = gen_lowpart (Pmode, operands[1]);
10632   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10633
10634   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10635   if (Pmode != SImode)
10636     pat = gen_rtx_SUBREG (SImode, pat, 0);
10637   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10638   DONE;
10639 })
10640
10641 ;; Rare case of shifting RSP is handled by generating move and shift
10642 (define_split
10643   [(set (match_operand 0 "register_operand" "")
10644         (ashift (match_operand 1 "register_operand" "")
10645                 (match_operand:QI 2 "const_int_operand" "")))
10646    (clobber (reg:CC FLAGS_REG))]
10647   "reload_completed
10648    && true_regnum (operands[0]) != true_regnum (operands[1])"
10649   [(const_int 0)]
10650 {
10651   rtx pat, clob;
10652   emit_move_insn (operands[0], operands[1]);
10653   pat = gen_rtx_SET (VOIDmode, operands[0],
10654                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10655                                      operands[0], operands[2]));
10656   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10657   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10658   DONE;
10659 })
10660
10661 (define_insn "*ashlsi3_1_zext"
10662   [(set (match_operand:DI 0 "register_operand" "=r,r")
10663         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10664                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10665    (clobber (reg:CC FLAGS_REG))]
10666   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10667 {
10668   switch (get_attr_type (insn))
10669     {
10670     case TYPE_ALU:
10671       gcc_assert (operands[2] == const1_rtx);
10672       return "add{l}\t{%k0, %k0|%k0, %k0}";
10673
10674     case TYPE_LEA:
10675       return "#";
10676
10677     default:
10678       if (REG_P (operands[2]))
10679         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10680       else if (operands[2] == const1_rtx
10681                && (TARGET_SHIFT1 || optimize_size))
10682         return "sal{l}\t%k0";
10683       else
10684         return "sal{l}\t{%2, %k0|%k0, %2}";
10685     }
10686 }
10687   [(set (attr "type")
10688      (cond [(eq_attr "alternative" "1")
10689               (const_string "lea")
10690             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10691                      (const_int 0))
10692                  (match_operand 2 "const1_operand" ""))
10693               (const_string "alu")
10694            ]
10695            (const_string "ishift")))
10696    (set_attr "mode" "SI")])
10697
10698 ;; Convert lea to the lea pattern to avoid flags dependency.
10699 (define_split
10700   [(set (match_operand:DI 0 "register_operand" "")
10701         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10702                                 (match_operand:QI 2 "const_int_operand" ""))))
10703    (clobber (reg:CC FLAGS_REG))]
10704   "TARGET_64BIT && reload_completed
10705    && true_regnum (operands[0]) != true_regnum (operands[1])"
10706   [(set (match_dup 0) (zero_extend:DI
10707                         (subreg:SI (mult:SI (match_dup 1)
10708                                             (match_dup 2)) 0)))]
10709 {
10710   operands[1] = gen_lowpart (Pmode, operands[1]);
10711   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10712 })
10713
10714 ;; This pattern can't accept a variable shift count, since shifts by
10715 ;; zero don't affect the flags.  We assume that shifts by constant
10716 ;; zero are optimized away.
10717 (define_insn "*ashlsi3_cmp"
10718   [(set (reg FLAGS_REG)
10719         (compare
10720           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10721                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10722           (const_int 0)))
10723    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10724         (ashift:SI (match_dup 1) (match_dup 2)))]
10725   "ix86_match_ccmode (insn, CCGOCmode)
10726    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10727    && (optimize_size
10728        || !TARGET_PARTIAL_FLAG_REG_STALL
10729        || (operands[2] == const1_rtx
10730            && (TARGET_SHIFT1
10731                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10732 {
10733   switch (get_attr_type (insn))
10734     {
10735     case TYPE_ALU:
10736       gcc_assert (operands[2] == const1_rtx);
10737       return "add{l}\t{%0, %0|%0, %0}";
10738
10739     default:
10740       if (REG_P (operands[2]))
10741         return "sal{l}\t{%b2, %0|%0, %b2}";
10742       else if (operands[2] == const1_rtx
10743                && (TARGET_SHIFT1 || optimize_size))
10744         return "sal{l}\t%0";
10745       else
10746         return "sal{l}\t{%2, %0|%0, %2}";
10747     }
10748 }
10749   [(set (attr "type")
10750      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10751                           (const_int 0))
10752                       (match_operand 0 "register_operand" ""))
10753                  (match_operand 2 "const1_operand" ""))
10754               (const_string "alu")
10755            ]
10756            (const_string "ishift")))
10757    (set_attr "mode" "SI")])
10758
10759 (define_insn "*ashlsi3_cconly"
10760   [(set (reg FLAGS_REG)
10761         (compare
10762           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10763                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10764           (const_int 0)))
10765    (clobber (match_scratch:SI 0 "=r"))]
10766   "ix86_match_ccmode (insn, CCGOCmode)
10767    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10768    && (optimize_size
10769        || !TARGET_PARTIAL_FLAG_REG_STALL
10770        || (operands[2] == const1_rtx
10771            && (TARGET_SHIFT1
10772                || TARGET_DOUBLE_WITH_ADD)))"
10773 {
10774   switch (get_attr_type (insn))
10775     {
10776     case TYPE_ALU:
10777       gcc_assert (operands[2] == const1_rtx);
10778       return "add{l}\t{%0, %0|%0, %0}";
10779
10780     default:
10781       if (REG_P (operands[2]))
10782         return "sal{l}\t{%b2, %0|%0, %b2}";
10783       else if (operands[2] == const1_rtx
10784                && (TARGET_SHIFT1 || optimize_size))
10785         return "sal{l}\t%0";
10786       else
10787         return "sal{l}\t{%2, %0|%0, %2}";
10788     }
10789 }
10790   [(set (attr "type")
10791      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792                           (const_int 0))
10793                       (match_operand 0 "register_operand" ""))
10794                  (match_operand 2 "const1_operand" ""))
10795               (const_string "alu")
10796            ]
10797            (const_string "ishift")))
10798    (set_attr "mode" "SI")])
10799
10800 (define_insn "*ashlsi3_cmp_zext"
10801   [(set (reg FLAGS_REG)
10802         (compare
10803           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10804                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10805           (const_int 0)))
10806    (set (match_operand:DI 0 "register_operand" "=r")
10807         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10808   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10809    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10810    && (optimize_size
10811        || !TARGET_PARTIAL_FLAG_REG_STALL
10812        || (operands[2] == const1_rtx
10813            && (TARGET_SHIFT1
10814                || TARGET_DOUBLE_WITH_ADD)))"
10815 {
10816   switch (get_attr_type (insn))
10817     {
10818     case TYPE_ALU:
10819       gcc_assert (operands[2] == const1_rtx);
10820       return "add{l}\t{%k0, %k0|%k0, %k0}";
10821
10822     default:
10823       if (REG_P (operands[2]))
10824         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10825       else if (operands[2] == const1_rtx
10826                && (TARGET_SHIFT1 || optimize_size))
10827         return "sal{l}\t%k0";
10828       else
10829         return "sal{l}\t{%2, %k0|%k0, %2}";
10830     }
10831 }
10832   [(set (attr "type")
10833      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10834                      (const_int 0))
10835                  (match_operand 2 "const1_operand" ""))
10836               (const_string "alu")
10837            ]
10838            (const_string "ishift")))
10839    (set_attr "mode" "SI")])
10840
10841 (define_expand "ashlhi3"
10842   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10843         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10844                    (match_operand:QI 2 "nonmemory_operand" "")))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "TARGET_HIMODE_MATH"
10847   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10848
10849 (define_insn "*ashlhi3_1_lea"
10850   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10851         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10852                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10853    (clobber (reg:CC FLAGS_REG))]
10854   "!TARGET_PARTIAL_REG_STALL
10855    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10856 {
10857   switch (get_attr_type (insn))
10858     {
10859     case TYPE_LEA:
10860       return "#";
10861     case TYPE_ALU:
10862       gcc_assert (operands[2] == const1_rtx);
10863       return "add{w}\t{%0, %0|%0, %0}";
10864
10865     default:
10866       if (REG_P (operands[2]))
10867         return "sal{w}\t{%b2, %0|%0, %b2}";
10868       else if (operands[2] == const1_rtx
10869                && (TARGET_SHIFT1 || optimize_size))
10870         return "sal{w}\t%0";
10871       else
10872         return "sal{w}\t{%2, %0|%0, %2}";
10873     }
10874 }
10875   [(set (attr "type")
10876      (cond [(eq_attr "alternative" "1")
10877               (const_string "lea")
10878             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10879                           (const_int 0))
10880                       (match_operand 0 "register_operand" ""))
10881                  (match_operand 2 "const1_operand" ""))
10882               (const_string "alu")
10883            ]
10884            (const_string "ishift")))
10885    (set_attr "mode" "HI,SI")])
10886
10887 (define_insn "*ashlhi3_1"
10888   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10889         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10890                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10891    (clobber (reg:CC FLAGS_REG))]
10892   "TARGET_PARTIAL_REG_STALL
10893    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10894 {
10895   switch (get_attr_type (insn))
10896     {
10897     case TYPE_ALU:
10898       gcc_assert (operands[2] == const1_rtx);
10899       return "add{w}\t{%0, %0|%0, %0}";
10900
10901     default:
10902       if (REG_P (operands[2]))
10903         return "sal{w}\t{%b2, %0|%0, %b2}";
10904       else if (operands[2] == const1_rtx
10905                && (TARGET_SHIFT1 || optimize_size))
10906         return "sal{w}\t%0";
10907       else
10908         return "sal{w}\t{%2, %0|%0, %2}";
10909     }
10910 }
10911   [(set (attr "type")
10912      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10913                           (const_int 0))
10914                       (match_operand 0 "register_operand" ""))
10915                  (match_operand 2 "const1_operand" ""))
10916               (const_string "alu")
10917            ]
10918            (const_string "ishift")))
10919    (set_attr "mode" "HI")])
10920
10921 ;; This pattern can't accept a variable shift count, since shifts by
10922 ;; zero don't affect the flags.  We assume that shifts by constant
10923 ;; zero are optimized away.
10924 (define_insn "*ashlhi3_cmp"
10925   [(set (reg FLAGS_REG)
10926         (compare
10927           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10928                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10929           (const_int 0)))
10930    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10931         (ashift:HI (match_dup 1) (match_dup 2)))]
10932   "ix86_match_ccmode (insn, CCGOCmode)
10933    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10934    && (optimize_size
10935        || !TARGET_PARTIAL_FLAG_REG_STALL
10936        || (operands[2] == const1_rtx
10937            && (TARGET_SHIFT1
10938                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10939 {
10940   switch (get_attr_type (insn))
10941     {
10942     case TYPE_ALU:
10943       gcc_assert (operands[2] == const1_rtx);
10944       return "add{w}\t{%0, %0|%0, %0}";
10945
10946     default:
10947       if (REG_P (operands[2]))
10948         return "sal{w}\t{%b2, %0|%0, %b2}";
10949       else if (operands[2] == const1_rtx
10950                && (TARGET_SHIFT1 || optimize_size))
10951         return "sal{w}\t%0";
10952       else
10953         return "sal{w}\t{%2, %0|%0, %2}";
10954     }
10955 }
10956   [(set (attr "type")
10957      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10958                           (const_int 0))
10959                       (match_operand 0 "register_operand" ""))
10960                  (match_operand 2 "const1_operand" ""))
10961               (const_string "alu")
10962            ]
10963            (const_string "ishift")))
10964    (set_attr "mode" "HI")])
10965
10966 (define_insn "*ashlhi3_cconly"
10967   [(set (reg FLAGS_REG)
10968         (compare
10969           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10970                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10971           (const_int 0)))
10972    (clobber (match_scratch:HI 0 "=r"))]
10973   "ix86_match_ccmode (insn, CCGOCmode)
10974    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10975    && (optimize_size
10976        || !TARGET_PARTIAL_FLAG_REG_STALL
10977        || (operands[2] == const1_rtx
10978            && (TARGET_SHIFT1
10979                || TARGET_DOUBLE_WITH_ADD)))"
10980 {
10981   switch (get_attr_type (insn))
10982     {
10983     case TYPE_ALU:
10984       gcc_assert (operands[2] == const1_rtx);
10985       return "add{w}\t{%0, %0|%0, %0}";
10986
10987     default:
10988       if (REG_P (operands[2]))
10989         return "sal{w}\t{%b2, %0|%0, %b2}";
10990       else if (operands[2] == const1_rtx
10991                && (TARGET_SHIFT1 || optimize_size))
10992         return "sal{w}\t%0";
10993       else
10994         return "sal{w}\t{%2, %0|%0, %2}";
10995     }
10996 }
10997   [(set (attr "type")
10998      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10999                           (const_int 0))
11000                       (match_operand 0 "register_operand" ""))
11001                  (match_operand 2 "const1_operand" ""))
11002               (const_string "alu")
11003            ]
11004            (const_string "ishift")))
11005    (set_attr "mode" "HI")])
11006
11007 (define_expand "ashlqi3"
11008   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11009         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11010                    (match_operand:QI 2 "nonmemory_operand" "")))
11011    (clobber (reg:CC FLAGS_REG))]
11012   "TARGET_QIMODE_MATH"
11013   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11014
11015 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11016
11017 (define_insn "*ashlqi3_1_lea"
11018   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11019         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11020                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "!TARGET_PARTIAL_REG_STALL
11023    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11024 {
11025   switch (get_attr_type (insn))
11026     {
11027     case TYPE_LEA:
11028       return "#";
11029     case TYPE_ALU:
11030       gcc_assert (operands[2] == const1_rtx);
11031       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11032         return "add{l}\t{%k0, %k0|%k0, %k0}";
11033       else
11034         return "add{b}\t{%0, %0|%0, %0}";
11035
11036     default:
11037       if (REG_P (operands[2]))
11038         {
11039           if (get_attr_mode (insn) == MODE_SI)
11040             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11041           else
11042             return "sal{b}\t{%b2, %0|%0, %b2}";
11043         }
11044       else if (operands[2] == const1_rtx
11045                && (TARGET_SHIFT1 || optimize_size))
11046         {
11047           if (get_attr_mode (insn) == MODE_SI)
11048             return "sal{l}\t%0";
11049           else
11050             return "sal{b}\t%0";
11051         }
11052       else
11053         {
11054           if (get_attr_mode (insn) == MODE_SI)
11055             return "sal{l}\t{%2, %k0|%k0, %2}";
11056           else
11057             return "sal{b}\t{%2, %0|%0, %2}";
11058         }
11059     }
11060 }
11061   [(set (attr "type")
11062      (cond [(eq_attr "alternative" "2")
11063               (const_string "lea")
11064             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065                           (const_int 0))
11066                       (match_operand 0 "register_operand" ""))
11067                  (match_operand 2 "const1_operand" ""))
11068               (const_string "alu")
11069            ]
11070            (const_string "ishift")))
11071    (set_attr "mode" "QI,SI,SI")])
11072
11073 (define_insn "*ashlqi3_1"
11074   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11075         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11076                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11077    (clobber (reg:CC FLAGS_REG))]
11078   "TARGET_PARTIAL_REG_STALL
11079    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080 {
11081   switch (get_attr_type (insn))
11082     {
11083     case TYPE_ALU:
11084       gcc_assert (operands[2] == const1_rtx);
11085       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11086         return "add{l}\t{%k0, %k0|%k0, %k0}";
11087       else
11088         return "add{b}\t{%0, %0|%0, %0}";
11089
11090     default:
11091       if (REG_P (operands[2]))
11092         {
11093           if (get_attr_mode (insn) == MODE_SI)
11094             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11095           else
11096             return "sal{b}\t{%b2, %0|%0, %b2}";
11097         }
11098       else if (operands[2] == const1_rtx
11099                && (TARGET_SHIFT1 || optimize_size))
11100         {
11101           if (get_attr_mode (insn) == MODE_SI)
11102             return "sal{l}\t%0";
11103           else
11104             return "sal{b}\t%0";
11105         }
11106       else
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t{%2, %k0|%k0, %2}";
11110           else
11111             return "sal{b}\t{%2, %0|%0, %2}";
11112         }
11113     }
11114 }
11115   [(set (attr "type")
11116      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117                           (const_int 0))
11118                       (match_operand 0 "register_operand" ""))
11119                  (match_operand 2 "const1_operand" ""))
11120               (const_string "alu")
11121            ]
11122            (const_string "ishift")))
11123    (set_attr "mode" "QI,SI")])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashlqi3_cmp"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11132                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11133           (const_int 0)))
11134    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11135         (ashift:QI (match_dup 1) (match_dup 2)))]
11136   "ix86_match_ccmode (insn, CCGOCmode)
11137    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11138    && (optimize_size
11139        || !TARGET_PARTIAL_FLAG_REG_STALL
11140        || (operands[2] == const1_rtx
11141            && (TARGET_SHIFT1
11142                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11143 {
11144   switch (get_attr_type (insn))
11145     {
11146     case TYPE_ALU:
11147       gcc_assert (operands[2] == const1_rtx);
11148       return "add{b}\t{%0, %0|%0, %0}";
11149
11150     default:
11151       if (REG_P (operands[2]))
11152         return "sal{b}\t{%b2, %0|%0, %b2}";
11153       else if (operands[2] == const1_rtx
11154                && (TARGET_SHIFT1 || optimize_size))
11155         return "sal{b}\t%0";
11156       else
11157         return "sal{b}\t{%2, %0|%0, %2}";
11158     }
11159 }
11160   [(set (attr "type")
11161      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11162                           (const_int 0))
11163                       (match_operand 0 "register_operand" ""))
11164                  (match_operand 2 "const1_operand" ""))
11165               (const_string "alu")
11166            ]
11167            (const_string "ishift")))
11168    (set_attr "mode" "QI")])
11169
11170 (define_insn "*ashlqi3_cconly"
11171   [(set (reg FLAGS_REG)
11172         (compare
11173           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11174                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11175           (const_int 0)))
11176    (clobber (match_scratch:QI 0 "=q"))]
11177   "ix86_match_ccmode (insn, CCGOCmode)
11178    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11179    && (optimize_size
11180        || !TARGET_PARTIAL_FLAG_REG_STALL
11181        || (operands[2] == const1_rtx
11182            && (TARGET_SHIFT1
11183                || TARGET_DOUBLE_WITH_ADD)))"
11184 {
11185   switch (get_attr_type (insn))
11186     {
11187     case TYPE_ALU:
11188       gcc_assert (operands[2] == const1_rtx);
11189       return "add{b}\t{%0, %0|%0, %0}";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         return "sal{b}\t{%b2, %0|%0, %b2}";
11194       else if (operands[2] == const1_rtx
11195                && (TARGET_SHIFT1 || optimize_size))
11196         return "sal{b}\t%0";
11197       else
11198         return "sal{b}\t{%2, %0|%0, %2}";
11199     }
11200 }
11201   [(set (attr "type")
11202      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203                           (const_int 0))
11204                       (match_operand 0 "register_operand" ""))
11205                  (match_operand 2 "const1_operand" ""))
11206               (const_string "alu")
11207            ]
11208            (const_string "ishift")))
11209    (set_attr "mode" "QI")])
11210
11211 ;; See comment above `ashldi3' about how this works.
11212
11213 (define_expand "ashrti3"
11214   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11215                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11216                                 (match_operand:QI 2 "nonmemory_operand" "")))
11217               (clobber (reg:CC FLAGS_REG))])]
11218   "TARGET_64BIT"
11219 {
11220   if (! immediate_operand (operands[2], QImode))
11221     {
11222       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11223       DONE;
11224     }
11225   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11226   DONE;
11227 })
11228
11229 (define_insn "ashrti3_1"
11230   [(set (match_operand:TI 0 "register_operand" "=r")
11231         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11232                      (match_operand:QI 2 "register_operand" "c")))
11233    (clobber (match_scratch:DI 3 "=&r"))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "TARGET_64BIT"
11236   "#"
11237   [(set_attr "type" "multi")])
11238
11239 (define_insn "*ashrti3_2"
11240   [(set (match_operand:TI 0 "register_operand" "=r")
11241         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11242                      (match_operand:QI 2 "immediate_operand" "O")))
11243    (clobber (reg:CC FLAGS_REG))]
11244   "TARGET_64BIT"
11245   "#"
11246   [(set_attr "type" "multi")])
11247
11248 (define_split
11249   [(set (match_operand:TI 0 "register_operand" "")
11250         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11251                      (match_operand:QI 2 "register_operand" "")))
11252    (clobber (match_scratch:DI 3 ""))
11253    (clobber (reg:CC FLAGS_REG))]
11254   "TARGET_64BIT && reload_completed"
11255   [(const_int 0)]
11256   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11257
11258 (define_split
11259   [(set (match_operand:TI 0 "register_operand" "")
11260         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11261                      (match_operand:QI 2 "immediate_operand" "")))
11262    (clobber (reg:CC FLAGS_REG))]
11263   "TARGET_64BIT && reload_completed"
11264   [(const_int 0)]
11265   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11266
11267 (define_insn "x86_64_shrd"
11268   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11269         (ior:DI (ashiftrt:DI (match_dup 0)
11270                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11271                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11272                   (minus:QI (const_int 64) (match_dup 2)))))
11273    (clobber (reg:CC FLAGS_REG))]
11274   "TARGET_64BIT"
11275   "@
11276    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11277    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11278   [(set_attr "type" "ishift")
11279    (set_attr "prefix_0f" "1")
11280    (set_attr "mode" "DI")
11281    (set_attr "athlon_decode" "vector")])
11282
11283 (define_expand "ashrdi3"
11284   [(set (match_operand:DI 0 "shiftdi_operand" "")
11285         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11286                      (match_operand:QI 2 "nonmemory_operand" "")))]
11287   ""
11288   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11289
11290 (define_insn "*ashrdi3_63_rex64"
11291   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11292         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11293                      (match_operand:DI 2 "const_int_operand" "i,i")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "TARGET_64BIT && INTVAL (operands[2]) == 63
11296    && (TARGET_USE_CLTD || optimize_size)
11297    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11298   "@
11299    {cqto|cqo}
11300    sar{q}\t{%2, %0|%0, %2}"
11301   [(set_attr "type" "imovx,ishift")
11302    (set_attr "prefix_0f" "0,*")
11303    (set_attr "length_immediate" "0,*")
11304    (set_attr "modrm" "0,1")
11305    (set_attr "mode" "DI")])
11306
11307 (define_insn "*ashrdi3_1_one_bit_rex64"
11308   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11310                      (match_operand:QI 2 "const1_operand" "")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11313    && (TARGET_SHIFT1 || optimize_size)"
11314   "sar{q}\t%0"
11315   [(set_attr "type" "ishift")
11316    (set (attr "length") 
11317      (if_then_else (match_operand:DI 0 "register_operand" "") 
11318         (const_string "2")
11319         (const_string "*")))])
11320
11321 (define_insn "*ashrdi3_1_rex64"
11322   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11323         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11324                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11327   "@
11328    sar{q}\t{%2, %0|%0, %2}
11329    sar{q}\t{%b2, %0|%0, %b2}"
11330   [(set_attr "type" "ishift")
11331    (set_attr "mode" "DI")])
11332
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags.  We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340                        (match_operand:QI 2 "const1_operand" ""))
11341           (const_int 0)))
11342    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11344   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345    && (TARGET_SHIFT1 || optimize_size)
11346    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347   "sar{q}\t%0"
11348   [(set_attr "type" "ishift")
11349    (set (attr "length") 
11350      (if_then_else (match_operand:DI 0 "register_operand" "") 
11351         (const_string "2")
11352         (const_string "*")))])
11353
11354 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11355   [(set (reg FLAGS_REG)
11356         (compare
11357           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11358                        (match_operand:QI 2 "const1_operand" ""))
11359           (const_int 0)))
11360    (clobber (match_scratch:DI 0 "=r"))]
11361   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11362    && (TARGET_SHIFT1 || optimize_size)
11363    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11364   "sar{q}\t%0"
11365   [(set_attr "type" "ishift")
11366    (set_attr "length" "2")])
11367
11368 ;; This pattern can't accept a variable shift count, since shifts by
11369 ;; zero don't affect the flags.  We assume that shifts by constant
11370 ;; zero are optimized away.
11371 (define_insn "*ashrdi3_cmp_rex64"
11372   [(set (reg FLAGS_REG)
11373         (compare
11374           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11375                        (match_operand:QI 2 "const_int_operand" "n"))
11376           (const_int 0)))
11377    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11378         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11379   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11380    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11381    && (optimize_size
11382        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11383   "sar{q}\t{%2, %0|%0, %2}"
11384   [(set_attr "type" "ishift")
11385    (set_attr "mode" "DI")])
11386
11387 (define_insn "*ashrdi3_cconly_rex64"
11388   [(set (reg FLAGS_REG)
11389         (compare
11390           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391                        (match_operand:QI 2 "const_int_operand" "n"))
11392           (const_int 0)))
11393    (clobber (match_scratch:DI 0 "=r"))]
11394   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11396    && (optimize_size
11397        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398   "sar{q}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "DI")])
11401
11402 (define_insn "*ashrdi3_1"
11403   [(set (match_operand:DI 0 "register_operand" "=r")
11404         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11405                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "!TARGET_64BIT"
11408   "#"
11409   [(set_attr "type" "multi")])
11410
11411 ;; By default we don't ask for a scratch register, because when DImode
11412 ;; values are manipulated, registers are already at a premium.  But if
11413 ;; we have one handy, we won't turn it away.
11414 (define_peephole2
11415   [(match_scratch:SI 3 "r")
11416    (parallel [(set (match_operand:DI 0 "register_operand" "")
11417                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11418                                 (match_operand:QI 2 "nonmemory_operand" "")))
11419               (clobber (reg:CC FLAGS_REG))])
11420    (match_dup 3)]
11421   "!TARGET_64BIT && TARGET_CMOVE"
11422   [(const_int 0)]
11423   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11424
11425 (define_split
11426   [(set (match_operand:DI 0 "register_operand" "")
11427         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11428                      (match_operand:QI 2 "nonmemory_operand" "")))
11429    (clobber (reg:CC FLAGS_REG))]
11430   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11431                      ? flow2_completed : reload_completed)"
11432   [(const_int 0)]
11433   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11434
11435 (define_insn "x86_shrd_1"
11436   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11437         (ior:SI (ashiftrt:SI (match_dup 0)
11438                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11439                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11440                   (minus:QI (const_int 32) (match_dup 2)))))
11441    (clobber (reg:CC FLAGS_REG))]
11442   ""
11443   "@
11444    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11445    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11446   [(set_attr "type" "ishift")
11447    (set_attr "prefix_0f" "1")
11448    (set_attr "pent_pair" "np")
11449    (set_attr "mode" "SI")])
11450
11451 (define_expand "x86_shift_adj_3"
11452   [(use (match_operand:SI 0 "register_operand" ""))
11453    (use (match_operand:SI 1 "register_operand" ""))
11454    (use (match_operand:QI 2 "register_operand" ""))]
11455   ""
11456 {
11457   rtx label = gen_label_rtx ();
11458   rtx tmp;
11459
11460   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11461
11462   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11463   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11464   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11465                               gen_rtx_LABEL_REF (VOIDmode, label),
11466                               pc_rtx);
11467   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11468   JUMP_LABEL (tmp) = label;
11469
11470   emit_move_insn (operands[0], operands[1]);
11471   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11472
11473   emit_label (label);
11474   LABEL_NUSES (label) = 1;
11475
11476   DONE;
11477 })
11478
11479 (define_insn "ashrsi3_31"
11480   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11481         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11482                      (match_operand:SI 2 "const_int_operand" "i,i")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11485    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11486   "@
11487    {cltd|cdq}
11488    sar{l}\t{%2, %0|%0, %2}"
11489   [(set_attr "type" "imovx,ishift")
11490    (set_attr "prefix_0f" "0,*")
11491    (set_attr "length_immediate" "0,*")
11492    (set_attr "modrm" "0,1")
11493    (set_attr "mode" "SI")])
11494
11495 (define_insn "*ashrsi3_31_zext"
11496   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11497         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11498                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11501    && INTVAL (operands[2]) == 31
11502    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11503   "@
11504    {cltd|cdq}
11505    sar{l}\t{%2, %k0|%k0, %2}"
11506   [(set_attr "type" "imovx,ishift")
11507    (set_attr "prefix_0f" "0,*")
11508    (set_attr "length_immediate" "0,*")
11509    (set_attr "modrm" "0,1")
11510    (set_attr "mode" "SI")])
11511
11512 (define_expand "ashrsi3"
11513   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11514         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11515                      (match_operand:QI 2 "nonmemory_operand" "")))
11516    (clobber (reg:CC FLAGS_REG))]
11517   ""
11518   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11519
11520 (define_insn "*ashrsi3_1_one_bit"
11521   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11522         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11523                      (match_operand:QI 2 "const1_operand" "")))
11524    (clobber (reg:CC FLAGS_REG))]
11525   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11526    && (TARGET_SHIFT1 || optimize_size)"
11527   "sar{l}\t%0"
11528   [(set_attr "type" "ishift")
11529    (set (attr "length") 
11530      (if_then_else (match_operand:SI 0 "register_operand" "") 
11531         (const_string "2")
11532         (const_string "*")))])
11533
11534 (define_insn "*ashrsi3_1_one_bit_zext"
11535   [(set (match_operand:DI 0 "register_operand" "=r")
11536         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11537                                      (match_operand:QI 2 "const1_operand" ""))))
11538    (clobber (reg:CC FLAGS_REG))]
11539   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11540    && (TARGET_SHIFT1 || optimize_size)"
11541   "sar{l}\t%k0"
11542   [(set_attr "type" "ishift")
11543    (set_attr "length" "2")])
11544
11545 (define_insn "*ashrsi3_1"
11546   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11547         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11548                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11549    (clobber (reg:CC FLAGS_REG))]
11550   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551   "@
11552    sar{l}\t{%2, %0|%0, %2}
11553    sar{l}\t{%b2, %0|%0, %b2}"
11554   [(set_attr "type" "ishift")
11555    (set_attr "mode" "SI")])
11556
11557 (define_insn "*ashrsi3_1_zext"
11558   [(set (match_operand:DI 0 "register_operand" "=r,r")
11559         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11560                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11561    (clobber (reg:CC FLAGS_REG))]
11562   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11563   "@
11564    sar{l}\t{%2, %k0|%k0, %2}
11565    sar{l}\t{%b2, %k0|%k0, %b2}"
11566   [(set_attr "type" "ishift")
11567    (set_attr "mode" "SI")])
11568
11569 ;; This pattern can't accept a variable shift count, since shifts by
11570 ;; zero don't affect the flags.  We assume that shifts by constant
11571 ;; zero are optimized away.
11572 (define_insn "*ashrsi3_one_bit_cmp"
11573   [(set (reg FLAGS_REG)
11574         (compare
11575           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11576                        (match_operand:QI 2 "const1_operand" ""))
11577           (const_int 0)))
11578    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11579         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11580   "ix86_match_ccmode (insn, CCGOCmode)
11581    && (TARGET_SHIFT1 || optimize_size)
11582    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11583   "sar{l}\t%0"
11584   [(set_attr "type" "ishift")
11585    (set (attr "length") 
11586      (if_then_else (match_operand:SI 0 "register_operand" "") 
11587         (const_string "2")
11588         (const_string "*")))])
11589
11590 (define_insn "*ashrsi3_one_bit_cconly"
11591   [(set (reg FLAGS_REG)
11592         (compare
11593           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11594                        (match_operand:QI 2 "const1_operand" ""))
11595           (const_int 0)))
11596    (clobber (match_scratch:SI 0 "=r"))]
11597   "ix86_match_ccmode (insn, CCGOCmode)
11598    && (TARGET_SHIFT1 || optimize_size)
11599    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600   "sar{l}\t%0"
11601   [(set_attr "type" "ishift")
11602    (set_attr "length" "2")])
11603
11604 (define_insn "*ashrsi3_one_bit_cmp_zext"
11605   [(set (reg FLAGS_REG)
11606         (compare
11607           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11608                        (match_operand:QI 2 "const1_operand" ""))
11609           (const_int 0)))
11610    (set (match_operand:DI 0 "register_operand" "=r")
11611         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11612   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11613    && (TARGET_SHIFT1 || optimize_size)
11614    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11615   "sar{l}\t%k0"
11616   [(set_attr "type" "ishift")
11617    (set_attr "length" "2")])
11618
11619 ;; This pattern can't accept a variable shift count, since shifts by
11620 ;; zero don't affect the flags.  We assume that shifts by constant
11621 ;; zero are optimized away.
11622 (define_insn "*ashrsi3_cmp"
11623   [(set (reg FLAGS_REG)
11624         (compare
11625           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11626                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11627           (const_int 0)))
11628    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11629         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11630   "ix86_match_ccmode (insn, CCGOCmode)
11631    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11632    && (optimize_size
11633        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11634   "sar{l}\t{%2, %0|%0, %2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "SI")])
11637
11638 (define_insn "*ashrsi3_cconly"
11639   [(set (reg FLAGS_REG)
11640         (compare
11641           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11642                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11643           (const_int 0)))
11644    (clobber (match_scratch:SI 0 "=r"))]
11645   "ix86_match_ccmode (insn, CCGOCmode)
11646    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11647    && (optimize_size
11648        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649   "sar{l}\t{%2, %0|%0, %2}"
11650   [(set_attr "type" "ishift")
11651    (set_attr "mode" "SI")])
11652
11653 (define_insn "*ashrsi3_cmp_zext"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11657                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11658           (const_int 0)))
11659    (set (match_operand:DI 0 "register_operand" "=r")
11660         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11661   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11663    && (optimize_size
11664        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11665   "sar{l}\t{%2, %k0|%k0, %2}"
11666   [(set_attr "type" "ishift")
11667    (set_attr "mode" "SI")])
11668
11669 (define_expand "ashrhi3"
11670   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11671         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11672                      (match_operand:QI 2 "nonmemory_operand" "")))
11673    (clobber (reg:CC FLAGS_REG))]
11674   "TARGET_HIMODE_MATH"
11675   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11676
11677 (define_insn "*ashrhi3_1_one_bit"
11678   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11679         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11680                      (match_operand:QI 2 "const1_operand" "")))
11681    (clobber (reg:CC FLAGS_REG))]
11682   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11683    && (TARGET_SHIFT1 || optimize_size)"
11684   "sar{w}\t%0"
11685   [(set_attr "type" "ishift")
11686    (set (attr "length") 
11687      (if_then_else (match_operand 0 "register_operand" "") 
11688         (const_string "2")
11689         (const_string "*")))])
11690
11691 (define_insn "*ashrhi3_1"
11692   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11693         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11694                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11695    (clobber (reg:CC FLAGS_REG))]
11696   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11697   "@
11698    sar{w}\t{%2, %0|%0, %2}
11699    sar{w}\t{%b2, %0|%0, %b2}"
11700   [(set_attr "type" "ishift")
11701    (set_attr "mode" "HI")])
11702
11703 ;; This pattern can't accept a variable shift count, since shifts by
11704 ;; zero don't affect the flags.  We assume that shifts by constant
11705 ;; zero are optimized away.
11706 (define_insn "*ashrhi3_one_bit_cmp"
11707   [(set (reg FLAGS_REG)
11708         (compare
11709           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11710                        (match_operand:QI 2 "const1_operand" ""))
11711           (const_int 0)))
11712    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11713         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11714   "ix86_match_ccmode (insn, CCGOCmode)
11715    && (TARGET_SHIFT1 || optimize_size)
11716    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11717   "sar{w}\t%0"
11718   [(set_attr "type" "ishift")
11719    (set (attr "length") 
11720      (if_then_else (match_operand 0 "register_operand" "") 
11721         (const_string "2")
11722         (const_string "*")))])
11723
11724 (define_insn "*ashrhi3_one_bit_cconly"
11725   [(set (reg FLAGS_REG)
11726         (compare
11727           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11728                        (match_operand:QI 2 "const1_operand" ""))
11729           (const_int 0)))
11730    (clobber (match_scratch:HI 0 "=r"))]
11731   "ix86_match_ccmode (insn, CCGOCmode)
11732    && (TARGET_SHIFT1 || optimize_size)
11733    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734   "sar{w}\t%0"
11735   [(set_attr "type" "ishift")
11736    (set_attr "length" "2")])
11737
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags.  We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashrhi3_cmp"
11742   [(set (reg FLAGS_REG)
11743         (compare
11744           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11745                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11746           (const_int 0)))
11747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11748         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11749   "ix86_match_ccmode (insn, CCGOCmode)
11750    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11751    && (optimize_size
11752        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11753   "sar{w}\t{%2, %0|%0, %2}"
11754   [(set_attr "type" "ishift")
11755    (set_attr "mode" "HI")])
11756
11757 (define_insn "*ashrhi3_cconly"
11758   [(set (reg FLAGS_REG)
11759         (compare
11760           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11761                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11762           (const_int 0)))
11763    (clobber (match_scratch:HI 0 "=r"))]
11764   "ix86_match_ccmode (insn, CCGOCmode)
11765    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11766    && (optimize_size
11767        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768   "sar{w}\t{%2, %0|%0, %2}"
11769   [(set_attr "type" "ishift")
11770    (set_attr "mode" "HI")])
11771
11772 (define_expand "ashrqi3"
11773   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11774         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11775                      (match_operand:QI 2 "nonmemory_operand" "")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "TARGET_QIMODE_MATH"
11778   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11779
11780 (define_insn "*ashrqi3_1_one_bit"
11781   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11782         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783                      (match_operand:QI 2 "const1_operand" "")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11786    && (TARGET_SHIFT1 || optimize_size)"
11787   "sar{b}\t%0"
11788   [(set_attr "type" "ishift")
11789    (set (attr "length") 
11790      (if_then_else (match_operand 0 "register_operand" "") 
11791         (const_string "2")
11792         (const_string "*")))])
11793
11794 (define_insn "*ashrqi3_1_one_bit_slp"
11795   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11796         (ashiftrt:QI (match_dup 0)
11797                      (match_operand:QI 1 "const1_operand" "")))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11800    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11801    && (TARGET_SHIFT1 || optimize_size)"
11802   "sar{b}\t%0"
11803   [(set_attr "type" "ishift1")
11804    (set (attr "length") 
11805      (if_then_else (match_operand 0 "register_operand" "") 
11806         (const_string "2")
11807         (const_string "*")))])
11808
11809 (define_insn "*ashrqi3_1"
11810   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11811         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11812                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11813    (clobber (reg:CC FLAGS_REG))]
11814   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11815   "@
11816    sar{b}\t{%2, %0|%0, %2}
11817    sar{b}\t{%b2, %0|%0, %b2}"
11818   [(set_attr "type" "ishift")
11819    (set_attr "mode" "QI")])
11820
11821 (define_insn "*ashrqi3_1_slp"
11822   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11823         (ashiftrt:QI (match_dup 0)
11824                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11825    (clobber (reg:CC FLAGS_REG))]
11826   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11827    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11828   "@
11829    sar{b}\t{%1, %0|%0, %1}
11830    sar{b}\t{%b1, %0|%0, %b1}"
11831   [(set_attr "type" "ishift1")
11832    (set_attr "mode" "QI")])
11833
11834 ;; This pattern can't accept a variable shift count, since shifts by
11835 ;; zero don't affect the flags.  We assume that shifts by constant
11836 ;; zero are optimized away.
11837 (define_insn "*ashrqi3_one_bit_cmp"
11838   [(set (reg FLAGS_REG)
11839         (compare
11840           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11841                        (match_operand:QI 2 "const1_operand" "I"))
11842           (const_int 0)))
11843    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11844         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11845   "ix86_match_ccmode (insn, CCGOCmode)
11846    && (TARGET_SHIFT1 || optimize_size)
11847    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11848   "sar{b}\t%0"
11849   [(set_attr "type" "ishift")
11850    (set (attr "length") 
11851      (if_then_else (match_operand 0 "register_operand" "") 
11852         (const_string "2")
11853         (const_string "*")))])
11854
11855 (define_insn "*ashrqi3_one_bit_cconly"
11856   [(set (reg FLAGS_REG)
11857         (compare
11858           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11859                        (match_operand:QI 2 "const1_operand" "I"))
11860           (const_int 0)))
11861    (clobber (match_scratch:QI 0 "=q"))]
11862   "ix86_match_ccmode (insn, CCGOCmode)
11863    && (TARGET_SHIFT1 || optimize_size)
11864    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11865   "sar{b}\t%0"
11866   [(set_attr "type" "ishift")
11867    (set_attr "length" "2")])
11868
11869 ;; This pattern can't accept a variable shift count, since shifts by
11870 ;; zero don't affect the flags.  We assume that shifts by constant
11871 ;; zero are optimized away.
11872 (define_insn "*ashrqi3_cmp"
11873   [(set (reg FLAGS_REG)
11874         (compare
11875           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11876                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11877           (const_int 0)))
11878    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11879         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11880   "ix86_match_ccmode (insn, CCGOCmode)
11881    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11882    && (optimize_size
11883        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11884   "sar{b}\t{%2, %0|%0, %2}"
11885   [(set_attr "type" "ishift")
11886    (set_attr "mode" "QI")])
11887
11888 (define_insn "*ashrqi3_cconly"
11889   [(set (reg FLAGS_REG)
11890         (compare
11891           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11892                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11893           (const_int 0)))
11894    (clobber (match_scratch:QI 0 "=q"))]
11895   "ix86_match_ccmode (insn, CCGOCmode)
11896    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11897    && (optimize_size
11898        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899   "sar{b}\t{%2, %0|%0, %2}"
11900   [(set_attr "type" "ishift")
11901    (set_attr "mode" "QI")])
11902
11903 \f
11904 ;; Logical shift instructions
11905
11906 ;; See comment above `ashldi3' about how this works.
11907
11908 (define_expand "lshrti3"
11909   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11910                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11911                                 (match_operand:QI 2 "nonmemory_operand" "")))
11912               (clobber (reg:CC FLAGS_REG))])]
11913   "TARGET_64BIT"
11914 {
11915   if (! immediate_operand (operands[2], QImode))
11916     {
11917       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11918       DONE;
11919     }
11920   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11921   DONE;
11922 })
11923
11924 (define_insn "lshrti3_1"
11925   [(set (match_operand:TI 0 "register_operand" "=r")
11926         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11927                      (match_operand:QI 2 "register_operand" "c")))
11928    (clobber (match_scratch:DI 3 "=&r"))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "TARGET_64BIT"
11931   "#"
11932   [(set_attr "type" "multi")])
11933
11934 (define_insn "*lshrti3_2"
11935   [(set (match_operand:TI 0 "register_operand" "=r")
11936         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11937                      (match_operand:QI 2 "immediate_operand" "O")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "TARGET_64BIT"
11940   "#"
11941   [(set_attr "type" "multi")])
11942
11943 (define_split 
11944   [(set (match_operand:TI 0 "register_operand" "")
11945         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11946                      (match_operand:QI 2 "register_operand" "")))
11947    (clobber (match_scratch:DI 3 ""))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "TARGET_64BIT && reload_completed"
11950   [(const_int 0)]
11951   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11952
11953 (define_split 
11954   [(set (match_operand:TI 0 "register_operand" "")
11955         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11956                      (match_operand:QI 2 "immediate_operand" "")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "TARGET_64BIT && reload_completed"
11959   [(const_int 0)]
11960   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11961
11962 (define_expand "lshrdi3"
11963   [(set (match_operand:DI 0 "shiftdi_operand" "")
11964         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11965                      (match_operand:QI 2 "nonmemory_operand" "")))]
11966   ""
11967   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11968
11969 (define_insn "*lshrdi3_1_one_bit_rex64"
11970   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11971         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11972                      (match_operand:QI 2 "const1_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11975    && (TARGET_SHIFT1 || optimize_size)"
11976   "shr{q}\t%0"
11977   [(set_attr "type" "ishift")
11978    (set (attr "length") 
11979      (if_then_else (match_operand:DI 0 "register_operand" "") 
11980         (const_string "2")
11981         (const_string "*")))])
11982
11983 (define_insn "*lshrdi3_1_rex64"
11984   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11985         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11986                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11989   "@
11990    shr{q}\t{%2, %0|%0, %2}
11991    shr{q}\t{%b2, %0|%0, %b2}"
11992   [(set_attr "type" "ishift")
11993    (set_attr "mode" "DI")])
11994
11995 ;; This pattern can't accept a variable shift count, since shifts by
11996 ;; zero don't affect the flags.  We assume that shifts by constant
11997 ;; zero are optimized away.
11998 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11999   [(set (reg FLAGS_REG)
12000         (compare
12001           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002                        (match_operand:QI 2 "const1_operand" ""))
12003           (const_int 0)))
12004    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12005         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12006   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12007    && (TARGET_SHIFT1 || optimize_size)
12008    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12009   "shr{q}\t%0"
12010   [(set_attr "type" "ishift")
12011    (set (attr "length") 
12012      (if_then_else (match_operand:DI 0 "register_operand" "") 
12013         (const_string "2")
12014         (const_string "*")))])
12015
12016 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12017   [(set (reg FLAGS_REG)
12018         (compare
12019           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12020                        (match_operand:QI 2 "const1_operand" ""))
12021           (const_int 0)))
12022    (clobber (match_scratch:DI 0 "=r"))]
12023   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12024    && (TARGET_SHIFT1 || optimize_size)
12025    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026   "shr{q}\t%0"
12027   [(set_attr "type" "ishift")
12028    (set_attr "length" "2")])
12029
12030 ;; This pattern can't accept a variable shift count, since shifts by
12031 ;; zero don't affect the flags.  We assume that shifts by constant
12032 ;; zero are optimized away.
12033 (define_insn "*lshrdi3_cmp_rex64"
12034   [(set (reg FLAGS_REG)
12035         (compare
12036           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12037                        (match_operand:QI 2 "const_int_operand" "e"))
12038           (const_int 0)))
12039    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12040         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12041   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12042    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12043    && (optimize_size
12044        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12045   "shr{q}\t{%2, %0|%0, %2}"
12046   [(set_attr "type" "ishift")
12047    (set_attr "mode" "DI")])
12048
12049 (define_insn "*lshrdi3_cconly_rex64"
12050   [(set (reg FLAGS_REG)
12051         (compare
12052           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053                        (match_operand:QI 2 "const_int_operand" "e"))
12054           (const_int 0)))
12055    (clobber (match_scratch:DI 0 "=r"))]
12056   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12058    && (optimize_size
12059        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060   "shr{q}\t{%2, %0|%0, %2}"
12061   [(set_attr "type" "ishift")
12062    (set_attr "mode" "DI")])
12063
12064 (define_insn "*lshrdi3_1"
12065   [(set (match_operand:DI 0 "register_operand" "=r")
12066         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12067                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "!TARGET_64BIT"
12070   "#"
12071   [(set_attr "type" "multi")])
12072
12073 ;; By default we don't ask for a scratch register, because when DImode
12074 ;; values are manipulated, registers are already at a premium.  But if
12075 ;; we have one handy, we won't turn it away.
12076 (define_peephole2
12077   [(match_scratch:SI 3 "r")
12078    (parallel [(set (match_operand:DI 0 "register_operand" "")
12079                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12080                                 (match_operand:QI 2 "nonmemory_operand" "")))
12081               (clobber (reg:CC FLAGS_REG))])
12082    (match_dup 3)]
12083   "!TARGET_64BIT && TARGET_CMOVE"
12084   [(const_int 0)]
12085   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12086
12087 (define_split 
12088   [(set (match_operand:DI 0 "register_operand" "")
12089         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12090                      (match_operand:QI 2 "nonmemory_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12093                      ? flow2_completed : reload_completed)"
12094   [(const_int 0)]
12095   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12096
12097 (define_expand "lshrsi3"
12098   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12099         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12100                      (match_operand:QI 2 "nonmemory_operand" "")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   ""
12103   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12104
12105 (define_insn "*lshrsi3_1_one_bit"
12106   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12107         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12108                      (match_operand:QI 2 "const1_operand" "")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111    && (TARGET_SHIFT1 || optimize_size)"
12112   "shr{l}\t%0"
12113   [(set_attr "type" "ishift")
12114    (set (attr "length") 
12115      (if_then_else (match_operand:SI 0 "register_operand" "") 
12116         (const_string "2")
12117         (const_string "*")))])
12118
12119 (define_insn "*lshrsi3_1_one_bit_zext"
12120   [(set (match_operand:DI 0 "register_operand" "=r")
12121         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12122                      (match_operand:QI 2 "const1_operand" "")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12125    && (TARGET_SHIFT1 || optimize_size)"
12126   "shr{l}\t%k0"
12127   [(set_attr "type" "ishift")
12128    (set_attr "length" "2")])
12129
12130 (define_insn "*lshrsi3_1"
12131   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12132         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12133                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12136   "@
12137    shr{l}\t{%2, %0|%0, %2}
12138    shr{l}\t{%b2, %0|%0, %b2}"
12139   [(set_attr "type" "ishift")
12140    (set_attr "mode" "SI")])
12141
12142 (define_insn "*lshrsi3_1_zext"
12143   [(set (match_operand:DI 0 "register_operand" "=r,r")
12144         (zero_extend:DI
12145           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12146                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12149   "@
12150    shr{l}\t{%2, %k0|%k0, %2}
12151    shr{l}\t{%b2, %k0|%k0, %b2}"
12152   [(set_attr "type" "ishift")
12153    (set_attr "mode" "SI")])
12154
12155 ;; This pattern can't accept a variable shift count, since shifts by
12156 ;; zero don't affect the flags.  We assume that shifts by constant
12157 ;; zero are optimized away.
12158 (define_insn "*lshrsi3_one_bit_cmp"
12159   [(set (reg FLAGS_REG)
12160         (compare
12161           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162                        (match_operand:QI 2 "const1_operand" ""))
12163           (const_int 0)))
12164    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12165         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12166   "ix86_match_ccmode (insn, CCGOCmode)
12167    && (TARGET_SHIFT1 || optimize_size)
12168    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12169   "shr{l}\t%0"
12170   [(set_attr "type" "ishift")
12171    (set (attr "length") 
12172      (if_then_else (match_operand:SI 0 "register_operand" "") 
12173         (const_string "2")
12174         (const_string "*")))])
12175
12176 (define_insn "*lshrsi3_one_bit_cconly"
12177   [(set (reg FLAGS_REG)
12178         (compare
12179           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180                        (match_operand:QI 2 "const1_operand" ""))
12181           (const_int 0)))
12182    (clobber (match_scratch:SI 0 "=r"))]
12183   "ix86_match_ccmode (insn, CCGOCmode)
12184    && (TARGET_SHIFT1 || optimize_size)
12185    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12186   "shr{l}\t%0"
12187   [(set_attr "type" "ishift")
12188    (set_attr "length" "2")])
12189
12190 (define_insn "*lshrsi3_cmp_one_bit_zext"
12191   [(set (reg FLAGS_REG)
12192         (compare
12193           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12194                        (match_operand:QI 2 "const1_operand" ""))
12195           (const_int 0)))
12196    (set (match_operand:DI 0 "register_operand" "=r")
12197         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12198   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12199    && (TARGET_SHIFT1 || optimize_size)
12200    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201   "shr{l}\t%k0"
12202   [(set_attr "type" "ishift")
12203    (set_attr "length" "2")])
12204
12205 ;; This pattern can't accept a variable shift count, since shifts by
12206 ;; zero don't affect the flags.  We assume that shifts by constant
12207 ;; zero are optimized away.
12208 (define_insn "*lshrsi3_cmp"
12209   [(set (reg FLAGS_REG)
12210         (compare
12211           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12213           (const_int 0)))
12214    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12215         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12216   "ix86_match_ccmode (insn, CCGOCmode)
12217    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12218    && (optimize_size
12219        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12220   "shr{l}\t{%2, %0|%0, %2}"
12221   [(set_attr "type" "ishift")
12222    (set_attr "mode" "SI")])
12223
12224 (define_insn "*lshrsi3_cconly"
12225   [(set (reg FLAGS_REG)
12226       (compare
12227         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12229         (const_int 0)))
12230    (clobber (match_scratch:SI 0 "=r"))]
12231   "ix86_match_ccmode (insn, CCGOCmode)
12232    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12233    && (optimize_size
12234        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235   "shr{l}\t{%2, %0|%0, %2}"
12236   [(set_attr "type" "ishift")
12237    (set_attr "mode" "SI")])
12238
12239 (define_insn "*lshrsi3_cmp_zext"
12240   [(set (reg FLAGS_REG)
12241         (compare
12242           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12243                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244           (const_int 0)))
12245    (set (match_operand:DI 0 "register_operand" "=r")
12246         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12247   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12248    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12249    && (optimize_size
12250        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12251   "shr{l}\t{%2, %k0|%k0, %2}"
12252   [(set_attr "type" "ishift")
12253    (set_attr "mode" "SI")])
12254
12255 (define_expand "lshrhi3"
12256   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12257         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12258                      (match_operand:QI 2 "nonmemory_operand" "")))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "TARGET_HIMODE_MATH"
12261   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12262
12263 (define_insn "*lshrhi3_1_one_bit"
12264   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12265         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12266                      (match_operand:QI 2 "const1_operand" "")))
12267    (clobber (reg:CC FLAGS_REG))]
12268   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12269    && (TARGET_SHIFT1 || optimize_size)"
12270   "shr{w}\t%0"
12271   [(set_attr "type" "ishift")
12272    (set (attr "length") 
12273      (if_then_else (match_operand 0 "register_operand" "") 
12274         (const_string "2")
12275         (const_string "*")))])
12276
12277 (define_insn "*lshrhi3_1"
12278   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12279         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12280                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12281    (clobber (reg:CC FLAGS_REG))]
12282   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12283   "@
12284    shr{w}\t{%2, %0|%0, %2}
12285    shr{w}\t{%b2, %0|%0, %b2}"
12286   [(set_attr "type" "ishift")
12287    (set_attr "mode" "HI")])
12288
12289 ;; This pattern can't accept a variable shift count, since shifts by
12290 ;; zero don't affect the flags.  We assume that shifts by constant
12291 ;; zero are optimized away.
12292 (define_insn "*lshrhi3_one_bit_cmp"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12296                        (match_operand:QI 2 "const1_operand" ""))
12297           (const_int 0)))
12298    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12299         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12300   "ix86_match_ccmode (insn, CCGOCmode)
12301    && (TARGET_SHIFT1 || optimize_size)
12302    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303   "shr{w}\t%0"
12304   [(set_attr "type" "ishift")
12305    (set (attr "length") 
12306      (if_then_else (match_operand:SI 0 "register_operand" "") 
12307         (const_string "2")
12308         (const_string "*")))])
12309
12310 (define_insn "*lshrhi3_one_bit_cconly"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const1_operand" ""))
12315           (const_int 0)))
12316    (clobber (match_scratch:HI 0 "=r"))]
12317   "ix86_match_ccmode (insn, CCGOCmode)
12318    && (TARGET_SHIFT1 || optimize_size)
12319    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320   "shr{w}\t%0"
12321   [(set_attr "type" "ishift")
12322    (set_attr "length" "2")])
12323
12324 ;; This pattern can't accept a variable shift count, since shifts by
12325 ;; zero don't affect the flags.  We assume that shifts by constant
12326 ;; zero are optimized away.
12327 (define_insn "*lshrhi3_cmp"
12328   [(set (reg FLAGS_REG)
12329         (compare
12330           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12331                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332           (const_int 0)))
12333    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12334         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12335   "ix86_match_ccmode (insn, CCGOCmode)
12336    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12337    && (optimize_size
12338        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12339   "shr{w}\t{%2, %0|%0, %2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "mode" "HI")])
12342
12343 (define_insn "*lshrhi3_cconly"
12344   [(set (reg FLAGS_REG)
12345         (compare
12346           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12347                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12348           (const_int 0)))
12349    (clobber (match_scratch:HI 0 "=r"))]
12350   "ix86_match_ccmode (insn, CCGOCmode)
12351    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352    && (optimize_size
12353        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354   "shr{w}\t{%2, %0|%0, %2}"
12355   [(set_attr "type" "ishift")
12356    (set_attr "mode" "HI")])
12357
12358 (define_expand "lshrqi3"
12359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12360         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12361                      (match_operand:QI 2 "nonmemory_operand" "")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_QIMODE_MATH"
12364   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12365
12366 (define_insn "*lshrqi3_1_one_bit"
12367   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12368         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12369                      (match_operand:QI 2 "const1_operand" "")))
12370    (clobber (reg:CC FLAGS_REG))]
12371   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12372    && (TARGET_SHIFT1 || optimize_size)"
12373   "shr{b}\t%0"
12374   [(set_attr "type" "ishift")
12375    (set (attr "length") 
12376      (if_then_else (match_operand 0 "register_operand" "") 
12377         (const_string "2")
12378         (const_string "*")))])
12379
12380 (define_insn "*lshrqi3_1_one_bit_slp"
12381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382         (lshiftrt:QI (match_dup 0)
12383                      (match_operand:QI 1 "const1_operand" "")))
12384    (clobber (reg:CC FLAGS_REG))]
12385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12386    && (TARGET_SHIFT1 || optimize_size)"
12387   "shr{b}\t%0"
12388   [(set_attr "type" "ishift1")
12389    (set (attr "length") 
12390      (if_then_else (match_operand 0 "register_operand" "") 
12391         (const_string "2")
12392         (const_string "*")))])
12393
12394 (define_insn "*lshrqi3_1"
12395   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12396         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12397                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12400   "@
12401    shr{b}\t{%2, %0|%0, %2}
12402    shr{b}\t{%b2, %0|%0, %b2}"
12403   [(set_attr "type" "ishift")
12404    (set_attr "mode" "QI")])
12405
12406 (define_insn "*lshrqi3_1_slp"
12407   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12408         (lshiftrt:QI (match_dup 0)
12409                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12410    (clobber (reg:CC FLAGS_REG))]
12411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12412    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12413   "@
12414    shr{b}\t{%1, %0|%0, %1}
12415    shr{b}\t{%b1, %0|%0, %b1}"
12416   [(set_attr "type" "ishift1")
12417    (set_attr "mode" "QI")])
12418
12419 ;; This pattern can't accept a variable shift count, since shifts by
12420 ;; zero don't affect the flags.  We assume that shifts by constant
12421 ;; zero are optimized away.
12422 (define_insn "*lshrqi2_one_bit_cmp"
12423   [(set (reg FLAGS_REG)
12424         (compare
12425           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12426                        (match_operand:QI 2 "const1_operand" ""))
12427           (const_int 0)))
12428    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12429         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12430   "ix86_match_ccmode (insn, CCGOCmode)
12431    && (TARGET_SHIFT1 || optimize_size)
12432    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12433   "shr{b}\t%0"
12434   [(set_attr "type" "ishift")
12435    (set (attr "length") 
12436      (if_then_else (match_operand:SI 0 "register_operand" "") 
12437         (const_string "2")
12438         (const_string "*")))])
12439
12440 (define_insn "*lshrqi2_one_bit_cconly"
12441   [(set (reg FLAGS_REG)
12442         (compare
12443           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12444                        (match_operand:QI 2 "const1_operand" ""))
12445           (const_int 0)))
12446    (clobber (match_scratch:QI 0 "=q"))]
12447   "ix86_match_ccmode (insn, CCGOCmode)
12448    && (TARGET_SHIFT1 || optimize_size)
12449    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12450   "shr{b}\t%0"
12451   [(set_attr "type" "ishift")
12452    (set_attr "length" "2")])
12453
12454 ;; This pattern can't accept a variable shift count, since shifts by
12455 ;; zero don't affect the flags.  We assume that shifts by constant
12456 ;; zero are optimized away.
12457 (define_insn "*lshrqi2_cmp"
12458   [(set (reg FLAGS_REG)
12459         (compare
12460           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12461                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12462           (const_int 0)))
12463    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12464         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12465   "ix86_match_ccmode (insn, CCGOCmode)
12466    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12467    && (optimize_size
12468        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12469   "shr{b}\t{%2, %0|%0, %2}"
12470   [(set_attr "type" "ishift")
12471    (set_attr "mode" "QI")])
12472
12473 (define_insn "*lshrqi2_cconly"
12474   [(set (reg FLAGS_REG)
12475         (compare
12476           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12478           (const_int 0)))
12479    (clobber (match_scratch:QI 0 "=q"))]
12480   "ix86_match_ccmode (insn, CCGOCmode)
12481    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12482    && (optimize_size
12483        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484   "shr{b}\t{%2, %0|%0, %2}"
12485   [(set_attr "type" "ishift")
12486    (set_attr "mode" "QI")])
12487 \f
12488 ;; Rotate instructions
12489
12490 (define_expand "rotldi3"
12491   [(set (match_operand:DI 0 "shiftdi_operand" "")
12492         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12493                    (match_operand:QI 2 "nonmemory_operand" "")))
12494    (clobber (reg:CC FLAGS_REG))]
12495  ""
12496 {
12497   if (TARGET_64BIT)
12498     {
12499       ix86_expand_binary_operator (ROTATE, DImode, operands);
12500       DONE;
12501     }
12502   if (!const_1_to_31_operand (operands[2], VOIDmode))
12503     FAIL;
12504   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12505   DONE;
12506 })
12507
12508 ;; Implement rotation using two double-precision shift instructions
12509 ;; and a scratch register.   
12510 (define_insn_and_split "ix86_rotldi3"
12511  [(set (match_operand:DI 0 "register_operand" "=r")
12512        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12513                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12514   (clobber (reg:CC FLAGS_REG))
12515   (clobber (match_scratch:SI 3 "=&r"))]
12516  "!TARGET_64BIT"
12517  "" 
12518  "&& reload_completed"
12519  [(set (match_dup 3) (match_dup 4))
12520   (parallel
12521    [(set (match_dup 4)
12522          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12523                  (lshiftrt:SI (match_dup 5)
12524                               (minus:QI (const_int 32) (match_dup 2)))))
12525     (clobber (reg:CC FLAGS_REG))])
12526   (parallel
12527    [(set (match_dup 5)
12528          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12529                  (lshiftrt:SI (match_dup 3)
12530                               (minus:QI (const_int 32) (match_dup 2)))))
12531     (clobber (reg:CC FLAGS_REG))])]
12532  "split_di (operands, 1, operands + 4, operands + 5);")
12533  
12534 (define_insn "*rotlsi3_1_one_bit_rex64"
12535   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12536         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12537                    (match_operand:QI 2 "const1_operand" "")))
12538    (clobber (reg:CC FLAGS_REG))]
12539   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12540    && (TARGET_SHIFT1 || optimize_size)"
12541   "rol{q}\t%0"
12542   [(set_attr "type" "rotate")
12543    (set (attr "length") 
12544      (if_then_else (match_operand:DI 0 "register_operand" "") 
12545         (const_string "2")
12546         (const_string "*")))])
12547
12548 (define_insn "*rotldi3_1_rex64"
12549   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12550         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12551                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12554   "@
12555    rol{q}\t{%2, %0|%0, %2}
12556    rol{q}\t{%b2, %0|%0, %b2}"
12557   [(set_attr "type" "rotate")
12558    (set_attr "mode" "DI")])
12559
12560 (define_expand "rotlsi3"
12561   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12562         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12563                    (match_operand:QI 2 "nonmemory_operand" "")))
12564    (clobber (reg:CC FLAGS_REG))]
12565   ""
12566   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12567
12568 (define_insn "*rotlsi3_1_one_bit"
12569   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12570         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12571                    (match_operand:QI 2 "const1_operand" "")))
12572    (clobber (reg:CC FLAGS_REG))]
12573   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12574    && (TARGET_SHIFT1 || optimize_size)"
12575   "rol{l}\t%0"
12576   [(set_attr "type" "rotate")
12577    (set (attr "length") 
12578      (if_then_else (match_operand:SI 0 "register_operand" "") 
12579         (const_string "2")
12580         (const_string "*")))])
12581
12582 (define_insn "*rotlsi3_1_one_bit_zext"
12583   [(set (match_operand:DI 0 "register_operand" "=r")
12584         (zero_extend:DI
12585           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12586                      (match_operand:QI 2 "const1_operand" ""))))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12589    && (TARGET_SHIFT1 || optimize_size)"
12590   "rol{l}\t%k0"
12591   [(set_attr "type" "rotate")
12592    (set_attr "length" "2")])
12593
12594 (define_insn "*rotlsi3_1"
12595   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12596         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12597                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12600   "@
12601    rol{l}\t{%2, %0|%0, %2}
12602    rol{l}\t{%b2, %0|%0, %b2}"
12603   [(set_attr "type" "rotate")
12604    (set_attr "mode" "SI")])
12605
12606 (define_insn "*rotlsi3_1_zext"
12607   [(set (match_operand:DI 0 "register_operand" "=r,r")
12608         (zero_extend:DI
12609           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12610                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12611    (clobber (reg:CC FLAGS_REG))]
12612   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12613   "@
12614    rol{l}\t{%2, %k0|%k0, %2}
12615    rol{l}\t{%b2, %k0|%k0, %b2}"
12616   [(set_attr "type" "rotate")
12617    (set_attr "mode" "SI")])
12618
12619 (define_expand "rotlhi3"
12620   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12621         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12622                    (match_operand:QI 2 "nonmemory_operand" "")))
12623    (clobber (reg:CC FLAGS_REG))]
12624   "TARGET_HIMODE_MATH"
12625   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12626
12627 (define_insn "*rotlhi3_1_one_bit"
12628   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12630                    (match_operand:QI 2 "const1_operand" "")))
12631    (clobber (reg:CC FLAGS_REG))]
12632   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12633    && (TARGET_SHIFT1 || optimize_size)"
12634   "rol{w}\t%0"
12635   [(set_attr "type" "rotate")
12636    (set (attr "length") 
12637      (if_then_else (match_operand 0 "register_operand" "") 
12638         (const_string "2")
12639         (const_string "*")))])
12640
12641 (define_insn "*rotlhi3_1"
12642   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12643         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12644                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12647   "@
12648    rol{w}\t{%2, %0|%0, %2}
12649    rol{w}\t{%b2, %0|%0, %b2}"
12650   [(set_attr "type" "rotate")
12651    (set_attr "mode" "HI")])
12652
12653 (define_expand "rotlqi3"
12654   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12655         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12656                    (match_operand:QI 2 "nonmemory_operand" "")))
12657    (clobber (reg:CC FLAGS_REG))]
12658   "TARGET_QIMODE_MATH"
12659   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12660
12661 (define_insn "*rotlqi3_1_one_bit_slp"
12662   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12663         (rotate:QI (match_dup 0)
12664                    (match_operand:QI 1 "const1_operand" "")))
12665    (clobber (reg:CC FLAGS_REG))]
12666   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12667    && (TARGET_SHIFT1 || optimize_size)"
12668   "rol{b}\t%0"
12669   [(set_attr "type" "rotate1")
12670    (set (attr "length") 
12671      (if_then_else (match_operand 0 "register_operand" "") 
12672         (const_string "2")
12673         (const_string "*")))])
12674
12675 (define_insn "*rotlqi3_1_one_bit"
12676   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12677         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12678                    (match_operand:QI 2 "const1_operand" "")))
12679    (clobber (reg:CC FLAGS_REG))]
12680   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12681    && (TARGET_SHIFT1 || optimize_size)"
12682   "rol{b}\t%0"
12683   [(set_attr "type" "rotate")
12684    (set (attr "length") 
12685      (if_then_else (match_operand 0 "register_operand" "") 
12686         (const_string "2")
12687         (const_string "*")))])
12688
12689 (define_insn "*rotlqi3_1_slp"
12690   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12691         (rotate:QI (match_dup 0)
12692                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12693    (clobber (reg:CC FLAGS_REG))]
12694   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12695    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12696   "@
12697    rol{b}\t{%1, %0|%0, %1}
12698    rol{b}\t{%b1, %0|%0, %b1}"
12699   [(set_attr "type" "rotate1")
12700    (set_attr "mode" "QI")])
12701
12702 (define_insn "*rotlqi3_1"
12703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706    (clobber (reg:CC FLAGS_REG))]
12707   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12708   "@
12709    rol{b}\t{%2, %0|%0, %2}
12710    rol{b}\t{%b2, %0|%0, %b2}"
12711   [(set_attr "type" "rotate")
12712    (set_attr "mode" "QI")])
12713
12714 (define_expand "rotrdi3"
12715   [(set (match_operand:DI 0 "shiftdi_operand" "")
12716         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12717                    (match_operand:QI 2 "nonmemory_operand" "")))
12718    (clobber (reg:CC FLAGS_REG))]
12719  ""
12720 {
12721   if (TARGET_64BIT)
12722     {
12723       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12724       DONE;
12725     }
12726   if (!const_1_to_31_operand (operands[2], VOIDmode))
12727     FAIL;
12728   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12729   DONE;
12730 })
12731   
12732 ;; Implement rotation using two double-precision shift instructions
12733 ;; and a scratch register.   
12734 (define_insn_and_split "ix86_rotrdi3"
12735  [(set (match_operand:DI 0 "register_operand" "=r")
12736        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12737                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12738   (clobber (reg:CC FLAGS_REG))
12739   (clobber (match_scratch:SI 3 "=&r"))]
12740  "!TARGET_64BIT"
12741  ""
12742  "&& reload_completed"
12743  [(set (match_dup 3) (match_dup 4))
12744   (parallel
12745    [(set (match_dup 4)
12746          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12747                  (ashift:SI (match_dup 5)
12748                             (minus:QI (const_int 32) (match_dup 2)))))
12749     (clobber (reg:CC FLAGS_REG))])
12750   (parallel
12751    [(set (match_dup 5)
12752          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12753                  (ashift:SI (match_dup 3)
12754                             (minus:QI (const_int 32) (match_dup 2)))))
12755     (clobber (reg:CC FLAGS_REG))])]
12756  "split_di (operands, 1, operands + 4, operands + 5);")
12757
12758 (define_insn "*rotrdi3_1_one_bit_rex64"
12759   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12760         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12761                      (match_operand:QI 2 "const1_operand" "")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12764    && (TARGET_SHIFT1 || optimize_size)"
12765   "ror{q}\t%0"
12766   [(set_attr "type" "rotate")
12767    (set (attr "length") 
12768      (if_then_else (match_operand:DI 0 "register_operand" "") 
12769         (const_string "2")
12770         (const_string "*")))])
12771
12772 (define_insn "*rotrdi3_1_rex64"
12773   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12774         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12775                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12776    (clobber (reg:CC FLAGS_REG))]
12777   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12778   "@
12779    ror{q}\t{%2, %0|%0, %2}
12780    ror{q}\t{%b2, %0|%0, %b2}"
12781   [(set_attr "type" "rotate")
12782    (set_attr "mode" "DI")])
12783
12784 (define_expand "rotrsi3"
12785   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12786         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12787                      (match_operand:QI 2 "nonmemory_operand" "")))
12788    (clobber (reg:CC FLAGS_REG))]
12789   ""
12790   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12791
12792 (define_insn "*rotrsi3_1_one_bit"
12793   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12794         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12795                      (match_operand:QI 2 "const1_operand" "")))
12796    (clobber (reg:CC FLAGS_REG))]
12797   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12798    && (TARGET_SHIFT1 || optimize_size)"
12799   "ror{l}\t%0"
12800   [(set_attr "type" "rotate")
12801    (set (attr "length") 
12802      (if_then_else (match_operand:SI 0 "register_operand" "") 
12803         (const_string "2")
12804         (const_string "*")))])
12805
12806 (define_insn "*rotrsi3_1_one_bit_zext"
12807   [(set (match_operand:DI 0 "register_operand" "=r")
12808         (zero_extend:DI
12809           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12810                        (match_operand:QI 2 "const1_operand" ""))))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813    && (TARGET_SHIFT1 || optimize_size)"
12814   "ror{l}\t%k0"
12815   [(set_attr "type" "rotate")
12816    (set (attr "length") 
12817      (if_then_else (match_operand:SI 0 "register_operand" "") 
12818         (const_string "2")
12819         (const_string "*")))])
12820
12821 (define_insn "*rotrsi3_1"
12822   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12823         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12824                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12825    (clobber (reg:CC FLAGS_REG))]
12826   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12827   "@
12828    ror{l}\t{%2, %0|%0, %2}
12829    ror{l}\t{%b2, %0|%0, %b2}"
12830   [(set_attr "type" "rotate")
12831    (set_attr "mode" "SI")])
12832
12833 (define_insn "*rotrsi3_1_zext"
12834   [(set (match_operand:DI 0 "register_operand" "=r,r")
12835         (zero_extend:DI
12836           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12837                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12838    (clobber (reg:CC FLAGS_REG))]
12839   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12840   "@
12841    ror{l}\t{%2, %k0|%k0, %2}
12842    ror{l}\t{%b2, %k0|%k0, %b2}"
12843   [(set_attr "type" "rotate")
12844    (set_attr "mode" "SI")])
12845
12846 (define_expand "rotrhi3"
12847   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12848         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12849                      (match_operand:QI 2 "nonmemory_operand" "")))
12850    (clobber (reg:CC FLAGS_REG))]
12851   "TARGET_HIMODE_MATH"
12852   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12853
12854 (define_insn "*rotrhi3_one_bit"
12855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12856         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12857                      (match_operand:QI 2 "const1_operand" "")))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12860    && (TARGET_SHIFT1 || optimize_size)"
12861   "ror{w}\t%0"
12862   [(set_attr "type" "rotate")
12863    (set (attr "length") 
12864      (if_then_else (match_operand 0 "register_operand" "") 
12865         (const_string "2")
12866         (const_string "*")))])
12867
12868 (define_insn "*rotrhi3"
12869   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12870         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12871                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12872    (clobber (reg:CC FLAGS_REG))]
12873   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12874   "@
12875    ror{w}\t{%2, %0|%0, %2}
12876    ror{w}\t{%b2, %0|%0, %b2}"
12877   [(set_attr "type" "rotate")
12878    (set_attr "mode" "HI")])
12879
12880 (define_expand "rotrqi3"
12881   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12882         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12883                      (match_operand:QI 2 "nonmemory_operand" "")))
12884    (clobber (reg:CC FLAGS_REG))]
12885   "TARGET_QIMODE_MATH"
12886   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12887
12888 (define_insn "*rotrqi3_1_one_bit"
12889   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12890         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12891                      (match_operand:QI 2 "const1_operand" "")))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12894    && (TARGET_SHIFT1 || optimize_size)"
12895   "ror{b}\t%0"
12896   [(set_attr "type" "rotate")
12897    (set (attr "length") 
12898      (if_then_else (match_operand 0 "register_operand" "") 
12899         (const_string "2")
12900         (const_string "*")))])
12901
12902 (define_insn "*rotrqi3_1_one_bit_slp"
12903   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12904         (rotatert:QI (match_dup 0)
12905                      (match_operand:QI 1 "const1_operand" "")))
12906    (clobber (reg:CC FLAGS_REG))]
12907   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12908    && (TARGET_SHIFT1 || optimize_size)"
12909   "ror{b}\t%0"
12910   [(set_attr "type" "rotate1")
12911    (set (attr "length") 
12912      (if_then_else (match_operand 0 "register_operand" "") 
12913         (const_string "2")
12914         (const_string "*")))])
12915
12916 (define_insn "*rotrqi3_1"
12917   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12918         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12919                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12920    (clobber (reg:CC FLAGS_REG))]
12921   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12922   "@
12923    ror{b}\t{%2, %0|%0, %2}
12924    ror{b}\t{%b2, %0|%0, %b2}"
12925   [(set_attr "type" "rotate")
12926    (set_attr "mode" "QI")])
12927
12928 (define_insn "*rotrqi3_1_slp"
12929   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12930         (rotatert:QI (match_dup 0)
12931                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12932    (clobber (reg:CC FLAGS_REG))]
12933   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12934    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12935   "@
12936    ror{b}\t{%1, %0|%0, %1}
12937    ror{b}\t{%b1, %0|%0, %b1}"
12938   [(set_attr "type" "rotate1")
12939    (set_attr "mode" "QI")])
12940 \f
12941 ;; Bit set / bit test instructions
12942
12943 (define_expand "extv"
12944   [(set (match_operand:SI 0 "register_operand" "")
12945         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12946                          (match_operand:SI 2 "const8_operand" "")
12947                          (match_operand:SI 3 "const8_operand" "")))]
12948   ""
12949 {
12950   /* Handle extractions from %ah et al.  */
12951   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12952     FAIL;
12953
12954   /* From mips.md: extract_bit_field doesn't verify that our source
12955      matches the predicate, so check it again here.  */
12956   if (! ext_register_operand (operands[1], VOIDmode))
12957     FAIL;
12958 })
12959
12960 (define_expand "extzv"
12961   [(set (match_operand:SI 0 "register_operand" "")
12962         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12963                          (match_operand:SI 2 "const8_operand" "")
12964                          (match_operand:SI 3 "const8_operand" "")))]
12965   ""
12966 {
12967   /* Handle extractions from %ah et al.  */
12968   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12969     FAIL;
12970
12971   /* From mips.md: extract_bit_field doesn't verify that our source
12972      matches the predicate, so check it again here.  */
12973   if (! ext_register_operand (operands[1], VOIDmode))
12974     FAIL;
12975 })
12976
12977 (define_expand "insv"
12978   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12979                       (match_operand 1 "const8_operand" "")
12980                       (match_operand 2 "const8_operand" ""))
12981         (match_operand 3 "register_operand" ""))]
12982   ""
12983 {
12984   /* Handle insertions to %ah et al.  */
12985   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12986     FAIL;
12987
12988   /* From mips.md: insert_bit_field doesn't verify that our source
12989      matches the predicate, so check it again here.  */
12990   if (! ext_register_operand (operands[0], VOIDmode))
12991     FAIL;
12992
12993   if (TARGET_64BIT)
12994     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12995   else
12996     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12997
12998   DONE;
12999 })
13000
13001 ;; %%% bts, btr, btc, bt.
13002 ;; In general these instructions are *slow* when applied to memory,
13003 ;; since they enforce atomic operation.  When applied to registers,
13004 ;; it depends on the cpu implementation.  They're never faster than
13005 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13006 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13007 ;; within the instruction itself, so operating on bits in the high
13008 ;; 32-bits of a register becomes easier.
13009 ;;
13010 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13011 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13012 ;; negdf respectively, so they can never be disabled entirely.
13013
13014 (define_insn "*btsq"
13015   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13016                          (const_int 1)
13017                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13018         (const_int 1))
13019    (clobber (reg:CC FLAGS_REG))]
13020   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13021   "bts{q} %1,%0"
13022   [(set_attr "type" "alu1")])
13023
13024 (define_insn "*btrq"
13025   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13026                          (const_int 1)
13027                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13028         (const_int 0))
13029    (clobber (reg:CC FLAGS_REG))]
13030   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13031   "btr{q} %1,%0"
13032   [(set_attr "type" "alu1")])
13033
13034 (define_insn "*btcq"
13035   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13036                          (const_int 1)
13037                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13038         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13039    (clobber (reg:CC FLAGS_REG))]
13040   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13041   "btc{q} %1,%0"
13042   [(set_attr "type" "alu1")])
13043
13044 ;; Allow Nocona to avoid these instructions if a register is available.
13045
13046 (define_peephole2
13047   [(match_scratch:DI 2 "r")
13048    (parallel [(set (zero_extract:DI
13049                      (match_operand:DI 0 "register_operand" "")
13050                      (const_int 1)
13051                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13052                    (const_int 1))
13053               (clobber (reg:CC FLAGS_REG))])]
13054   "TARGET_64BIT && !TARGET_USE_BT"
13055   [(const_int 0)]
13056 {
13057   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13058   rtx op1;
13059
13060   if (HOST_BITS_PER_WIDE_INT >= 64)
13061     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13062   else if (i < HOST_BITS_PER_WIDE_INT)
13063     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13064   else
13065     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13066
13067   op1 = immed_double_const (lo, hi, DImode);
13068   if (i >= 31)
13069     {
13070       emit_move_insn (operands[2], op1);
13071       op1 = operands[2];
13072     }
13073
13074   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13075   DONE;
13076 })
13077
13078 (define_peephole2
13079   [(match_scratch:DI 2 "r")
13080    (parallel [(set (zero_extract:DI
13081                      (match_operand:DI 0 "register_operand" "")
13082                      (const_int 1)
13083                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13084                    (const_int 0))
13085               (clobber (reg:CC FLAGS_REG))])]
13086   "TARGET_64BIT && !TARGET_USE_BT"
13087   [(const_int 0)]
13088 {
13089   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13090   rtx op1;
13091
13092   if (HOST_BITS_PER_WIDE_INT >= 64)
13093     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13094   else if (i < HOST_BITS_PER_WIDE_INT)
13095     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13096   else
13097     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13098
13099   op1 = immed_double_const (~lo, ~hi, DImode);
13100   if (i >= 32)
13101     {
13102       emit_move_insn (operands[2], op1);
13103       op1 = operands[2];
13104     }
13105
13106   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13107   DONE;
13108 })
13109
13110 (define_peephole2
13111   [(match_scratch:DI 2 "r")
13112    (parallel [(set (zero_extract:DI
13113                      (match_operand:DI 0 "register_operand" "")
13114                      (const_int 1)
13115                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13116               (not:DI (zero_extract:DI
13117                         (match_dup 0) (const_int 1) (match_dup 1))))
13118               (clobber (reg:CC FLAGS_REG))])]
13119   "TARGET_64BIT && !TARGET_USE_BT"
13120   [(const_int 0)]
13121 {
13122   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13123   rtx op1;
13124
13125   if (HOST_BITS_PER_WIDE_INT >= 64)
13126     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13127   else if (i < HOST_BITS_PER_WIDE_INT)
13128     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13129   else
13130     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13131
13132   op1 = immed_double_const (lo, hi, DImode);
13133   if (i >= 31)
13134     {
13135       emit_move_insn (operands[2], op1);
13136       op1 = operands[2];
13137     }
13138
13139   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13140   DONE;
13141 })
13142 \f
13143 ;; Store-flag instructions.
13144
13145 ;; For all sCOND expanders, also expand the compare or test insn that
13146 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13147
13148 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13149 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13150 ;; way, which can later delete the movzx if only QImode is needed.
13151
13152 (define_expand "seq"
13153   [(set (match_operand:QI 0 "register_operand" "")
13154         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13155   ""
13156   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13157
13158 (define_expand "sne"
13159   [(set (match_operand:QI 0 "register_operand" "")
13160         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13161   ""
13162   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13163
13164 (define_expand "sgt"
13165   [(set (match_operand:QI 0 "register_operand" "")
13166         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167   ""
13168   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13169
13170 (define_expand "sgtu"
13171   [(set (match_operand:QI 0 "register_operand" "")
13172         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173   ""
13174   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13175
13176 (define_expand "slt"
13177   [(set (match_operand:QI 0 "register_operand" "")
13178         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179   ""
13180   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13181
13182 (define_expand "sltu"
13183   [(set (match_operand:QI 0 "register_operand" "")
13184         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185   ""
13186   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13187
13188 (define_expand "sge"
13189   [(set (match_operand:QI 0 "register_operand" "")
13190         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191   ""
13192   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13193
13194 (define_expand "sgeu"
13195   [(set (match_operand:QI 0 "register_operand" "")
13196         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197   ""
13198   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13199
13200 (define_expand "sle"
13201   [(set (match_operand:QI 0 "register_operand" "")
13202         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203   ""
13204   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13205
13206 (define_expand "sleu"
13207   [(set (match_operand:QI 0 "register_operand" "")
13208         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209   ""
13210   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13211
13212 (define_expand "sunordered"
13213   [(set (match_operand:QI 0 "register_operand" "")
13214         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215   "TARGET_80387 || TARGET_SSE"
13216   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13217
13218 (define_expand "sordered"
13219   [(set (match_operand:QI 0 "register_operand" "")
13220         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221   "TARGET_80387"
13222   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13223
13224 (define_expand "suneq"
13225   [(set (match_operand:QI 0 "register_operand" "")
13226         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227   "TARGET_80387 || TARGET_SSE"
13228   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13229
13230 (define_expand "sunge"
13231   [(set (match_operand:QI 0 "register_operand" "")
13232         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233   "TARGET_80387 || TARGET_SSE"
13234   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13235
13236 (define_expand "sungt"
13237   [(set (match_operand:QI 0 "register_operand" "")
13238         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239   "TARGET_80387 || TARGET_SSE"
13240   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13241
13242 (define_expand "sunle"
13243   [(set (match_operand:QI 0 "register_operand" "")
13244         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245   "TARGET_80387 || TARGET_SSE"
13246   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13247
13248 (define_expand "sunlt"
13249   [(set (match_operand:QI 0 "register_operand" "")
13250         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251   "TARGET_80387 || TARGET_SSE"
13252   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13253
13254 (define_expand "sltgt"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   "TARGET_80387 || TARGET_SSE"
13258   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13259
13260 (define_insn "*setcc_1"
13261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13262         (match_operator:QI 1 "ix86_comparison_operator"
13263           [(reg FLAGS_REG) (const_int 0)]))]
13264   ""
13265   "set%C1\t%0"
13266   [(set_attr "type" "setcc")
13267    (set_attr "mode" "QI")])
13268
13269 (define_insn "*setcc_2"
13270   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13271         (match_operator:QI 1 "ix86_comparison_operator"
13272           [(reg FLAGS_REG) (const_int 0)]))]
13273   ""
13274   "set%C1\t%0"
13275   [(set_attr "type" "setcc")
13276    (set_attr "mode" "QI")])
13277
13278 ;; In general it is not safe to assume too much about CCmode registers,
13279 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13280 ;; conditions this is safe on x86, so help combine not create
13281 ;;
13282 ;;      seta    %al
13283 ;;      testb   %al, %al
13284 ;;      sete    %al
13285
13286 (define_split 
13287   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13288         (ne:QI (match_operator 1 "ix86_comparison_operator"
13289                  [(reg FLAGS_REG) (const_int 0)])
13290             (const_int 0)))]
13291   ""
13292   [(set (match_dup 0) (match_dup 1))]
13293 {
13294   PUT_MODE (operands[1], QImode);
13295 })
13296
13297 (define_split 
13298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13299         (ne:QI (match_operator 1 "ix86_comparison_operator"
13300                  [(reg FLAGS_REG) (const_int 0)])
13301             (const_int 0)))]
13302   ""
13303   [(set (match_dup 0) (match_dup 1))]
13304 {
13305   PUT_MODE (operands[1], QImode);
13306 })
13307
13308 (define_split 
13309   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13310         (eq:QI (match_operator 1 "ix86_comparison_operator"
13311                  [(reg FLAGS_REG) (const_int 0)])
13312             (const_int 0)))]
13313   ""
13314   [(set (match_dup 0) (match_dup 1))]
13315 {
13316   rtx new_op1 = copy_rtx (operands[1]);
13317   operands[1] = new_op1;
13318   PUT_MODE (new_op1, QImode);
13319   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13320                                              GET_MODE (XEXP (new_op1, 0))));
13321
13322   /* Make sure that (a) the CCmode we have for the flags is strong
13323      enough for the reversed compare or (b) we have a valid FP compare.  */
13324   if (! ix86_comparison_operator (new_op1, VOIDmode))
13325     FAIL;
13326 })
13327
13328 (define_split 
13329   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13330         (eq:QI (match_operator 1 "ix86_comparison_operator"
13331                  [(reg FLAGS_REG) (const_int 0)])
13332             (const_int 0)))]
13333   ""
13334   [(set (match_dup 0) (match_dup 1))]
13335 {
13336   rtx new_op1 = copy_rtx (operands[1]);
13337   operands[1] = new_op1;
13338   PUT_MODE (new_op1, QImode);
13339   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13340                                              GET_MODE (XEXP (new_op1, 0))));
13341
13342   /* Make sure that (a) the CCmode we have for the flags is strong
13343      enough for the reversed compare or (b) we have a valid FP compare.  */
13344   if (! ix86_comparison_operator (new_op1, VOIDmode))
13345     FAIL;
13346 })
13347
13348 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13349 ;; subsequent logical operations are used to imitate conditional moves.
13350 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13351 ;; it directly.
13352
13353 (define_insn "*sse_setccsf"
13354   [(set (match_operand:SF 0 "register_operand" "=x")
13355         (match_operator:SF 1 "sse_comparison_operator"
13356           [(match_operand:SF 2 "register_operand" "0")
13357            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13358   "TARGET_SSE"
13359   "cmp%D1ss\t{%3, %0|%0, %3}"
13360   [(set_attr "type" "ssecmp")
13361    (set_attr "mode" "SF")])
13362
13363 (define_insn "*sse_setccdf"
13364   [(set (match_operand:DF 0 "register_operand" "=Y")
13365         (match_operator:DF 1 "sse_comparison_operator"
13366           [(match_operand:DF 2 "register_operand" "0")
13367            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13368   "TARGET_SSE2"
13369   "cmp%D1sd\t{%3, %0|%0, %3}"
13370   [(set_attr "type" "ssecmp")
13371    (set_attr "mode" "DF")])
13372 \f
13373 ;; Basic conditional jump instructions.
13374 ;; We ignore the overflow flag for signed branch instructions.
13375
13376 ;; For all bCOND expanders, also expand the compare or test insn that
13377 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13378
13379 (define_expand "beq"
13380   [(set (pc)
13381         (if_then_else (match_dup 1)
13382                       (label_ref (match_operand 0 "" ""))
13383                       (pc)))]
13384   ""
13385   "ix86_expand_branch (EQ, operands[0]); DONE;")
13386
13387 (define_expand "bne"
13388   [(set (pc)
13389         (if_then_else (match_dup 1)
13390                       (label_ref (match_operand 0 "" ""))
13391                       (pc)))]
13392   ""
13393   "ix86_expand_branch (NE, operands[0]); DONE;")
13394
13395 (define_expand "bgt"
13396   [(set (pc)
13397         (if_then_else (match_dup 1)
13398                       (label_ref (match_operand 0 "" ""))
13399                       (pc)))]
13400   ""
13401   "ix86_expand_branch (GT, operands[0]); DONE;")
13402
13403 (define_expand "bgtu"
13404   [(set (pc)
13405         (if_then_else (match_dup 1)
13406                       (label_ref (match_operand 0 "" ""))
13407                       (pc)))]
13408   ""
13409   "ix86_expand_branch (GTU, operands[0]); DONE;")
13410
13411 (define_expand "blt"
13412   [(set (pc)
13413         (if_then_else (match_dup 1)
13414                       (label_ref (match_operand 0 "" ""))
13415                       (pc)))]
13416   ""
13417   "ix86_expand_branch (LT, operands[0]); DONE;")
13418
13419 (define_expand "bltu"
13420   [(set (pc)
13421         (if_then_else (match_dup 1)
13422                       (label_ref (match_operand 0 "" ""))
13423                       (pc)))]
13424   ""
13425   "ix86_expand_branch (LTU, operands[0]); DONE;")
13426
13427 (define_expand "bge"
13428   [(set (pc)
13429         (if_then_else (match_dup 1)
13430                       (label_ref (match_operand 0 "" ""))
13431                       (pc)))]
13432   ""
13433   "ix86_expand_branch (GE, operands[0]); DONE;")
13434
13435 (define_expand "bgeu"
13436   [(set (pc)
13437         (if_then_else (match_dup 1)
13438                       (label_ref (match_operand 0 "" ""))
13439                       (pc)))]
13440   ""
13441   "ix86_expand_branch (GEU, operands[0]); DONE;")
13442
13443 (define_expand "ble"
13444   [(set (pc)
13445         (if_then_else (match_dup 1)
13446                       (label_ref (match_operand 0 "" ""))
13447                       (pc)))]
13448   ""
13449   "ix86_expand_branch (LE, operands[0]); DONE;")
13450
13451 (define_expand "bleu"
13452   [(set (pc)
13453         (if_then_else (match_dup 1)
13454                       (label_ref (match_operand 0 "" ""))
13455                       (pc)))]
13456   ""
13457   "ix86_expand_branch (LEU, operands[0]); DONE;")
13458
13459 (define_expand "bunordered"
13460   [(set (pc)
13461         (if_then_else (match_dup 1)
13462                       (label_ref (match_operand 0 "" ""))
13463                       (pc)))]
13464   "TARGET_80387 || TARGET_SSE_MATH"
13465   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13466
13467 (define_expand "bordered"
13468   [(set (pc)
13469         (if_then_else (match_dup 1)
13470                       (label_ref (match_operand 0 "" ""))
13471                       (pc)))]
13472   "TARGET_80387 || TARGET_SSE_MATH"
13473   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13474
13475 (define_expand "buneq"
13476   [(set (pc)
13477         (if_then_else (match_dup 1)
13478                       (label_ref (match_operand 0 "" ""))
13479                       (pc)))]
13480   "TARGET_80387 || TARGET_SSE_MATH"
13481   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13482
13483 (define_expand "bunge"
13484   [(set (pc)
13485         (if_then_else (match_dup 1)
13486                       (label_ref (match_operand 0 "" ""))
13487                       (pc)))]
13488   "TARGET_80387 || TARGET_SSE_MATH"
13489   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13490
13491 (define_expand "bungt"
13492   [(set (pc)
13493         (if_then_else (match_dup 1)
13494                       (label_ref (match_operand 0 "" ""))
13495                       (pc)))]
13496   "TARGET_80387 || TARGET_SSE_MATH"
13497   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13498
13499 (define_expand "bunle"
13500   [(set (pc)
13501         (if_then_else (match_dup 1)
13502                       (label_ref (match_operand 0 "" ""))
13503                       (pc)))]
13504   "TARGET_80387 || TARGET_SSE_MATH"
13505   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13506
13507 (define_expand "bunlt"
13508   [(set (pc)
13509         (if_then_else (match_dup 1)
13510                       (label_ref (match_operand 0 "" ""))
13511                       (pc)))]
13512   "TARGET_80387 || TARGET_SSE_MATH"
13513   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13514
13515 (define_expand "bltgt"
13516   [(set (pc)
13517         (if_then_else (match_dup 1)
13518                       (label_ref (match_operand 0 "" ""))
13519                       (pc)))]
13520   "TARGET_80387 || TARGET_SSE_MATH"
13521   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13522
13523 (define_insn "*jcc_1"
13524   [(set (pc)
13525         (if_then_else (match_operator 1 "ix86_comparison_operator"
13526                                       [(reg FLAGS_REG) (const_int 0)])
13527                       (label_ref (match_operand 0 "" ""))
13528                       (pc)))]
13529   ""
13530   "%+j%C1\t%l0"
13531   [(set_attr "type" "ibr")
13532    (set_attr "modrm" "0")
13533    (set (attr "length")
13534            (if_then_else (and (ge (minus (match_dup 0) (pc))
13535                                   (const_int -126))
13536                               (lt (minus (match_dup 0) (pc))
13537                                   (const_int 128)))
13538              (const_int 2)
13539              (const_int 6)))])
13540
13541 (define_insn "*jcc_2"
13542   [(set (pc)
13543         (if_then_else (match_operator 1 "ix86_comparison_operator"
13544                                       [(reg FLAGS_REG) (const_int 0)])
13545                       (pc)
13546                       (label_ref (match_operand 0 "" ""))))]
13547   ""
13548   "%+j%c1\t%l0"
13549   [(set_attr "type" "ibr")
13550    (set_attr "modrm" "0")
13551    (set (attr "length")
13552            (if_then_else (and (ge (minus (match_dup 0) (pc))
13553                                   (const_int -126))
13554                               (lt (minus (match_dup 0) (pc))
13555                                   (const_int 128)))
13556              (const_int 2)
13557              (const_int 6)))])
13558
13559 ;; In general it is not safe to assume too much about CCmode registers,
13560 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13561 ;; conditions this is safe on x86, so help combine not create
13562 ;;
13563 ;;      seta    %al
13564 ;;      testb   %al, %al
13565 ;;      je      Lfoo
13566
13567 (define_split 
13568   [(set (pc)
13569         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13570                                       [(reg FLAGS_REG) (const_int 0)])
13571                           (const_int 0))
13572                       (label_ref (match_operand 1 "" ""))
13573                       (pc)))]
13574   ""
13575   [(set (pc)
13576         (if_then_else (match_dup 0)
13577                       (label_ref (match_dup 1))
13578                       (pc)))]
13579 {
13580   PUT_MODE (operands[0], VOIDmode);
13581 })
13582   
13583 (define_split 
13584   [(set (pc)
13585         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13586                                       [(reg FLAGS_REG) (const_int 0)])
13587                           (const_int 0))
13588                       (label_ref (match_operand 1 "" ""))
13589                       (pc)))]
13590   ""
13591   [(set (pc)
13592         (if_then_else (match_dup 0)
13593                       (label_ref (match_dup 1))
13594                       (pc)))]
13595 {
13596   rtx new_op0 = copy_rtx (operands[0]);
13597   operands[0] = new_op0;
13598   PUT_MODE (new_op0, VOIDmode);
13599   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13600                                              GET_MODE (XEXP (new_op0, 0))));
13601
13602   /* Make sure that (a) the CCmode we have for the flags is strong
13603      enough for the reversed compare or (b) we have a valid FP compare.  */
13604   if (! ix86_comparison_operator (new_op0, VOIDmode))
13605     FAIL;
13606 })
13607
13608 ;; Define combination compare-and-branch fp compare instructions to use
13609 ;; during early optimization.  Splitting the operation apart early makes
13610 ;; for bad code when we want to reverse the operation.
13611
13612 (define_insn "*fp_jcc_1_mixed"
13613   [(set (pc)
13614         (if_then_else (match_operator 0 "comparison_operator"
13615                         [(match_operand 1 "register_operand" "f,x")
13616                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13617           (label_ref (match_operand 3 "" ""))
13618           (pc)))
13619    (clobber (reg:CCFP FPSR_REG))
13620    (clobber (reg:CCFP FLAGS_REG))]
13621   "TARGET_MIX_SSE_I387
13622    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13623    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13624    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625   "#")
13626
13627 (define_insn "*fp_jcc_1_sse"
13628   [(set (pc)
13629         (if_then_else (match_operator 0 "comparison_operator"
13630                         [(match_operand 1 "register_operand" "x")
13631                          (match_operand 2 "nonimmediate_operand" "xm")])
13632           (label_ref (match_operand 3 "" ""))
13633           (pc)))
13634    (clobber (reg:CCFP FPSR_REG))
13635    (clobber (reg:CCFP FLAGS_REG))]
13636   "TARGET_SSE_MATH
13637    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640   "#")
13641
13642 (define_insn "*fp_jcc_1_387"
13643   [(set (pc)
13644         (if_then_else (match_operator 0 "comparison_operator"
13645                         [(match_operand 1 "register_operand" "f")
13646                          (match_operand 2 "register_operand" "f")])
13647           (label_ref (match_operand 3 "" ""))
13648           (pc)))
13649    (clobber (reg:CCFP FPSR_REG))
13650    (clobber (reg:CCFP FLAGS_REG))]
13651   "TARGET_CMOVE && TARGET_80387
13652    && FLOAT_MODE_P (GET_MODE (operands[1]))
13653    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13655   "#")
13656
13657 (define_insn "*fp_jcc_2_mixed"
13658   [(set (pc)
13659         (if_then_else (match_operator 0 "comparison_operator"
13660                         [(match_operand 1 "register_operand" "f,x")
13661                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13662           (pc)
13663           (label_ref (match_operand 3 "" ""))))
13664    (clobber (reg:CCFP FPSR_REG))
13665    (clobber (reg:CCFP FLAGS_REG))]
13666   "TARGET_MIX_SSE_I387
13667    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13668    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670   "#")
13671
13672 (define_insn "*fp_jcc_2_sse"
13673   [(set (pc)
13674         (if_then_else (match_operator 0 "comparison_operator"
13675                         [(match_operand 1 "register_operand" "x")
13676                          (match_operand 2 "nonimmediate_operand" "xm")])
13677           (pc)
13678           (label_ref (match_operand 3 "" ""))))
13679    (clobber (reg:CCFP FPSR_REG))
13680    (clobber (reg:CCFP FLAGS_REG))]
13681   "TARGET_SSE_MATH
13682    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13685   "#")
13686
13687 (define_insn "*fp_jcc_2_387"
13688   [(set (pc)
13689         (if_then_else (match_operator 0 "comparison_operator"
13690                         [(match_operand 1 "register_operand" "f")
13691                          (match_operand 2 "register_operand" "f")])
13692           (pc)
13693           (label_ref (match_operand 3 "" ""))))
13694    (clobber (reg:CCFP FPSR_REG))
13695    (clobber (reg:CCFP FLAGS_REG))]
13696   "TARGET_CMOVE && TARGET_80387
13697    && FLOAT_MODE_P (GET_MODE (operands[1]))
13698    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13700   "#")
13701
13702 (define_insn "*fp_jcc_3_387"
13703   [(set (pc)
13704         (if_then_else (match_operator 0 "comparison_operator"
13705                         [(match_operand 1 "register_operand" "f")
13706                          (match_operand 2 "nonimmediate_operand" "fm")])
13707           (label_ref (match_operand 3 "" ""))
13708           (pc)))
13709    (clobber (reg:CCFP FPSR_REG))
13710    (clobber (reg:CCFP FLAGS_REG))
13711    (clobber (match_scratch:HI 4 "=a"))]
13712   "TARGET_80387
13713    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13714    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13715    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13716    && SELECT_CC_MODE (GET_CODE (operands[0]),
13717                       operands[1], operands[2]) == CCFPmode
13718    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13719   "#")
13720
13721 (define_insn "*fp_jcc_4_387"
13722   [(set (pc)
13723         (if_then_else (match_operator 0 "comparison_operator"
13724                         [(match_operand 1 "register_operand" "f")
13725                          (match_operand 2 "nonimmediate_operand" "fm")])
13726           (pc)
13727           (label_ref (match_operand 3 "" ""))))
13728    (clobber (reg:CCFP FPSR_REG))
13729    (clobber (reg:CCFP FLAGS_REG))
13730    (clobber (match_scratch:HI 4 "=a"))]
13731   "TARGET_80387
13732    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13733    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13734    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13735    && SELECT_CC_MODE (GET_CODE (operands[0]),
13736                       operands[1], operands[2]) == CCFPmode
13737    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13738   "#")
13739
13740 (define_insn "*fp_jcc_5_387"
13741   [(set (pc)
13742         (if_then_else (match_operator 0 "comparison_operator"
13743                         [(match_operand 1 "register_operand" "f")
13744                          (match_operand 2 "register_operand" "f")])
13745           (label_ref (match_operand 3 "" ""))
13746           (pc)))
13747    (clobber (reg:CCFP FPSR_REG))
13748    (clobber (reg:CCFP FLAGS_REG))
13749    (clobber (match_scratch:HI 4 "=a"))]
13750   "TARGET_80387
13751    && FLOAT_MODE_P (GET_MODE (operands[1]))
13752    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13753    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13754   "#")
13755
13756 (define_insn "*fp_jcc_6_387"
13757   [(set (pc)
13758         (if_then_else (match_operator 0 "comparison_operator"
13759                         [(match_operand 1 "register_operand" "f")
13760                          (match_operand 2 "register_operand" "f")])
13761           (pc)
13762           (label_ref (match_operand 3 "" ""))))
13763    (clobber (reg:CCFP FPSR_REG))
13764    (clobber (reg:CCFP FLAGS_REG))
13765    (clobber (match_scratch:HI 4 "=a"))]
13766   "TARGET_80387
13767    && FLOAT_MODE_P (GET_MODE (operands[1]))
13768    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13769    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13770   "#")
13771
13772 (define_insn "*fp_jcc_7_387"
13773   [(set (pc)
13774         (if_then_else (match_operator 0 "comparison_operator"
13775                         [(match_operand 1 "register_operand" "f")
13776                          (match_operand 2 "const0_operand" "X")])
13777           (label_ref (match_operand 3 "" ""))
13778           (pc)))
13779    (clobber (reg:CCFP FPSR_REG))
13780    (clobber (reg:CCFP FLAGS_REG))
13781    (clobber (match_scratch:HI 4 "=a"))]
13782   "TARGET_80387
13783    && FLOAT_MODE_P (GET_MODE (operands[1]))
13784    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13785    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13786    && SELECT_CC_MODE (GET_CODE (operands[0]),
13787                       operands[1], operands[2]) == CCFPmode
13788    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13789   "#")
13790
13791 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13792 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13793 ;; with a precedence over other operators and is always put in the first
13794 ;; place. Swap condition and operands to match ficom instruction.
13795
13796 (define_insn "*fp_jcc_8<mode>_387"
13797   [(set (pc)
13798         (if_then_else (match_operator 0 "comparison_operator"
13799                         [(match_operator 1 "float_operator"
13800                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13801                            (match_operand 3 "register_operand" "f,f")])
13802           (label_ref (match_operand 4 "" ""))
13803           (pc)))
13804    (clobber (reg:CCFP FPSR_REG))
13805    (clobber (reg:CCFP FLAGS_REG))
13806    (clobber (match_scratch:HI 5 "=a,a"))]
13807   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13808    && FLOAT_MODE_P (GET_MODE (operands[3]))
13809    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13810    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13811    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13812    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13813   "#")
13814
13815 (define_split
13816   [(set (pc)
13817         (if_then_else (match_operator 0 "comparison_operator"
13818                         [(match_operand 1 "register_operand" "")
13819                          (match_operand 2 "nonimmediate_operand" "")])
13820           (match_operand 3 "" "")
13821           (match_operand 4 "" "")))
13822    (clobber (reg:CCFP FPSR_REG))
13823    (clobber (reg:CCFP FLAGS_REG))]
13824   "reload_completed"
13825   [(const_int 0)]
13826 {
13827   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13828                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13829   DONE;
13830 })
13831
13832 (define_split
13833   [(set (pc)
13834         (if_then_else (match_operator 0 "comparison_operator"
13835                         [(match_operand 1 "register_operand" "")
13836                          (match_operand 2 "general_operand" "")])
13837           (match_operand 3 "" "")
13838           (match_operand 4 "" "")))
13839    (clobber (reg:CCFP FPSR_REG))
13840    (clobber (reg:CCFP FLAGS_REG))
13841    (clobber (match_scratch:HI 5 "=a"))]
13842   "reload_completed"
13843   [(const_int 0)]
13844 {
13845   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13846                         operands[3], operands[4], operands[5], NULL_RTX);
13847   DONE;
13848 })
13849
13850 (define_split
13851   [(set (pc)
13852         (if_then_else (match_operator 0 "comparison_operator"
13853                         [(match_operator 1 "float_operator"
13854                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13855                            (match_operand 3 "register_operand" "")])
13856           (match_operand 4 "" "")
13857           (match_operand 5 "" "")))
13858    (clobber (reg:CCFP FPSR_REG))
13859    (clobber (reg:CCFP FLAGS_REG))
13860    (clobber (match_scratch:HI 6 "=a"))]
13861   "reload_completed"
13862   [(const_int 0)]
13863 {
13864   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13865   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13866                         operands[3], operands[7],
13867                         operands[4], operands[5], operands[6], NULL_RTX);
13868   DONE;
13869 })
13870
13871 ;; %%% Kill this when reload knows how to do it.
13872 (define_split
13873   [(set (pc)
13874         (if_then_else (match_operator 0 "comparison_operator"
13875                         [(match_operator 1 "float_operator"
13876                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13877                            (match_operand 3 "register_operand" "")])
13878           (match_operand 4 "" "")
13879           (match_operand 5 "" "")))
13880    (clobber (reg:CCFP FPSR_REG))
13881    (clobber (reg:CCFP FLAGS_REG))
13882    (clobber (match_scratch:HI 6 "=a"))]
13883   "reload_completed"
13884   [(const_int 0)]
13885 {
13886   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13887   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13888   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13889                         operands[3], operands[7],
13890                         operands[4], operands[5], operands[6], operands[2]);
13891   DONE;
13892 })
13893 \f
13894 ;; Unconditional and other jump instructions
13895
13896 (define_insn "jump"
13897   [(set (pc)
13898         (label_ref (match_operand 0 "" "")))]
13899   ""
13900   "jmp\t%l0"
13901   [(set_attr "type" "ibr")
13902    (set (attr "length")
13903            (if_then_else (and (ge (minus (match_dup 0) (pc))
13904                                   (const_int -126))
13905                               (lt (minus (match_dup 0) (pc))
13906                                   (const_int 128)))
13907              (const_int 2)
13908              (const_int 5)))
13909    (set_attr "modrm" "0")])
13910
13911 (define_expand "indirect_jump"
13912   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13913   ""
13914   "")
13915
13916 (define_insn "*indirect_jump"
13917   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13918   "!TARGET_64BIT"
13919   "jmp\t%A0"
13920   [(set_attr "type" "ibr")
13921    (set_attr "length_immediate" "0")])
13922
13923 (define_insn "*indirect_jump_rtx64"
13924   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13925   "TARGET_64BIT"
13926   "jmp\t%A0"
13927   [(set_attr "type" "ibr")
13928    (set_attr "length_immediate" "0")])
13929
13930 (define_expand "tablejump"
13931   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13932               (use (label_ref (match_operand 1 "" "")))])]
13933   ""
13934 {
13935   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13936      relative.  Convert the relative address to an absolute address.  */
13937   if (flag_pic)
13938     {
13939       rtx op0, op1;
13940       enum rtx_code code;
13941
13942       if (TARGET_64BIT)
13943         {
13944           code = PLUS;
13945           op0 = operands[0];
13946           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13947         }
13948       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13949         {
13950           code = PLUS;
13951           op0 = operands[0];
13952           op1 = pic_offset_table_rtx;
13953         }
13954       else
13955         {
13956           code = MINUS;
13957           op0 = pic_offset_table_rtx;
13958           op1 = operands[0];
13959         }
13960
13961       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13962                                          OPTAB_DIRECT);
13963     }
13964 })
13965
13966 (define_insn "*tablejump_1"
13967   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13968    (use (label_ref (match_operand 1 "" "")))]
13969   "!TARGET_64BIT"
13970   "jmp\t%A0"
13971   [(set_attr "type" "ibr")
13972    (set_attr "length_immediate" "0")])
13973
13974 (define_insn "*tablejump_1_rtx64"
13975   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13976    (use (label_ref (match_operand 1 "" "")))]
13977   "TARGET_64BIT"
13978   "jmp\t%A0"
13979   [(set_attr "type" "ibr")
13980    (set_attr "length_immediate" "0")])
13981 \f
13982 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13983
13984 (define_peephole2
13985   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13986    (set (match_operand:QI 1 "register_operand" "")
13987         (match_operator:QI 2 "ix86_comparison_operator"
13988           [(reg FLAGS_REG) (const_int 0)]))
13989    (set (match_operand 3 "q_regs_operand" "")
13990         (zero_extend (match_dup 1)))]
13991   "(peep2_reg_dead_p (3, operands[1])
13992     || operands_match_p (operands[1], operands[3]))
13993    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13994   [(set (match_dup 4) (match_dup 0))
13995    (set (strict_low_part (match_dup 5))
13996         (match_dup 2))]
13997 {
13998   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13999   operands[5] = gen_lowpart (QImode, operands[3]);
14000   ix86_expand_clear (operands[3]);
14001 })
14002
14003 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14004
14005 (define_peephole2
14006   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14007    (set (match_operand:QI 1 "register_operand" "")
14008         (match_operator:QI 2 "ix86_comparison_operator"
14009           [(reg FLAGS_REG) (const_int 0)]))
14010    (parallel [(set (match_operand 3 "q_regs_operand" "")
14011                    (zero_extend (match_dup 1)))
14012               (clobber (reg:CC FLAGS_REG))])]
14013   "(peep2_reg_dead_p (3, operands[1])
14014     || operands_match_p (operands[1], operands[3]))
14015    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14016   [(set (match_dup 4) (match_dup 0))
14017    (set (strict_low_part (match_dup 5))
14018         (match_dup 2))]
14019 {
14020   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14021   operands[5] = gen_lowpart (QImode, operands[3]);
14022   ix86_expand_clear (operands[3]);
14023 })
14024 \f
14025 ;; Call instructions.
14026
14027 ;; The predicates normally associated with named expanders are not properly
14028 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14029 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14030
14031 ;; Call subroutine returning no value.
14032
14033 (define_expand "call_pop"
14034   [(parallel [(call (match_operand:QI 0 "" "")
14035                     (match_operand:SI 1 "" ""))
14036               (set (reg:SI SP_REG)
14037                    (plus:SI (reg:SI SP_REG)
14038                             (match_operand:SI 3 "" "")))])]
14039   "!TARGET_64BIT"
14040 {
14041   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14042   DONE;
14043 })
14044
14045 (define_insn "*call_pop_0"
14046   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14047          (match_operand:SI 1 "" ""))
14048    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14049                             (match_operand:SI 2 "immediate_operand" "")))]
14050   "!TARGET_64BIT"
14051 {
14052   if (SIBLING_CALL_P (insn))
14053     return "jmp\t%P0";
14054   else
14055     return "call\t%P0";
14056 }
14057   [(set_attr "type" "call")])
14058   
14059 (define_insn "*call_pop_1"
14060   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14061          (match_operand:SI 1 "" ""))
14062    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14063                             (match_operand:SI 2 "immediate_operand" "i")))]
14064   "!TARGET_64BIT"
14065 {
14066   if (constant_call_address_operand (operands[0], Pmode))
14067     {
14068       if (SIBLING_CALL_P (insn))
14069         return "jmp\t%P0";
14070       else
14071         return "call\t%P0";
14072     }
14073   if (SIBLING_CALL_P (insn))
14074     return "jmp\t%A0";
14075   else
14076     return "call\t%A0";
14077 }
14078   [(set_attr "type" "call")])
14079
14080 (define_expand "call"
14081   [(call (match_operand:QI 0 "" "")
14082          (match_operand 1 "" ""))
14083    (use (match_operand 2 "" ""))]
14084   ""
14085 {
14086   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14087   DONE;
14088 })
14089
14090 (define_expand "sibcall"
14091   [(call (match_operand:QI 0 "" "")
14092          (match_operand 1 "" ""))
14093    (use (match_operand 2 "" ""))]
14094   ""
14095 {
14096   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14097   DONE;
14098 })
14099
14100 (define_insn "*call_0"
14101   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14102          (match_operand 1 "" ""))]
14103   ""
14104 {
14105   if (SIBLING_CALL_P (insn))
14106     return "jmp\t%P0";
14107   else
14108     return "call\t%P0";
14109 }
14110   [(set_attr "type" "call")])
14111
14112 (define_insn "*call_1"
14113   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14114          (match_operand 1 "" ""))]
14115   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14116 {
14117   if (constant_call_address_operand (operands[0], Pmode))
14118     return "call\t%P0";
14119   return "call\t%A0";
14120 }
14121   [(set_attr "type" "call")])
14122
14123 (define_insn "*sibcall_1"
14124   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14125          (match_operand 1 "" ""))]
14126   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14127 {
14128   if (constant_call_address_operand (operands[0], Pmode))
14129     return "jmp\t%P0";
14130   return "jmp\t%A0";
14131 }
14132   [(set_attr "type" "call")])
14133
14134 (define_insn "*call_1_rex64"
14135   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14136          (match_operand 1 "" ""))]
14137   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14138 {
14139   if (constant_call_address_operand (operands[0], Pmode))
14140     return "call\t%P0";
14141   return "call\t%A0";
14142 }
14143   [(set_attr "type" "call")])
14144
14145 (define_insn "*sibcall_1_rex64"
14146   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14147          (match_operand 1 "" ""))]
14148   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14149   "jmp\t%P0"
14150   [(set_attr "type" "call")])
14151
14152 (define_insn "*sibcall_1_rex64_v"
14153   [(call (mem:QI (reg:DI 40))
14154          (match_operand 0 "" ""))]
14155   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14156   "jmp\t*%%r11"
14157   [(set_attr "type" "call")])
14158
14159
14160 ;; Call subroutine, returning value in operand 0
14161
14162 (define_expand "call_value_pop"
14163   [(parallel [(set (match_operand 0 "" "")
14164                    (call (match_operand:QI 1 "" "")
14165                          (match_operand:SI 2 "" "")))
14166               (set (reg:SI SP_REG)
14167                    (plus:SI (reg:SI SP_REG)
14168                             (match_operand:SI 4 "" "")))])]
14169   "!TARGET_64BIT"
14170 {
14171   ix86_expand_call (operands[0], operands[1], operands[2],
14172                     operands[3], operands[4], 0);
14173   DONE;
14174 })
14175
14176 (define_expand "call_value"
14177   [(set (match_operand 0 "" "")
14178         (call (match_operand:QI 1 "" "")
14179               (match_operand:SI 2 "" "")))
14180    (use (match_operand:SI 3 "" ""))]
14181   ;; Operand 2 not used on the i386.
14182   ""
14183 {
14184   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14185   DONE;
14186 })
14187
14188 (define_expand "sibcall_value"
14189   [(set (match_operand 0 "" "")
14190         (call (match_operand:QI 1 "" "")
14191               (match_operand:SI 2 "" "")))
14192    (use (match_operand:SI 3 "" ""))]
14193   ;; Operand 2 not used on the i386.
14194   ""
14195 {
14196   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14197   DONE;
14198 })
14199
14200 ;; Call subroutine returning any type.
14201
14202 (define_expand "untyped_call"
14203   [(parallel [(call (match_operand 0 "" "")
14204                     (const_int 0))
14205               (match_operand 1 "" "")
14206               (match_operand 2 "" "")])]
14207   ""
14208 {
14209   int i;
14210
14211   /* In order to give reg-stack an easier job in validating two
14212      coprocessor registers as containing a possible return value,
14213      simply pretend the untyped call returns a complex long double
14214      value.  */
14215
14216   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14217                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14218                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14219                     NULL, 0);
14220
14221   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14222     {
14223       rtx set = XVECEXP (operands[2], 0, i);
14224       emit_move_insn (SET_DEST (set), SET_SRC (set));
14225     }
14226
14227   /* The optimizer does not know that the call sets the function value
14228      registers we stored in the result block.  We avoid problems by
14229      claiming that all hard registers are used and clobbered at this
14230      point.  */
14231   emit_insn (gen_blockage (const0_rtx));
14232
14233   DONE;
14234 })
14235 \f
14236 ;; Prologue and epilogue instructions
14237
14238 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14239 ;; all of memory.  This blocks insns from being moved across this point.
14240
14241 (define_insn "blockage"
14242   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14243   ""
14244   ""
14245   [(set_attr "length" "0")])
14246
14247 ;; Insn emitted into the body of a function to return from a function.
14248 ;; This is only done if the function's epilogue is known to be simple.
14249 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14250
14251 (define_expand "return"
14252   [(return)]
14253   "ix86_can_use_return_insn_p ()"
14254 {
14255   if (current_function_pops_args)
14256     {
14257       rtx popc = GEN_INT (current_function_pops_args);
14258       emit_jump_insn (gen_return_pop_internal (popc));
14259       DONE;
14260     }
14261 })
14262
14263 (define_insn "return_internal"
14264   [(return)]
14265   "reload_completed"
14266   "ret"
14267   [(set_attr "length" "1")
14268    (set_attr "length_immediate" "0")
14269    (set_attr "modrm" "0")])
14270
14271 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14272 ;; instruction Athlon and K8 have.
14273
14274 (define_insn "return_internal_long"
14275   [(return)
14276    (unspec [(const_int 0)] UNSPEC_REP)]
14277   "reload_completed"
14278   "rep {;} ret"
14279   [(set_attr "length" "1")
14280    (set_attr "length_immediate" "0")
14281    (set_attr "prefix_rep" "1")
14282    (set_attr "modrm" "0")])
14283
14284 (define_insn "return_pop_internal"
14285   [(return)
14286    (use (match_operand:SI 0 "const_int_operand" ""))]
14287   "reload_completed"
14288   "ret\t%0"
14289   [(set_attr "length" "3")
14290    (set_attr "length_immediate" "2")
14291    (set_attr "modrm" "0")])
14292
14293 (define_insn "return_indirect_internal"
14294   [(return)
14295    (use (match_operand:SI 0 "register_operand" "r"))]
14296   "reload_completed"
14297   "jmp\t%A0"
14298   [(set_attr "type" "ibr")
14299    (set_attr "length_immediate" "0")])
14300
14301 (define_insn "nop"
14302   [(const_int 0)]
14303   ""
14304   "nop"
14305   [(set_attr "length" "1")
14306    (set_attr "length_immediate" "0")
14307    (set_attr "modrm" "0")])
14308
14309 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14310 ;; branch prediction penalty for the third jump in a 16-byte
14311 ;; block on K8.
14312
14313 (define_insn "align"
14314   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14315   ""
14316 {
14317 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14318   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14319 #else
14320   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14321      The align insn is used to avoid 3 jump instructions in the row to improve
14322      branch prediction and the benefits hardly outweigh the cost of extra 8
14323      nops on the average inserted by full alignment pseudo operation.  */
14324 #endif
14325   return "";
14326 }
14327   [(set_attr "length" "16")])
14328
14329 (define_expand "prologue"
14330   [(const_int 1)]
14331   ""
14332   "ix86_expand_prologue (); DONE;")
14333
14334 (define_insn "set_got"
14335   [(set (match_operand:SI 0 "register_operand" "=r")
14336         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14337    (clobber (reg:CC FLAGS_REG))]
14338   "!TARGET_64BIT"
14339   { return output_set_got (operands[0], NULL_RTX); }
14340   [(set_attr "type" "multi")
14341    (set_attr "length" "12")])
14342
14343 (define_insn "set_got_labelled"
14344   [(set (match_operand:SI 0 "register_operand" "=r")
14345         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14346          UNSPEC_SET_GOT))
14347    (clobber (reg:CC FLAGS_REG))]
14348   "!TARGET_64BIT"
14349   { return output_set_got (operands[0], operands[1]); }
14350   [(set_attr "type" "multi")
14351    (set_attr "length" "12")])
14352
14353 (define_insn "set_got_rex64"
14354   [(set (match_operand:DI 0 "register_operand" "=r")
14355         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14356   "TARGET_64BIT"
14357   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14358   [(set_attr "type" "lea")
14359    (set_attr "length" "6")])
14360
14361 (define_expand "epilogue"
14362   [(const_int 1)]
14363   ""
14364   "ix86_expand_epilogue (1); DONE;")
14365
14366 (define_expand "sibcall_epilogue"
14367   [(const_int 1)]
14368   ""
14369   "ix86_expand_epilogue (0); DONE;")
14370
14371 (define_expand "eh_return"
14372   [(use (match_operand 0 "register_operand" ""))]
14373   ""
14374 {
14375   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14376
14377   /* Tricky bit: we write the address of the handler to which we will
14378      be returning into someone else's stack frame, one word below the
14379      stack address we wish to restore.  */
14380   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14381   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14382   tmp = gen_rtx_MEM (Pmode, tmp);
14383   emit_move_insn (tmp, ra);
14384
14385   if (Pmode == SImode)
14386     emit_jump_insn (gen_eh_return_si (sa));
14387   else
14388     emit_jump_insn (gen_eh_return_di (sa));
14389   emit_barrier ();
14390   DONE;
14391 })
14392
14393 (define_insn_and_split "eh_return_si"
14394   [(set (pc) 
14395         (unspec [(match_operand:SI 0 "register_operand" "c")]
14396                  UNSPEC_EH_RETURN))]
14397   "!TARGET_64BIT"
14398   "#"
14399   "reload_completed"
14400   [(const_int 1)]
14401   "ix86_expand_epilogue (2); DONE;")
14402
14403 (define_insn_and_split "eh_return_di"
14404   [(set (pc) 
14405         (unspec [(match_operand:DI 0 "register_operand" "c")]
14406                  UNSPEC_EH_RETURN))]
14407   "TARGET_64BIT"
14408   "#"
14409   "reload_completed"
14410   [(const_int 1)]
14411   "ix86_expand_epilogue (2); DONE;")
14412
14413 (define_insn "leave"
14414   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14415    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14416    (clobber (mem:BLK (scratch)))]
14417   "!TARGET_64BIT"
14418   "leave"
14419   [(set_attr "type" "leave")])
14420
14421 (define_insn "leave_rex64"
14422   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14423    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14424    (clobber (mem:BLK (scratch)))]
14425   "TARGET_64BIT"
14426   "leave"
14427   [(set_attr "type" "leave")])
14428 \f
14429 (define_expand "ffssi2"
14430   [(parallel
14431      [(set (match_operand:SI 0 "register_operand" "") 
14432            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14433       (clobber (match_scratch:SI 2 ""))
14434       (clobber (reg:CC FLAGS_REG))])]
14435   ""
14436   "")
14437
14438 (define_insn_and_split "*ffs_cmove"
14439   [(set (match_operand:SI 0 "register_operand" "=r") 
14440         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14441    (clobber (match_scratch:SI 2 "=&r"))
14442    (clobber (reg:CC FLAGS_REG))]
14443   "TARGET_CMOVE"
14444   "#"
14445   "&& reload_completed"
14446   [(set (match_dup 2) (const_int -1))
14447    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14448               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14449    (set (match_dup 0) (if_then_else:SI
14450                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14451                         (match_dup 2)
14452                         (match_dup 0)))
14453    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14454               (clobber (reg:CC FLAGS_REG))])]
14455   "")
14456
14457 (define_insn_and_split "*ffs_no_cmove"
14458   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14459         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14460    (clobber (match_scratch:SI 2 "=&q"))
14461    (clobber (reg:CC FLAGS_REG))]
14462   ""
14463   "#"
14464   "reload_completed"
14465   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14466               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14467    (set (strict_low_part (match_dup 3))
14468         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14469    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14470               (clobber (reg:CC FLAGS_REG))])
14471    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14472               (clobber (reg:CC FLAGS_REG))])
14473    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14474               (clobber (reg:CC FLAGS_REG))])]
14475 {
14476   operands[3] = gen_lowpart (QImode, operands[2]);
14477   ix86_expand_clear (operands[2]);
14478 })
14479
14480 (define_insn "*ffssi_1"
14481   [(set (reg:CCZ FLAGS_REG)
14482         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14483                      (const_int 0)))
14484    (set (match_operand:SI 0 "register_operand" "=r")
14485         (ctz:SI (match_dup 1)))]
14486   ""
14487   "bsf{l}\t{%1, %0|%0, %1}"
14488   [(set_attr "prefix_0f" "1")])
14489
14490 (define_expand "ffsdi2"
14491   [(parallel
14492      [(set (match_operand:DI 0 "register_operand" "") 
14493            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14494       (clobber (match_scratch:DI 2 ""))
14495       (clobber (reg:CC FLAGS_REG))])]
14496   "TARGET_64BIT && TARGET_CMOVE"
14497   "")
14498
14499 (define_insn_and_split "*ffs_rex64"
14500   [(set (match_operand:DI 0 "register_operand" "=r") 
14501         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14502    (clobber (match_scratch:DI 2 "=&r"))
14503    (clobber (reg:CC FLAGS_REG))]
14504   "TARGET_64BIT && TARGET_CMOVE"
14505   "#"
14506   "&& reload_completed"
14507   [(set (match_dup 2) (const_int -1))
14508    (parallel [(set (reg:CCZ FLAGS_REG)
14509                    (compare:CCZ (match_dup 1) (const_int 0)))
14510               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14511    (set (match_dup 0) (if_then_else:DI
14512                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14513                         (match_dup 2)
14514                         (match_dup 0)))
14515    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14516               (clobber (reg:CC FLAGS_REG))])]
14517   "")
14518
14519 (define_insn "*ffsdi_1"
14520   [(set (reg:CCZ FLAGS_REG)
14521         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14522                      (const_int 0)))
14523    (set (match_operand:DI 0 "register_operand" "=r")
14524         (ctz:DI (match_dup 1)))]
14525   "TARGET_64BIT"
14526   "bsf{q}\t{%1, %0|%0, %1}"
14527   [(set_attr "prefix_0f" "1")])
14528
14529 (define_insn "ctzsi2"
14530   [(set (match_operand:SI 0 "register_operand" "=r")
14531         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14532    (clobber (reg:CC FLAGS_REG))]
14533   ""
14534   "bsf{l}\t{%1, %0|%0, %1}"
14535   [(set_attr "prefix_0f" "1")])
14536
14537 (define_insn "ctzdi2"
14538   [(set (match_operand:DI 0 "register_operand" "=r")
14539         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14540    (clobber (reg:CC FLAGS_REG))]
14541   "TARGET_64BIT"
14542   "bsf{q}\t{%1, %0|%0, %1}"
14543   [(set_attr "prefix_0f" "1")])
14544
14545 (define_expand "clzsi2"
14546   [(parallel
14547      [(set (match_operand:SI 0 "register_operand" "")
14548            (minus:SI (const_int 31)
14549                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14550       (clobber (reg:CC FLAGS_REG))])
14551    (parallel
14552      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14553       (clobber (reg:CC FLAGS_REG))])]
14554   ""
14555   "")
14556
14557 (define_insn "*bsr"
14558   [(set (match_operand:SI 0 "register_operand" "=r")
14559         (minus:SI (const_int 31)
14560                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14561    (clobber (reg:CC FLAGS_REG))]
14562   ""
14563   "bsr{l}\t{%1, %0|%0, %1}"
14564   [(set_attr "prefix_0f" "1")])
14565
14566 (define_expand "clzdi2"
14567   [(parallel
14568      [(set (match_operand:DI 0 "register_operand" "")
14569            (minus:DI (const_int 63)
14570                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14571       (clobber (reg:CC FLAGS_REG))])
14572    (parallel
14573      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14574       (clobber (reg:CC FLAGS_REG))])]
14575   "TARGET_64BIT"
14576   "")
14577
14578 (define_insn "*bsr_rex64"
14579   [(set (match_operand:DI 0 "register_operand" "=r")
14580         (minus:DI (const_int 63)
14581                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14582    (clobber (reg:CC FLAGS_REG))]
14583   "TARGET_64BIT"
14584   "bsr{q}\t{%1, %0|%0, %1}"
14585   [(set_attr "prefix_0f" "1")])
14586 \f
14587 ;; Thread-local storage patterns for ELF.
14588 ;;
14589 ;; Note that these code sequences must appear exactly as shown
14590 ;; in order to allow linker relaxation.
14591
14592 (define_insn "*tls_global_dynamic_32_gnu"
14593   [(set (match_operand:SI 0 "register_operand" "=a")
14594         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595                     (match_operand:SI 2 "tls_symbolic_operand" "")
14596                     (match_operand:SI 3 "call_insn_operand" "")]
14597                     UNSPEC_TLS_GD))
14598    (clobber (match_scratch:SI 4 "=d"))
14599    (clobber (match_scratch:SI 5 "=c"))
14600    (clobber (reg:CC FLAGS_REG))]
14601   "!TARGET_64BIT && TARGET_GNU_TLS"
14602   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14603   [(set_attr "type" "multi")
14604    (set_attr "length" "12")])
14605
14606 (define_insn "*tls_global_dynamic_32_sun"
14607   [(set (match_operand:SI 0 "register_operand" "=a")
14608         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609                     (match_operand:SI 2 "tls_symbolic_operand" "")
14610                     (match_operand:SI 3 "call_insn_operand" "")]
14611                     UNSPEC_TLS_GD))
14612    (clobber (match_scratch:SI 4 "=d"))
14613    (clobber (match_scratch:SI 5 "=c"))
14614    (clobber (reg:CC FLAGS_REG))]
14615   "!TARGET_64BIT && TARGET_SUN_TLS"
14616   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14617         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14618   [(set_attr "type" "multi")
14619    (set_attr "length" "14")])
14620
14621 (define_expand "tls_global_dynamic_32"
14622   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14623                    (unspec:SI
14624                     [(match_dup 2)
14625                      (match_operand:SI 1 "tls_symbolic_operand" "")
14626                      (match_dup 3)]
14627                     UNSPEC_TLS_GD))
14628               (clobber (match_scratch:SI 4 ""))
14629               (clobber (match_scratch:SI 5 ""))
14630               (clobber (reg:CC FLAGS_REG))])]
14631   ""
14632 {
14633   if (flag_pic)
14634     operands[2] = pic_offset_table_rtx;
14635   else
14636     {
14637       operands[2] = gen_reg_rtx (Pmode);
14638       emit_insn (gen_set_got (operands[2]));
14639     }
14640   if (TARGET_GNU2_TLS)
14641     {
14642        emit_insn (gen_tls_dynamic_gnu2_32
14643                   (operands[0], operands[1], operands[2]));
14644        DONE;
14645     }
14646   operands[3] = ix86_tls_get_addr ();
14647 })
14648
14649 (define_insn "*tls_global_dynamic_64"
14650   [(set (match_operand:DI 0 "register_operand" "=a")
14651         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14652                  (match_operand:DI 3 "" "")))
14653    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14654               UNSPEC_TLS_GD)]
14655   "TARGET_64BIT"
14656   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14657   [(set_attr "type" "multi")
14658    (set_attr "length" "16")])
14659
14660 (define_expand "tls_global_dynamic_64"
14661   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14662                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14663               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14664                          UNSPEC_TLS_GD)])]
14665   ""
14666 {
14667   if (TARGET_GNU2_TLS)
14668     {
14669        emit_insn (gen_tls_dynamic_gnu2_64
14670                   (operands[0], operands[1]));
14671        DONE;
14672     }
14673   operands[2] = ix86_tls_get_addr ();
14674 })
14675
14676 (define_insn "*tls_local_dynamic_base_32_gnu"
14677   [(set (match_operand:SI 0 "register_operand" "=a")
14678         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14679                     (match_operand:SI 2 "call_insn_operand" "")]
14680                    UNSPEC_TLS_LD_BASE))
14681    (clobber (match_scratch:SI 3 "=d"))
14682    (clobber (match_scratch:SI 4 "=c"))
14683    (clobber (reg:CC FLAGS_REG))]
14684   "!TARGET_64BIT && TARGET_GNU_TLS"
14685   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14686   [(set_attr "type" "multi")
14687    (set_attr "length" "11")])
14688
14689 (define_insn "*tls_local_dynamic_base_32_sun"
14690   [(set (match_operand:SI 0 "register_operand" "=a")
14691         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14692                     (match_operand:SI 2 "call_insn_operand" "")]
14693                    UNSPEC_TLS_LD_BASE))
14694    (clobber (match_scratch:SI 3 "=d"))
14695    (clobber (match_scratch:SI 4 "=c"))
14696    (clobber (reg:CC FLAGS_REG))]
14697   "!TARGET_64BIT && TARGET_SUN_TLS"
14698   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14699         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14700   [(set_attr "type" "multi")
14701    (set_attr "length" "13")])
14702
14703 (define_expand "tls_local_dynamic_base_32"
14704   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14705                    (unspec:SI [(match_dup 1) (match_dup 2)]
14706                               UNSPEC_TLS_LD_BASE))
14707               (clobber (match_scratch:SI 3 ""))
14708               (clobber (match_scratch:SI 4 ""))
14709               (clobber (reg:CC FLAGS_REG))])]
14710   ""
14711 {
14712   if (flag_pic)
14713     operands[1] = pic_offset_table_rtx;
14714   else
14715     {
14716       operands[1] = gen_reg_rtx (Pmode);
14717       emit_insn (gen_set_got (operands[1]));
14718     }
14719   if (TARGET_GNU2_TLS)
14720     {
14721        emit_insn (gen_tls_dynamic_gnu2_32
14722                   (operands[0], ix86_tls_module_base (), operands[1]));
14723        DONE;
14724     }
14725   operands[2] = ix86_tls_get_addr ();
14726 })
14727
14728 (define_insn "*tls_local_dynamic_base_64"
14729   [(set (match_operand:DI 0 "register_operand" "=a")
14730         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14731                  (match_operand:DI 2 "" "")))
14732    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14733   "TARGET_64BIT"
14734   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14735   [(set_attr "type" "multi")
14736    (set_attr "length" "12")])
14737
14738 (define_expand "tls_local_dynamic_base_64"
14739   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14740                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14741               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14742   ""
14743 {
14744   if (TARGET_GNU2_TLS)
14745     {
14746        emit_insn (gen_tls_dynamic_gnu2_64
14747                   (operands[0], ix86_tls_module_base ()));
14748        DONE;
14749     }
14750   operands[1] = ix86_tls_get_addr ();
14751 })
14752
14753 ;; Local dynamic of a single variable is a lose.  Show combine how
14754 ;; to convert that back to global dynamic.
14755
14756 (define_insn_and_split "*tls_local_dynamic_32_once"
14757   [(set (match_operand:SI 0 "register_operand" "=a")
14758         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14759                              (match_operand:SI 2 "call_insn_operand" "")]
14760                             UNSPEC_TLS_LD_BASE)
14761                  (const:SI (unspec:SI
14762                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14763                             UNSPEC_DTPOFF))))
14764    (clobber (match_scratch:SI 4 "=d"))
14765    (clobber (match_scratch:SI 5 "=c"))
14766    (clobber (reg:CC FLAGS_REG))]
14767   ""
14768   "#"
14769   ""
14770   [(parallel [(set (match_dup 0)
14771                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14772                               UNSPEC_TLS_GD))
14773               (clobber (match_dup 4))
14774               (clobber (match_dup 5))
14775               (clobber (reg:CC FLAGS_REG))])]
14776   "")
14777
14778 ;; Load and add the thread base pointer from %gs:0.
14779
14780 (define_insn "*load_tp_si"
14781   [(set (match_operand:SI 0 "register_operand" "=r")
14782         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14783   "!TARGET_64BIT"
14784   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14785   [(set_attr "type" "imov")
14786    (set_attr "modrm" "0")
14787    (set_attr "length" "7")
14788    (set_attr "memory" "load")
14789    (set_attr "imm_disp" "false")])
14790
14791 (define_insn "*add_tp_si"
14792   [(set (match_operand:SI 0 "register_operand" "=r")
14793         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14794                  (match_operand:SI 1 "register_operand" "0")))
14795    (clobber (reg:CC FLAGS_REG))]
14796   "!TARGET_64BIT"
14797   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14798   [(set_attr "type" "alu")
14799    (set_attr "modrm" "0")
14800    (set_attr "length" "7")
14801    (set_attr "memory" "load")
14802    (set_attr "imm_disp" "false")])
14803
14804 (define_insn "*load_tp_di"
14805   [(set (match_operand:DI 0 "register_operand" "=r")
14806         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14807   "TARGET_64BIT"
14808   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14809   [(set_attr "type" "imov")
14810    (set_attr "modrm" "0")
14811    (set_attr "length" "7")
14812    (set_attr "memory" "load")
14813    (set_attr "imm_disp" "false")])
14814
14815 (define_insn "*add_tp_di"
14816   [(set (match_operand:DI 0 "register_operand" "=r")
14817         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14818                  (match_operand:DI 1 "register_operand" "0")))
14819    (clobber (reg:CC FLAGS_REG))]
14820   "TARGET_64BIT"
14821   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14822   [(set_attr "type" "alu")
14823    (set_attr "modrm" "0")
14824    (set_attr "length" "7")
14825    (set_attr "memory" "load")
14826    (set_attr "imm_disp" "false")])
14827
14828 ;; GNU2 TLS patterns can be split.
14829
14830 (define_expand "tls_dynamic_gnu2_32"
14831   [(set (match_dup 3)
14832         (plus:SI (match_operand:SI 2 "register_operand" "")
14833                  (const:SI
14834                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14835                              UNSPEC_TLSDESC))))
14836    (parallel
14837     [(set (match_operand:SI 0 "register_operand" "")
14838           (unspec:SI [(match_dup 1) (match_dup 3)
14839                       (match_dup 2) (reg:SI SP_REG)]
14840                       UNSPEC_TLSDESC))
14841      (clobber (reg:CC FLAGS_REG))])]
14842   "!TARGET_64BIT && TARGET_GNU2_TLS"
14843 {
14844   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14845   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14846 })
14847
14848 (define_insn "*tls_dynamic_lea_32"
14849   [(set (match_operand:SI 0 "register_operand" "=r")
14850         (plus:SI (match_operand:SI 1 "register_operand" "b")
14851                  (const:SI
14852                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14853                               UNSPEC_TLSDESC))))]
14854   "!TARGET_64BIT && TARGET_GNU2_TLS"
14855   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14856   [(set_attr "type" "lea")
14857    (set_attr "mode" "SI")
14858    (set_attr "length" "6")
14859    (set_attr "length_address" "4")])
14860
14861 (define_insn "*tls_dynamic_call_32"
14862   [(set (match_operand:SI 0 "register_operand" "=a")
14863         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14864                     (match_operand:SI 2 "register_operand" "0")
14865                     ;; we have to make sure %ebx still points to the GOT
14866                     (match_operand:SI 3 "register_operand" "b")
14867                     (reg:SI SP_REG)]
14868                    UNSPEC_TLSDESC))
14869    (clobber (reg:CC FLAGS_REG))]
14870   "!TARGET_64BIT && TARGET_GNU2_TLS"
14871   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14872   [(set_attr "type" "call")
14873    (set_attr "length" "2")
14874    (set_attr "length_address" "0")])
14875
14876 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14877   [(set (match_operand:SI 0 "register_operand" "=&a")
14878         (plus:SI
14879          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14880                      (match_operand:SI 4 "" "")
14881                      (match_operand:SI 2 "register_operand" "b")
14882                      (reg:SI SP_REG)]
14883                     UNSPEC_TLSDESC)
14884          (const:SI (unspec:SI
14885                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14886                     UNSPEC_DTPOFF))))
14887    (clobber (reg:CC FLAGS_REG))]
14888   "!TARGET_64BIT && TARGET_GNU2_TLS"
14889   "#"
14890   ""
14891   [(set (match_dup 0) (match_dup 5))]
14892 {
14893   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14894   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14895 })
14896
14897 (define_expand "tls_dynamic_gnu2_64"
14898   [(set (match_dup 2)
14899         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14900                    UNSPEC_TLSDESC))
14901    (parallel
14902     [(set (match_operand:DI 0 "register_operand" "")
14903           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14904                      UNSPEC_TLSDESC))
14905      (clobber (reg:CC FLAGS_REG))])]
14906   "TARGET_64BIT && TARGET_GNU2_TLS"
14907 {
14908   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14910 })
14911
14912 (define_insn "*tls_dynamic_lea_64"
14913   [(set (match_operand:DI 0 "register_operand" "=r")
14914         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14915                    UNSPEC_TLSDESC))]
14916   "TARGET_64BIT && TARGET_GNU2_TLS"
14917   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14918   [(set_attr "type" "lea")
14919    (set_attr "mode" "DI")
14920    (set_attr "length" "7")
14921    (set_attr "length_address" "4")])
14922
14923 (define_insn "*tls_dynamic_call_64"
14924   [(set (match_operand:DI 0 "register_operand" "=a")
14925         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14926                     (match_operand:DI 2 "register_operand" "0")
14927                     (reg:DI SP_REG)]
14928                    UNSPEC_TLSDESC))
14929    (clobber (reg:CC FLAGS_REG))]
14930   "TARGET_64BIT && TARGET_GNU2_TLS"
14931   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14932   [(set_attr "type" "call")
14933    (set_attr "length" "2")
14934    (set_attr "length_address" "0")])
14935
14936 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14937   [(set (match_operand:DI 0 "register_operand" "=&a")
14938         (plus:DI
14939          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14940                      (match_operand:DI 3 "" "")
14941                      (reg:DI SP_REG)]
14942                     UNSPEC_TLSDESC)
14943          (const:DI (unspec:DI
14944                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14945                     UNSPEC_DTPOFF))))
14946    (clobber (reg:CC FLAGS_REG))]
14947   "TARGET_64BIT && TARGET_GNU2_TLS"
14948   "#"
14949   ""
14950   [(set (match_dup 0) (match_dup 4))]
14951 {
14952   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14953   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14954 })
14955
14956 ;;
14957 \f
14958 ;; These patterns match the binary 387 instructions for addM3, subM3,
14959 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14960 ;; SFmode.  The first is the normal insn, the second the same insn but
14961 ;; with one operand a conversion, and the third the same insn but with
14962 ;; the other operand a conversion.  The conversion may be SFmode or
14963 ;; SImode if the target mode DFmode, but only SImode if the target mode
14964 ;; is SFmode.
14965
14966 ;; Gcc is slightly more smart about handling normal two address instructions
14967 ;; so use special patterns for add and mull.
14968
14969 (define_insn "*fop_sf_comm_mixed"
14970   [(set (match_operand:SF 0 "register_operand" "=f,x")
14971         (match_operator:SF 3 "binary_fp_operator"
14972                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14973                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14974   "TARGET_MIX_SSE_I387
14975    && COMMUTATIVE_ARITH_P (operands[3])
14976    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14977   "* return output_387_binary_op (insn, operands);"
14978   [(set (attr "type") 
14979         (if_then_else (eq_attr "alternative" "1")
14980            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14981               (const_string "ssemul")
14982               (const_string "sseadd"))
14983            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14984               (const_string "fmul")
14985               (const_string "fop"))))
14986    (set_attr "mode" "SF")])
14987
14988 (define_insn "*fop_sf_comm_sse"
14989   [(set (match_operand:SF 0 "register_operand" "=x")
14990         (match_operator:SF 3 "binary_fp_operator"
14991                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14992                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14993   "TARGET_SSE_MATH
14994    && COMMUTATIVE_ARITH_P (operands[3])
14995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14996   "* return output_387_binary_op (insn, operands);"
14997   [(set (attr "type") 
14998         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14999            (const_string "ssemul")
15000            (const_string "sseadd")))
15001    (set_attr "mode" "SF")])
15002
15003 (define_insn "*fop_sf_comm_i387"
15004   [(set (match_operand:SF 0 "register_operand" "=f")
15005         (match_operator:SF 3 "binary_fp_operator"
15006                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15008   "TARGET_80387
15009    && COMMUTATIVE_ARITH_P (operands[3])
15010    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011   "* return output_387_binary_op (insn, operands);"
15012   [(set (attr "type") 
15013         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15014            (const_string "fmul")
15015            (const_string "fop")))
15016    (set_attr "mode" "SF")])
15017
15018 (define_insn "*fop_sf_1_mixed"
15019   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15020         (match_operator:SF 3 "binary_fp_operator"
15021                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15022                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15023   "TARGET_MIX_SSE_I387
15024    && !COMMUTATIVE_ARITH_P (operands[3])
15025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026   "* return output_387_binary_op (insn, operands);"
15027   [(set (attr "type") 
15028         (cond [(and (eq_attr "alternative" "2")
15029                     (match_operand:SF 3 "mult_operator" ""))
15030                  (const_string "ssemul")
15031                (and (eq_attr "alternative" "2")
15032                     (match_operand:SF 3 "div_operator" ""))
15033                  (const_string "ssediv")
15034                (eq_attr "alternative" "2")
15035                  (const_string "sseadd")
15036                (match_operand:SF 3 "mult_operator" "") 
15037                  (const_string "fmul")
15038                (match_operand:SF 3 "div_operator" "") 
15039                  (const_string "fdiv")
15040               ]
15041               (const_string "fop")))
15042    (set_attr "mode" "SF")])
15043
15044 (define_insn "*fop_sf_1_sse"
15045   [(set (match_operand:SF 0 "register_operand" "=x")
15046         (match_operator:SF 3 "binary_fp_operator"
15047                         [(match_operand:SF 1 "register_operand" "0")
15048                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15049   "TARGET_SSE_MATH
15050    && !COMMUTATIVE_ARITH_P (operands[3])"
15051   "* return output_387_binary_op (insn, operands);"
15052   [(set (attr "type") 
15053         (cond [(match_operand:SF 3 "mult_operator" "")
15054                  (const_string "ssemul")
15055                (match_operand:SF 3 "div_operator" "")
15056                  (const_string "ssediv")
15057               ]
15058               (const_string "sseadd")))
15059    (set_attr "mode" "SF")])
15060
15061 ;; This pattern is not fully shadowed by the pattern above.
15062 (define_insn "*fop_sf_1_i387"
15063   [(set (match_operand:SF 0 "register_operand" "=f,f")
15064         (match_operator:SF 3 "binary_fp_operator"
15065                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15066                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15067   "TARGET_80387 && !TARGET_SSE_MATH
15068    && !COMMUTATIVE_ARITH_P (operands[3])
15069    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15070   "* return output_387_binary_op (insn, operands);"
15071   [(set (attr "type") 
15072         (cond [(match_operand:SF 3 "mult_operator" "") 
15073                  (const_string "fmul")
15074                (match_operand:SF 3 "div_operator" "") 
15075                  (const_string "fdiv")
15076               ]
15077               (const_string "fop")))
15078    (set_attr "mode" "SF")])
15079
15080 ;; ??? Add SSE splitters for these!
15081 (define_insn "*fop_sf_2<mode>_i387"
15082   [(set (match_operand:SF 0 "register_operand" "=f,f")
15083         (match_operator:SF 3 "binary_fp_operator"
15084           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15085            (match_operand:SF 2 "register_operand" "0,0")]))]
15086   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15087   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15088   [(set (attr "type") 
15089         (cond [(match_operand:SF 3 "mult_operator" "") 
15090                  (const_string "fmul")
15091                (match_operand:SF 3 "div_operator" "") 
15092                  (const_string "fdiv")
15093               ]
15094               (const_string "fop")))
15095    (set_attr "fp_int_src" "true")
15096    (set_attr "mode" "<MODE>")])
15097
15098 (define_insn "*fop_sf_3<mode>_i387"
15099   [(set (match_operand:SF 0 "register_operand" "=f,f")
15100         (match_operator:SF 3 "binary_fp_operator"
15101           [(match_operand:SF 1 "register_operand" "0,0")
15102            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15103   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15104   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15105   [(set (attr "type") 
15106         (cond [(match_operand:SF 3 "mult_operator" "") 
15107                  (const_string "fmul")
15108                (match_operand:SF 3 "div_operator" "") 
15109                  (const_string "fdiv")
15110               ]
15111               (const_string "fop")))
15112    (set_attr "fp_int_src" "true")
15113    (set_attr "mode" "<MODE>")])
15114
15115 (define_insn "*fop_df_comm_mixed"
15116   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15117         (match_operator:DF 3 "binary_fp_operator"
15118                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15119                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15120   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15121    && COMMUTATIVE_ARITH_P (operands[3])
15122    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15123   "* return output_387_binary_op (insn, operands);"
15124   [(set (attr "type") 
15125         (if_then_else (eq_attr "alternative" "1")
15126            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15127               (const_string "ssemul")
15128               (const_string "sseadd"))
15129            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15130               (const_string "fmul")
15131               (const_string "fop"))))
15132    (set_attr "mode" "DF")])
15133
15134 (define_insn "*fop_df_comm_sse"
15135   [(set (match_operand:DF 0 "register_operand" "=Y")
15136         (match_operator:DF 3 "binary_fp_operator"
15137                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15138                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15139   "TARGET_SSE2 && TARGET_SSE_MATH
15140    && COMMUTATIVE_ARITH_P (operands[3])
15141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15142   "* return output_387_binary_op (insn, operands);"
15143   [(set (attr "type") 
15144         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15145            (const_string "ssemul")
15146            (const_string "sseadd")))
15147    (set_attr "mode" "DF")])
15148
15149 (define_insn "*fop_df_comm_i387"
15150   [(set (match_operand:DF 0 "register_operand" "=f")
15151         (match_operator:DF 3 "binary_fp_operator"
15152                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15154   "TARGET_80387
15155    && COMMUTATIVE_ARITH_P (operands[3])
15156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157   "* return output_387_binary_op (insn, operands);"
15158   [(set (attr "type") 
15159         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15160            (const_string "fmul")
15161            (const_string "fop")))
15162    (set_attr "mode" "DF")])
15163
15164 (define_insn "*fop_df_1_mixed"
15165   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15166         (match_operator:DF 3 "binary_fp_operator"
15167                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15168                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15169   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15170    && !COMMUTATIVE_ARITH_P (operands[3])
15171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172   "* return output_387_binary_op (insn, operands);"
15173   [(set (attr "type") 
15174         (cond [(and (eq_attr "alternative" "2")
15175                     (match_operand:DF 3 "mult_operator" ""))
15176                  (const_string "ssemul")
15177                (and (eq_attr "alternative" "2")
15178                     (match_operand:DF 3 "div_operator" ""))
15179                  (const_string "ssediv")
15180                (eq_attr "alternative" "2")
15181                  (const_string "sseadd")
15182                (match_operand:DF 3 "mult_operator" "") 
15183                  (const_string "fmul")
15184                (match_operand:DF 3 "div_operator" "") 
15185                  (const_string "fdiv")
15186               ]
15187               (const_string "fop")))
15188    (set_attr "mode" "DF")])
15189
15190 (define_insn "*fop_df_1_sse"
15191   [(set (match_operand:DF 0 "register_operand" "=Y")
15192         (match_operator:DF 3 "binary_fp_operator"
15193                         [(match_operand:DF 1 "register_operand" "0")
15194                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15195   "TARGET_SSE2 && TARGET_SSE_MATH
15196    && !COMMUTATIVE_ARITH_P (operands[3])"
15197   "* return output_387_binary_op (insn, operands);"
15198   [(set_attr "mode" "DF")
15199    (set (attr "type") 
15200         (cond [(match_operand:DF 3 "mult_operator" "")
15201                  (const_string "ssemul")
15202                (match_operand:DF 3 "div_operator" "")
15203                  (const_string "ssediv")
15204               ]
15205               (const_string "sseadd")))])
15206
15207 ;; This pattern is not fully shadowed by the pattern above.
15208 (define_insn "*fop_df_1_i387"
15209   [(set (match_operand:DF 0 "register_operand" "=f,f")
15210         (match_operator:DF 3 "binary_fp_operator"
15211                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15212                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15213   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15214    && !COMMUTATIVE_ARITH_P (operands[3])
15215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15216   "* return output_387_binary_op (insn, operands);"
15217   [(set (attr "type") 
15218         (cond [(match_operand:DF 3 "mult_operator" "") 
15219                  (const_string "fmul")
15220                (match_operand:DF 3 "div_operator" "")
15221                  (const_string "fdiv")
15222               ]
15223               (const_string "fop")))
15224    (set_attr "mode" "DF")])
15225
15226 ;; ??? Add SSE splitters for these!
15227 (define_insn "*fop_df_2<mode>_i387"
15228   [(set (match_operand:DF 0 "register_operand" "=f,f")
15229         (match_operator:DF 3 "binary_fp_operator"
15230            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15231             (match_operand:DF 2 "register_operand" "0,0")]))]
15232   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15233    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15234   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15235   [(set (attr "type") 
15236         (cond [(match_operand:DF 3 "mult_operator" "") 
15237                  (const_string "fmul")
15238                (match_operand:DF 3 "div_operator" "") 
15239                  (const_string "fdiv")
15240               ]
15241               (const_string "fop")))
15242    (set_attr "fp_int_src" "true")
15243    (set_attr "mode" "<MODE>")])
15244
15245 (define_insn "*fop_df_3<mode>_i387"
15246   [(set (match_operand:DF 0 "register_operand" "=f,f")
15247         (match_operator:DF 3 "binary_fp_operator"
15248            [(match_operand:DF 1 "register_operand" "0,0")
15249             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15250   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15251    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15252   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15253   [(set (attr "type") 
15254         (cond [(match_operand:DF 3 "mult_operator" "") 
15255                  (const_string "fmul")
15256                (match_operand:DF 3 "div_operator" "") 
15257                  (const_string "fdiv")
15258               ]
15259               (const_string "fop")))
15260    (set_attr "fp_int_src" "true")
15261    (set_attr "mode" "<MODE>")])
15262
15263 (define_insn "*fop_df_4_i387"
15264   [(set (match_operand:DF 0 "register_operand" "=f,f")
15265         (match_operator:DF 3 "binary_fp_operator"
15266            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15267             (match_operand:DF 2 "register_operand" "0,f")]))]
15268   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set (attr "type") 
15272         (cond [(match_operand:DF 3 "mult_operator" "") 
15273                  (const_string "fmul")
15274                (match_operand:DF 3 "div_operator" "") 
15275                  (const_string "fdiv")
15276               ]
15277               (const_string "fop")))
15278    (set_attr "mode" "SF")])
15279
15280 (define_insn "*fop_df_5_i387"
15281   [(set (match_operand:DF 0 "register_operand" "=f,f")
15282         (match_operator:DF 3 "binary_fp_operator"
15283           [(match_operand:DF 1 "register_operand" "0,f")
15284            (float_extend:DF
15285             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15286   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15287   "* return output_387_binary_op (insn, operands);"
15288   [(set (attr "type") 
15289         (cond [(match_operand:DF 3 "mult_operator" "") 
15290                  (const_string "fmul")
15291                (match_operand:DF 3 "div_operator" "") 
15292                  (const_string "fdiv")
15293               ]
15294               (const_string "fop")))
15295    (set_attr "mode" "SF")])
15296
15297 (define_insn "*fop_df_6_i387"
15298   [(set (match_operand:DF 0 "register_operand" "=f,f")
15299         (match_operator:DF 3 "binary_fp_operator"
15300           [(float_extend:DF
15301             (match_operand:SF 1 "register_operand" "0,f"))
15302            (float_extend:DF
15303             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15304   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15305   "* return output_387_binary_op (insn, operands);"
15306   [(set (attr "type") 
15307         (cond [(match_operand:DF 3 "mult_operator" "") 
15308                  (const_string "fmul")
15309                (match_operand:DF 3 "div_operator" "") 
15310                  (const_string "fdiv")
15311               ]
15312               (const_string "fop")))
15313    (set_attr "mode" "SF")])
15314
15315 (define_insn "*fop_xf_comm_i387"
15316   [(set (match_operand:XF 0 "register_operand" "=f")
15317         (match_operator:XF 3 "binary_fp_operator"
15318                         [(match_operand:XF 1 "register_operand" "%0")
15319                          (match_operand:XF 2 "register_operand" "f")]))]
15320   "TARGET_80387
15321    && COMMUTATIVE_ARITH_P (operands[3])"
15322   "* return output_387_binary_op (insn, operands);"
15323   [(set (attr "type") 
15324         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15325            (const_string "fmul")
15326            (const_string "fop")))
15327    (set_attr "mode" "XF")])
15328
15329 (define_insn "*fop_xf_1_i387"
15330   [(set (match_operand:XF 0 "register_operand" "=f,f")
15331         (match_operator:XF 3 "binary_fp_operator"
15332                         [(match_operand:XF 1 "register_operand" "0,f")
15333                          (match_operand:XF 2 "register_operand" "f,0")]))]
15334   "TARGET_80387
15335    && !COMMUTATIVE_ARITH_P (operands[3])"
15336   "* return output_387_binary_op (insn, operands);"
15337   [(set (attr "type") 
15338         (cond [(match_operand:XF 3 "mult_operator" "") 
15339                  (const_string "fmul")
15340                (match_operand:XF 3 "div_operator" "") 
15341                  (const_string "fdiv")
15342               ]
15343               (const_string "fop")))
15344    (set_attr "mode" "XF")])
15345
15346 (define_insn "*fop_xf_2<mode>_i387"
15347   [(set (match_operand:XF 0 "register_operand" "=f,f")
15348         (match_operator:XF 3 "binary_fp_operator"
15349            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15350             (match_operand:XF 2 "register_operand" "0,0")]))]
15351   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15352   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15353   [(set (attr "type") 
15354         (cond [(match_operand:XF 3 "mult_operator" "") 
15355                  (const_string "fmul")
15356                (match_operand:XF 3 "div_operator" "") 
15357                  (const_string "fdiv")
15358               ]
15359               (const_string "fop")))
15360    (set_attr "fp_int_src" "true")
15361    (set_attr "mode" "<MODE>")])
15362
15363 (define_insn "*fop_xf_3<mode>_i387"
15364   [(set (match_operand:XF 0 "register_operand" "=f,f")
15365         (match_operator:XF 3 "binary_fp_operator"
15366           [(match_operand:XF 1 "register_operand" "0,0")
15367            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15368   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15369   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15370   [(set (attr "type") 
15371         (cond [(match_operand:XF 3 "mult_operator" "") 
15372                  (const_string "fmul")
15373                (match_operand:XF 3 "div_operator" "") 
15374                  (const_string "fdiv")
15375               ]
15376               (const_string "fop")))
15377    (set_attr "fp_int_src" "true")
15378    (set_attr "mode" "<MODE>")])
15379
15380 (define_insn "*fop_xf_4_i387"
15381   [(set (match_operand:XF 0 "register_operand" "=f,f")
15382         (match_operator:XF 3 "binary_fp_operator"
15383            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15384             (match_operand:XF 2 "register_operand" "0,f")]))]
15385   "TARGET_80387"
15386   "* return output_387_binary_op (insn, operands);"
15387   [(set (attr "type") 
15388         (cond [(match_operand:XF 3 "mult_operator" "") 
15389                  (const_string "fmul")
15390                (match_operand:XF 3 "div_operator" "") 
15391                  (const_string "fdiv")
15392               ]
15393               (const_string "fop")))
15394    (set_attr "mode" "SF")])
15395
15396 (define_insn "*fop_xf_5_i387"
15397   [(set (match_operand:XF 0 "register_operand" "=f,f")
15398         (match_operator:XF 3 "binary_fp_operator"
15399           [(match_operand:XF 1 "register_operand" "0,f")
15400            (float_extend:XF
15401             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15402   "TARGET_80387"
15403   "* return output_387_binary_op (insn, operands);"
15404   [(set (attr "type") 
15405         (cond [(match_operand:XF 3 "mult_operator" "") 
15406                  (const_string "fmul")
15407                (match_operand:XF 3 "div_operator" "") 
15408                  (const_string "fdiv")
15409               ]
15410               (const_string "fop")))
15411    (set_attr "mode" "SF")])
15412
15413 (define_insn "*fop_xf_6_i387"
15414   [(set (match_operand:XF 0 "register_operand" "=f,f")
15415         (match_operator:XF 3 "binary_fp_operator"
15416           [(float_extend:XF
15417             (match_operand 1 "register_operand" "0,f"))
15418            (float_extend:XF
15419             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15420   "TARGET_80387"
15421   "* return output_387_binary_op (insn, operands);"
15422   [(set (attr "type") 
15423         (cond [(match_operand:XF 3 "mult_operator" "") 
15424                  (const_string "fmul")
15425                (match_operand:XF 3 "div_operator" "") 
15426                  (const_string "fdiv")
15427               ]
15428               (const_string "fop")))
15429    (set_attr "mode" "SF")])
15430
15431 (define_split
15432   [(set (match_operand 0 "register_operand" "")
15433         (match_operator 3 "binary_fp_operator"
15434            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15435             (match_operand 2 "register_operand" "")]))]
15436   "TARGET_80387 && reload_completed
15437    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15438   [(const_int 0)]
15439
15440   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15441   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15442   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15443                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15444                                           GET_MODE (operands[3]),
15445                                           operands[4],
15446                                           operands[2])));
15447   ix86_free_from_memory (GET_MODE (operands[1]));
15448   DONE;
15449 })
15450
15451 (define_split
15452   [(set (match_operand 0 "register_operand" "")
15453         (match_operator 3 "binary_fp_operator"
15454            [(match_operand 1 "register_operand" "")
15455             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15456   "TARGET_80387 && reload_completed
15457    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15458   [(const_int 0)]
15459 {
15460   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15461   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15462   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15463                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15464                                           GET_MODE (operands[3]),
15465                                           operands[1],
15466                                           operands[4])));
15467   ix86_free_from_memory (GET_MODE (operands[2]));
15468   DONE;
15469 })
15470 \f
15471 ;; FPU special functions.
15472
15473 (define_expand "sqrtsf2"
15474   [(set (match_operand:SF 0 "register_operand" "")
15475         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15476   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15477 {
15478   if (!TARGET_SSE_MATH)
15479     operands[1] = force_reg (SFmode, operands[1]);
15480 })
15481
15482 (define_insn "*sqrtsf2_mixed"
15483   [(set (match_operand:SF 0 "register_operand" "=f,x")
15484         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15485   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15486   "@
15487    fsqrt
15488    sqrtss\t{%1, %0|%0, %1}"
15489   [(set_attr "type" "fpspc,sse")
15490    (set_attr "mode" "SF,SF")
15491    (set_attr "athlon_decode" "direct,*")])
15492
15493 (define_insn "*sqrtsf2_sse"
15494   [(set (match_operand:SF 0 "register_operand" "=x")
15495         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15496   "TARGET_SSE_MATH"
15497   "sqrtss\t{%1, %0|%0, %1}"
15498   [(set_attr "type" "sse")
15499    (set_attr "mode" "SF")
15500    (set_attr "athlon_decode" "*")])
15501
15502 (define_insn "*sqrtsf2_i387"
15503   [(set (match_operand:SF 0 "register_operand" "=f")
15504         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15505   "TARGET_USE_FANCY_MATH_387"
15506   "fsqrt"
15507   [(set_attr "type" "fpspc")
15508    (set_attr "mode" "SF")
15509    (set_attr "athlon_decode" "direct")])
15510
15511 (define_expand "sqrtdf2"
15512   [(set (match_operand:DF 0 "register_operand" "")
15513         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15514   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15515 {
15516   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15517     operands[1] = force_reg (DFmode, operands[1]);
15518 })
15519
15520 (define_insn "*sqrtdf2_mixed"
15521   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15522         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15523   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15524   "@
15525    fsqrt
15526    sqrtsd\t{%1, %0|%0, %1}"
15527   [(set_attr "type" "fpspc,sse")
15528    (set_attr "mode" "DF,DF")
15529    (set_attr "athlon_decode" "direct,*")])
15530
15531 (define_insn "*sqrtdf2_sse"
15532   [(set (match_operand:DF 0 "register_operand" "=Y")
15533         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15534   "TARGET_SSE2 && TARGET_SSE_MATH"
15535   "sqrtsd\t{%1, %0|%0, %1}"
15536   [(set_attr "type" "sse")
15537    (set_attr "mode" "DF")
15538    (set_attr "athlon_decode" "*")])
15539
15540 (define_insn "*sqrtdf2_i387"
15541   [(set (match_operand:DF 0 "register_operand" "=f")
15542         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15543   "TARGET_USE_FANCY_MATH_387"
15544   "fsqrt"
15545   [(set_attr "type" "fpspc")
15546    (set_attr "mode" "DF")
15547    (set_attr "athlon_decode" "direct")])
15548
15549 (define_insn "*sqrtextendsfdf2_i387"
15550   [(set (match_operand:DF 0 "register_operand" "=f")
15551         (sqrt:DF (float_extend:DF
15552                   (match_operand:SF 1 "register_operand" "0"))))]
15553   "TARGET_USE_FANCY_MATH_387
15554    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15555   "fsqrt"
15556   [(set_attr "type" "fpspc")
15557    (set_attr "mode" "DF")
15558    (set_attr "athlon_decode" "direct")])
15559
15560 (define_insn "sqrtxf2"
15561   [(set (match_operand:XF 0 "register_operand" "=f")
15562         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15563   "TARGET_USE_FANCY_MATH_387"
15564   "fsqrt"
15565   [(set_attr "type" "fpspc")
15566    (set_attr "mode" "XF")
15567    (set_attr "athlon_decode" "direct")])
15568
15569 (define_insn "*sqrtextendsfxf2_i387"
15570   [(set (match_operand:XF 0 "register_operand" "=f")
15571         (sqrt:XF (float_extend:XF
15572                   (match_operand:SF 1 "register_operand" "0"))))]
15573   "TARGET_USE_FANCY_MATH_387"
15574   "fsqrt"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")
15577    (set_attr "athlon_decode" "direct")])
15578
15579 (define_insn "*sqrtextenddfxf2_i387"
15580   [(set (match_operand:XF 0 "register_operand" "=f")
15581         (sqrt:XF (float_extend:XF
15582                   (match_operand:DF 1 "register_operand" "0"))))]
15583   "TARGET_USE_FANCY_MATH_387"
15584   "fsqrt"
15585   [(set_attr "type" "fpspc")
15586    (set_attr "mode" "XF")
15587    (set_attr "athlon_decode" "direct")])
15588
15589 (define_insn "fpremxf4"
15590   [(set (match_operand:XF 0 "register_operand" "=f")
15591         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15592                     (match_operand:XF 3 "register_operand" "1")]
15593                    UNSPEC_FPREM_F))
15594    (set (match_operand:XF 1 "register_operand" "=u")
15595         (unspec:XF [(match_dup 2) (match_dup 3)]
15596                    UNSPEC_FPREM_U))
15597    (set (reg:CCFP FPSR_REG)
15598         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15599   "TARGET_USE_FANCY_MATH_387
15600    && flag_unsafe_math_optimizations"
15601   "fprem"
15602   [(set_attr "type" "fpspc")
15603    (set_attr "mode" "XF")])
15604
15605 (define_expand "fmodsf3"
15606   [(use (match_operand:SF 0 "register_operand" ""))
15607    (use (match_operand:SF 1 "register_operand" ""))
15608    (use (match_operand:SF 2 "register_operand" ""))]
15609   "TARGET_USE_FANCY_MATH_387
15610    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15611    && flag_unsafe_math_optimizations"
15612 {
15613   rtx label = gen_label_rtx ();
15614
15615   rtx op1 = gen_reg_rtx (XFmode);
15616   rtx op2 = gen_reg_rtx (XFmode);
15617
15618   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15619   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15620
15621   emit_label (label);
15622
15623   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15624   ix86_emit_fp_unordered_jump (label);
15625
15626   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15627   DONE;
15628 })
15629
15630 (define_expand "fmoddf3"
15631   [(use (match_operand:DF 0 "register_operand" ""))
15632    (use (match_operand:DF 1 "register_operand" ""))
15633    (use (match_operand:DF 2 "register_operand" ""))]
15634   "TARGET_USE_FANCY_MATH_387
15635    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15636    && flag_unsafe_math_optimizations"
15637 {
15638   rtx label = gen_label_rtx ();
15639
15640   rtx op1 = gen_reg_rtx (XFmode);
15641   rtx op2 = gen_reg_rtx (XFmode);
15642
15643   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15644   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15645
15646   emit_label (label);
15647
15648   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15649   ix86_emit_fp_unordered_jump (label);
15650
15651   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15652   DONE;
15653 })
15654
15655 (define_expand "fmodxf3"
15656   [(use (match_operand:XF 0 "register_operand" ""))
15657    (use (match_operand:XF 1 "register_operand" ""))
15658    (use (match_operand:XF 2 "register_operand" ""))]
15659   "TARGET_USE_FANCY_MATH_387
15660    && flag_unsafe_math_optimizations"
15661 {
15662   rtx label = gen_label_rtx ();
15663
15664   emit_label (label);
15665
15666   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15667                            operands[1], operands[2]));
15668   ix86_emit_fp_unordered_jump (label);
15669
15670   emit_move_insn (operands[0], operands[1]);
15671   DONE;
15672 })
15673
15674 (define_insn "fprem1xf4"
15675   [(set (match_operand:XF 0 "register_operand" "=f")
15676         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15677                     (match_operand:XF 3 "register_operand" "1")]
15678                    UNSPEC_FPREM1_F))
15679    (set (match_operand:XF 1 "register_operand" "=u")
15680         (unspec:XF [(match_dup 2) (match_dup 3)]
15681                    UNSPEC_FPREM1_U))
15682    (set (reg:CCFP FPSR_REG)
15683         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15684   "TARGET_USE_FANCY_MATH_387
15685    && flag_unsafe_math_optimizations"
15686   "fprem1"
15687   [(set_attr "type" "fpspc")
15688    (set_attr "mode" "XF")])
15689
15690 (define_expand "dremsf3"
15691   [(use (match_operand:SF 0 "register_operand" ""))
15692    (use (match_operand:SF 1 "register_operand" ""))
15693    (use (match_operand:SF 2 "register_operand" ""))]
15694   "TARGET_USE_FANCY_MATH_387
15695    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15696    && flag_unsafe_math_optimizations"
15697 {
15698   rtx label = gen_label_rtx ();
15699
15700   rtx op1 = gen_reg_rtx (XFmode);
15701   rtx op2 = gen_reg_rtx (XFmode);
15702
15703   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15704   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15705
15706   emit_label (label);
15707
15708   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15709   ix86_emit_fp_unordered_jump (label);
15710
15711   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15712   DONE;
15713 })
15714
15715 (define_expand "dremdf3"
15716   [(use (match_operand:DF 0 "register_operand" ""))
15717    (use (match_operand:DF 1 "register_operand" ""))
15718    (use (match_operand:DF 2 "register_operand" ""))]
15719   "TARGET_USE_FANCY_MATH_387
15720    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15721    && flag_unsafe_math_optimizations"
15722 {
15723   rtx label = gen_label_rtx ();
15724
15725   rtx op1 = gen_reg_rtx (XFmode);
15726   rtx op2 = gen_reg_rtx (XFmode);
15727
15728   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15729   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15730
15731   emit_label (label);
15732
15733   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15734   ix86_emit_fp_unordered_jump (label);
15735
15736   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15737   DONE;
15738 })
15739
15740 (define_expand "dremxf3"
15741   [(use (match_operand:XF 0 "register_operand" ""))
15742    (use (match_operand:XF 1 "register_operand" ""))
15743    (use (match_operand:XF 2 "register_operand" ""))]
15744   "TARGET_USE_FANCY_MATH_387
15745    && flag_unsafe_math_optimizations"
15746 {
15747   rtx label = gen_label_rtx ();
15748
15749   emit_label (label);
15750
15751   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15752                             operands[1], operands[2]));
15753   ix86_emit_fp_unordered_jump (label);
15754
15755   emit_move_insn (operands[0], operands[1]);
15756   DONE;
15757 })
15758
15759 (define_insn "*sindf2"
15760   [(set (match_operand:DF 0 "register_operand" "=f")
15761         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15762   "TARGET_USE_FANCY_MATH_387
15763    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15764    && flag_unsafe_math_optimizations"
15765   "fsin"
15766   [(set_attr "type" "fpspc")
15767    (set_attr "mode" "DF")])
15768
15769 (define_insn "*sinsf2"
15770   [(set (match_operand:SF 0 "register_operand" "=f")
15771         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15772   "TARGET_USE_FANCY_MATH_387
15773    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15774    && flag_unsafe_math_optimizations"
15775   "fsin"
15776   [(set_attr "type" "fpspc")
15777    (set_attr "mode" "SF")])
15778
15779 (define_insn "*sinextendsfdf2"
15780   [(set (match_operand:DF 0 "register_operand" "=f")
15781         (unspec:DF [(float_extend:DF
15782                      (match_operand:SF 1 "register_operand" "0"))]
15783                    UNSPEC_SIN))]
15784   "TARGET_USE_FANCY_MATH_387
15785    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15786    && flag_unsafe_math_optimizations"
15787   "fsin"
15788   [(set_attr "type" "fpspc")
15789    (set_attr "mode" "DF")])
15790
15791 (define_insn "*sinxf2"
15792   [(set (match_operand:XF 0 "register_operand" "=f")
15793         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15794   "TARGET_USE_FANCY_MATH_387
15795    && flag_unsafe_math_optimizations"
15796   "fsin"
15797   [(set_attr "type" "fpspc")
15798    (set_attr "mode" "XF")])
15799
15800 (define_insn "*cosdf2"
15801   [(set (match_operand:DF 0 "register_operand" "=f")
15802         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15803   "TARGET_USE_FANCY_MATH_387
15804    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15805    && flag_unsafe_math_optimizations"
15806   "fcos"
15807   [(set_attr "type" "fpspc")
15808    (set_attr "mode" "DF")])
15809
15810 (define_insn "*cossf2"
15811   [(set (match_operand:SF 0 "register_operand" "=f")
15812         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15813   "TARGET_USE_FANCY_MATH_387
15814    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15815    && flag_unsafe_math_optimizations"
15816   "fcos"
15817   [(set_attr "type" "fpspc")
15818    (set_attr "mode" "SF")])
15819
15820 (define_insn "*cosextendsfdf2"
15821   [(set (match_operand:DF 0 "register_operand" "=f")
15822         (unspec:DF [(float_extend:DF
15823                      (match_operand:SF 1 "register_operand" "0"))]
15824                    UNSPEC_COS))]
15825   "TARGET_USE_FANCY_MATH_387
15826    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827    && flag_unsafe_math_optimizations"
15828   "fcos"
15829   [(set_attr "type" "fpspc")
15830    (set_attr "mode" "DF")])
15831
15832 (define_insn "*cosxf2"
15833   [(set (match_operand:XF 0 "register_operand" "=f")
15834         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15835   "TARGET_USE_FANCY_MATH_387
15836    && flag_unsafe_math_optimizations"
15837   "fcos"
15838   [(set_attr "type" "fpspc")
15839    (set_attr "mode" "XF")])
15840
15841 ;; With sincos pattern defined, sin and cos builtin function will be
15842 ;; expanded to sincos pattern with one of its outputs left unused. 
15843 ;; Cse pass  will detected, if two sincos patterns can be combined,
15844 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15845 ;; depending on the unused output.
15846
15847 (define_insn "sincosdf3"
15848   [(set (match_operand:DF 0 "register_operand" "=f")
15849         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15850                    UNSPEC_SINCOS_COS))
15851    (set (match_operand:DF 1 "register_operand" "=u")
15852         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15853   "TARGET_USE_FANCY_MATH_387
15854    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15855    && flag_unsafe_math_optimizations"
15856   "fsincos"
15857   [(set_attr "type" "fpspc")
15858    (set_attr "mode" "DF")])
15859
15860 (define_split
15861   [(set (match_operand:DF 0 "register_operand" "")
15862         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15863                    UNSPEC_SINCOS_COS))
15864    (set (match_operand:DF 1 "register_operand" "")
15865         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15866   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15867    && !reload_completed && !reload_in_progress"
15868   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15869   "")
15870
15871 (define_split
15872   [(set (match_operand:DF 0 "register_operand" "")
15873         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15874                    UNSPEC_SINCOS_COS))
15875    (set (match_operand:DF 1 "register_operand" "")
15876         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15877   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15878    && !reload_completed && !reload_in_progress"
15879   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15880   "")
15881
15882 (define_insn "sincossf3"
15883   [(set (match_operand:SF 0 "register_operand" "=f")
15884         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15885                    UNSPEC_SINCOS_COS))
15886    (set (match_operand:SF 1 "register_operand" "=u")
15887         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15888   "TARGET_USE_FANCY_MATH_387
15889    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15890    && flag_unsafe_math_optimizations"
15891   "fsincos"
15892   [(set_attr "type" "fpspc")
15893    (set_attr "mode" "SF")])
15894
15895 (define_split
15896   [(set (match_operand:SF 0 "register_operand" "")
15897         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15898                    UNSPEC_SINCOS_COS))
15899    (set (match_operand:SF 1 "register_operand" "")
15900         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15901   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15902    && !reload_completed && !reload_in_progress"
15903   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15904   "")
15905
15906 (define_split
15907   [(set (match_operand:SF 0 "register_operand" "")
15908         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15909                    UNSPEC_SINCOS_COS))
15910    (set (match_operand:SF 1 "register_operand" "")
15911         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15912   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15913    && !reload_completed && !reload_in_progress"
15914   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15915   "")
15916
15917 (define_insn "*sincosextendsfdf3"
15918   [(set (match_operand:DF 0 "register_operand" "=f")
15919         (unspec:DF [(float_extend:DF
15920                      (match_operand:SF 2 "register_operand" "0"))]
15921                    UNSPEC_SINCOS_COS))
15922    (set (match_operand:DF 1 "register_operand" "=u")
15923         (unspec:DF [(float_extend:DF
15924                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15925   "TARGET_USE_FANCY_MATH_387
15926    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15927    && flag_unsafe_math_optimizations"
15928   "fsincos"
15929   [(set_attr "type" "fpspc")
15930    (set_attr "mode" "DF")])
15931
15932 (define_split
15933   [(set (match_operand:DF 0 "register_operand" "")
15934         (unspec:DF [(float_extend:DF
15935                      (match_operand:SF 2 "register_operand" ""))]
15936                    UNSPEC_SINCOS_COS))
15937    (set (match_operand:DF 1 "register_operand" "")
15938         (unspec:DF [(float_extend:DF
15939                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15940   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15941    && !reload_completed && !reload_in_progress"
15942   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15943                                    (match_dup 2))] UNSPEC_SIN))]
15944   "")
15945
15946 (define_split
15947   [(set (match_operand:DF 0 "register_operand" "")
15948         (unspec:DF [(float_extend:DF
15949                      (match_operand:SF 2 "register_operand" ""))]
15950                    UNSPEC_SINCOS_COS))
15951    (set (match_operand:DF 1 "register_operand" "")
15952         (unspec:DF [(float_extend:DF
15953                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15954   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15955    && !reload_completed && !reload_in_progress"
15956   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15957                                    (match_dup 2))] UNSPEC_COS))]
15958   "")
15959
15960 (define_insn "sincosxf3"
15961   [(set (match_operand:XF 0 "register_operand" "=f")
15962         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15963                    UNSPEC_SINCOS_COS))
15964    (set (match_operand:XF 1 "register_operand" "=u")
15965         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15966   "TARGET_USE_FANCY_MATH_387
15967    && flag_unsafe_math_optimizations"
15968   "fsincos"
15969   [(set_attr "type" "fpspc")
15970    (set_attr "mode" "XF")])
15971
15972 (define_split
15973   [(set (match_operand:XF 0 "register_operand" "")
15974         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15975                    UNSPEC_SINCOS_COS))
15976    (set (match_operand:XF 1 "register_operand" "")
15977         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15978   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15979    && !reload_completed && !reload_in_progress"
15980   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15981   "")
15982
15983 (define_split
15984   [(set (match_operand:XF 0 "register_operand" "")
15985         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15986                    UNSPEC_SINCOS_COS))
15987    (set (match_operand:XF 1 "register_operand" "")
15988         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15989   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15990    && !reload_completed && !reload_in_progress"
15991   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15992   "")
15993
15994 (define_insn "*tandf3_1"
15995   [(set (match_operand:DF 0 "register_operand" "=f")
15996         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15997                    UNSPEC_TAN_ONE))
15998    (set (match_operand:DF 1 "register_operand" "=u")
15999         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16000   "TARGET_USE_FANCY_MATH_387
16001    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16002    && flag_unsafe_math_optimizations"
16003   "fptan"
16004   [(set_attr "type" "fpspc")
16005    (set_attr "mode" "DF")])
16006
16007 ;; optimize sequence: fptan
16008 ;;                    fstp    %st(0)
16009 ;;                    fld1
16010 ;; into fptan insn.
16011
16012 (define_peephole2
16013   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16014                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16015                              UNSPEC_TAN_ONE))
16016              (set (match_operand:DF 1 "register_operand" "")
16017                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16018    (set (match_dup 0)
16019         (match_operand:DF 3 "immediate_operand" ""))]
16020   "standard_80387_constant_p (operands[3]) == 2"
16021   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16022              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16023   "")
16024
16025 (define_expand "tandf2"
16026   [(parallel [(set (match_dup 2)
16027                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16028                               UNSPEC_TAN_ONE))
16029               (set (match_operand:DF 0 "register_operand" "")
16030                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16031   "TARGET_USE_FANCY_MATH_387
16032    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16033    && flag_unsafe_math_optimizations"
16034 {
16035   operands[2] = gen_reg_rtx (DFmode);
16036 })
16037
16038 (define_insn "*tansf3_1"
16039   [(set (match_operand:SF 0 "register_operand" "=f")
16040         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16041                    UNSPEC_TAN_ONE))
16042    (set (match_operand:SF 1 "register_operand" "=u")
16043         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16044   "TARGET_USE_FANCY_MATH_387
16045    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16046    && flag_unsafe_math_optimizations"
16047   "fptan"
16048   [(set_attr "type" "fpspc")
16049    (set_attr "mode" "SF")])
16050
16051 ;; optimize sequence: fptan
16052 ;;                    fstp    %st(0)
16053 ;;                    fld1
16054 ;; into fptan insn.
16055
16056 (define_peephole2
16057   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16058                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16059                              UNSPEC_TAN_ONE))
16060              (set (match_operand:SF 1 "register_operand" "")
16061                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16062    (set (match_dup 0)
16063         (match_operand:SF 3 "immediate_operand" ""))]
16064   "standard_80387_constant_p (operands[3]) == 2"
16065   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16066              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16067   "")
16068
16069 (define_expand "tansf2"
16070   [(parallel [(set (match_dup 2)
16071                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16072                               UNSPEC_TAN_ONE))
16073               (set (match_operand:SF 0 "register_operand" "")
16074                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16075   "TARGET_USE_FANCY_MATH_387
16076    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16077    && flag_unsafe_math_optimizations"
16078 {
16079   operands[2] = gen_reg_rtx (SFmode);
16080 })
16081
16082 (define_insn "*tanxf3_1"
16083   [(set (match_operand:XF 0 "register_operand" "=f")
16084         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16085                    UNSPEC_TAN_ONE))
16086    (set (match_operand:XF 1 "register_operand" "=u")
16087         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16088   "TARGET_USE_FANCY_MATH_387
16089    && flag_unsafe_math_optimizations"
16090   "fptan"
16091   [(set_attr "type" "fpspc")
16092    (set_attr "mode" "XF")])
16093
16094 ;; optimize sequence: fptan
16095 ;;                    fstp    %st(0)
16096 ;;                    fld1
16097 ;; into fptan insn.
16098
16099 (define_peephole2
16100   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16101                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16102                              UNSPEC_TAN_ONE))
16103              (set (match_operand:XF 1 "register_operand" "")
16104                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16105    (set (match_dup 0)
16106         (match_operand:XF 3 "immediate_operand" ""))]
16107   "standard_80387_constant_p (operands[3]) == 2"
16108   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16109              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16110   "")
16111
16112 (define_expand "tanxf2"
16113   [(parallel [(set (match_dup 2)
16114                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16115                               UNSPEC_TAN_ONE))
16116               (set (match_operand:XF 0 "register_operand" "")
16117                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16120 {
16121   operands[2] = gen_reg_rtx (XFmode);
16122 })
16123
16124 (define_insn "atan2df3_1"
16125   [(set (match_operand:DF 0 "register_operand" "=f")
16126         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16127                     (match_operand:DF 1 "register_operand" "u")]
16128                    UNSPEC_FPATAN))
16129    (clobber (match_scratch:DF 3 "=1"))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16132    && flag_unsafe_math_optimizations"
16133   "fpatan"
16134   [(set_attr "type" "fpspc")
16135    (set_attr "mode" "DF")])
16136
16137 (define_expand "atan2df3"
16138   [(use (match_operand:DF 0 "register_operand" ""))
16139    (use (match_operand:DF 2 "register_operand" ""))
16140    (use (match_operand:DF 1 "register_operand" ""))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16144 {
16145   rtx copy = gen_reg_rtx (DFmode);
16146   emit_move_insn (copy, operands[1]);
16147   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16148   DONE;
16149 })
16150
16151 (define_expand "atandf2"
16152   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16153                    (unspec:DF [(match_dup 2)
16154                                (match_operand:DF 1 "register_operand" "")]
16155                     UNSPEC_FPATAN))
16156               (clobber (match_scratch:DF 3 ""))])]
16157   "TARGET_USE_FANCY_MATH_387
16158    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16159    && flag_unsafe_math_optimizations"
16160 {
16161   operands[2] = gen_reg_rtx (DFmode);
16162   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16163 })
16164
16165 (define_insn "atan2sf3_1"
16166   [(set (match_operand:SF 0 "register_operand" "=f")
16167         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16168                     (match_operand:SF 1 "register_operand" "u")]
16169                    UNSPEC_FPATAN))
16170    (clobber (match_scratch:SF 3 "=1"))]
16171   "TARGET_USE_FANCY_MATH_387
16172    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16173    && flag_unsafe_math_optimizations"
16174   "fpatan"
16175   [(set_attr "type" "fpspc")
16176    (set_attr "mode" "SF")])
16177
16178 (define_expand "atan2sf3"
16179   [(use (match_operand:SF 0 "register_operand" ""))
16180    (use (match_operand:SF 2 "register_operand" ""))
16181    (use (match_operand:SF 1 "register_operand" ""))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16184    && flag_unsafe_math_optimizations"
16185 {
16186   rtx copy = gen_reg_rtx (SFmode);
16187   emit_move_insn (copy, operands[1]);
16188   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16189   DONE;
16190 })
16191
16192 (define_expand "atansf2"
16193   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16194                    (unspec:SF [(match_dup 2)
16195                                (match_operand:SF 1 "register_operand" "")]
16196                     UNSPEC_FPATAN))
16197               (clobber (match_scratch:SF 3 ""))])]
16198   "TARGET_USE_FANCY_MATH_387
16199    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16200    && flag_unsafe_math_optimizations"
16201 {
16202   operands[2] = gen_reg_rtx (SFmode);
16203   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16204 })
16205
16206 (define_insn "atan2xf3_1"
16207   [(set (match_operand:XF 0 "register_operand" "=f")
16208         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16209                     (match_operand:XF 1 "register_operand" "u")]
16210                    UNSPEC_FPATAN))
16211    (clobber (match_scratch:XF 3 "=1"))]
16212   "TARGET_USE_FANCY_MATH_387
16213    && flag_unsafe_math_optimizations"
16214   "fpatan"
16215   [(set_attr "type" "fpspc")
16216    (set_attr "mode" "XF")])
16217
16218 (define_expand "atan2xf3"
16219   [(use (match_operand:XF 0 "register_operand" ""))
16220    (use (match_operand:XF 2 "register_operand" ""))
16221    (use (match_operand:XF 1 "register_operand" ""))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224 {
16225   rtx copy = gen_reg_rtx (XFmode);
16226   emit_move_insn (copy, operands[1]);
16227   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16228   DONE;
16229 })
16230
16231 (define_expand "atanxf2"
16232   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16233                    (unspec:XF [(match_dup 2)
16234                                (match_operand:XF 1 "register_operand" "")]
16235                     UNSPEC_FPATAN))
16236               (clobber (match_scratch:XF 3 ""))])]
16237   "TARGET_USE_FANCY_MATH_387
16238    && flag_unsafe_math_optimizations"
16239 {
16240   operands[2] = gen_reg_rtx (XFmode);
16241   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16242 })
16243
16244 (define_expand "asindf2"
16245   [(set (match_dup 2)
16246         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16247    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16248    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16249    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16250    (parallel [(set (match_dup 7)
16251                    (unspec:XF [(match_dup 6) (match_dup 2)]
16252                               UNSPEC_FPATAN))
16253               (clobber (match_scratch:XF 8 ""))])
16254    (set (match_operand:DF 0 "register_operand" "")
16255         (float_truncate:DF (match_dup 7)))]
16256   "TARGET_USE_FANCY_MATH_387
16257    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16258    && flag_unsafe_math_optimizations"
16259 {
16260   int i;
16261
16262   for (i=2; i<8; i++)
16263     operands[i] = gen_reg_rtx (XFmode);
16264
16265   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16266 })
16267
16268 (define_expand "asinsf2"
16269   [(set (match_dup 2)
16270         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16271    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16272    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16273    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16274    (parallel [(set (match_dup 7)
16275                    (unspec:XF [(match_dup 6) (match_dup 2)]
16276                               UNSPEC_FPATAN))
16277               (clobber (match_scratch:XF 8 ""))])
16278    (set (match_operand:SF 0 "register_operand" "")
16279         (float_truncate:SF (match_dup 7)))]
16280   "TARGET_USE_FANCY_MATH_387
16281    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16282    && flag_unsafe_math_optimizations"
16283 {
16284   int i;
16285
16286   for (i=2; i<8; i++)
16287     operands[i] = gen_reg_rtx (XFmode);
16288
16289   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16290 })
16291
16292 (define_expand "asinxf2"
16293   [(set (match_dup 2)
16294         (mult:XF (match_operand:XF 1 "register_operand" "")
16295                  (match_dup 1)))
16296    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16297    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16298    (parallel [(set (match_operand:XF 0 "register_operand" "")
16299                    (unspec:XF [(match_dup 5) (match_dup 1)]
16300                               UNSPEC_FPATAN))
16301               (clobber (match_scratch:XF 6 ""))])]
16302   "TARGET_USE_FANCY_MATH_387
16303    && flag_unsafe_math_optimizations"
16304 {
16305   int i;
16306
16307   for (i=2; i<6; i++)
16308     operands[i] = gen_reg_rtx (XFmode);
16309
16310   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16311 })
16312
16313 (define_expand "acosdf2"
16314   [(set (match_dup 2)
16315         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16316    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16317    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16318    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16319    (parallel [(set (match_dup 7)
16320                    (unspec:XF [(match_dup 2) (match_dup 6)]
16321                               UNSPEC_FPATAN))
16322               (clobber (match_scratch:XF 8 ""))])
16323    (set (match_operand:DF 0 "register_operand" "")
16324         (float_truncate:DF (match_dup 7)))]
16325   "TARGET_USE_FANCY_MATH_387
16326    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16327    && flag_unsafe_math_optimizations"
16328 {
16329   int i;
16330
16331   for (i=2; i<8; i++)
16332     operands[i] = gen_reg_rtx (XFmode);
16333
16334   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16335 })
16336
16337 (define_expand "acossf2"
16338   [(set (match_dup 2)
16339         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16340    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16341    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16342    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16343    (parallel [(set (match_dup 7)
16344                    (unspec:XF [(match_dup 2) (match_dup 6)]
16345                               UNSPEC_FPATAN))
16346               (clobber (match_scratch:XF 8 ""))])
16347    (set (match_operand:SF 0 "register_operand" "")
16348         (float_truncate:SF (match_dup 7)))]
16349   "TARGET_USE_FANCY_MATH_387
16350    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16351    && flag_unsafe_math_optimizations"
16352 {
16353   int i;
16354
16355   for (i=2; i<8; i++)
16356     operands[i] = gen_reg_rtx (XFmode);
16357
16358   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16359 })
16360
16361 (define_expand "acosxf2"
16362   [(set (match_dup 2)
16363         (mult:XF (match_operand:XF 1 "register_operand" "")
16364                  (match_dup 1)))
16365    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16366    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16367    (parallel [(set (match_operand:XF 0 "register_operand" "")
16368                    (unspec:XF [(match_dup 1) (match_dup 5)]
16369                               UNSPEC_FPATAN))
16370               (clobber (match_scratch:XF 6 ""))])]
16371   "TARGET_USE_FANCY_MATH_387
16372    && flag_unsafe_math_optimizations"
16373 {
16374   int i;
16375
16376   for (i=2; i<6; i++)
16377     operands[i] = gen_reg_rtx (XFmode);
16378
16379   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16380 })
16381
16382 (define_insn "fyl2x_xf3"
16383   [(set (match_operand:XF 0 "register_operand" "=f")
16384         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16385                     (match_operand:XF 1 "register_operand" "u")]
16386                    UNSPEC_FYL2X))
16387    (clobber (match_scratch:XF 3 "=1"))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16390   "fyl2x"
16391   [(set_attr "type" "fpspc")
16392    (set_attr "mode" "XF")])
16393
16394 (define_expand "logsf2"
16395   [(set (match_dup 2)
16396         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16397    (parallel [(set (match_dup 4)
16398                    (unspec:XF [(match_dup 2)
16399                                (match_dup 3)] UNSPEC_FYL2X))
16400               (clobber (match_scratch:XF 5 ""))])
16401    (set (match_operand:SF 0 "register_operand" "")
16402         (float_truncate:SF (match_dup 4)))]
16403   "TARGET_USE_FANCY_MATH_387
16404    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16405    && flag_unsafe_math_optimizations"
16406 {
16407   rtx temp;
16408
16409   operands[2] = gen_reg_rtx (XFmode);
16410   operands[3] = gen_reg_rtx (XFmode);
16411   operands[4] = gen_reg_rtx (XFmode);
16412
16413   temp = standard_80387_constant_rtx (4); /* fldln2 */
16414   emit_move_insn (operands[3], temp);
16415 })
16416
16417 (define_expand "logdf2"
16418   [(set (match_dup 2)
16419         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16420    (parallel [(set (match_dup 4)
16421                    (unspec:XF [(match_dup 2)
16422                                (match_dup 3)] UNSPEC_FYL2X))
16423               (clobber (match_scratch:XF 5 ""))])
16424    (set (match_operand:DF 0 "register_operand" "")
16425         (float_truncate:DF (match_dup 4)))]
16426   "TARGET_USE_FANCY_MATH_387
16427    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16428    && flag_unsafe_math_optimizations"
16429 {
16430   rtx temp;
16431
16432   operands[2] = gen_reg_rtx (XFmode);
16433   operands[3] = gen_reg_rtx (XFmode);
16434   operands[4] = gen_reg_rtx (XFmode);
16435
16436   temp = standard_80387_constant_rtx (4); /* fldln2 */
16437   emit_move_insn (operands[3], temp);
16438 })
16439
16440 (define_expand "logxf2"
16441   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16442                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16443                                (match_dup 2)] UNSPEC_FYL2X))
16444               (clobber (match_scratch:XF 3 ""))])]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations"
16447 {
16448   rtx temp;
16449
16450   operands[2] = gen_reg_rtx (XFmode);
16451   temp = standard_80387_constant_rtx (4); /* fldln2 */
16452   emit_move_insn (operands[2], temp);
16453 })
16454
16455 (define_expand "log10sf2"
16456   [(set (match_dup 2)
16457         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16458    (parallel [(set (match_dup 4)
16459                    (unspec:XF [(match_dup 2)
16460                                (match_dup 3)] UNSPEC_FYL2X))
16461               (clobber (match_scratch:XF 5 ""))])
16462    (set (match_operand:SF 0 "register_operand" "")
16463         (float_truncate:SF (match_dup 4)))]
16464   "TARGET_USE_FANCY_MATH_387
16465    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466    && flag_unsafe_math_optimizations"
16467 {
16468   rtx temp;
16469
16470   operands[2] = gen_reg_rtx (XFmode);
16471   operands[3] = gen_reg_rtx (XFmode);
16472   operands[4] = gen_reg_rtx (XFmode);
16473
16474   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16475   emit_move_insn (operands[3], temp);
16476 })
16477
16478 (define_expand "log10df2"
16479   [(set (match_dup 2)
16480         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16481    (parallel [(set (match_dup 4)
16482                    (unspec:XF [(match_dup 2)
16483                                (match_dup 3)] UNSPEC_FYL2X))
16484               (clobber (match_scratch:XF 5 ""))])
16485    (set (match_operand:DF 0 "register_operand" "")
16486         (float_truncate:DF (match_dup 4)))]
16487   "TARGET_USE_FANCY_MATH_387
16488    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16489    && flag_unsafe_math_optimizations"
16490 {
16491   rtx temp;
16492
16493   operands[2] = gen_reg_rtx (XFmode);
16494   operands[3] = gen_reg_rtx (XFmode);
16495   operands[4] = gen_reg_rtx (XFmode);
16496
16497   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16498   emit_move_insn (operands[3], temp);
16499 })
16500
16501 (define_expand "log10xf2"
16502   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16503                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16504                                (match_dup 2)] UNSPEC_FYL2X))
16505               (clobber (match_scratch:XF 3 ""))])]
16506   "TARGET_USE_FANCY_MATH_387
16507    && flag_unsafe_math_optimizations"
16508 {
16509   rtx temp;
16510
16511   operands[2] = gen_reg_rtx (XFmode);
16512   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16513   emit_move_insn (operands[2], temp);
16514 })
16515
16516 (define_expand "log2sf2"
16517   [(set (match_dup 2)
16518         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16519    (parallel [(set (match_dup 4)
16520                    (unspec:XF [(match_dup 2)
16521                                (match_dup 3)] UNSPEC_FYL2X))
16522               (clobber (match_scratch:XF 5 ""))])
16523    (set (match_operand:SF 0 "register_operand" "")
16524         (float_truncate:SF (match_dup 4)))]
16525   "TARGET_USE_FANCY_MATH_387
16526    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16527    && flag_unsafe_math_optimizations"
16528 {
16529   operands[2] = gen_reg_rtx (XFmode);
16530   operands[3] = gen_reg_rtx (XFmode);
16531   operands[4] = gen_reg_rtx (XFmode);
16532
16533   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16534 })
16535
16536 (define_expand "log2df2"
16537   [(set (match_dup 2)
16538         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16539    (parallel [(set (match_dup 4)
16540                    (unspec:XF [(match_dup 2)
16541                                (match_dup 3)] UNSPEC_FYL2X))
16542               (clobber (match_scratch:XF 5 ""))])
16543    (set (match_operand:DF 0 "register_operand" "")
16544         (float_truncate:DF (match_dup 4)))]
16545   "TARGET_USE_FANCY_MATH_387
16546    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16547    && flag_unsafe_math_optimizations"
16548 {
16549   operands[2] = gen_reg_rtx (XFmode);
16550   operands[3] = gen_reg_rtx (XFmode);
16551   operands[4] = gen_reg_rtx (XFmode);
16552
16553   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16554 })
16555
16556 (define_expand "log2xf2"
16557   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16558                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16559                                (match_dup 2)] UNSPEC_FYL2X))
16560               (clobber (match_scratch:XF 3 ""))])]
16561   "TARGET_USE_FANCY_MATH_387
16562    && flag_unsafe_math_optimizations"
16563 {
16564   operands[2] = gen_reg_rtx (XFmode);
16565   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16566 })
16567
16568 (define_insn "fyl2xp1_xf3"
16569   [(set (match_operand:XF 0 "register_operand" "=f")
16570         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16571                     (match_operand:XF 1 "register_operand" "u")]
16572                    UNSPEC_FYL2XP1))
16573    (clobber (match_scratch:XF 3 "=1"))]
16574   "TARGET_USE_FANCY_MATH_387
16575    && flag_unsafe_math_optimizations"
16576   "fyl2xp1"
16577   [(set_attr "type" "fpspc")
16578    (set_attr "mode" "XF")])
16579
16580 (define_expand "log1psf2"
16581   [(use (match_operand:SF 0 "register_operand" ""))
16582    (use (match_operand:SF 1 "register_operand" ""))]
16583   "TARGET_USE_FANCY_MATH_387
16584    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16585    && flag_unsafe_math_optimizations"
16586 {
16587   rtx op0 = gen_reg_rtx (XFmode);
16588   rtx op1 = gen_reg_rtx (XFmode);
16589
16590   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16591   ix86_emit_i387_log1p (op0, op1);
16592   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16593   DONE;
16594 })
16595
16596 (define_expand "log1pdf2"
16597   [(use (match_operand:DF 0 "register_operand" ""))
16598    (use (match_operand:DF 1 "register_operand" ""))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16601    && flag_unsafe_math_optimizations"
16602 {
16603   rtx op0 = gen_reg_rtx (XFmode);
16604   rtx op1 = gen_reg_rtx (XFmode);
16605
16606   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16607   ix86_emit_i387_log1p (op0, op1);
16608   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16609   DONE;
16610 })
16611
16612 (define_expand "log1pxf2"
16613   [(use (match_operand:XF 0 "register_operand" ""))
16614    (use (match_operand:XF 1 "register_operand" ""))]
16615   "TARGET_USE_FANCY_MATH_387
16616    && flag_unsafe_math_optimizations"
16617 {
16618   ix86_emit_i387_log1p (operands[0], operands[1]);
16619   DONE;
16620 })
16621
16622 (define_insn "*fxtractxf3"
16623   [(set (match_operand:XF 0 "register_operand" "=f")
16624         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16625                    UNSPEC_XTRACT_FRACT))
16626    (set (match_operand:XF 1 "register_operand" "=u")
16627         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16628   "TARGET_USE_FANCY_MATH_387
16629    && flag_unsafe_math_optimizations"
16630   "fxtract"
16631   [(set_attr "type" "fpspc")
16632    (set_attr "mode" "XF")])
16633
16634 (define_expand "logbsf2"
16635   [(set (match_dup 2)
16636         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16637    (parallel [(set (match_dup 3)
16638                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16639               (set (match_dup 4)
16640                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16641    (set (match_operand:SF 0 "register_operand" "")
16642         (float_truncate:SF (match_dup 4)))]
16643   "TARGET_USE_FANCY_MATH_387
16644    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16645    && flag_unsafe_math_optimizations"
16646 {
16647   operands[2] = gen_reg_rtx (XFmode);
16648   operands[3] = gen_reg_rtx (XFmode);
16649   operands[4] = gen_reg_rtx (XFmode);
16650 })
16651
16652 (define_expand "logbdf2"
16653   [(set (match_dup 2)
16654         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16655    (parallel [(set (match_dup 3)
16656                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16657               (set (match_dup 4)
16658                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16659    (set (match_operand:DF 0 "register_operand" "")
16660         (float_truncate:DF (match_dup 4)))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16663    && flag_unsafe_math_optimizations"
16664 {
16665   operands[2] = gen_reg_rtx (XFmode);
16666   operands[3] = gen_reg_rtx (XFmode);
16667   operands[4] = gen_reg_rtx (XFmode);
16668 })
16669
16670 (define_expand "logbxf2"
16671   [(parallel [(set (match_dup 2)
16672                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16673                               UNSPEC_XTRACT_FRACT))
16674               (set (match_operand:XF 0 "register_operand" "")
16675                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16676   "TARGET_USE_FANCY_MATH_387
16677    && flag_unsafe_math_optimizations"
16678 {
16679   operands[2] = gen_reg_rtx (XFmode);
16680 })
16681
16682 (define_expand "ilogbsi2"
16683   [(parallel [(set (match_dup 2)
16684                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685                               UNSPEC_XTRACT_FRACT))
16686               (set (match_operand:XF 3 "register_operand" "")
16687                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16688    (parallel [(set (match_operand:SI 0 "register_operand" "")
16689                    (fix:SI (match_dup 3)))
16690               (clobber (reg:CC FLAGS_REG))])]
16691   "TARGET_USE_FANCY_MATH_387
16692    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16693    && flag_unsafe_math_optimizations"
16694 {
16695   operands[2] = gen_reg_rtx (XFmode);
16696   operands[3] = gen_reg_rtx (XFmode);
16697 })
16698
16699 (define_insn "*f2xm1xf2"
16700   [(set (match_operand:XF 0 "register_operand" "=f")
16701         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16702          UNSPEC_F2XM1))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && flag_unsafe_math_optimizations"
16705   "f2xm1"
16706   [(set_attr "type" "fpspc")
16707    (set_attr "mode" "XF")])
16708
16709 (define_insn "*fscalexf4"
16710   [(set (match_operand:XF 0 "register_operand" "=f")
16711         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16712                     (match_operand:XF 3 "register_operand" "1")]
16713                    UNSPEC_FSCALE_FRACT))
16714    (set (match_operand:XF 1 "register_operand" "=u")
16715         (unspec:XF [(match_dup 2) (match_dup 3)]
16716                    UNSPEC_FSCALE_EXP))]
16717   "TARGET_USE_FANCY_MATH_387
16718    && flag_unsafe_math_optimizations"
16719   "fscale"
16720   [(set_attr "type" "fpspc")
16721    (set_attr "mode" "XF")])
16722
16723 (define_expand "expsf2"
16724   [(set (match_dup 2)
16725         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16726    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16727    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16728    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16729    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16730    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16731    (parallel [(set (match_dup 10)
16732                    (unspec:XF [(match_dup 9) (match_dup 5)]
16733                               UNSPEC_FSCALE_FRACT))
16734               (set (match_dup 11)
16735                    (unspec:XF [(match_dup 9) (match_dup 5)]
16736                               UNSPEC_FSCALE_EXP))])
16737    (set (match_operand:SF 0 "register_operand" "")
16738         (float_truncate:SF (match_dup 10)))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16741    && flag_unsafe_math_optimizations"
16742 {
16743   rtx temp;
16744   int i;
16745
16746   for (i=2; i<12; i++)
16747     operands[i] = gen_reg_rtx (XFmode);
16748   temp = standard_80387_constant_rtx (5); /* fldl2e */
16749   emit_move_insn (operands[3], temp);
16750   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16751 })
16752
16753 (define_expand "expdf2"
16754   [(set (match_dup 2)
16755         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16756    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16757    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16758    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16759    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16760    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16761    (parallel [(set (match_dup 10)
16762                    (unspec:XF [(match_dup 9) (match_dup 5)]
16763                               UNSPEC_FSCALE_FRACT))
16764               (set (match_dup 11)
16765                    (unspec:XF [(match_dup 9) (match_dup 5)]
16766                               UNSPEC_FSCALE_EXP))])
16767    (set (match_operand:DF 0 "register_operand" "")
16768         (float_truncate:DF (match_dup 10)))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16771    && flag_unsafe_math_optimizations"
16772 {
16773   rtx temp;
16774   int i;
16775
16776   for (i=2; i<12; i++)
16777     operands[i] = gen_reg_rtx (XFmode);
16778   temp = standard_80387_constant_rtx (5); /* fldl2e */
16779   emit_move_insn (operands[3], temp);
16780   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16781 })
16782
16783 (define_expand "expxf2"
16784   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16785                                (match_dup 2)))
16786    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16787    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16788    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16789    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16790    (parallel [(set (match_operand:XF 0 "register_operand" "")
16791                    (unspec:XF [(match_dup 8) (match_dup 4)]
16792                               UNSPEC_FSCALE_FRACT))
16793               (set (match_dup 9)
16794                    (unspec:XF [(match_dup 8) (match_dup 4)]
16795                               UNSPEC_FSCALE_EXP))])]
16796   "TARGET_USE_FANCY_MATH_387
16797    && flag_unsafe_math_optimizations"
16798 {
16799   rtx temp;
16800   int i;
16801
16802   for (i=2; i<10; i++)
16803     operands[i] = gen_reg_rtx (XFmode);
16804   temp = standard_80387_constant_rtx (5); /* fldl2e */
16805   emit_move_insn (operands[2], temp);
16806   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16807 })
16808
16809 (define_expand "exp10sf2"
16810   [(set (match_dup 2)
16811         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16812    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16813    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16814    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16815    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16816    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16817    (parallel [(set (match_dup 10)
16818                    (unspec:XF [(match_dup 9) (match_dup 5)]
16819                               UNSPEC_FSCALE_FRACT))
16820               (set (match_dup 11)
16821                    (unspec:XF [(match_dup 9) (match_dup 5)]
16822                               UNSPEC_FSCALE_EXP))])
16823    (set (match_operand:SF 0 "register_operand" "")
16824         (float_truncate:SF (match_dup 10)))]
16825   "TARGET_USE_FANCY_MATH_387
16826    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16827    && flag_unsafe_math_optimizations"
16828 {
16829   rtx temp;
16830   int i;
16831
16832   for (i=2; i<12; i++)
16833     operands[i] = gen_reg_rtx (XFmode);
16834   temp = standard_80387_constant_rtx (6); /* fldl2t */
16835   emit_move_insn (operands[3], temp);
16836   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16837 })
16838
16839 (define_expand "exp10df2"
16840   [(set (match_dup 2)
16841         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16842    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16843    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16844    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16845    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16846    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16847    (parallel [(set (match_dup 10)
16848                    (unspec:XF [(match_dup 9) (match_dup 5)]
16849                               UNSPEC_FSCALE_FRACT))
16850               (set (match_dup 11)
16851                    (unspec:XF [(match_dup 9) (match_dup 5)]
16852                               UNSPEC_FSCALE_EXP))])
16853    (set (match_operand:DF 0 "register_operand" "")
16854         (float_truncate:DF (match_dup 10)))]
16855   "TARGET_USE_FANCY_MATH_387
16856    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16857    && flag_unsafe_math_optimizations"
16858 {
16859   rtx temp;
16860   int i;
16861
16862   for (i=2; i<12; i++)
16863     operands[i] = gen_reg_rtx (XFmode);
16864   temp = standard_80387_constant_rtx (6); /* fldl2t */
16865   emit_move_insn (operands[3], temp);
16866   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16867 })
16868
16869 (define_expand "exp10xf2"
16870   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16871                                (match_dup 2)))
16872    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16873    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16874    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16875    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16876    (parallel [(set (match_operand:XF 0 "register_operand" "")
16877                    (unspec:XF [(match_dup 8) (match_dup 4)]
16878                               UNSPEC_FSCALE_FRACT))
16879               (set (match_dup 9)
16880                    (unspec:XF [(match_dup 8) (match_dup 4)]
16881                               UNSPEC_FSCALE_EXP))])]
16882   "TARGET_USE_FANCY_MATH_387
16883    && flag_unsafe_math_optimizations"
16884 {
16885   rtx temp;
16886   int i;
16887
16888   for (i=2; i<10; i++)
16889     operands[i] = gen_reg_rtx (XFmode);
16890   temp = standard_80387_constant_rtx (6); /* fldl2t */
16891   emit_move_insn (operands[2], temp);
16892   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16893 })
16894
16895 (define_expand "exp2sf2"
16896   [(set (match_dup 2)
16897         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16898    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16899    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16900    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16901    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16902    (parallel [(set (match_dup 8)
16903                    (unspec:XF [(match_dup 7) (match_dup 3)]
16904                               UNSPEC_FSCALE_FRACT))
16905               (set (match_dup 9)
16906                    (unspec:XF [(match_dup 7) (match_dup 3)]
16907                               UNSPEC_FSCALE_EXP))])
16908    (set (match_operand:SF 0 "register_operand" "")
16909         (float_truncate:SF (match_dup 8)))]
16910   "TARGET_USE_FANCY_MATH_387
16911    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16912    && flag_unsafe_math_optimizations"
16913 {
16914   int i;
16915
16916   for (i=2; i<10; i++)
16917     operands[i] = gen_reg_rtx (XFmode);
16918   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16919 })
16920
16921 (define_expand "exp2df2"
16922   [(set (match_dup 2)
16923         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16924    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16925    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16926    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16927    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16928    (parallel [(set (match_dup 8)
16929                    (unspec:XF [(match_dup 7) (match_dup 3)]
16930                               UNSPEC_FSCALE_FRACT))
16931               (set (match_dup 9)
16932                    (unspec:XF [(match_dup 7) (match_dup 3)]
16933                               UNSPEC_FSCALE_EXP))])
16934    (set (match_operand:DF 0 "register_operand" "")
16935         (float_truncate:DF (match_dup 8)))]
16936   "TARGET_USE_FANCY_MATH_387
16937    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16938    && flag_unsafe_math_optimizations"
16939 {
16940   int i;
16941
16942   for (i=2; i<10; i++)
16943     operands[i] = gen_reg_rtx (XFmode);
16944   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16945 })
16946
16947 (define_expand "exp2xf2"
16948   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16949    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16950    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16951    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16952    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16953    (parallel [(set (match_operand:XF 0 "register_operand" "")
16954                    (unspec:XF [(match_dup 7) (match_dup 3)]
16955                               UNSPEC_FSCALE_FRACT))
16956               (set (match_dup 8)
16957                    (unspec:XF [(match_dup 7) (match_dup 3)]
16958                               UNSPEC_FSCALE_EXP))])]
16959   "TARGET_USE_FANCY_MATH_387
16960    && flag_unsafe_math_optimizations"
16961 {
16962   int i;
16963
16964   for (i=2; i<9; i++)
16965     operands[i] = gen_reg_rtx (XFmode);
16966   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16967 })
16968
16969 (define_expand "expm1df2"
16970   [(set (match_dup 2)
16971         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16972    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16973    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16974    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16975    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16976    (parallel [(set (match_dup 8)
16977                    (unspec:XF [(match_dup 7) (match_dup 5)]
16978                               UNSPEC_FSCALE_FRACT))
16979                    (set (match_dup 9)
16980                    (unspec:XF [(match_dup 7) (match_dup 5)]
16981                               UNSPEC_FSCALE_EXP))])
16982    (parallel [(set (match_dup 11)
16983                    (unspec:XF [(match_dup 10) (match_dup 9)]
16984                               UNSPEC_FSCALE_FRACT))
16985               (set (match_dup 12)
16986                    (unspec:XF [(match_dup 10) (match_dup 9)]
16987                               UNSPEC_FSCALE_EXP))])
16988    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16989    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16990    (set (match_operand:DF 0 "register_operand" "")
16991         (float_truncate:DF (match_dup 14)))]
16992   "TARGET_USE_FANCY_MATH_387
16993    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16994    && flag_unsafe_math_optimizations"
16995 {
16996   rtx temp;
16997   int i;
16998
16999   for (i=2; i<15; i++)
17000     operands[i] = gen_reg_rtx (XFmode);
17001   temp = standard_80387_constant_rtx (5); /* fldl2e */
17002   emit_move_insn (operands[3], temp);
17003   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17004 })
17005
17006 (define_expand "expm1sf2"
17007   [(set (match_dup 2)
17008         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17009    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17010    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17011    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17012    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17013    (parallel [(set (match_dup 8)
17014                    (unspec:XF [(match_dup 7) (match_dup 5)]
17015                               UNSPEC_FSCALE_FRACT))
17016                    (set (match_dup 9)
17017                    (unspec:XF [(match_dup 7) (match_dup 5)]
17018                               UNSPEC_FSCALE_EXP))])
17019    (parallel [(set (match_dup 11)
17020                    (unspec:XF [(match_dup 10) (match_dup 9)]
17021                               UNSPEC_FSCALE_FRACT))
17022               (set (match_dup 12)
17023                    (unspec:XF [(match_dup 10) (match_dup 9)]
17024                               UNSPEC_FSCALE_EXP))])
17025    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17026    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17027    (set (match_operand:SF 0 "register_operand" "")
17028         (float_truncate:SF (match_dup 14)))]
17029   "TARGET_USE_FANCY_MATH_387
17030    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17031    && flag_unsafe_math_optimizations"
17032 {
17033   rtx temp;
17034   int i;
17035
17036   for (i=2; i<15; i++)
17037     operands[i] = gen_reg_rtx (XFmode);
17038   temp = standard_80387_constant_rtx (5); /* fldl2e */
17039   emit_move_insn (operands[3], temp);
17040   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17041 })
17042
17043 (define_expand "expm1xf2"
17044   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17045                                (match_dup 2)))
17046    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17047    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17048    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17049    (parallel [(set (match_dup 7)
17050                    (unspec:XF [(match_dup 6) (match_dup 4)]
17051                               UNSPEC_FSCALE_FRACT))
17052                    (set (match_dup 8)
17053                    (unspec:XF [(match_dup 6) (match_dup 4)]
17054                               UNSPEC_FSCALE_EXP))])
17055    (parallel [(set (match_dup 10)
17056                    (unspec:XF [(match_dup 9) (match_dup 8)]
17057                               UNSPEC_FSCALE_FRACT))
17058               (set (match_dup 11)
17059                    (unspec:XF [(match_dup 9) (match_dup 8)]
17060                               UNSPEC_FSCALE_EXP))])
17061    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17062    (set (match_operand:XF 0 "register_operand" "")
17063         (plus:XF (match_dup 12) (match_dup 7)))]
17064   "TARGET_USE_FANCY_MATH_387
17065    && flag_unsafe_math_optimizations"
17066 {
17067   rtx temp;
17068   int i;
17069
17070   for (i=2; i<13; i++)
17071     operands[i] = gen_reg_rtx (XFmode);
17072   temp = standard_80387_constant_rtx (5); /* fldl2e */
17073   emit_move_insn (operands[2], temp);
17074   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17075 })
17076
17077 (define_expand "ldexpdf3"
17078   [(set (match_dup 3)
17079         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17080    (set (match_dup 4)
17081         (float:XF (match_operand:SI 2 "register_operand" "")))
17082    (parallel [(set (match_dup 5)
17083                    (unspec:XF [(match_dup 3) (match_dup 4)]
17084                               UNSPEC_FSCALE_FRACT))
17085               (set (match_dup 6)
17086                    (unspec:XF [(match_dup 3) (match_dup 4)]
17087                               UNSPEC_FSCALE_EXP))])
17088    (set (match_operand:DF 0 "register_operand" "")
17089         (float_truncate:DF (match_dup 5)))]
17090   "TARGET_USE_FANCY_MATH_387
17091    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17092    && flag_unsafe_math_optimizations"
17093 {
17094   int i;
17095
17096   for (i=3; i<7; i++)
17097     operands[i] = gen_reg_rtx (XFmode);
17098 })
17099
17100 (define_expand "ldexpsf3"
17101   [(set (match_dup 3)
17102         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17103    (set (match_dup 4)
17104         (float:XF (match_operand:SI 2 "register_operand" "")))
17105    (parallel [(set (match_dup 5)
17106                    (unspec:XF [(match_dup 3) (match_dup 4)]
17107                               UNSPEC_FSCALE_FRACT))
17108               (set (match_dup 6)
17109                    (unspec:XF [(match_dup 3) (match_dup 4)]
17110                               UNSPEC_FSCALE_EXP))])
17111    (set (match_operand:SF 0 "register_operand" "")
17112         (float_truncate:SF (match_dup 5)))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17115    && flag_unsafe_math_optimizations"
17116 {
17117   int i;
17118
17119   for (i=3; i<7; i++)
17120     operands[i] = gen_reg_rtx (XFmode);
17121 })
17122
17123 (define_expand "ldexpxf3"
17124   [(set (match_dup 3)
17125         (float:XF (match_operand:SI 2 "register_operand" "")))
17126    (parallel [(set (match_operand:XF 0 " register_operand" "")
17127                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17128                                (match_dup 3)]
17129                               UNSPEC_FSCALE_FRACT))
17130               (set (match_dup 4)
17131                    (unspec:XF [(match_dup 1) (match_dup 3)]
17132                               UNSPEC_FSCALE_EXP))])]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135 {
17136   int i;
17137
17138   for (i=3; i<5; i++)
17139     operands[i] = gen_reg_rtx (XFmode);
17140 })
17141 \f
17142
17143 (define_insn "frndintxf2"
17144   [(set (match_operand:XF 0 "register_operand" "=f")
17145         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17146          UNSPEC_FRNDINT))]
17147   "TARGET_USE_FANCY_MATH_387
17148    && flag_unsafe_math_optimizations"
17149   "frndint"
17150   [(set_attr "type" "fpspc")
17151    (set_attr "mode" "XF")])
17152
17153 (define_expand "rintdf2"
17154   [(use (match_operand:DF 0 "register_operand" ""))
17155    (use (match_operand:DF 1 "register_operand" ""))]
17156   "TARGET_USE_FANCY_MATH_387
17157    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17158    && flag_unsafe_math_optimizations"
17159 {
17160   rtx op0 = gen_reg_rtx (XFmode);
17161   rtx op1 = gen_reg_rtx (XFmode);
17162
17163   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17164   emit_insn (gen_frndintxf2 (op0, op1));
17165
17166   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17167   DONE;
17168 })
17169
17170 (define_expand "rintsf2"
17171   [(use (match_operand:SF 0 "register_operand" ""))
17172    (use (match_operand:SF 1 "register_operand" ""))]
17173   "TARGET_USE_FANCY_MATH_387
17174    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17175    && flag_unsafe_math_optimizations"
17176 {
17177   rtx op0 = gen_reg_rtx (XFmode);
17178   rtx op1 = gen_reg_rtx (XFmode);
17179
17180   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17181   emit_insn (gen_frndintxf2 (op0, op1));
17182
17183   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17184   DONE;
17185 })
17186
17187 (define_expand "rintxf2"
17188   [(use (match_operand:XF 0 "register_operand" ""))
17189    (use (match_operand:XF 1 "register_operand" ""))]
17190   "TARGET_USE_FANCY_MATH_387
17191    && flag_unsafe_math_optimizations"
17192 {
17193   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17194   DONE;
17195 })
17196
17197 (define_insn_and_split "*fistdi2_1"
17198   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17199         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17200          UNSPEC_FIST))]
17201   "TARGET_USE_FANCY_MATH_387
17202    && flag_unsafe_math_optimizations
17203    && !(reload_completed || reload_in_progress)"
17204   "#"
17205   "&& 1"
17206   [(const_int 0)]
17207 {
17208   if (memory_operand (operands[0], VOIDmode))
17209     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17210   else
17211     {
17212       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17213       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17214                                          operands[2]));
17215     }
17216   DONE;
17217 }
17218   [(set_attr "type" "fpspc")
17219    (set_attr "mode" "DI")])
17220
17221 (define_insn "fistdi2"
17222   [(set (match_operand:DI 0 "memory_operand" "=m")
17223         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17224          UNSPEC_FIST))
17225    (clobber (match_scratch:XF 2 "=&1f"))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && flag_unsafe_math_optimizations"
17228   "* return output_fix_trunc (insn, operands, 0);"
17229   [(set_attr "type" "fpspc")
17230    (set_attr "mode" "DI")])
17231
17232 (define_insn "fistdi2_with_temp"
17233   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17234         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17235          UNSPEC_FIST))
17236    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17237    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17238   "TARGET_USE_FANCY_MATH_387
17239    && flag_unsafe_math_optimizations"
17240   "#"
17241   [(set_attr "type" "fpspc")
17242    (set_attr "mode" "DI")])
17243
17244 (define_split 
17245   [(set (match_operand:DI 0 "register_operand" "")
17246         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17247          UNSPEC_FIST))
17248    (clobber (match_operand:DI 2 "memory_operand" ""))
17249    (clobber (match_scratch 3 ""))]
17250   "reload_completed"
17251   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17252               (clobber (match_dup 3))])
17253    (set (match_dup 0) (match_dup 2))]
17254   "")
17255
17256 (define_split 
17257   [(set (match_operand:DI 0 "memory_operand" "")
17258         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17259          UNSPEC_FIST))
17260    (clobber (match_operand:DI 2 "memory_operand" ""))
17261    (clobber (match_scratch 3 ""))]
17262   "reload_completed"
17263   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264               (clobber (match_dup 3))])]
17265   "")
17266
17267 (define_insn_and_split "*fist<mode>2_1"
17268   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17269         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17270          UNSPEC_FIST))]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations
17273    && !(reload_completed || reload_in_progress)"
17274   "#"
17275   "&& 1"
17276   [(const_int 0)]
17277 {
17278   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17279   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17280                                         operands[2]));
17281   DONE;
17282 }
17283   [(set_attr "type" "fpspc")
17284    (set_attr "mode" "<MODE>")])
17285
17286 (define_insn "fist<mode>2"
17287   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17288         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17289          UNSPEC_FIST))]
17290   "TARGET_USE_FANCY_MATH_387
17291    && flag_unsafe_math_optimizations"
17292   "* return output_fix_trunc (insn, operands, 0);"
17293   [(set_attr "type" "fpspc")
17294    (set_attr "mode" "<MODE>")])
17295
17296 (define_insn "fist<mode>2_with_temp"
17297   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17298         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17299          UNSPEC_FIST))
17300    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17301   "TARGET_USE_FANCY_MATH_387
17302    && flag_unsafe_math_optimizations"
17303   "#"
17304   [(set_attr "type" "fpspc")
17305    (set_attr "mode" "<MODE>")])
17306
17307 (define_split 
17308   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17310          UNSPEC_FIST))
17311    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17312   "reload_completed"
17313   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17314                        UNSPEC_FIST))
17315    (set (match_dup 0) (match_dup 2))]
17316   "")
17317
17318 (define_split 
17319   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17320         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17321          UNSPEC_FIST))
17322    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17323   "reload_completed"
17324   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17325                        UNSPEC_FIST))]
17326   "")
17327
17328 (define_expand "lrint<mode>2"
17329   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17330         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17331          UNSPEC_FIST))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334    && flag_unsafe_math_optimizations"
17335   "")
17336
17337 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17338 (define_insn_and_split "frndintxf2_floor"
17339   [(set (match_operand:XF 0 "register_operand" "=f")
17340         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17341          UNSPEC_FRNDINT_FLOOR))
17342    (clobber (reg:CC FLAGS_REG))]
17343   "TARGET_USE_FANCY_MATH_387
17344    && flag_unsafe_math_optimizations
17345    && !(reload_completed || reload_in_progress)"
17346   "#"
17347   "&& 1"
17348   [(const_int 0)]
17349 {
17350   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17351
17352   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17353   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17354
17355   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17356                                         operands[2], operands[3]));
17357   DONE;
17358 }
17359   [(set_attr "type" "frndint")
17360    (set_attr "i387_cw" "floor")
17361    (set_attr "mode" "XF")])
17362
17363 (define_insn "frndintxf2_floor_i387"
17364   [(set (match_operand:XF 0 "register_operand" "=f")
17365         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17366          UNSPEC_FRNDINT_FLOOR))
17367    (use (match_operand:HI 2 "memory_operand" "m"))
17368    (use (match_operand:HI 3 "memory_operand" "m"))]
17369   "TARGET_USE_FANCY_MATH_387
17370    && flag_unsafe_math_optimizations"
17371   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17372   [(set_attr "type" "frndint")
17373    (set_attr "i387_cw" "floor")
17374    (set_attr "mode" "XF")])
17375
17376 (define_expand "floorxf2"
17377   [(use (match_operand:XF 0 "register_operand" ""))
17378    (use (match_operand:XF 1 "register_operand" ""))]
17379   "TARGET_USE_FANCY_MATH_387
17380    && flag_unsafe_math_optimizations"
17381 {
17382   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17383   DONE;
17384 })
17385
17386 (define_expand "floordf2"
17387   [(use (match_operand:DF 0 "register_operand" ""))
17388    (use (match_operand:DF 1 "register_operand" ""))]
17389   "TARGET_USE_FANCY_MATH_387
17390    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17391    && flag_unsafe_math_optimizations"
17392 {
17393   rtx op0 = gen_reg_rtx (XFmode);
17394   rtx op1 = gen_reg_rtx (XFmode);
17395
17396   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17397   emit_insn (gen_frndintxf2_floor (op0, op1));
17398
17399   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17400   DONE;
17401 })
17402
17403 (define_expand "floorsf2"
17404   [(use (match_operand:SF 0 "register_operand" ""))
17405    (use (match_operand:SF 1 "register_operand" ""))]
17406   "TARGET_USE_FANCY_MATH_387
17407    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17408    && flag_unsafe_math_optimizations"
17409 {
17410   rtx op0 = gen_reg_rtx (XFmode);
17411   rtx op1 = gen_reg_rtx (XFmode);
17412
17413   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17414   emit_insn (gen_frndintxf2_floor (op0, op1));
17415
17416   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17417   DONE;
17418 })
17419
17420 (define_insn_and_split "*fist<mode>2_floor_1"
17421   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17422         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17423          UNSPEC_FIST_FLOOR))
17424    (clobber (reg:CC FLAGS_REG))]
17425   "TARGET_USE_FANCY_MATH_387
17426    && flag_unsafe_math_optimizations
17427    && !(reload_completed || reload_in_progress)"
17428   "#"
17429   "&& 1"
17430   [(const_int 0)]
17431 {
17432   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17433
17434   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17435   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17436   if (memory_operand (operands[0], VOIDmode))
17437     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17438                                       operands[2], operands[3]));
17439   else
17440     {
17441       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17442       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17443                                                   operands[2], operands[3],
17444                                                   operands[4]));
17445     }
17446   DONE;
17447 }
17448   [(set_attr "type" "fistp")
17449    (set_attr "i387_cw" "floor")
17450    (set_attr "mode" "<MODE>")])
17451
17452 (define_insn "fistdi2_floor"
17453   [(set (match_operand:DI 0 "memory_operand" "=m")
17454         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17455          UNSPEC_FIST_FLOOR))
17456    (use (match_operand:HI 2 "memory_operand" "m"))
17457    (use (match_operand:HI 3 "memory_operand" "m"))
17458    (clobber (match_scratch:XF 4 "=&1f"))]
17459   "TARGET_USE_FANCY_MATH_387
17460    && flag_unsafe_math_optimizations"
17461   "* return output_fix_trunc (insn, operands, 0);"
17462   [(set_attr "type" "fistp")
17463    (set_attr "i387_cw" "floor")
17464    (set_attr "mode" "DI")])
17465
17466 (define_insn "fistdi2_floor_with_temp"
17467   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17468         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17469          UNSPEC_FIST_FLOOR))
17470    (use (match_operand:HI 2 "memory_operand" "m,m"))
17471    (use (match_operand:HI 3 "memory_operand" "m,m"))
17472    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17473    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17474   "TARGET_USE_FANCY_MATH_387
17475    && flag_unsafe_math_optimizations"
17476   "#"
17477   [(set_attr "type" "fistp")
17478    (set_attr "i387_cw" "floor")
17479    (set_attr "mode" "DI")])
17480
17481 (define_split 
17482   [(set (match_operand:DI 0 "register_operand" "")
17483         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17484          UNSPEC_FIST_FLOOR))
17485    (use (match_operand:HI 2 "memory_operand" ""))
17486    (use (match_operand:HI 3 "memory_operand" ""))
17487    (clobber (match_operand:DI 4 "memory_operand" ""))
17488    (clobber (match_scratch 5 ""))]
17489   "reload_completed"
17490   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17491               (use (match_dup 2))
17492               (use (match_dup 3))
17493               (clobber (match_dup 5))])
17494    (set (match_dup 0) (match_dup 4))]
17495   "")
17496
17497 (define_split 
17498   [(set (match_operand:DI 0 "memory_operand" "")
17499         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17500          UNSPEC_FIST_FLOOR))
17501    (use (match_operand:HI 2 "memory_operand" ""))
17502    (use (match_operand:HI 3 "memory_operand" ""))
17503    (clobber (match_operand:DI 4 "memory_operand" ""))
17504    (clobber (match_scratch 5 ""))]
17505   "reload_completed"
17506   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17507               (use (match_dup 2))
17508               (use (match_dup 3))
17509               (clobber (match_dup 5))])]
17510   "")
17511
17512 (define_insn "fist<mode>2_floor"
17513   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17514         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17515          UNSPEC_FIST_FLOOR))
17516    (use (match_operand:HI 2 "memory_operand" "m"))
17517    (use (match_operand:HI 3 "memory_operand" "m"))]
17518   "TARGET_USE_FANCY_MATH_387
17519    && flag_unsafe_math_optimizations"
17520   "* return output_fix_trunc (insn, operands, 0);"
17521   [(set_attr "type" "fistp")
17522    (set_attr "i387_cw" "floor")
17523    (set_attr "mode" "<MODE>")])
17524
17525 (define_insn "fist<mode>2_floor_with_temp"
17526   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17527         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17528          UNSPEC_FIST_FLOOR))
17529    (use (match_operand:HI 2 "memory_operand" "m,m"))
17530    (use (match_operand:HI 3 "memory_operand" "m,m"))
17531    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17532   "TARGET_USE_FANCY_MATH_387
17533    && flag_unsafe_math_optimizations"
17534   "#"
17535   [(set_attr "type" "fistp")
17536    (set_attr "i387_cw" "floor")
17537    (set_attr "mode" "<MODE>")])
17538
17539 (define_split 
17540   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17541         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17542          UNSPEC_FIST_FLOOR))
17543    (use (match_operand:HI 2 "memory_operand" ""))
17544    (use (match_operand:HI 3 "memory_operand" ""))
17545    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17546   "reload_completed"
17547   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17548                                   UNSPEC_FIST_FLOOR))
17549               (use (match_dup 2))
17550               (use (match_dup 3))])
17551    (set (match_dup 0) (match_dup 4))]
17552   "")
17553
17554 (define_split 
17555   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17556         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17557          UNSPEC_FIST_FLOOR))
17558    (use (match_operand:HI 2 "memory_operand" ""))
17559    (use (match_operand:HI 3 "memory_operand" ""))
17560    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17561   "reload_completed"
17562   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17563                                   UNSPEC_FIST_FLOOR))
17564               (use (match_dup 2))
17565               (use (match_dup 3))])]
17566   "")
17567
17568 (define_expand "lfloor<mode>2"
17569   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17570                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17571                     UNSPEC_FIST_FLOOR))
17572               (clobber (reg:CC FLAGS_REG))])]
17573   "TARGET_USE_FANCY_MATH_387
17574    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575    && flag_unsafe_math_optimizations"
17576   "")
17577
17578 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17579 (define_insn_and_split "frndintxf2_ceil"
17580   [(set (match_operand:XF 0 "register_operand" "=f")
17581         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17582          UNSPEC_FRNDINT_CEIL))
17583    (clobber (reg:CC FLAGS_REG))]
17584   "TARGET_USE_FANCY_MATH_387
17585    && flag_unsafe_math_optimizations
17586    && !(reload_completed || reload_in_progress)"
17587   "#"
17588   "&& 1"
17589   [(const_int 0)]
17590 {
17591   ix86_optimize_mode_switching[I387_CEIL] = 1;
17592
17593   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17594   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17595
17596   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17597                                        operands[2], operands[3]));
17598   DONE;
17599 }
17600   [(set_attr "type" "frndint")
17601    (set_attr "i387_cw" "ceil")
17602    (set_attr "mode" "XF")])
17603
17604 (define_insn "frndintxf2_ceil_i387"
17605   [(set (match_operand:XF 0 "register_operand" "=f")
17606         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607          UNSPEC_FRNDINT_CEIL))
17608    (use (match_operand:HI 2 "memory_operand" "m"))
17609    (use (match_operand:HI 3 "memory_operand" "m"))]
17610   "TARGET_USE_FANCY_MATH_387
17611    && flag_unsafe_math_optimizations"
17612   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17613   [(set_attr "type" "frndint")
17614    (set_attr "i387_cw" "ceil")
17615    (set_attr "mode" "XF")])
17616
17617 (define_expand "ceilxf2"
17618   [(use (match_operand:XF 0 "register_operand" ""))
17619    (use (match_operand:XF 1 "register_operand" ""))]
17620   "TARGET_USE_FANCY_MATH_387
17621    && flag_unsafe_math_optimizations"
17622 {
17623   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17624   DONE;
17625 })
17626
17627 (define_expand "ceildf2"
17628   [(use (match_operand:DF 0 "register_operand" ""))
17629    (use (match_operand:DF 1 "register_operand" ""))]
17630   "TARGET_USE_FANCY_MATH_387
17631    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17632    && flag_unsafe_math_optimizations"
17633 {
17634   rtx op0 = gen_reg_rtx (XFmode);
17635   rtx op1 = gen_reg_rtx (XFmode);
17636
17637   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17638   emit_insn (gen_frndintxf2_ceil (op0, op1));
17639
17640   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17641   DONE;
17642 })
17643
17644 (define_expand "ceilsf2"
17645   [(use (match_operand:SF 0 "register_operand" ""))
17646    (use (match_operand:SF 1 "register_operand" ""))]
17647   "TARGET_USE_FANCY_MATH_387
17648    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17649    && flag_unsafe_math_optimizations"
17650 {
17651   rtx op0 = gen_reg_rtx (XFmode);
17652   rtx op1 = gen_reg_rtx (XFmode);
17653
17654   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17655   emit_insn (gen_frndintxf2_ceil (op0, op1));
17656
17657   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17658   DONE;
17659 })
17660
17661 (define_insn_and_split "*fist<mode>2_ceil_1"
17662   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17663         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17664          UNSPEC_FIST_CEIL))
17665    (clobber (reg:CC FLAGS_REG))]
17666   "TARGET_USE_FANCY_MATH_387
17667    && flag_unsafe_math_optimizations
17668    && !(reload_completed || reload_in_progress)"
17669   "#"
17670   "&& 1"
17671   [(const_int 0)]
17672 {
17673   ix86_optimize_mode_switching[I387_CEIL] = 1;
17674
17675   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17676   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17677   if (memory_operand (operands[0], VOIDmode))
17678     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17679                                      operands[2], operands[3]));
17680   else
17681     {
17682       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17683       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17684                                                  operands[2], operands[3],
17685                                                  operands[4]));
17686     }
17687   DONE;
17688 }
17689   [(set_attr "type" "fistp")
17690    (set_attr "i387_cw" "ceil")
17691    (set_attr "mode" "<MODE>")])
17692
17693 (define_insn "fistdi2_ceil"
17694   [(set (match_operand:DI 0 "memory_operand" "=m")
17695         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17696          UNSPEC_FIST_CEIL))
17697    (use (match_operand:HI 2 "memory_operand" "m"))
17698    (use (match_operand:HI 3 "memory_operand" "m"))
17699    (clobber (match_scratch:XF 4 "=&1f"))]
17700   "TARGET_USE_FANCY_MATH_387
17701    && flag_unsafe_math_optimizations"
17702   "* return output_fix_trunc (insn, operands, 0);"
17703   [(set_attr "type" "fistp")
17704    (set_attr "i387_cw" "ceil")
17705    (set_attr "mode" "DI")])
17706
17707 (define_insn "fistdi2_ceil_with_temp"
17708   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17709         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17710          UNSPEC_FIST_CEIL))
17711    (use (match_operand:HI 2 "memory_operand" "m,m"))
17712    (use (match_operand:HI 3 "memory_operand" "m,m"))
17713    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17714    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17715   "TARGET_USE_FANCY_MATH_387
17716    && flag_unsafe_math_optimizations"
17717   "#"
17718   [(set_attr "type" "fistp")
17719    (set_attr "i387_cw" "ceil")
17720    (set_attr "mode" "DI")])
17721
17722 (define_split 
17723   [(set (match_operand:DI 0 "register_operand" "")
17724         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17725          UNSPEC_FIST_CEIL))
17726    (use (match_operand:HI 2 "memory_operand" ""))
17727    (use (match_operand:HI 3 "memory_operand" ""))
17728    (clobber (match_operand:DI 4 "memory_operand" ""))
17729    (clobber (match_scratch 5 ""))]
17730   "reload_completed"
17731   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17732               (use (match_dup 2))
17733               (use (match_dup 3))
17734               (clobber (match_dup 5))])
17735    (set (match_dup 0) (match_dup 4))]
17736   "")
17737
17738 (define_split 
17739   [(set (match_operand:DI 0 "memory_operand" "")
17740         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17741          UNSPEC_FIST_CEIL))
17742    (use (match_operand:HI 2 "memory_operand" ""))
17743    (use (match_operand:HI 3 "memory_operand" ""))
17744    (clobber (match_operand:DI 4 "memory_operand" ""))
17745    (clobber (match_scratch 5 ""))]
17746   "reload_completed"
17747   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17748               (use (match_dup 2))
17749               (use (match_dup 3))
17750               (clobber (match_dup 5))])]
17751   "")
17752
17753 (define_insn "fist<mode>2_ceil"
17754   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17755         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17756          UNSPEC_FIST_CEIL))
17757    (use (match_operand:HI 2 "memory_operand" "m"))
17758    (use (match_operand:HI 3 "memory_operand" "m"))]
17759   "TARGET_USE_FANCY_MATH_387
17760    && flag_unsafe_math_optimizations"
17761   "* return output_fix_trunc (insn, operands, 0);"
17762   [(set_attr "type" "fistp")
17763    (set_attr "i387_cw" "ceil")
17764    (set_attr "mode" "<MODE>")])
17765
17766 (define_insn "fist<mode>2_ceil_with_temp"
17767   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17768         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17769          UNSPEC_FIST_CEIL))
17770    (use (match_operand:HI 2 "memory_operand" "m,m"))
17771    (use (match_operand:HI 3 "memory_operand" "m,m"))
17772    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17773   "TARGET_USE_FANCY_MATH_387
17774    && flag_unsafe_math_optimizations"
17775   "#"
17776   [(set_attr "type" "fistp")
17777    (set_attr "i387_cw" "ceil")
17778    (set_attr "mode" "<MODE>")])
17779
17780 (define_split 
17781   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17782         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17783          UNSPEC_FIST_CEIL))
17784    (use (match_operand:HI 2 "memory_operand" ""))
17785    (use (match_operand:HI 3 "memory_operand" ""))
17786    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17787   "reload_completed"
17788   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17789                                   UNSPEC_FIST_CEIL))
17790               (use (match_dup 2))
17791               (use (match_dup 3))])
17792    (set (match_dup 0) (match_dup 4))]
17793   "")
17794
17795 (define_split 
17796   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17797         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17798          UNSPEC_FIST_CEIL))
17799    (use (match_operand:HI 2 "memory_operand" ""))
17800    (use (match_operand:HI 3 "memory_operand" ""))
17801    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17802   "reload_completed"
17803   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17804                                   UNSPEC_FIST_CEIL))
17805               (use (match_dup 2))
17806               (use (match_dup 3))])]
17807   "")
17808
17809 (define_expand "lceil<mode>2"
17810   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17811                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17812                     UNSPEC_FIST_CEIL))
17813               (clobber (reg:CC FLAGS_REG))])]
17814   "TARGET_USE_FANCY_MATH_387
17815    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17816    && flag_unsafe_math_optimizations"
17817   "")
17818
17819 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17820 (define_insn_and_split "frndintxf2_trunc"
17821   [(set (match_operand:XF 0 "register_operand" "=f")
17822         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17823          UNSPEC_FRNDINT_TRUNC))
17824    (clobber (reg:CC FLAGS_REG))]
17825   "TARGET_USE_FANCY_MATH_387
17826    && flag_unsafe_math_optimizations
17827    && !(reload_completed || reload_in_progress)"
17828   "#"
17829   "&& 1"
17830   [(const_int 0)]
17831 {
17832   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17833
17834   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17835   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17836
17837   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17838                                         operands[2], operands[3]));
17839   DONE;
17840 }
17841   [(set_attr "type" "frndint")
17842    (set_attr "i387_cw" "trunc")
17843    (set_attr "mode" "XF")])
17844
17845 (define_insn "frndintxf2_trunc_i387"
17846   [(set (match_operand:XF 0 "register_operand" "=f")
17847         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848          UNSPEC_FRNDINT_TRUNC))
17849    (use (match_operand:HI 2 "memory_operand" "m"))
17850    (use (match_operand:HI 3 "memory_operand" "m"))]
17851   "TARGET_USE_FANCY_MATH_387
17852    && flag_unsafe_math_optimizations"
17853   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17854   [(set_attr "type" "frndint")
17855    (set_attr "i387_cw" "trunc")
17856    (set_attr "mode" "XF")])
17857
17858 (define_expand "btruncxf2"
17859   [(use (match_operand:XF 0 "register_operand" ""))
17860    (use (match_operand:XF 1 "register_operand" ""))]
17861   "TARGET_USE_FANCY_MATH_387
17862    && flag_unsafe_math_optimizations"
17863 {
17864   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17865   DONE;
17866 })
17867
17868 (define_expand "btruncdf2"
17869   [(use (match_operand:DF 0 "register_operand" ""))
17870    (use (match_operand:DF 1 "register_operand" ""))]
17871   "TARGET_USE_FANCY_MATH_387
17872    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17873    && flag_unsafe_math_optimizations"
17874 {
17875   rtx op0 = gen_reg_rtx (XFmode);
17876   rtx op1 = gen_reg_rtx (XFmode);
17877
17878   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17879   emit_insn (gen_frndintxf2_trunc (op0, op1));
17880
17881   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17882   DONE;
17883 })
17884
17885 (define_expand "btruncsf2"
17886   [(use (match_operand:SF 0 "register_operand" ""))
17887    (use (match_operand:SF 1 "register_operand" ""))]
17888   "TARGET_USE_FANCY_MATH_387
17889    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17890    && flag_unsafe_math_optimizations"
17891 {
17892   rtx op0 = gen_reg_rtx (XFmode);
17893   rtx op1 = gen_reg_rtx (XFmode);
17894
17895   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17896   emit_insn (gen_frndintxf2_trunc (op0, op1));
17897
17898   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17899   DONE;
17900 })
17901
17902 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17903 (define_insn_and_split "frndintxf2_mask_pm"
17904   [(set (match_operand:XF 0 "register_operand" "=f")
17905         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17906          UNSPEC_FRNDINT_MASK_PM))
17907    (clobber (reg:CC FLAGS_REG))]
17908   "TARGET_USE_FANCY_MATH_387
17909    && flag_unsafe_math_optimizations
17910    && !(reload_completed || reload_in_progress)"
17911   "#"
17912   "&& 1"
17913   [(const_int 0)]
17914 {
17915   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17916
17917   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17918   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17919
17920   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17921                                           operands[2], operands[3]));
17922   DONE;
17923 }
17924   [(set_attr "type" "frndint")
17925    (set_attr "i387_cw" "mask_pm")
17926    (set_attr "mode" "XF")])
17927
17928 (define_insn "frndintxf2_mask_pm_i387"
17929   [(set (match_operand:XF 0 "register_operand" "=f")
17930         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17931          UNSPEC_FRNDINT_MASK_PM))
17932    (use (match_operand:HI 2 "memory_operand" "m"))
17933    (use (match_operand:HI 3 "memory_operand" "m"))]
17934   "TARGET_USE_FANCY_MATH_387
17935    && flag_unsafe_math_optimizations"
17936   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17937   [(set_attr "type" "frndint")
17938    (set_attr "i387_cw" "mask_pm")
17939    (set_attr "mode" "XF")])
17940
17941 (define_expand "nearbyintxf2"
17942   [(use (match_operand:XF 0 "register_operand" ""))
17943    (use (match_operand:XF 1 "register_operand" ""))]
17944   "TARGET_USE_FANCY_MATH_387
17945    && flag_unsafe_math_optimizations"
17946 {
17947   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17948
17949   DONE;
17950 })
17951
17952 (define_expand "nearbyintdf2"
17953   [(use (match_operand:DF 0 "register_operand" ""))
17954    (use (match_operand:DF 1 "register_operand" ""))]
17955   "TARGET_USE_FANCY_MATH_387
17956    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17957    && flag_unsafe_math_optimizations"
17958 {
17959   rtx op0 = gen_reg_rtx (XFmode);
17960   rtx op1 = gen_reg_rtx (XFmode);
17961
17962   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17963   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17964
17965   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17966   DONE;
17967 })
17968
17969 (define_expand "nearbyintsf2"
17970   [(use (match_operand:SF 0 "register_operand" ""))
17971    (use (match_operand:SF 1 "register_operand" ""))]
17972   "TARGET_USE_FANCY_MATH_387
17973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17974    && flag_unsafe_math_optimizations"
17975 {
17976   rtx op0 = gen_reg_rtx (XFmode);
17977   rtx op1 = gen_reg_rtx (XFmode);
17978
17979   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17980   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17981
17982   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17983   DONE;
17984 })
17985
17986 \f
17987 ;; Block operation instructions
17988
17989 (define_insn "cld"
17990  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17991  ""
17992  "cld"
17993   [(set_attr "type" "cld")])
17994
17995 (define_expand "movmemsi"
17996   [(use (match_operand:BLK 0 "memory_operand" ""))
17997    (use (match_operand:BLK 1 "memory_operand" ""))
17998    (use (match_operand:SI 2 "nonmemory_operand" ""))
17999    (use (match_operand:SI 3 "const_int_operand" ""))]
18000   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18001 {
18002  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18003    DONE;
18004  else
18005    FAIL;
18006 })
18007
18008 (define_expand "movmemdi"
18009   [(use (match_operand:BLK 0 "memory_operand" ""))
18010    (use (match_operand:BLK 1 "memory_operand" ""))
18011    (use (match_operand:DI 2 "nonmemory_operand" ""))
18012    (use (match_operand:DI 3 "const_int_operand" ""))]
18013   "TARGET_64BIT"
18014 {
18015  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18016    DONE;
18017  else
18018    FAIL;
18019 })
18020
18021 ;; Most CPUs don't like single string operations
18022 ;; Handle this case here to simplify previous expander.
18023
18024 (define_expand "strmov"
18025   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18026    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18027    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18028               (clobber (reg:CC FLAGS_REG))])
18029    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18030               (clobber (reg:CC FLAGS_REG))])]
18031   ""
18032 {
18033   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18034
18035   /* If .md ever supports :P for Pmode, these can be directly
18036      in the pattern above.  */
18037   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18038   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18039
18040   if (TARGET_SINGLE_STRINGOP || optimize_size)
18041     {
18042       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18043                                       operands[2], operands[3],
18044                                       operands[5], operands[6]));
18045       DONE;
18046     }
18047
18048   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18049 })
18050
18051 (define_expand "strmov_singleop"
18052   [(parallel [(set (match_operand 1 "memory_operand" "")
18053                    (match_operand 3 "memory_operand" ""))
18054               (set (match_operand 0 "register_operand" "")
18055                    (match_operand 4 "" ""))
18056               (set (match_operand 2 "register_operand" "")
18057                    (match_operand 5 "" ""))
18058               (use (reg:SI DIRFLAG_REG))])]
18059   "TARGET_SINGLE_STRINGOP || optimize_size"
18060   "")
18061
18062 (define_insn "*strmovdi_rex_1"
18063   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18064         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18065    (set (match_operand:DI 0 "register_operand" "=D")
18066         (plus:DI (match_dup 2)
18067                  (const_int 8)))
18068    (set (match_operand:DI 1 "register_operand" "=S")
18069         (plus:DI (match_dup 3)
18070                  (const_int 8)))
18071    (use (reg:SI DIRFLAG_REG))]
18072   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18073   "movsq"
18074   [(set_attr "type" "str")
18075    (set_attr "mode" "DI")
18076    (set_attr "memory" "both")])
18077
18078 (define_insn "*strmovsi_1"
18079   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18080         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18081    (set (match_operand:SI 0 "register_operand" "=D")
18082         (plus:SI (match_dup 2)
18083                  (const_int 4)))
18084    (set (match_operand:SI 1 "register_operand" "=S")
18085         (plus:SI (match_dup 3)
18086                  (const_int 4)))
18087    (use (reg:SI DIRFLAG_REG))]
18088   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18089   "{movsl|movsd}"
18090   [(set_attr "type" "str")
18091    (set_attr "mode" "SI")
18092    (set_attr "memory" "both")])
18093
18094 (define_insn "*strmovsi_rex_1"
18095   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18096         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18097    (set (match_operand:DI 0 "register_operand" "=D")
18098         (plus:DI (match_dup 2)
18099                  (const_int 4)))
18100    (set (match_operand:DI 1 "register_operand" "=S")
18101         (plus:DI (match_dup 3)
18102                  (const_int 4)))
18103    (use (reg:SI DIRFLAG_REG))]
18104   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18105   "{movsl|movsd}"
18106   [(set_attr "type" "str")
18107    (set_attr "mode" "SI")
18108    (set_attr "memory" "both")])
18109
18110 (define_insn "*strmovhi_1"
18111   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18112         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18113    (set (match_operand:SI 0 "register_operand" "=D")
18114         (plus:SI (match_dup 2)
18115                  (const_int 2)))
18116    (set (match_operand:SI 1 "register_operand" "=S")
18117         (plus:SI (match_dup 3)
18118                  (const_int 2)))
18119    (use (reg:SI DIRFLAG_REG))]
18120   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18121   "movsw"
18122   [(set_attr "type" "str")
18123    (set_attr "memory" "both")
18124    (set_attr "mode" "HI")])
18125
18126 (define_insn "*strmovhi_rex_1"
18127   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18128         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18129    (set (match_operand:DI 0 "register_operand" "=D")
18130         (plus:DI (match_dup 2)
18131                  (const_int 2)))
18132    (set (match_operand:DI 1 "register_operand" "=S")
18133         (plus:DI (match_dup 3)
18134                  (const_int 2)))
18135    (use (reg:SI DIRFLAG_REG))]
18136   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18137   "movsw"
18138   [(set_attr "type" "str")
18139    (set_attr "memory" "both")
18140    (set_attr "mode" "HI")])
18141
18142 (define_insn "*strmovqi_1"
18143   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18144         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18145    (set (match_operand:SI 0 "register_operand" "=D")
18146         (plus:SI (match_dup 2)
18147                  (const_int 1)))
18148    (set (match_operand:SI 1 "register_operand" "=S")
18149         (plus:SI (match_dup 3)
18150                  (const_int 1)))
18151    (use (reg:SI DIRFLAG_REG))]
18152   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18153   "movsb"
18154   [(set_attr "type" "str")
18155    (set_attr "memory" "both")
18156    (set_attr "mode" "QI")])
18157
18158 (define_insn "*strmovqi_rex_1"
18159   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18160         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18161    (set (match_operand:DI 0 "register_operand" "=D")
18162         (plus:DI (match_dup 2)
18163                  (const_int 1)))
18164    (set (match_operand:DI 1 "register_operand" "=S")
18165         (plus:DI (match_dup 3)
18166                  (const_int 1)))
18167    (use (reg:SI DIRFLAG_REG))]
18168   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18169   "movsb"
18170   [(set_attr "type" "str")
18171    (set_attr "memory" "both")
18172    (set_attr "mode" "QI")])
18173
18174 (define_expand "rep_mov"
18175   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18176               (set (match_operand 0 "register_operand" "")
18177                    (match_operand 5 "" ""))
18178               (set (match_operand 2 "register_operand" "")
18179                    (match_operand 6 "" ""))
18180               (set (match_operand 1 "memory_operand" "")
18181                    (match_operand 3 "memory_operand" ""))
18182               (use (match_dup 4))
18183               (use (reg:SI DIRFLAG_REG))])]
18184   ""
18185   "")
18186
18187 (define_insn "*rep_movdi_rex64"
18188   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18189    (set (match_operand:DI 0 "register_operand" "=D") 
18190         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18191                             (const_int 3))
18192                  (match_operand:DI 3 "register_operand" "0")))
18193    (set (match_operand:DI 1 "register_operand" "=S") 
18194         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18195                  (match_operand:DI 4 "register_operand" "1")))
18196    (set (mem:BLK (match_dup 3))
18197         (mem:BLK (match_dup 4)))
18198    (use (match_dup 5))
18199    (use (reg:SI DIRFLAG_REG))]
18200   "TARGET_64BIT"
18201   "{rep\;movsq|rep movsq}"
18202   [(set_attr "type" "str")
18203    (set_attr "prefix_rep" "1")
18204    (set_attr "memory" "both")
18205    (set_attr "mode" "DI")])
18206
18207 (define_insn "*rep_movsi"
18208   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18209    (set (match_operand:SI 0 "register_operand" "=D") 
18210         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18211                             (const_int 2))
18212                  (match_operand:SI 3 "register_operand" "0")))
18213    (set (match_operand:SI 1 "register_operand" "=S") 
18214         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18215                  (match_operand:SI 4 "register_operand" "1")))
18216    (set (mem:BLK (match_dup 3))
18217         (mem:BLK (match_dup 4)))
18218    (use (match_dup 5))
18219    (use (reg:SI DIRFLAG_REG))]
18220   "!TARGET_64BIT"
18221   "{rep\;movsl|rep movsd}"
18222   [(set_attr "type" "str")
18223    (set_attr "prefix_rep" "1")
18224    (set_attr "memory" "both")
18225    (set_attr "mode" "SI")])
18226
18227 (define_insn "*rep_movsi_rex64"
18228   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18229    (set (match_operand:DI 0 "register_operand" "=D") 
18230         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18231                             (const_int 2))
18232                  (match_operand:DI 3 "register_operand" "0")))
18233    (set (match_operand:DI 1 "register_operand" "=S") 
18234         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18235                  (match_operand:DI 4 "register_operand" "1")))
18236    (set (mem:BLK (match_dup 3))
18237         (mem:BLK (match_dup 4)))
18238    (use (match_dup 5))
18239    (use (reg:SI DIRFLAG_REG))]
18240   "TARGET_64BIT"
18241   "{rep\;movsl|rep movsd}"
18242   [(set_attr "type" "str")
18243    (set_attr "prefix_rep" "1")
18244    (set_attr "memory" "both")
18245    (set_attr "mode" "SI")])
18246
18247 (define_insn "*rep_movqi"
18248   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18249    (set (match_operand:SI 0 "register_operand" "=D") 
18250         (plus:SI (match_operand:SI 3 "register_operand" "0")
18251                  (match_operand:SI 5 "register_operand" "2")))
18252    (set (match_operand:SI 1 "register_operand" "=S") 
18253         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18254    (set (mem:BLK (match_dup 3))
18255         (mem:BLK (match_dup 4)))
18256    (use (match_dup 5))
18257    (use (reg:SI DIRFLAG_REG))]
18258   "!TARGET_64BIT"
18259   "{rep\;movsb|rep movsb}"
18260   [(set_attr "type" "str")
18261    (set_attr "prefix_rep" "1")
18262    (set_attr "memory" "both")
18263    (set_attr "mode" "SI")])
18264
18265 (define_insn "*rep_movqi_rex64"
18266   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18267    (set (match_operand:DI 0 "register_operand" "=D") 
18268         (plus:DI (match_operand:DI 3 "register_operand" "0")
18269                  (match_operand:DI 5 "register_operand" "2")))
18270    (set (match_operand:DI 1 "register_operand" "=S") 
18271         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18272    (set (mem:BLK (match_dup 3))
18273         (mem:BLK (match_dup 4)))
18274    (use (match_dup 5))
18275    (use (reg:SI DIRFLAG_REG))]
18276   "TARGET_64BIT"
18277   "{rep\;movsb|rep movsb}"
18278   [(set_attr "type" "str")
18279    (set_attr "prefix_rep" "1")
18280    (set_attr "memory" "both")
18281    (set_attr "mode" "SI")])
18282
18283 (define_expand "setmemsi"
18284    [(use (match_operand:BLK 0 "memory_operand" ""))
18285     (use (match_operand:SI 1 "nonmemory_operand" ""))
18286     (use (match_operand 2 "const_int_operand" ""))
18287     (use (match_operand 3 "const_int_operand" ""))]
18288   ""
18289 {
18290  /* If value to set is not zero, use the library routine.  */
18291  if (operands[2] != const0_rtx)
18292    FAIL;
18293
18294  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18295    DONE;
18296  else
18297    FAIL;
18298 })
18299
18300 (define_expand "setmemdi"
18301    [(use (match_operand:BLK 0 "memory_operand" ""))
18302     (use (match_operand:DI 1 "nonmemory_operand" ""))
18303     (use (match_operand 2 "const_int_operand" ""))
18304     (use (match_operand 3 "const_int_operand" ""))]
18305   "TARGET_64BIT"
18306 {
18307  /* If value to set is not zero, use the library routine.  */
18308  if (operands[2] != const0_rtx)
18309    FAIL;
18310
18311  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18312    DONE;
18313  else
18314    FAIL;
18315 })
18316
18317 ;; Most CPUs don't like single string operations
18318 ;; Handle this case here to simplify previous expander.
18319
18320 (define_expand "strset"
18321   [(set (match_operand 1 "memory_operand" "")
18322         (match_operand 2 "register_operand" ""))
18323    (parallel [(set (match_operand 0 "register_operand" "")
18324                    (match_dup 3))
18325               (clobber (reg:CC FLAGS_REG))])]
18326   ""
18327 {
18328   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18329     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18330
18331   /* If .md ever supports :P for Pmode, this can be directly
18332      in the pattern above.  */
18333   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18334                               GEN_INT (GET_MODE_SIZE (GET_MODE
18335                                                       (operands[2]))));
18336   if (TARGET_SINGLE_STRINGOP || optimize_size)
18337     {
18338       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18339                                       operands[3]));
18340       DONE;
18341     }
18342 })
18343
18344 (define_expand "strset_singleop"
18345   [(parallel [(set (match_operand 1 "memory_operand" "")
18346                    (match_operand 2 "register_operand" ""))
18347               (set (match_operand 0 "register_operand" "")
18348                    (match_operand 3 "" ""))
18349               (use (reg:SI DIRFLAG_REG))])]
18350   "TARGET_SINGLE_STRINGOP || optimize_size"
18351   "")
18352
18353 (define_insn "*strsetdi_rex_1"
18354   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18355         (match_operand:DI 2 "register_operand" "a"))
18356    (set (match_operand:DI 0 "register_operand" "=D")
18357         (plus:DI (match_dup 1)
18358                  (const_int 8)))
18359    (use (reg:SI DIRFLAG_REG))]
18360   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361   "stosq"
18362   [(set_attr "type" "str")
18363    (set_attr "memory" "store")
18364    (set_attr "mode" "DI")])
18365
18366 (define_insn "*strsetsi_1"
18367   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18368         (match_operand:SI 2 "register_operand" "a"))
18369    (set (match_operand:SI 0 "register_operand" "=D")
18370         (plus:SI (match_dup 1)
18371                  (const_int 4)))
18372    (use (reg:SI DIRFLAG_REG))]
18373   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374   "{stosl|stosd}"
18375   [(set_attr "type" "str")
18376    (set_attr "memory" "store")
18377    (set_attr "mode" "SI")])
18378
18379 (define_insn "*strsetsi_rex_1"
18380   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18381         (match_operand:SI 2 "register_operand" "a"))
18382    (set (match_operand:DI 0 "register_operand" "=D")
18383         (plus:DI (match_dup 1)
18384                  (const_int 4)))
18385    (use (reg:SI DIRFLAG_REG))]
18386   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387   "{stosl|stosd}"
18388   [(set_attr "type" "str")
18389    (set_attr "memory" "store")
18390    (set_attr "mode" "SI")])
18391
18392 (define_insn "*strsethi_1"
18393   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18394         (match_operand:HI 2 "register_operand" "a"))
18395    (set (match_operand:SI 0 "register_operand" "=D")
18396         (plus:SI (match_dup 1)
18397                  (const_int 2)))
18398    (use (reg:SI DIRFLAG_REG))]
18399   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400   "stosw"
18401   [(set_attr "type" "str")
18402    (set_attr "memory" "store")
18403    (set_attr "mode" "HI")])
18404
18405 (define_insn "*strsethi_rex_1"
18406   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18407         (match_operand:HI 2 "register_operand" "a"))
18408    (set (match_operand:DI 0 "register_operand" "=D")
18409         (plus:DI (match_dup 1)
18410                  (const_int 2)))
18411    (use (reg:SI DIRFLAG_REG))]
18412   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413   "stosw"
18414   [(set_attr "type" "str")
18415    (set_attr "memory" "store")
18416    (set_attr "mode" "HI")])
18417
18418 (define_insn "*strsetqi_1"
18419   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18420         (match_operand:QI 2 "register_operand" "a"))
18421    (set (match_operand:SI 0 "register_operand" "=D")
18422         (plus:SI (match_dup 1)
18423                  (const_int 1)))
18424    (use (reg:SI DIRFLAG_REG))]
18425   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426   "stosb"
18427   [(set_attr "type" "str")
18428    (set_attr "memory" "store")
18429    (set_attr "mode" "QI")])
18430
18431 (define_insn "*strsetqi_rex_1"
18432   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18433         (match_operand:QI 2 "register_operand" "a"))
18434    (set (match_operand:DI 0 "register_operand" "=D")
18435         (plus:DI (match_dup 1)
18436                  (const_int 1)))
18437    (use (reg:SI DIRFLAG_REG))]
18438   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18439   "stosb"
18440   [(set_attr "type" "str")
18441    (set_attr "memory" "store")
18442    (set_attr "mode" "QI")])
18443
18444 (define_expand "rep_stos"
18445   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18446               (set (match_operand 0 "register_operand" "")
18447                    (match_operand 4 "" ""))
18448               (set (match_operand 2 "memory_operand" "") (const_int 0))
18449               (use (match_operand 3 "register_operand" ""))
18450               (use (match_dup 1))
18451               (use (reg:SI DIRFLAG_REG))])]
18452   ""
18453   "")
18454
18455 (define_insn "*rep_stosdi_rex64"
18456   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18457    (set (match_operand:DI 0 "register_operand" "=D") 
18458         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18459                             (const_int 3))
18460                  (match_operand:DI 3 "register_operand" "0")))
18461    (set (mem:BLK (match_dup 3))
18462         (const_int 0))
18463    (use (match_operand:DI 2 "register_operand" "a"))
18464    (use (match_dup 4))
18465    (use (reg:SI DIRFLAG_REG))]
18466   "TARGET_64BIT"
18467   "{rep\;stosq|rep stosq}"
18468   [(set_attr "type" "str")
18469    (set_attr "prefix_rep" "1")
18470    (set_attr "memory" "store")
18471    (set_attr "mode" "DI")])
18472
18473 (define_insn "*rep_stossi"
18474   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18475    (set (match_operand:SI 0 "register_operand" "=D") 
18476         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18477                             (const_int 2))
18478                  (match_operand:SI 3 "register_operand" "0")))
18479    (set (mem:BLK (match_dup 3))
18480         (const_int 0))
18481    (use (match_operand:SI 2 "register_operand" "a"))
18482    (use (match_dup 4))
18483    (use (reg:SI DIRFLAG_REG))]
18484   "!TARGET_64BIT"
18485   "{rep\;stosl|rep stosd}"
18486   [(set_attr "type" "str")
18487    (set_attr "prefix_rep" "1")
18488    (set_attr "memory" "store")
18489    (set_attr "mode" "SI")])
18490
18491 (define_insn "*rep_stossi_rex64"
18492   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18493    (set (match_operand:DI 0 "register_operand" "=D") 
18494         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18495                             (const_int 2))
18496                  (match_operand:DI 3 "register_operand" "0")))
18497    (set (mem:BLK (match_dup 3))
18498         (const_int 0))
18499    (use (match_operand:SI 2 "register_operand" "a"))
18500    (use (match_dup 4))
18501    (use (reg:SI DIRFLAG_REG))]
18502   "TARGET_64BIT"
18503   "{rep\;stosl|rep stosd}"
18504   [(set_attr "type" "str")
18505    (set_attr "prefix_rep" "1")
18506    (set_attr "memory" "store")
18507    (set_attr "mode" "SI")])
18508
18509 (define_insn "*rep_stosqi"
18510   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18511    (set (match_operand:SI 0 "register_operand" "=D") 
18512         (plus:SI (match_operand:SI 3 "register_operand" "0")
18513                  (match_operand:SI 4 "register_operand" "1")))
18514    (set (mem:BLK (match_dup 3))
18515         (const_int 0))
18516    (use (match_operand:QI 2 "register_operand" "a"))
18517    (use (match_dup 4))
18518    (use (reg:SI DIRFLAG_REG))]
18519   "!TARGET_64BIT"
18520   "{rep\;stosb|rep stosb}"
18521   [(set_attr "type" "str")
18522    (set_attr "prefix_rep" "1")
18523    (set_attr "memory" "store")
18524    (set_attr "mode" "QI")])
18525
18526 (define_insn "*rep_stosqi_rex64"
18527   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18528    (set (match_operand:DI 0 "register_operand" "=D") 
18529         (plus:DI (match_operand:DI 3 "register_operand" "0")
18530                  (match_operand:DI 4 "register_operand" "1")))
18531    (set (mem:BLK (match_dup 3))
18532         (const_int 0))
18533    (use (match_operand:QI 2 "register_operand" "a"))
18534    (use (match_dup 4))
18535    (use (reg:SI DIRFLAG_REG))]
18536   "TARGET_64BIT"
18537   "{rep\;stosb|rep stosb}"
18538   [(set_attr "type" "str")
18539    (set_attr "prefix_rep" "1")
18540    (set_attr "memory" "store")
18541    (set_attr "mode" "QI")])
18542
18543 (define_expand "cmpstrnsi"
18544   [(set (match_operand:SI 0 "register_operand" "")
18545         (compare:SI (match_operand:BLK 1 "general_operand" "")
18546                     (match_operand:BLK 2 "general_operand" "")))
18547    (use (match_operand 3 "general_operand" ""))
18548    (use (match_operand 4 "immediate_operand" ""))]
18549   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18550 {
18551   rtx addr1, addr2, out, outlow, count, countreg, align;
18552
18553   /* Can't use this if the user has appropriated esi or edi.  */
18554   if (global_regs[4] || global_regs[5])
18555     FAIL;
18556
18557   out = operands[0];
18558   if (GET_CODE (out) != REG)
18559     out = gen_reg_rtx (SImode);
18560
18561   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18562   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18563   if (addr1 != XEXP (operands[1], 0))
18564     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18565   if (addr2 != XEXP (operands[2], 0))
18566     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18567
18568   count = operands[3];
18569   countreg = ix86_zero_extend_to_Pmode (count);
18570
18571   /* %%% Iff we are testing strict equality, we can use known alignment
18572      to good advantage.  This may be possible with combine, particularly
18573      once cc0 is dead.  */
18574   align = operands[4];
18575
18576   emit_insn (gen_cld ());
18577   if (GET_CODE (count) == CONST_INT)
18578     {
18579       if (INTVAL (count) == 0)
18580         {
18581           emit_move_insn (operands[0], const0_rtx);
18582           DONE;
18583         }
18584       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18585                                      operands[1], operands[2]));
18586     }
18587   else
18588     {
18589       if (TARGET_64BIT)
18590         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18591       else
18592         emit_insn (gen_cmpsi_1 (countreg, countreg));
18593       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18594                                   operands[1], operands[2]));
18595     }
18596
18597   outlow = gen_lowpart (QImode, out);
18598   emit_insn (gen_cmpintqi (outlow));
18599   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18600
18601   if (operands[0] != out)
18602     emit_move_insn (operands[0], out);
18603
18604   DONE;
18605 })
18606
18607 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18608
18609 (define_expand "cmpintqi"
18610   [(set (match_dup 1)
18611         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18612    (set (match_dup 2)
18613         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18614    (parallel [(set (match_operand:QI 0 "register_operand" "")
18615                    (minus:QI (match_dup 1)
18616                              (match_dup 2)))
18617               (clobber (reg:CC FLAGS_REG))])]
18618   ""
18619   "operands[1] = gen_reg_rtx (QImode);
18620    operands[2] = gen_reg_rtx (QImode);")
18621
18622 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18623 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18624
18625 (define_expand "cmpstrnqi_nz_1"
18626   [(parallel [(set (reg:CC FLAGS_REG)
18627                    (compare:CC (match_operand 4 "memory_operand" "")
18628                                (match_operand 5 "memory_operand" "")))
18629               (use (match_operand 2 "register_operand" ""))
18630               (use (match_operand:SI 3 "immediate_operand" ""))
18631               (use (reg:SI DIRFLAG_REG))
18632               (clobber (match_operand 0 "register_operand" ""))
18633               (clobber (match_operand 1 "register_operand" ""))
18634               (clobber (match_dup 2))])]
18635   ""
18636   "")
18637
18638 (define_insn "*cmpstrnqi_nz_1"
18639   [(set (reg:CC FLAGS_REG)
18640         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18641                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18642    (use (match_operand:SI 6 "register_operand" "2"))
18643    (use (match_operand:SI 3 "immediate_operand" "i"))
18644    (use (reg:SI DIRFLAG_REG))
18645    (clobber (match_operand:SI 0 "register_operand" "=S"))
18646    (clobber (match_operand:SI 1 "register_operand" "=D"))
18647    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18648   "!TARGET_64BIT"
18649   "repz{\;| }cmpsb"
18650   [(set_attr "type" "str")
18651    (set_attr "mode" "QI")
18652    (set_attr "prefix_rep" "1")])
18653
18654 (define_insn "*cmpstrnqi_nz_rex_1"
18655   [(set (reg:CC FLAGS_REG)
18656         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18657                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18658    (use (match_operand:DI 6 "register_operand" "2"))
18659    (use (match_operand:SI 3 "immediate_operand" "i"))
18660    (use (reg:SI DIRFLAG_REG))
18661    (clobber (match_operand:DI 0 "register_operand" "=S"))
18662    (clobber (match_operand:DI 1 "register_operand" "=D"))
18663    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18664   "TARGET_64BIT"
18665   "repz{\;| }cmpsb"
18666   [(set_attr "type" "str")
18667    (set_attr "mode" "QI")
18668    (set_attr "prefix_rep" "1")])
18669
18670 ;; The same, but the count is not known to not be zero.
18671
18672 (define_expand "cmpstrnqi_1"
18673   [(parallel [(set (reg:CC FLAGS_REG)
18674                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18675                                      (const_int 0))
18676                   (compare:CC (match_operand 4 "memory_operand" "")
18677                               (match_operand 5 "memory_operand" ""))
18678                   (const_int 0)))
18679               (use (match_operand:SI 3 "immediate_operand" ""))
18680               (use (reg:CC FLAGS_REG))
18681               (use (reg:SI DIRFLAG_REG))
18682               (clobber (match_operand 0 "register_operand" ""))
18683               (clobber (match_operand 1 "register_operand" ""))
18684               (clobber (match_dup 2))])]
18685   ""
18686   "")
18687
18688 (define_insn "*cmpstrnqi_1"
18689   [(set (reg:CC FLAGS_REG)
18690         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18691                              (const_int 0))
18692           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18693                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18694           (const_int 0)))
18695    (use (match_operand:SI 3 "immediate_operand" "i"))
18696    (use (reg:CC FLAGS_REG))
18697    (use (reg:SI DIRFLAG_REG))
18698    (clobber (match_operand:SI 0 "register_operand" "=S"))
18699    (clobber (match_operand:SI 1 "register_operand" "=D"))
18700    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18701   "!TARGET_64BIT"
18702   "repz{\;| }cmpsb"
18703   [(set_attr "type" "str")
18704    (set_attr "mode" "QI")
18705    (set_attr "prefix_rep" "1")])
18706
18707 (define_insn "*cmpstrnqi_rex_1"
18708   [(set (reg:CC FLAGS_REG)
18709         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18710                              (const_int 0))
18711           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18712                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18713           (const_int 0)))
18714    (use (match_operand:SI 3 "immediate_operand" "i"))
18715    (use (reg:CC FLAGS_REG))
18716    (use (reg:SI DIRFLAG_REG))
18717    (clobber (match_operand:DI 0 "register_operand" "=S"))
18718    (clobber (match_operand:DI 1 "register_operand" "=D"))
18719    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18720   "TARGET_64BIT"
18721   "repz{\;| }cmpsb"
18722   [(set_attr "type" "str")
18723    (set_attr "mode" "QI")
18724    (set_attr "prefix_rep" "1")])
18725
18726 (define_expand "strlensi"
18727   [(set (match_operand:SI 0 "register_operand" "")
18728         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18729                     (match_operand:QI 2 "immediate_operand" "")
18730                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18731   ""
18732 {
18733  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18734    DONE;
18735  else
18736    FAIL;
18737 })
18738
18739 (define_expand "strlendi"
18740   [(set (match_operand:DI 0 "register_operand" "")
18741         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18742                     (match_operand:QI 2 "immediate_operand" "")
18743                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18744   ""
18745 {
18746  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18747    DONE;
18748  else
18749    FAIL;
18750 })
18751
18752 (define_expand "strlenqi_1"
18753   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18754               (use (reg:SI DIRFLAG_REG))
18755               (clobber (match_operand 1 "register_operand" ""))
18756               (clobber (reg:CC FLAGS_REG))])]
18757   ""
18758   "")
18759
18760 (define_insn "*strlenqi_1"
18761   [(set (match_operand:SI 0 "register_operand" "=&c")
18762         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18763                     (match_operand:QI 2 "register_operand" "a")
18764                     (match_operand:SI 3 "immediate_operand" "i")
18765                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18766    (use (reg:SI DIRFLAG_REG))
18767    (clobber (match_operand:SI 1 "register_operand" "=D"))
18768    (clobber (reg:CC FLAGS_REG))]
18769   "!TARGET_64BIT"
18770   "repnz{\;| }scasb"
18771   [(set_attr "type" "str")
18772    (set_attr "mode" "QI")
18773    (set_attr "prefix_rep" "1")])
18774
18775 (define_insn "*strlenqi_rex_1"
18776   [(set (match_operand:DI 0 "register_operand" "=&c")
18777         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18778                     (match_operand:QI 2 "register_operand" "a")
18779                     (match_operand:DI 3 "immediate_operand" "i")
18780                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18781    (use (reg:SI DIRFLAG_REG))
18782    (clobber (match_operand:DI 1 "register_operand" "=D"))
18783    (clobber (reg:CC FLAGS_REG))]
18784   "TARGET_64BIT"
18785   "repnz{\;| }scasb"
18786   [(set_attr "type" "str")
18787    (set_attr "mode" "QI")
18788    (set_attr "prefix_rep" "1")])
18789
18790 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18791 ;; handled in combine, but it is not currently up to the task.
18792 ;; When used for their truth value, the cmpstrn* expanders generate
18793 ;; code like this:
18794 ;;
18795 ;;   repz cmpsb
18796 ;;   seta       %al
18797 ;;   setb       %dl
18798 ;;   cmpb       %al, %dl
18799 ;;   jcc        label
18800 ;;
18801 ;; The intermediate three instructions are unnecessary.
18802
18803 ;; This one handles cmpstrn*_nz_1...
18804 (define_peephole2
18805   [(parallel[
18806      (set (reg:CC FLAGS_REG)
18807           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18808                       (mem:BLK (match_operand 5 "register_operand" ""))))
18809      (use (match_operand 6 "register_operand" ""))
18810      (use (match_operand:SI 3 "immediate_operand" ""))
18811      (use (reg:SI DIRFLAG_REG))
18812      (clobber (match_operand 0 "register_operand" ""))
18813      (clobber (match_operand 1 "register_operand" ""))
18814      (clobber (match_operand 2 "register_operand" ""))])
18815    (set (match_operand:QI 7 "register_operand" "")
18816         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18817    (set (match_operand:QI 8 "register_operand" "")
18818         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18819    (set (reg FLAGS_REG)
18820         (compare (match_dup 7) (match_dup 8)))
18821   ]
18822   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18823   [(parallel[
18824      (set (reg:CC FLAGS_REG)
18825           (compare:CC (mem:BLK (match_dup 4))
18826                       (mem:BLK (match_dup 5))))
18827      (use (match_dup 6))
18828      (use (match_dup 3))
18829      (use (reg:SI DIRFLAG_REG))
18830      (clobber (match_dup 0))
18831      (clobber (match_dup 1))
18832      (clobber (match_dup 2))])]
18833   "")
18834
18835 ;; ...and this one handles cmpstrn*_1.
18836 (define_peephole2
18837   [(parallel[
18838      (set (reg:CC FLAGS_REG)
18839           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18840                                (const_int 0))
18841             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18842                         (mem:BLK (match_operand 5 "register_operand" "")))
18843             (const_int 0)))
18844      (use (match_operand:SI 3 "immediate_operand" ""))
18845      (use (reg:CC FLAGS_REG))
18846      (use (reg:SI DIRFLAG_REG))
18847      (clobber (match_operand 0 "register_operand" ""))
18848      (clobber (match_operand 1 "register_operand" ""))
18849      (clobber (match_operand 2 "register_operand" ""))])
18850    (set (match_operand:QI 7 "register_operand" "")
18851         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18852    (set (match_operand:QI 8 "register_operand" "")
18853         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18854    (set (reg FLAGS_REG)
18855         (compare (match_dup 7) (match_dup 8)))
18856   ]
18857   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18858   [(parallel[
18859      (set (reg:CC FLAGS_REG)
18860           (if_then_else:CC (ne (match_dup 6)
18861                                (const_int 0))
18862             (compare:CC (mem:BLK (match_dup 4))
18863                         (mem:BLK (match_dup 5)))
18864             (const_int 0)))
18865      (use (match_dup 3))
18866      (use (reg:CC FLAGS_REG))
18867      (use (reg:SI DIRFLAG_REG))
18868      (clobber (match_dup 0))
18869      (clobber (match_dup 1))
18870      (clobber (match_dup 2))])]
18871   "")
18872
18873
18874 \f
18875 ;; Conditional move instructions.
18876
18877 (define_expand "movdicc"
18878   [(set (match_operand:DI 0 "register_operand" "")
18879         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18880                          (match_operand:DI 2 "general_operand" "")
18881                          (match_operand:DI 3 "general_operand" "")))]
18882   "TARGET_64BIT"
18883   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18884
18885 (define_insn "x86_movdicc_0_m1_rex64"
18886   [(set (match_operand:DI 0 "register_operand" "=r")
18887         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18888           (const_int -1)
18889           (const_int 0)))
18890    (clobber (reg:CC FLAGS_REG))]
18891   "TARGET_64BIT"
18892   "sbb{q}\t%0, %0"
18893   ; Since we don't have the proper number of operands for an alu insn,
18894   ; fill in all the blanks.
18895   [(set_attr "type" "alu")
18896    (set_attr "pent_pair" "pu")
18897    (set_attr "memory" "none")
18898    (set_attr "imm_disp" "false")
18899    (set_attr "mode" "DI")
18900    (set_attr "length_immediate" "0")])
18901
18902 (define_insn "*movdicc_c_rex64"
18903   [(set (match_operand:DI 0 "register_operand" "=r,r")
18904         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18905                                 [(reg FLAGS_REG) (const_int 0)])
18906                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18907                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18908   "TARGET_64BIT && TARGET_CMOVE
18909    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18910   "@
18911    cmov%O2%C1\t{%2, %0|%0, %2}
18912    cmov%O2%c1\t{%3, %0|%0, %3}"
18913   [(set_attr "type" "icmov")
18914    (set_attr "mode" "DI")])
18915
18916 (define_expand "movsicc"
18917   [(set (match_operand:SI 0 "register_operand" "")
18918         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18919                          (match_operand:SI 2 "general_operand" "")
18920                          (match_operand:SI 3 "general_operand" "")))]
18921   ""
18922   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18923
18924 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18925 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18926 ;; So just document what we're doing explicitly.
18927
18928 (define_insn "x86_movsicc_0_m1"
18929   [(set (match_operand:SI 0 "register_operand" "=r")
18930         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18931           (const_int -1)
18932           (const_int 0)))
18933    (clobber (reg:CC FLAGS_REG))]
18934   ""
18935   "sbb{l}\t%0, %0"
18936   ; Since we don't have the proper number of operands for an alu insn,
18937   ; fill in all the blanks.
18938   [(set_attr "type" "alu")
18939    (set_attr "pent_pair" "pu")
18940    (set_attr "memory" "none")
18941    (set_attr "imm_disp" "false")
18942    (set_attr "mode" "SI")
18943    (set_attr "length_immediate" "0")])
18944
18945 (define_insn "*movsicc_noc"
18946   [(set (match_operand:SI 0 "register_operand" "=r,r")
18947         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18948                                 [(reg FLAGS_REG) (const_int 0)])
18949                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18950                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18951   "TARGET_CMOVE
18952    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18953   "@
18954    cmov%O2%C1\t{%2, %0|%0, %2}
18955    cmov%O2%c1\t{%3, %0|%0, %3}"
18956   [(set_attr "type" "icmov")
18957    (set_attr "mode" "SI")])
18958
18959 (define_expand "movhicc"
18960   [(set (match_operand:HI 0 "register_operand" "")
18961         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18962                          (match_operand:HI 2 "general_operand" "")
18963                          (match_operand:HI 3 "general_operand" "")))]
18964   "TARGET_HIMODE_MATH"
18965   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18966
18967 (define_insn "*movhicc_noc"
18968   [(set (match_operand:HI 0 "register_operand" "=r,r")
18969         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18970                                 [(reg FLAGS_REG) (const_int 0)])
18971                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18972                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18973   "TARGET_CMOVE
18974    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18975   "@
18976    cmov%O2%C1\t{%2, %0|%0, %2}
18977    cmov%O2%c1\t{%3, %0|%0, %3}"
18978   [(set_attr "type" "icmov")
18979    (set_attr "mode" "HI")])
18980
18981 (define_expand "movqicc"
18982   [(set (match_operand:QI 0 "register_operand" "")
18983         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18984                          (match_operand:QI 2 "general_operand" "")
18985                          (match_operand:QI 3 "general_operand" "")))]
18986   "TARGET_QIMODE_MATH"
18987   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18988
18989 (define_insn_and_split "*movqicc_noc"
18990   [(set (match_operand:QI 0 "register_operand" "=r,r")
18991         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18992                                 [(match_operand 4 "flags_reg_operand" "")
18993                                  (const_int 0)])
18994                       (match_operand:QI 2 "register_operand" "r,0")
18995                       (match_operand:QI 3 "register_operand" "0,r")))]
18996   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18997   "#"
18998   "&& reload_completed"
18999   [(set (match_dup 0)
19000         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19001                       (match_dup 2)
19002                       (match_dup 3)))]
19003   "operands[0] = gen_lowpart (SImode, operands[0]);
19004    operands[2] = gen_lowpart (SImode, operands[2]);
19005    operands[3] = gen_lowpart (SImode, operands[3]);"
19006   [(set_attr "type" "icmov")
19007    (set_attr "mode" "SI")])
19008
19009 (define_expand "movsfcc"
19010   [(set (match_operand:SF 0 "register_operand" "")
19011         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19012                          (match_operand:SF 2 "register_operand" "")
19013                          (match_operand:SF 3 "register_operand" "")))]
19014   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19015   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19016
19017 (define_insn "*movsfcc_1_387"
19018   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19019         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19020                                 [(reg FLAGS_REG) (const_int 0)])
19021                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19022                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19023   "TARGET_80387 && TARGET_CMOVE
19024    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19025   "@
19026    fcmov%F1\t{%2, %0|%0, %2}
19027    fcmov%f1\t{%3, %0|%0, %3}
19028    cmov%O2%C1\t{%2, %0|%0, %2}
19029    cmov%O2%c1\t{%3, %0|%0, %3}"
19030   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19031    (set_attr "mode" "SF,SF,SI,SI")])
19032
19033 (define_expand "movdfcc"
19034   [(set (match_operand:DF 0 "register_operand" "")
19035         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19036                          (match_operand:DF 2 "register_operand" "")
19037                          (match_operand:DF 3 "register_operand" "")))]
19038   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19039   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19040
19041 (define_insn "*movdfcc_1"
19042   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19043         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19044                                 [(reg FLAGS_REG) (const_int 0)])
19045                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19046                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19047   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19048    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19049   "@
19050    fcmov%F1\t{%2, %0|%0, %2}
19051    fcmov%f1\t{%3, %0|%0, %3}
19052    #
19053    #"
19054   [(set_attr "type" "fcmov,fcmov,multi,multi")
19055    (set_attr "mode" "DF")])
19056
19057 (define_insn "*movdfcc_1_rex64"
19058   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19059         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19060                                 [(reg FLAGS_REG) (const_int 0)])
19061                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19062                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19063   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19064    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19065   "@
19066    fcmov%F1\t{%2, %0|%0, %2}
19067    fcmov%f1\t{%3, %0|%0, %3}
19068    cmov%O2%C1\t{%2, %0|%0, %2}
19069    cmov%O2%c1\t{%3, %0|%0, %3}"
19070   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19071    (set_attr "mode" "DF")])
19072
19073 (define_split
19074   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19075         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19076                                 [(match_operand 4 "flags_reg_operand" "")
19077                                  (const_int 0)])
19078                       (match_operand:DF 2 "nonimmediate_operand" "")
19079                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19080   "!TARGET_64BIT && reload_completed"
19081   [(set (match_dup 2)
19082         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19083                       (match_dup 5)
19084                       (match_dup 7)))
19085    (set (match_dup 3)
19086         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19087                       (match_dup 6)
19088                       (match_dup 8)))]
19089   "split_di (operands+2, 1, operands+5, operands+6);
19090    split_di (operands+3, 1, operands+7, operands+8);
19091    split_di (operands, 1, operands+2, operands+3);")
19092
19093 (define_expand "movxfcc"
19094   [(set (match_operand:XF 0 "register_operand" "")
19095         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19096                          (match_operand:XF 2 "register_operand" "")
19097                          (match_operand:XF 3 "register_operand" "")))]
19098   "TARGET_80387 && TARGET_CMOVE"
19099   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19100
19101 (define_insn "*movxfcc_1"
19102   [(set (match_operand:XF 0 "register_operand" "=f,f")
19103         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19104                                 [(reg FLAGS_REG) (const_int 0)])
19105                       (match_operand:XF 2 "register_operand" "f,0")
19106                       (match_operand:XF 3 "register_operand" "0,f")))]
19107   "TARGET_80387 && TARGET_CMOVE"
19108   "@
19109    fcmov%F1\t{%2, %0|%0, %2}
19110    fcmov%f1\t{%3, %0|%0, %3}"
19111   [(set_attr "type" "fcmov")
19112    (set_attr "mode" "XF")])
19113
19114 ;; These versions of the min/max patterns are intentionally ignorant of
19115 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19116 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19117 ;; are undefined in this condition, we're certain this is correct.
19118
19119 (define_insn "sminsf3"
19120   [(set (match_operand:SF 0 "register_operand" "=x")
19121         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19122                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19123   "TARGET_SSE_MATH"
19124   "minss\t{%2, %0|%0, %2}"
19125   [(set_attr "type" "sseadd")
19126    (set_attr "mode" "SF")])
19127
19128 (define_insn "smaxsf3"
19129   [(set (match_operand:SF 0 "register_operand" "=x")
19130         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19131                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19132   "TARGET_SSE_MATH"
19133   "maxss\t{%2, %0|%0, %2}"
19134   [(set_attr "type" "sseadd")
19135    (set_attr "mode" "SF")])
19136
19137 (define_insn "smindf3"
19138   [(set (match_operand:DF 0 "register_operand" "=x")
19139         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19140                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19141   "TARGET_SSE2 && TARGET_SSE_MATH"
19142   "minsd\t{%2, %0|%0, %2}"
19143   [(set_attr "type" "sseadd")
19144    (set_attr "mode" "DF")])
19145
19146 (define_insn "smaxdf3"
19147   [(set (match_operand:DF 0 "register_operand" "=x")
19148         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19149                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19150   "TARGET_SSE2 && TARGET_SSE_MATH"
19151   "maxsd\t{%2, %0|%0, %2}"
19152   [(set_attr "type" "sseadd")
19153    (set_attr "mode" "DF")])
19154
19155 ;; These versions of the min/max patterns implement exactly the operations
19156 ;;   min = (op1 < op2 ? op1 : op2)
19157 ;;   max = (!(op1 < op2) ? op1 : op2)
19158 ;; Their operands are not commutative, and thus they may be used in the
19159 ;; presence of -0.0 and NaN.
19160
19161 (define_insn "*ieee_sminsf3"
19162   [(set (match_operand:SF 0 "register_operand" "=x")
19163         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19164                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19165                    UNSPEC_IEEE_MIN))]
19166   "TARGET_SSE_MATH"
19167   "minss\t{%2, %0|%0, %2}"
19168   [(set_attr "type" "sseadd")
19169    (set_attr "mode" "SF")])
19170
19171 (define_insn "*ieee_smaxsf3"
19172   [(set (match_operand:SF 0 "register_operand" "=x")
19173         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19174                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19175                    UNSPEC_IEEE_MAX))]
19176   "TARGET_SSE_MATH"
19177   "maxss\t{%2, %0|%0, %2}"
19178   [(set_attr "type" "sseadd")
19179    (set_attr "mode" "SF")])
19180
19181 (define_insn "*ieee_smindf3"
19182   [(set (match_operand:DF 0 "register_operand" "=x")
19183         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19184                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19185                    UNSPEC_IEEE_MIN))]
19186   "TARGET_SSE2 && TARGET_SSE_MATH"
19187   "minsd\t{%2, %0|%0, %2}"
19188   [(set_attr "type" "sseadd")
19189    (set_attr "mode" "DF")])
19190
19191 (define_insn "*ieee_smaxdf3"
19192   [(set (match_operand:DF 0 "register_operand" "=x")
19193         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19194                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19195                    UNSPEC_IEEE_MAX))]
19196   "TARGET_SSE2 && TARGET_SSE_MATH"
19197   "maxsd\t{%2, %0|%0, %2}"
19198   [(set_attr "type" "sseadd")
19199    (set_attr "mode" "DF")])
19200
19201 ;; Make two stack loads independent:
19202 ;;   fld aa              fld aa
19203 ;;   fld %st(0)     ->   fld bb
19204 ;;   fmul bb             fmul %st(1), %st
19205 ;;
19206 ;; Actually we only match the last two instructions for simplicity.
19207 (define_peephole2
19208   [(set (match_operand 0 "fp_register_operand" "")
19209         (match_operand 1 "fp_register_operand" ""))
19210    (set (match_dup 0)
19211         (match_operator 2 "binary_fp_operator"
19212            [(match_dup 0)
19213             (match_operand 3 "memory_operand" "")]))]
19214   "REGNO (operands[0]) != REGNO (operands[1])"
19215   [(set (match_dup 0) (match_dup 3))
19216    (set (match_dup 0) (match_dup 4))]
19217
19218   ;; The % modifier is not operational anymore in peephole2's, so we have to
19219   ;; swap the operands manually in the case of addition and multiplication.
19220   "if (COMMUTATIVE_ARITH_P (operands[2]))
19221      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19222                                  operands[0], operands[1]);
19223    else
19224      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19225                                  operands[1], operands[0]);")
19226
19227 ;; Conditional addition patterns
19228 (define_expand "addqicc"
19229   [(match_operand:QI 0 "register_operand" "")
19230    (match_operand 1 "comparison_operator" "")
19231    (match_operand:QI 2 "register_operand" "")
19232    (match_operand:QI 3 "const_int_operand" "")]
19233   ""
19234   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19235
19236 (define_expand "addhicc"
19237   [(match_operand:HI 0 "register_operand" "")
19238    (match_operand 1 "comparison_operator" "")
19239    (match_operand:HI 2 "register_operand" "")
19240    (match_operand:HI 3 "const_int_operand" "")]
19241   ""
19242   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19243
19244 (define_expand "addsicc"
19245   [(match_operand:SI 0 "register_operand" "")
19246    (match_operand 1 "comparison_operator" "")
19247    (match_operand:SI 2 "register_operand" "")
19248    (match_operand:SI 3 "const_int_operand" "")]
19249   ""
19250   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19251
19252 (define_expand "adddicc"
19253   [(match_operand:DI 0 "register_operand" "")
19254    (match_operand 1 "comparison_operator" "")
19255    (match_operand:DI 2 "register_operand" "")
19256    (match_operand:DI 3 "const_int_operand" "")]
19257   "TARGET_64BIT"
19258   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19259
19260 \f
19261 ;; Misc patterns (?)
19262
19263 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19264 ;; Otherwise there will be nothing to keep
19265 ;; 
19266 ;; [(set (reg ebp) (reg esp))]
19267 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19268 ;;  (clobber (eflags)]
19269 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19270 ;;
19271 ;; in proper program order.
19272 (define_insn "pro_epilogue_adjust_stack_1"
19273   [(set (match_operand:SI 0 "register_operand" "=r,r")
19274         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19275                  (match_operand:SI 2 "immediate_operand" "i,i")))
19276    (clobber (reg:CC FLAGS_REG))
19277    (clobber (mem:BLK (scratch)))]
19278   "!TARGET_64BIT"
19279 {
19280   switch (get_attr_type (insn))
19281     {
19282     case TYPE_IMOV:
19283       return "mov{l}\t{%1, %0|%0, %1}";
19284
19285     case TYPE_ALU:
19286       if (GET_CODE (operands[2]) == CONST_INT
19287           && (INTVAL (operands[2]) == 128
19288               || (INTVAL (operands[2]) < 0
19289                   && INTVAL (operands[2]) != -128)))
19290         {
19291           operands[2] = GEN_INT (-INTVAL (operands[2]));
19292           return "sub{l}\t{%2, %0|%0, %2}";
19293         }
19294       return "add{l}\t{%2, %0|%0, %2}";
19295
19296     case TYPE_LEA:
19297       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19298       return "lea{l}\t{%a2, %0|%0, %a2}";
19299
19300     default:
19301       gcc_unreachable ();
19302     }
19303 }
19304   [(set (attr "type")
19305         (cond [(eq_attr "alternative" "0")
19306                  (const_string "alu")
19307                (match_operand:SI 2 "const0_operand" "")
19308                  (const_string "imov")
19309               ]
19310               (const_string "lea")))
19311    (set_attr "mode" "SI")])
19312
19313 (define_insn "pro_epilogue_adjust_stack_rex64"
19314   [(set (match_operand:DI 0 "register_operand" "=r,r")
19315         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19316                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19317    (clobber (reg:CC FLAGS_REG))
19318    (clobber (mem:BLK (scratch)))]
19319   "TARGET_64BIT"
19320 {
19321   switch (get_attr_type (insn))
19322     {
19323     case TYPE_IMOV:
19324       return "mov{q}\t{%1, %0|%0, %1}";
19325
19326     case TYPE_ALU:
19327       if (GET_CODE (operands[2]) == CONST_INT
19328           /* Avoid overflows.  */
19329           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19330           && (INTVAL (operands[2]) == 128
19331               || (INTVAL (operands[2]) < 0
19332                   && INTVAL (operands[2]) != -128)))
19333         {
19334           operands[2] = GEN_INT (-INTVAL (operands[2]));
19335           return "sub{q}\t{%2, %0|%0, %2}";
19336         }
19337       return "add{q}\t{%2, %0|%0, %2}";
19338
19339     case TYPE_LEA:
19340       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19341       return "lea{q}\t{%a2, %0|%0, %a2}";
19342
19343     default:
19344       gcc_unreachable ();
19345     }
19346 }
19347   [(set (attr "type")
19348         (cond [(eq_attr "alternative" "0")
19349                  (const_string "alu")
19350                (match_operand:DI 2 "const0_operand" "")
19351                  (const_string "imov")
19352               ]
19353               (const_string "lea")))
19354    (set_attr "mode" "DI")])
19355
19356 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19357   [(set (match_operand:DI 0 "register_operand" "=r,r")
19358         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19359                  (match_operand:DI 3 "immediate_operand" "i,i")))
19360    (use (match_operand:DI 2 "register_operand" "r,r"))
19361    (clobber (reg:CC FLAGS_REG))
19362    (clobber (mem:BLK (scratch)))]
19363   "TARGET_64BIT"
19364 {
19365   switch (get_attr_type (insn))
19366     {
19367     case TYPE_ALU:
19368       return "add{q}\t{%2, %0|%0, %2}";
19369
19370     case TYPE_LEA:
19371       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19372       return "lea{q}\t{%a2, %0|%0, %a2}";
19373
19374     default:
19375       gcc_unreachable ();
19376     }
19377 }
19378   [(set_attr "type" "alu,lea")
19379    (set_attr "mode" "DI")])
19380
19381 (define_expand "allocate_stack_worker"
19382   [(match_operand:SI 0 "register_operand" "")]
19383   "TARGET_STACK_PROBE"
19384 {
19385   if (reload_completed)
19386     {
19387       if (TARGET_64BIT)
19388         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19389       else
19390         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19391     }
19392   else
19393     {
19394       if (TARGET_64BIT)
19395         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19396       else
19397         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19398     }
19399   DONE;
19400 })
19401
19402 (define_insn "allocate_stack_worker_1"
19403   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19404     UNSPECV_STACK_PROBE)
19405    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19406    (clobber (match_scratch:SI 1 "=0"))
19407    (clobber (reg:CC FLAGS_REG))]
19408   "!TARGET_64BIT && TARGET_STACK_PROBE"
19409   "call\t__alloca"
19410   [(set_attr "type" "multi")
19411    (set_attr "length" "5")])
19412
19413 (define_expand "allocate_stack_worker_postreload"
19414   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19415                                     UNSPECV_STACK_PROBE)
19416               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19417               (clobber (match_dup 0))
19418               (clobber (reg:CC FLAGS_REG))])]
19419   ""
19420   "")
19421
19422 (define_insn "allocate_stack_worker_rex64"
19423   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19424     UNSPECV_STACK_PROBE)
19425    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19426    (clobber (match_scratch:DI 1 "=0"))
19427    (clobber (reg:CC FLAGS_REG))]
19428   "TARGET_64BIT && TARGET_STACK_PROBE"
19429   "call\t__alloca"
19430   [(set_attr "type" "multi")
19431    (set_attr "length" "5")])
19432
19433 (define_expand "allocate_stack_worker_rex64_postreload"
19434   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19435                                     UNSPECV_STACK_PROBE)
19436               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19437               (clobber (match_dup 0))
19438               (clobber (reg:CC FLAGS_REG))])]
19439   ""
19440   "")
19441
19442 (define_expand "allocate_stack"
19443   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19444                    (minus:SI (reg:SI SP_REG)
19445                              (match_operand:SI 1 "general_operand" "")))
19446               (clobber (reg:CC FLAGS_REG))])
19447    (parallel [(set (reg:SI SP_REG)
19448                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19449               (clobber (reg:CC FLAGS_REG))])]
19450   "TARGET_STACK_PROBE"
19451 {
19452 #ifdef CHECK_STACK_LIMIT
19453   if (GET_CODE (operands[1]) == CONST_INT
19454       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19455     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19456                            operands[1]));
19457   else 
19458 #endif
19459     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19460                                                             operands[1])));
19461
19462   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19463   DONE;
19464 })
19465
19466 (define_expand "builtin_setjmp_receiver"
19467   [(label_ref (match_operand 0 "" ""))]
19468   "!TARGET_64BIT && flag_pic"
19469 {
19470   if (TARGET_MACHO)
19471     {
19472       rtx xops[3];
19473       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19474       rtx label_rtx = gen_label_rtx ();
19475       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19476       xops[0] = xops[1] = picreg;
19477       xops[2] = gen_rtx_CONST (SImode,
19478                   gen_rtx_MINUS (SImode,
19479                     gen_rtx_LABEL_REF (SImode, label_rtx),
19480                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19481       ix86_expand_binary_operator (MINUS, SImode, xops);
19482     }
19483   else
19484     emit_insn (gen_set_got (pic_offset_table_rtx));
19485   DONE;
19486 })
19487 \f
19488 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19489
19490 (define_split
19491   [(set (match_operand 0 "register_operand" "")
19492         (match_operator 3 "promotable_binary_operator"
19493            [(match_operand 1 "register_operand" "")
19494             (match_operand 2 "aligned_operand" "")]))
19495    (clobber (reg:CC FLAGS_REG))]
19496   "! TARGET_PARTIAL_REG_STALL && reload_completed
19497    && ((GET_MODE (operands[0]) == HImode 
19498         && ((!optimize_size && !TARGET_FAST_PREFIX)
19499             /* ??? next two lines just !satisfies_constraint_K (...) */
19500             || GET_CODE (operands[2]) != CONST_INT
19501             || satisfies_constraint_K (operands[2])))
19502        || (GET_MODE (operands[0]) == QImode 
19503            && (TARGET_PROMOTE_QImode || optimize_size)))"
19504   [(parallel [(set (match_dup 0)
19505                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19506               (clobber (reg:CC FLAGS_REG))])]
19507   "operands[0] = gen_lowpart (SImode, operands[0]);
19508    operands[1] = gen_lowpart (SImode, operands[1]);
19509    if (GET_CODE (operands[3]) != ASHIFT)
19510      operands[2] = gen_lowpart (SImode, operands[2]);
19511    PUT_MODE (operands[3], SImode);")
19512
19513 ; Promote the QImode tests, as i386 has encoding of the AND
19514 ; instruction with 32-bit sign-extended immediate and thus the
19515 ; instruction size is unchanged, except in the %eax case for
19516 ; which it is increased by one byte, hence the ! optimize_size.
19517 (define_split
19518   [(set (match_operand 0 "flags_reg_operand" "")
19519         (match_operator 2 "compare_operator"
19520           [(and (match_operand 3 "aligned_operand" "")
19521                 (match_operand 4 "const_int_operand" ""))
19522            (const_int 0)]))
19523    (set (match_operand 1 "register_operand" "")
19524         (and (match_dup 3) (match_dup 4)))]
19525   "! TARGET_PARTIAL_REG_STALL && reload_completed
19526    /* Ensure that the operand will remain sign-extended immediate.  */
19527    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19528    && ! optimize_size
19529    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19530        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19531   [(parallel [(set (match_dup 0)
19532                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19533                                     (const_int 0)]))
19534               (set (match_dup 1)
19535                    (and:SI (match_dup 3) (match_dup 4)))])]
19536 {
19537   operands[4]
19538     = gen_int_mode (INTVAL (operands[4])
19539                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19540   operands[1] = gen_lowpart (SImode, operands[1]);
19541   operands[3] = gen_lowpart (SImode, operands[3]);
19542 })
19543
19544 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19545 ; the TEST instruction with 32-bit sign-extended immediate and thus
19546 ; the instruction size would at least double, which is not what we
19547 ; want even with ! optimize_size.
19548 (define_split
19549   [(set (match_operand 0 "flags_reg_operand" "")
19550         (match_operator 1 "compare_operator"
19551           [(and (match_operand:HI 2 "aligned_operand" "")
19552                 (match_operand:HI 3 "const_int_operand" ""))
19553            (const_int 0)]))]
19554   "! TARGET_PARTIAL_REG_STALL && reload_completed
19555    /* Ensure that the operand will remain sign-extended immediate.  */
19556    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19557    && ! TARGET_FAST_PREFIX
19558    && ! optimize_size"
19559   [(set (match_dup 0)
19560         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19561                          (const_int 0)]))]
19562 {
19563   operands[3]
19564     = gen_int_mode (INTVAL (operands[3])
19565                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19566   operands[2] = gen_lowpart (SImode, operands[2]);
19567 })
19568
19569 (define_split
19570   [(set (match_operand 0 "register_operand" "")
19571         (neg (match_operand 1 "register_operand" "")))
19572    (clobber (reg:CC FLAGS_REG))]
19573   "! TARGET_PARTIAL_REG_STALL && reload_completed
19574    && (GET_MODE (operands[0]) == HImode
19575        || (GET_MODE (operands[0]) == QImode 
19576            && (TARGET_PROMOTE_QImode || optimize_size)))"
19577   [(parallel [(set (match_dup 0)
19578                    (neg:SI (match_dup 1)))
19579               (clobber (reg:CC FLAGS_REG))])]
19580   "operands[0] = gen_lowpart (SImode, operands[0]);
19581    operands[1] = gen_lowpart (SImode, operands[1]);")
19582
19583 (define_split
19584   [(set (match_operand 0 "register_operand" "")
19585         (not (match_operand 1 "register_operand" "")))]
19586   "! TARGET_PARTIAL_REG_STALL && reload_completed
19587    && (GET_MODE (operands[0]) == HImode
19588        || (GET_MODE (operands[0]) == QImode 
19589            && (TARGET_PROMOTE_QImode || optimize_size)))"
19590   [(set (match_dup 0)
19591         (not:SI (match_dup 1)))]
19592   "operands[0] = gen_lowpart (SImode, operands[0]);
19593    operands[1] = gen_lowpart (SImode, operands[1]);")
19594
19595 (define_split 
19596   [(set (match_operand 0 "register_operand" "")
19597         (if_then_else (match_operator 1 "comparison_operator" 
19598                                 [(reg FLAGS_REG) (const_int 0)])
19599                       (match_operand 2 "register_operand" "")
19600                       (match_operand 3 "register_operand" "")))]
19601   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19602    && (GET_MODE (operands[0]) == HImode
19603        || (GET_MODE (operands[0]) == QImode 
19604            && (TARGET_PROMOTE_QImode || optimize_size)))"
19605   [(set (match_dup 0)
19606         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19607   "operands[0] = gen_lowpart (SImode, operands[0]);
19608    operands[2] = gen_lowpart (SImode, operands[2]);
19609    operands[3] = gen_lowpart (SImode, operands[3]);")
19610                         
19611 \f
19612 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19613 ;; transform a complex memory operation into two memory to register operations.
19614
19615 ;; Don't push memory operands
19616 (define_peephole2
19617   [(set (match_operand:SI 0 "push_operand" "")
19618         (match_operand:SI 1 "memory_operand" ""))
19619    (match_scratch:SI 2 "r")]
19620   "!optimize_size && !TARGET_PUSH_MEMORY
19621    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19622   [(set (match_dup 2) (match_dup 1))
19623    (set (match_dup 0) (match_dup 2))]
19624   "")
19625
19626 (define_peephole2
19627   [(set (match_operand:DI 0 "push_operand" "")
19628         (match_operand:DI 1 "memory_operand" ""))
19629    (match_scratch:DI 2 "r")]
19630   "!optimize_size && !TARGET_PUSH_MEMORY
19631    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19632   [(set (match_dup 2) (match_dup 1))
19633    (set (match_dup 0) (match_dup 2))]
19634   "")
19635
19636 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19637 ;; SImode pushes.
19638 (define_peephole2
19639   [(set (match_operand:SF 0 "push_operand" "")
19640         (match_operand:SF 1 "memory_operand" ""))
19641    (match_scratch:SF 2 "r")]
19642   "!optimize_size && !TARGET_PUSH_MEMORY
19643    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19644   [(set (match_dup 2) (match_dup 1))
19645    (set (match_dup 0) (match_dup 2))]
19646   "")
19647
19648 (define_peephole2
19649   [(set (match_operand:HI 0 "push_operand" "")
19650         (match_operand:HI 1 "memory_operand" ""))
19651    (match_scratch:HI 2 "r")]
19652   "!optimize_size && !TARGET_PUSH_MEMORY
19653    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19654   [(set (match_dup 2) (match_dup 1))
19655    (set (match_dup 0) (match_dup 2))]
19656   "")
19657
19658 (define_peephole2
19659   [(set (match_operand:QI 0 "push_operand" "")
19660         (match_operand:QI 1 "memory_operand" ""))
19661    (match_scratch:QI 2 "q")]
19662   "!optimize_size && !TARGET_PUSH_MEMORY
19663    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19664   [(set (match_dup 2) (match_dup 1))
19665    (set (match_dup 0) (match_dup 2))]
19666   "")
19667
19668 ;; Don't move an immediate directly to memory when the instruction
19669 ;; gets too big.
19670 (define_peephole2
19671   [(match_scratch:SI 1 "r")
19672    (set (match_operand:SI 0 "memory_operand" "")
19673         (const_int 0))]
19674   "! optimize_size
19675    && ! TARGET_USE_MOV0
19676    && TARGET_SPLIT_LONG_MOVES
19677    && get_attr_length (insn) >= ix86_cost->large_insn
19678    && peep2_regno_dead_p (0, FLAGS_REG)"
19679   [(parallel [(set (match_dup 1) (const_int 0))
19680               (clobber (reg:CC FLAGS_REG))])
19681    (set (match_dup 0) (match_dup 1))]
19682   "")
19683
19684 (define_peephole2
19685   [(match_scratch:HI 1 "r")
19686    (set (match_operand:HI 0 "memory_operand" "")
19687         (const_int 0))]
19688   "! optimize_size
19689    && ! TARGET_USE_MOV0
19690    && TARGET_SPLIT_LONG_MOVES
19691    && get_attr_length (insn) >= ix86_cost->large_insn
19692    && peep2_regno_dead_p (0, FLAGS_REG)"
19693   [(parallel [(set (match_dup 2) (const_int 0))
19694               (clobber (reg:CC FLAGS_REG))])
19695    (set (match_dup 0) (match_dup 1))]
19696   "operands[2] = gen_lowpart (SImode, operands[1]);")
19697
19698 (define_peephole2
19699   [(match_scratch:QI 1 "q")
19700    (set (match_operand:QI 0 "memory_operand" "")
19701         (const_int 0))]
19702   "! optimize_size
19703    && ! TARGET_USE_MOV0
19704    && TARGET_SPLIT_LONG_MOVES
19705    && get_attr_length (insn) >= ix86_cost->large_insn
19706    && peep2_regno_dead_p (0, FLAGS_REG)"
19707   [(parallel [(set (match_dup 2) (const_int 0))
19708               (clobber (reg:CC FLAGS_REG))])
19709    (set (match_dup 0) (match_dup 1))]
19710   "operands[2] = gen_lowpart (SImode, operands[1]);")
19711
19712 (define_peephole2
19713   [(match_scratch:SI 2 "r")
19714    (set (match_operand:SI 0 "memory_operand" "")
19715         (match_operand:SI 1 "immediate_operand" ""))]
19716   "! optimize_size
19717    && get_attr_length (insn) >= ix86_cost->large_insn
19718    && TARGET_SPLIT_LONG_MOVES"
19719   [(set (match_dup 2) (match_dup 1))
19720    (set (match_dup 0) (match_dup 2))]
19721   "")
19722
19723 (define_peephole2
19724   [(match_scratch:HI 2 "r")
19725    (set (match_operand:HI 0 "memory_operand" "")
19726         (match_operand:HI 1 "immediate_operand" ""))]
19727   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19728   && TARGET_SPLIT_LONG_MOVES"
19729   [(set (match_dup 2) (match_dup 1))
19730    (set (match_dup 0) (match_dup 2))]
19731   "")
19732
19733 (define_peephole2
19734   [(match_scratch:QI 2 "q")
19735    (set (match_operand:QI 0 "memory_operand" "")
19736         (match_operand:QI 1 "immediate_operand" ""))]
19737   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19738   && TARGET_SPLIT_LONG_MOVES"
19739   [(set (match_dup 2) (match_dup 1))
19740    (set (match_dup 0) (match_dup 2))]
19741   "")
19742
19743 ;; Don't compare memory with zero, load and use a test instead.
19744 (define_peephole2
19745   [(set (match_operand 0 "flags_reg_operand" "")
19746         (match_operator 1 "compare_operator"
19747           [(match_operand:SI 2 "memory_operand" "")
19748            (const_int 0)]))
19749    (match_scratch:SI 3 "r")]
19750   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19751   [(set (match_dup 3) (match_dup 2))
19752    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19753   "")
19754
19755 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19756 ;; Don't split NOTs with a displacement operand, because resulting XOR
19757 ;; will not be pairable anyway.
19758 ;;
19759 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19760 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19761 ;; so this split helps here as well.
19762 ;;
19763 ;; Note: Can't do this as a regular split because we can't get proper
19764 ;; lifetime information then.
19765
19766 (define_peephole2
19767   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19768         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19769   "!optimize_size
19770    && peep2_regno_dead_p (0, FLAGS_REG)
19771    && ((TARGET_PENTIUM 
19772         && (GET_CODE (operands[0]) != MEM
19773             || !memory_displacement_operand (operands[0], SImode)))
19774        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19775   [(parallel [(set (match_dup 0)
19776                    (xor:SI (match_dup 1) (const_int -1)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "")
19779
19780 (define_peephole2
19781   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19782         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19783   "!optimize_size
19784    && peep2_regno_dead_p (0, FLAGS_REG)
19785    && ((TARGET_PENTIUM 
19786         && (GET_CODE (operands[0]) != MEM
19787             || !memory_displacement_operand (operands[0], HImode)))
19788        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19789   [(parallel [(set (match_dup 0)
19790                    (xor:HI (match_dup 1) (const_int -1)))
19791               (clobber (reg:CC FLAGS_REG))])]
19792   "")
19793
19794 (define_peephole2
19795   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19796         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19797   "!optimize_size
19798    && peep2_regno_dead_p (0, FLAGS_REG)
19799    && ((TARGET_PENTIUM 
19800         && (GET_CODE (operands[0]) != MEM
19801             || !memory_displacement_operand (operands[0], QImode)))
19802        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19803   [(parallel [(set (match_dup 0)
19804                    (xor:QI (match_dup 1) (const_int -1)))
19805               (clobber (reg:CC FLAGS_REG))])]
19806   "")
19807
19808 ;; Non pairable "test imm, reg" instructions can be translated to
19809 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19810 ;; byte opcode instead of two, have a short form for byte operands),
19811 ;; so do it for other CPUs as well.  Given that the value was dead,
19812 ;; this should not create any new dependencies.  Pass on the sub-word
19813 ;; versions if we're concerned about partial register stalls.
19814
19815 (define_peephole2
19816   [(set (match_operand 0 "flags_reg_operand" "")
19817         (match_operator 1 "compare_operator"
19818           [(and:SI (match_operand:SI 2 "register_operand" "")
19819                    (match_operand:SI 3 "immediate_operand" ""))
19820            (const_int 0)]))]
19821   "ix86_match_ccmode (insn, CCNOmode)
19822    && (true_regnum (operands[2]) != 0
19823        || satisfies_constraint_K (operands[3]))
19824    && peep2_reg_dead_p (1, operands[2])"
19825   [(parallel
19826      [(set (match_dup 0)
19827            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19828                             (const_int 0)]))
19829       (set (match_dup 2)
19830            (and:SI (match_dup 2) (match_dup 3)))])]
19831   "")
19832
19833 ;; We don't need to handle HImode case, because it will be promoted to SImode
19834 ;; on ! TARGET_PARTIAL_REG_STALL
19835
19836 (define_peephole2
19837   [(set (match_operand 0 "flags_reg_operand" "")
19838         (match_operator 1 "compare_operator"
19839           [(and:QI (match_operand:QI 2 "register_operand" "")
19840                    (match_operand:QI 3 "immediate_operand" ""))
19841            (const_int 0)]))]
19842   "! TARGET_PARTIAL_REG_STALL
19843    && ix86_match_ccmode (insn, CCNOmode)
19844    && true_regnum (operands[2]) != 0
19845    && peep2_reg_dead_p (1, operands[2])"
19846   [(parallel
19847      [(set (match_dup 0)
19848            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19849                             (const_int 0)]))
19850       (set (match_dup 2)
19851            (and:QI (match_dup 2) (match_dup 3)))])]
19852   "")
19853
19854 (define_peephole2
19855   [(set (match_operand 0 "flags_reg_operand" "")
19856         (match_operator 1 "compare_operator"
19857           [(and:SI
19858              (zero_extract:SI
19859                (match_operand 2 "ext_register_operand" "")
19860                (const_int 8)
19861                (const_int 8))
19862              (match_operand 3 "const_int_operand" ""))
19863            (const_int 0)]))]
19864   "! TARGET_PARTIAL_REG_STALL
19865    && ix86_match_ccmode (insn, CCNOmode)
19866    && true_regnum (operands[2]) != 0
19867    && peep2_reg_dead_p (1, operands[2])"
19868   [(parallel [(set (match_dup 0)
19869                    (match_op_dup 1
19870                      [(and:SI
19871                         (zero_extract:SI
19872                           (match_dup 2)
19873                           (const_int 8)
19874                           (const_int 8))
19875                         (match_dup 3))
19876                       (const_int 0)]))
19877               (set (zero_extract:SI (match_dup 2)
19878                                     (const_int 8)
19879                                     (const_int 8))
19880                    (and:SI 
19881                      (zero_extract:SI
19882                        (match_dup 2)
19883                        (const_int 8)
19884                        (const_int 8))
19885                      (match_dup 3)))])]
19886   "")
19887
19888 ;; Don't do logical operations with memory inputs.
19889 (define_peephole2
19890   [(match_scratch:SI 2 "r")
19891    (parallel [(set (match_operand:SI 0 "register_operand" "")
19892                    (match_operator:SI 3 "arith_or_logical_operator"
19893                      [(match_dup 0)
19894                       (match_operand:SI 1 "memory_operand" "")]))
19895               (clobber (reg:CC FLAGS_REG))])]
19896   "! optimize_size && ! TARGET_READ_MODIFY"
19897   [(set (match_dup 2) (match_dup 1))
19898    (parallel [(set (match_dup 0)
19899                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19900               (clobber (reg:CC FLAGS_REG))])]
19901   "")
19902
19903 (define_peephole2
19904   [(match_scratch:SI 2 "r")
19905    (parallel [(set (match_operand:SI 0 "register_operand" "")
19906                    (match_operator:SI 3 "arith_or_logical_operator"
19907                      [(match_operand:SI 1 "memory_operand" "")
19908                       (match_dup 0)]))
19909               (clobber (reg:CC FLAGS_REG))])]
19910   "! optimize_size && ! TARGET_READ_MODIFY"
19911   [(set (match_dup 2) (match_dup 1))
19912    (parallel [(set (match_dup 0)
19913                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19914               (clobber (reg:CC FLAGS_REG))])]
19915   "")
19916
19917 ; Don't do logical operations with memory outputs
19918 ;
19919 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19920 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19921 ; the same decoder scheduling characteristics as the original.
19922
19923 (define_peephole2
19924   [(match_scratch:SI 2 "r")
19925    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19926                    (match_operator:SI 3 "arith_or_logical_operator"
19927                      [(match_dup 0)
19928                       (match_operand:SI 1 "nonmemory_operand" "")]))
19929               (clobber (reg:CC FLAGS_REG))])]
19930   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19931   [(set (match_dup 2) (match_dup 0))
19932    (parallel [(set (match_dup 2)
19933                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19934               (clobber (reg:CC FLAGS_REG))])
19935    (set (match_dup 0) (match_dup 2))]
19936   "")
19937
19938 (define_peephole2
19939   [(match_scratch:SI 2 "r")
19940    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19941                    (match_operator:SI 3 "arith_or_logical_operator"
19942                      [(match_operand:SI 1 "nonmemory_operand" "")
19943                       (match_dup 0)]))
19944               (clobber (reg:CC FLAGS_REG))])]
19945   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19946   [(set (match_dup 2) (match_dup 0))
19947    (parallel [(set (match_dup 2)
19948                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19949               (clobber (reg:CC FLAGS_REG))])
19950    (set (match_dup 0) (match_dup 2))]
19951   "")
19952
19953 ;; Attempt to always use XOR for zeroing registers.
19954 (define_peephole2
19955   [(set (match_operand 0 "register_operand" "")
19956         (match_operand 1 "const0_operand" ""))]
19957   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19958    && (! TARGET_USE_MOV0 || optimize_size)
19959    && GENERAL_REG_P (operands[0])
19960    && peep2_regno_dead_p (0, FLAGS_REG)"
19961   [(parallel [(set (match_dup 0) (const_int 0))
19962               (clobber (reg:CC FLAGS_REG))])]
19963 {
19964   operands[0] = gen_lowpart (word_mode, operands[0]);
19965 })
19966
19967 (define_peephole2
19968   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19969         (const_int 0))]
19970   "(GET_MODE (operands[0]) == QImode
19971     || GET_MODE (operands[0]) == HImode)
19972    && (! TARGET_USE_MOV0 || optimize_size)
19973    && peep2_regno_dead_p (0, FLAGS_REG)"
19974   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19975               (clobber (reg:CC FLAGS_REG))])])
19976
19977 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19978 (define_peephole2
19979   [(set (match_operand 0 "register_operand" "")
19980         (const_int -1))]
19981   "(GET_MODE (operands[0]) == HImode
19982     || GET_MODE (operands[0]) == SImode 
19983     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19984    && (optimize_size || TARGET_PENTIUM)
19985    && peep2_regno_dead_p (0, FLAGS_REG)"
19986   [(parallel [(set (match_dup 0) (const_int -1))
19987               (clobber (reg:CC FLAGS_REG))])]
19988   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19989                               operands[0]);")
19990
19991 ;; Attempt to convert simple leas to adds. These can be created by
19992 ;; move expanders.
19993 (define_peephole2
19994   [(set (match_operand:SI 0 "register_operand" "")
19995         (plus:SI (match_dup 0)
19996                  (match_operand:SI 1 "nonmemory_operand" "")))]
19997   "peep2_regno_dead_p (0, FLAGS_REG)"
19998   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19999               (clobber (reg:CC FLAGS_REG))])]
20000   "")
20001
20002 (define_peephole2
20003   [(set (match_operand:SI 0 "register_operand" "")
20004         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20005                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20006   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20007   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20008               (clobber (reg:CC FLAGS_REG))])]
20009   "operands[2] = gen_lowpart (SImode, operands[2]);")
20010
20011 (define_peephole2
20012   [(set (match_operand:DI 0 "register_operand" "")
20013         (plus:DI (match_dup 0)
20014                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20015   "peep2_regno_dead_p (0, FLAGS_REG)"
20016   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20017               (clobber (reg:CC FLAGS_REG))])]
20018   "")
20019
20020 (define_peephole2
20021   [(set (match_operand:SI 0 "register_operand" "")
20022         (mult:SI (match_dup 0)
20023                  (match_operand:SI 1 "const_int_operand" "")))]
20024   "exact_log2 (INTVAL (operands[1])) >= 0
20025    && peep2_regno_dead_p (0, FLAGS_REG)"
20026   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20027               (clobber (reg:CC FLAGS_REG))])]
20028   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20029
20030 (define_peephole2
20031   [(set (match_operand:DI 0 "register_operand" "")
20032         (mult:DI (match_dup 0)
20033                  (match_operand:DI 1 "const_int_operand" "")))]
20034   "exact_log2 (INTVAL (operands[1])) >= 0
20035    && peep2_regno_dead_p (0, FLAGS_REG)"
20036   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20037               (clobber (reg:CC FLAGS_REG))])]
20038   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20039
20040 (define_peephole2
20041   [(set (match_operand:SI 0 "register_operand" "")
20042         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20043                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20044   "exact_log2 (INTVAL (operands[2])) >= 0
20045    && REGNO (operands[0]) == REGNO (operands[1])
20046    && peep2_regno_dead_p (0, FLAGS_REG)"
20047   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20048               (clobber (reg:CC FLAGS_REG))])]
20049   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20050
20051 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20052 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20053 ;; many CPUs it is also faster, since special hardware to avoid esp
20054 ;; dependencies is present.
20055
20056 ;; While some of these conversions may be done using splitters, we use peepholes
20057 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20058
20059 ;; Convert prologue esp subtractions to push.
20060 ;; We need register to push.  In order to keep verify_flow_info happy we have
20061 ;; two choices
20062 ;; - use scratch and clobber it in order to avoid dependencies
20063 ;; - use already live register
20064 ;; We can't use the second way right now, since there is no reliable way how to
20065 ;; verify that given register is live.  First choice will also most likely in
20066 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20067 ;; call clobbered registers are dead.  We may want to use base pointer as an
20068 ;; alternative when no register is available later.
20069
20070 (define_peephole2
20071   [(match_scratch:SI 0 "r")
20072    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20073               (clobber (reg:CC FLAGS_REG))
20074               (clobber (mem:BLK (scratch)))])]
20075   "optimize_size || !TARGET_SUB_ESP_4"
20076   [(clobber (match_dup 0))
20077    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20078               (clobber (mem:BLK (scratch)))])])
20079
20080 (define_peephole2
20081   [(match_scratch:SI 0 "r")
20082    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20083               (clobber (reg:CC FLAGS_REG))
20084               (clobber (mem:BLK (scratch)))])]
20085   "optimize_size || !TARGET_SUB_ESP_8"
20086   [(clobber (match_dup 0))
20087    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20088    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20089               (clobber (mem:BLK (scratch)))])])
20090
20091 ;; Convert esp subtractions to push.
20092 (define_peephole2
20093   [(match_scratch:SI 0 "r")
20094    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20095               (clobber (reg:CC FLAGS_REG))])]
20096   "optimize_size || !TARGET_SUB_ESP_4"
20097   [(clobber (match_dup 0))
20098    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20099
20100 (define_peephole2
20101   [(match_scratch:SI 0 "r")
20102    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20103               (clobber (reg:CC FLAGS_REG))])]
20104   "optimize_size || !TARGET_SUB_ESP_8"
20105   [(clobber (match_dup 0))
20106    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20107    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20108
20109 ;; Convert epilogue deallocator to pop.
20110 (define_peephole2
20111   [(match_scratch:SI 0 "r")
20112    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20113               (clobber (reg:CC FLAGS_REG))
20114               (clobber (mem:BLK (scratch)))])]
20115   "optimize_size || !TARGET_ADD_ESP_4"
20116   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20117               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20118               (clobber (mem:BLK (scratch)))])]
20119   "")
20120
20121 ;; Two pops case is tricky, since pop causes dependency on destination register.
20122 ;; We use two registers if available.
20123 (define_peephole2
20124   [(match_scratch:SI 0 "r")
20125    (match_scratch:SI 1 "r")
20126    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20127               (clobber (reg:CC FLAGS_REG))
20128               (clobber (mem:BLK (scratch)))])]
20129   "optimize_size || !TARGET_ADD_ESP_8"
20130   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20131               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20132               (clobber (mem:BLK (scratch)))])
20133    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20134               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20135   "")
20136
20137 (define_peephole2
20138   [(match_scratch:SI 0 "r")
20139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20140               (clobber (reg:CC FLAGS_REG))
20141               (clobber (mem:BLK (scratch)))])]
20142   "optimize_size"
20143   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20144               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20145               (clobber (mem:BLK (scratch)))])
20146    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20147               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20148   "")
20149
20150 ;; Convert esp additions to pop.
20151 (define_peephole2
20152   [(match_scratch:SI 0 "r")
20153    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20154               (clobber (reg:CC FLAGS_REG))])]
20155   ""
20156   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20157               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20158   "")
20159
20160 ;; Two pops case is tricky, since pop causes dependency on destination register.
20161 ;; We use two registers if available.
20162 (define_peephole2
20163   [(match_scratch:SI 0 "r")
20164    (match_scratch:SI 1 "r")
20165    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20166               (clobber (reg:CC FLAGS_REG))])]
20167   ""
20168   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20169               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20170    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20171               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20172   "")
20173
20174 (define_peephole2
20175   [(match_scratch:SI 0 "r")
20176    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20177               (clobber (reg:CC FLAGS_REG))])]
20178   "optimize_size"
20179   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20180               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20181    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20183   "")
20184 \f
20185 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20186 ;; required and register dies.  Similarly for 128 to plus -128.
20187 (define_peephole2
20188   [(set (match_operand 0 "flags_reg_operand" "")
20189         (match_operator 1 "compare_operator"
20190           [(match_operand 2 "register_operand" "")
20191            (match_operand 3 "const_int_operand" "")]))]
20192   "(INTVAL (operands[3]) == -1
20193     || INTVAL (operands[3]) == 1
20194     || INTVAL (operands[3]) == 128)
20195    && ix86_match_ccmode (insn, CCGCmode)
20196    && peep2_reg_dead_p (1, operands[2])"
20197   [(parallel [(set (match_dup 0)
20198                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20199               (clobber (match_dup 2))])]
20200   "")
20201 \f
20202 (define_peephole2
20203   [(match_scratch:DI 0 "r")
20204    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20205               (clobber (reg:CC FLAGS_REG))
20206               (clobber (mem:BLK (scratch)))])]
20207   "optimize_size || !TARGET_SUB_ESP_4"
20208   [(clobber (match_dup 0))
20209    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20210               (clobber (mem:BLK (scratch)))])])
20211
20212 (define_peephole2
20213   [(match_scratch:DI 0 "r")
20214    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20215               (clobber (reg:CC FLAGS_REG))
20216               (clobber (mem:BLK (scratch)))])]
20217   "optimize_size || !TARGET_SUB_ESP_8"
20218   [(clobber (match_dup 0))
20219    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20220    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20221               (clobber (mem:BLK (scratch)))])])
20222
20223 ;; Convert esp subtractions to push.
20224 (define_peephole2
20225   [(match_scratch:DI 0 "r")
20226    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20227               (clobber (reg:CC FLAGS_REG))])]
20228   "optimize_size || !TARGET_SUB_ESP_4"
20229   [(clobber (match_dup 0))
20230    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20231
20232 (define_peephole2
20233   [(match_scratch:DI 0 "r")
20234    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20235               (clobber (reg:CC FLAGS_REG))])]
20236   "optimize_size || !TARGET_SUB_ESP_8"
20237   [(clobber (match_dup 0))
20238    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20239    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20240
20241 ;; Convert epilogue deallocator to pop.
20242 (define_peephole2
20243   [(match_scratch:DI 0 "r")
20244    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20245               (clobber (reg:CC FLAGS_REG))
20246               (clobber (mem:BLK (scratch)))])]
20247   "optimize_size || !TARGET_ADD_ESP_4"
20248   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20249               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20250               (clobber (mem:BLK (scratch)))])]
20251   "")
20252
20253 ;; Two pops case is tricky, since pop causes dependency on destination register.
20254 ;; We use two registers if available.
20255 (define_peephole2
20256   [(match_scratch:DI 0 "r")
20257    (match_scratch:DI 1 "r")
20258    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20259               (clobber (reg:CC FLAGS_REG))
20260               (clobber (mem:BLK (scratch)))])]
20261   "optimize_size || !TARGET_ADD_ESP_8"
20262   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20263               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20264               (clobber (mem:BLK (scratch)))])
20265    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20266               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20267   "")
20268
20269 (define_peephole2
20270   [(match_scratch:DI 0 "r")
20271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20272               (clobber (reg:CC FLAGS_REG))
20273               (clobber (mem:BLK (scratch)))])]
20274   "optimize_size"
20275   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20276               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20277               (clobber (mem:BLK (scratch)))])
20278    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20279               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20280   "")
20281
20282 ;; Convert esp additions to pop.
20283 (define_peephole2
20284   [(match_scratch:DI 0 "r")
20285    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20286               (clobber (reg:CC FLAGS_REG))])]
20287   ""
20288   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20289               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20290   "")
20291
20292 ;; Two pops case is tricky, since pop causes dependency on destination register.
20293 ;; We use two registers if available.
20294 (define_peephole2
20295   [(match_scratch:DI 0 "r")
20296    (match_scratch:DI 1 "r")
20297    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20298               (clobber (reg:CC FLAGS_REG))])]
20299   ""
20300   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20301               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20302    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20303               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20304   "")
20305
20306 (define_peephole2
20307   [(match_scratch:DI 0 "r")
20308    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20309               (clobber (reg:CC FLAGS_REG))])]
20310   "optimize_size"
20311   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20312               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20313    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20315   "")
20316 \f
20317 ;; Convert imul by three, five and nine into lea
20318 (define_peephole2
20319   [(parallel
20320     [(set (match_operand:SI 0 "register_operand" "")
20321           (mult:SI (match_operand:SI 1 "register_operand" "")
20322                    (match_operand:SI 2 "const_int_operand" "")))
20323      (clobber (reg:CC FLAGS_REG))])]
20324   "INTVAL (operands[2]) == 3
20325    || INTVAL (operands[2]) == 5
20326    || INTVAL (operands[2]) == 9"
20327   [(set (match_dup 0)
20328         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20329                  (match_dup 1)))]
20330   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20331
20332 (define_peephole2
20333   [(parallel
20334     [(set (match_operand:SI 0 "register_operand" "")
20335           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20336                    (match_operand:SI 2 "const_int_operand" "")))
20337      (clobber (reg:CC FLAGS_REG))])]
20338   "!optimize_size 
20339    && (INTVAL (operands[2]) == 3
20340        || INTVAL (operands[2]) == 5
20341        || INTVAL (operands[2]) == 9)"
20342   [(set (match_dup 0) (match_dup 1))
20343    (set (match_dup 0)
20344         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20345                  (match_dup 0)))]
20346   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20347
20348 (define_peephole2
20349   [(parallel
20350     [(set (match_operand:DI 0 "register_operand" "")
20351           (mult:DI (match_operand:DI 1 "register_operand" "")
20352                    (match_operand:DI 2 "const_int_operand" "")))
20353      (clobber (reg:CC FLAGS_REG))])]
20354   "TARGET_64BIT
20355    && (INTVAL (operands[2]) == 3
20356        || INTVAL (operands[2]) == 5
20357        || INTVAL (operands[2]) == 9)"
20358   [(set (match_dup 0)
20359         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20360                  (match_dup 1)))]
20361   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20362
20363 (define_peephole2
20364   [(parallel
20365     [(set (match_operand:DI 0 "register_operand" "")
20366           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20367                    (match_operand:DI 2 "const_int_operand" "")))
20368      (clobber (reg:CC FLAGS_REG))])]
20369   "TARGET_64BIT
20370    && !optimize_size 
20371    && (INTVAL (operands[2]) == 3
20372        || INTVAL (operands[2]) == 5
20373        || INTVAL (operands[2]) == 9)"
20374   [(set (match_dup 0) (match_dup 1))
20375    (set (match_dup 0)
20376         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20377                  (match_dup 0)))]
20378   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20379
20380 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20381 ;; imul $32bit_imm, reg, reg is direct decoded.
20382 (define_peephole2
20383   [(match_scratch:DI 3 "r")
20384    (parallel [(set (match_operand:DI 0 "register_operand" "")
20385                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20386                             (match_operand:DI 2 "immediate_operand" "")))
20387               (clobber (reg:CC FLAGS_REG))])]
20388   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20389    && !satisfies_constraint_K (operands[2])"
20390   [(set (match_dup 3) (match_dup 1))
20391    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20392               (clobber (reg:CC FLAGS_REG))])]
20393 "")
20394
20395 (define_peephole2
20396   [(match_scratch:SI 3 "r")
20397    (parallel [(set (match_operand:SI 0 "register_operand" "")
20398                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20399                             (match_operand:SI 2 "immediate_operand" "")))
20400               (clobber (reg:CC FLAGS_REG))])]
20401   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402    && !satisfies_constraint_K (operands[2])"
20403   [(set (match_dup 3) (match_dup 1))
20404    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20405               (clobber (reg:CC FLAGS_REG))])]
20406 "")
20407
20408 (define_peephole2
20409   [(match_scratch:SI 3 "r")
20410    (parallel [(set (match_operand:DI 0 "register_operand" "")
20411                    (zero_extend:DI
20412                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20413                               (match_operand:SI 2 "immediate_operand" ""))))
20414               (clobber (reg:CC FLAGS_REG))])]
20415   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20416    && !satisfies_constraint_K (operands[2])"
20417   [(set (match_dup 3) (match_dup 1))
20418    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20419               (clobber (reg:CC FLAGS_REG))])]
20420 "")
20421
20422 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20423 ;; Convert it into imul reg, reg
20424 ;; It would be better to force assembler to encode instruction using long
20425 ;; immediate, but there is apparently no way to do so.
20426 (define_peephole2
20427   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20428                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20429                             (match_operand:DI 2 "const_int_operand" "")))
20430               (clobber (reg:CC FLAGS_REG))])
20431    (match_scratch:DI 3 "r")]
20432   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20433    && satisfies_constraint_K (operands[2])"
20434   [(set (match_dup 3) (match_dup 2))
20435    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20436               (clobber (reg:CC FLAGS_REG))])]
20437 {
20438   if (!rtx_equal_p (operands[0], operands[1]))
20439     emit_move_insn (operands[0], operands[1]);
20440 })
20441
20442 (define_peephole2
20443   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20444                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20445                             (match_operand:SI 2 "const_int_operand" "")))
20446               (clobber (reg:CC FLAGS_REG))])
20447    (match_scratch:SI 3 "r")]
20448   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20449    && satisfies_constraint_K (operands[2])"
20450   [(set (match_dup 3) (match_dup 2))
20451    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20452               (clobber (reg:CC FLAGS_REG))])]
20453 {
20454   if (!rtx_equal_p (operands[0], operands[1]))
20455     emit_move_insn (operands[0], operands[1]);
20456 })
20457
20458 (define_peephole2
20459   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20460                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20461                             (match_operand:HI 2 "immediate_operand" "")))
20462               (clobber (reg:CC FLAGS_REG))])
20463    (match_scratch:HI 3 "r")]
20464   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20465   [(set (match_dup 3) (match_dup 2))
20466    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20467               (clobber (reg:CC FLAGS_REG))])]
20468 {
20469   if (!rtx_equal_p (operands[0], operands[1]))
20470     emit_move_insn (operands[0], operands[1]);
20471 })
20472
20473 ;; After splitting up read-modify operations, array accesses with memory
20474 ;; operands might end up in form:
20475 ;;  sall    $2, %eax
20476 ;;  movl    4(%esp), %edx
20477 ;;  addl    %edx, %eax
20478 ;; instead of pre-splitting:
20479 ;;  sall    $2, %eax
20480 ;;  addl    4(%esp), %eax
20481 ;; Turn it into:
20482 ;;  movl    4(%esp), %edx
20483 ;;  leal    (%edx,%eax,4), %eax
20484
20485 (define_peephole2
20486   [(parallel [(set (match_operand 0 "register_operand" "")
20487                    (ashift (match_operand 1 "register_operand" "")
20488                            (match_operand 2 "const_int_operand" "")))
20489                (clobber (reg:CC FLAGS_REG))])
20490    (set (match_operand 3 "register_operand")
20491         (match_operand 4 "x86_64_general_operand" ""))
20492    (parallel [(set (match_operand 5 "register_operand" "")
20493                    (plus (match_operand 6 "register_operand" "")
20494                          (match_operand 7 "register_operand" "")))
20495                    (clobber (reg:CC FLAGS_REG))])]
20496   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20497    /* Validate MODE for lea.  */
20498    && ((!TARGET_PARTIAL_REG_STALL
20499         && (GET_MODE (operands[0]) == QImode
20500             || GET_MODE (operands[0]) == HImode))
20501        || GET_MODE (operands[0]) == SImode 
20502        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20503    /* We reorder load and the shift.  */
20504    && !rtx_equal_p (operands[1], operands[3])
20505    && !reg_overlap_mentioned_p (operands[0], operands[4])
20506    /* Last PLUS must consist of operand 0 and 3.  */
20507    && !rtx_equal_p (operands[0], operands[3])
20508    && (rtx_equal_p (operands[3], operands[6])
20509        || rtx_equal_p (operands[3], operands[7]))
20510    && (rtx_equal_p (operands[0], operands[6])
20511        || rtx_equal_p (operands[0], operands[7]))
20512    /* The intermediate operand 0 must die or be same as output.  */
20513    && (rtx_equal_p (operands[0], operands[5])
20514        || peep2_reg_dead_p (3, operands[0]))"
20515   [(set (match_dup 3) (match_dup 4))
20516    (set (match_dup 0) (match_dup 1))]
20517 {
20518   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20519   int scale = 1 << INTVAL (operands[2]);
20520   rtx index = gen_lowpart (Pmode, operands[1]);
20521   rtx base = gen_lowpart (Pmode, operands[3]);
20522   rtx dest = gen_lowpart (mode, operands[5]);
20523
20524   operands[1] = gen_rtx_PLUS (Pmode, base,
20525                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20526   if (mode != Pmode)
20527     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20528   operands[0] = dest;
20529 })
20530 \f
20531 ;; Call-value patterns last so that the wildcard operand does not
20532 ;; disrupt insn-recog's switch tables.
20533
20534 (define_insn "*call_value_pop_0"
20535   [(set (match_operand 0 "" "")
20536         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20537               (match_operand:SI 2 "" "")))
20538    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20539                             (match_operand:SI 3 "immediate_operand" "")))]
20540   "!TARGET_64BIT"
20541 {
20542   if (SIBLING_CALL_P (insn))
20543     return "jmp\t%P1";
20544   else
20545     return "call\t%P1";
20546 }
20547   [(set_attr "type" "callv")])
20548
20549 (define_insn "*call_value_pop_1"
20550   [(set (match_operand 0 "" "")
20551         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20552               (match_operand:SI 2 "" "")))
20553    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20554                             (match_operand:SI 3 "immediate_operand" "i")))]
20555   "!TARGET_64BIT"
20556 {
20557   if (constant_call_address_operand (operands[1], Pmode))
20558     {
20559       if (SIBLING_CALL_P (insn))
20560         return "jmp\t%P1";
20561       else
20562         return "call\t%P1";
20563     }
20564   if (SIBLING_CALL_P (insn))
20565     return "jmp\t%A1";
20566   else
20567     return "call\t%A1";
20568 }
20569   [(set_attr "type" "callv")])
20570
20571 (define_insn "*call_value_0"
20572   [(set (match_operand 0 "" "")
20573         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20574               (match_operand:SI 2 "" "")))]
20575   "!TARGET_64BIT"
20576 {
20577   if (SIBLING_CALL_P (insn))
20578     return "jmp\t%P1";
20579   else
20580     return "call\t%P1";
20581 }
20582   [(set_attr "type" "callv")])
20583
20584 (define_insn "*call_value_0_rex64"
20585   [(set (match_operand 0 "" "")
20586         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20587               (match_operand:DI 2 "const_int_operand" "")))]
20588   "TARGET_64BIT"
20589 {
20590   if (SIBLING_CALL_P (insn))
20591     return "jmp\t%P1";
20592   else
20593     return "call\t%P1";
20594 }
20595   [(set_attr "type" "callv")])
20596
20597 (define_insn "*call_value_1"
20598   [(set (match_operand 0 "" "")
20599         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20600               (match_operand:SI 2 "" "")))]
20601   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20602 {
20603   if (constant_call_address_operand (operands[1], Pmode))
20604     return "call\t%P1";
20605   return "call\t%A1";
20606 }
20607   [(set_attr "type" "callv")])
20608
20609 (define_insn "*sibcall_value_1"
20610   [(set (match_operand 0 "" "")
20611         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20612               (match_operand:SI 2 "" "")))]
20613   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20614 {
20615   if (constant_call_address_operand (operands[1], Pmode))
20616     return "jmp\t%P1";
20617   return "jmp\t%A1";
20618 }
20619   [(set_attr "type" "callv")])
20620
20621 (define_insn "*call_value_1_rex64"
20622   [(set (match_operand 0 "" "")
20623         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20624               (match_operand:DI 2 "" "")))]
20625   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20626 {
20627   if (constant_call_address_operand (operands[1], Pmode))
20628     return "call\t%P1";
20629   return "call\t%A1";
20630 }
20631   [(set_attr "type" "callv")])
20632
20633 (define_insn "*sibcall_value_1_rex64"
20634   [(set (match_operand 0 "" "")
20635         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20636               (match_operand:DI 2 "" "")))]
20637   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20638   "jmp\t%P1"
20639   [(set_attr "type" "callv")])
20640
20641 (define_insn "*sibcall_value_1_rex64_v"
20642   [(set (match_operand 0 "" "")
20643         (call (mem:QI (reg:DI 40))
20644               (match_operand:DI 1 "" "")))]
20645   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20646   "jmp\t*%%r11"
20647   [(set_attr "type" "callv")])
20648 \f
20649 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20650 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20651 ;; caught for use by garbage collectors and the like.  Using an insn that
20652 ;; maps to SIGILL makes it more likely the program will rightfully die.
20653 ;; Keeping with tradition, "6" is in honor of #UD.
20654 (define_insn "trap"
20655   [(trap_if (const_int 1) (const_int 6))]
20656   ""
20657   { return ASM_SHORT "0x0b0f"; }
20658   [(set_attr "length" "2")])
20659
20660 (define_expand "sse_prologue_save"
20661   [(parallel [(set (match_operand:BLK 0 "" "")
20662                    (unspec:BLK [(reg:DI 21)
20663                                 (reg:DI 22)
20664                                 (reg:DI 23)
20665                                 (reg:DI 24)
20666                                 (reg:DI 25)
20667                                 (reg:DI 26)
20668                                 (reg:DI 27)
20669                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20670               (use (match_operand:DI 1 "register_operand" ""))
20671               (use (match_operand:DI 2 "immediate_operand" ""))
20672               (use (label_ref:DI (match_operand 3 "" "")))])]
20673   "TARGET_64BIT"
20674   "")
20675
20676 (define_insn "*sse_prologue_save_insn"
20677   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20678                           (match_operand:DI 4 "const_int_operand" "n")))
20679         (unspec:BLK [(reg:DI 21)
20680                      (reg:DI 22)
20681                      (reg:DI 23)
20682                      (reg:DI 24)
20683                      (reg:DI 25)
20684                      (reg:DI 26)
20685                      (reg:DI 27)
20686                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20687    (use (match_operand:DI 1 "register_operand" "r"))
20688    (use (match_operand:DI 2 "const_int_operand" "i"))
20689    (use (label_ref:DI (match_operand 3 "" "X")))]
20690   "TARGET_64BIT
20691    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20692    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20693   "*
20694 {
20695   int i;
20696   operands[0] = gen_rtx_MEM (Pmode,
20697                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20698   output_asm_insn (\"jmp\\t%A1\", operands);
20699   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20700     {
20701       operands[4] = adjust_address (operands[0], DImode, i*16);
20702       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20703       PUT_MODE (operands[4], TImode);
20704       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20705         output_asm_insn (\"rex\", operands);
20706       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20707     }
20708   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20709                              CODE_LABEL_NUMBER (operands[3]));
20710   RET;
20711 }
20712   "
20713   [(set_attr "type" "other")
20714    (set_attr "length_immediate" "0")
20715    (set_attr "length_address" "0")
20716    (set_attr "length" "135")
20717    (set_attr "memory" "store")
20718    (set_attr "modrm" "0")
20719    (set_attr "mode" "DI")])
20720
20721 (define_expand "prefetch"
20722   [(prefetch (match_operand 0 "address_operand" "")
20723              (match_operand:SI 1 "const_int_operand" "")
20724              (match_operand:SI 2 "const_int_operand" ""))]
20725   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20726 {
20727   int rw = INTVAL (operands[1]);
20728   int locality = INTVAL (operands[2]);
20729
20730   gcc_assert (rw == 0 || rw == 1);
20731   gcc_assert (locality >= 0 && locality <= 3);
20732   gcc_assert (GET_MODE (operands[0]) == Pmode
20733               || GET_MODE (operands[0]) == VOIDmode);
20734
20735   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20736      supported by SSE counterpart or the SSE prefetch is not available
20737      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20738      of locality.  */
20739   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20740     operands[2] = GEN_INT (3);
20741   else
20742     operands[1] = const0_rtx;
20743 })
20744
20745 (define_insn "*prefetch_sse"
20746   [(prefetch (match_operand:SI 0 "address_operand" "p")
20747              (const_int 0)
20748              (match_operand:SI 1 "const_int_operand" ""))]
20749   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20750 {
20751   static const char * const patterns[4] = {
20752    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20753   };
20754
20755   int locality = INTVAL (operands[1]);
20756   gcc_assert (locality >= 0 && locality <= 3);
20757
20758   return patterns[locality];  
20759 }
20760   [(set_attr "type" "sse")
20761    (set_attr "memory" "none")])
20762
20763 (define_insn "*prefetch_sse_rex"
20764   [(prefetch (match_operand:DI 0 "address_operand" "p")
20765              (const_int 0)
20766              (match_operand:SI 1 "const_int_operand" ""))]
20767   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20768 {
20769   static const char * const patterns[4] = {
20770    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20771   };
20772
20773   int locality = INTVAL (operands[1]);
20774   gcc_assert (locality >= 0 && locality <= 3);
20775
20776   return patterns[locality];  
20777 }
20778   [(set_attr "type" "sse")
20779    (set_attr "memory" "none")])
20780
20781 (define_insn "*prefetch_3dnow"
20782   [(prefetch (match_operand:SI 0 "address_operand" "p")
20783              (match_operand:SI 1 "const_int_operand" "n")
20784              (const_int 3))]
20785   "TARGET_3DNOW && !TARGET_64BIT"
20786 {
20787   if (INTVAL (operands[1]) == 0)
20788     return "prefetch\t%a0";
20789   else
20790     return "prefetchw\t%a0";
20791 }
20792   [(set_attr "type" "mmx")
20793    (set_attr "memory" "none")])
20794
20795 (define_insn "*prefetch_3dnow_rex"
20796   [(prefetch (match_operand:DI 0 "address_operand" "p")
20797              (match_operand:SI 1 "const_int_operand" "n")
20798              (const_int 3))]
20799   "TARGET_3DNOW && TARGET_64BIT"
20800 {
20801   if (INTVAL (operands[1]) == 0)
20802     return "prefetch\t%a0";
20803   else
20804     return "prefetchw\t%a0";
20805 }
20806   [(set_attr "type" "mmx")
20807    (set_attr "memory" "none")])
20808
20809 (define_expand "stack_protect_set"
20810   [(match_operand 0 "memory_operand" "")
20811    (match_operand 1 "memory_operand" "")]
20812   ""
20813 {
20814 #ifdef TARGET_THREAD_SSP_OFFSET
20815   if (TARGET_64BIT)
20816     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20817                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20818   else
20819     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20820                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20821 #else
20822   if (TARGET_64BIT)
20823     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20824   else
20825     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20826 #endif
20827   DONE;
20828 })
20829
20830 (define_insn "stack_protect_set_si"
20831   [(set (match_operand:SI 0 "memory_operand" "=m")
20832         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20833    (set (match_scratch:SI 2 "=&r") (const_int 0))
20834    (clobber (reg:CC FLAGS_REG))]
20835   ""
20836   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20837   [(set_attr "type" "multi")])
20838
20839 (define_insn "stack_protect_set_di"
20840   [(set (match_operand:DI 0 "memory_operand" "=m")
20841         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20842    (set (match_scratch:DI 2 "=&r") (const_int 0))
20843    (clobber (reg:CC FLAGS_REG))]
20844   "TARGET_64BIT"
20845   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20846   [(set_attr "type" "multi")])
20847
20848 (define_insn "stack_tls_protect_set_si"
20849   [(set (match_operand:SI 0 "memory_operand" "=m")
20850         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20851    (set (match_scratch:SI 2 "=&r") (const_int 0))
20852    (clobber (reg:CC FLAGS_REG))]
20853   ""
20854   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20855   [(set_attr "type" "multi")])
20856
20857 (define_insn "stack_tls_protect_set_di"
20858   [(set (match_operand:DI 0 "memory_operand" "=m")
20859         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20860    (set (match_scratch:DI 2 "=&r") (const_int 0))
20861    (clobber (reg:CC FLAGS_REG))]
20862   "TARGET_64BIT"
20863   {
20864      /* The kernel uses a different segment register for performance reasons; a
20865         system call would not have to trash the userspace segment register,
20866         which would be expensive */
20867      if (ix86_cmodel != CM_KERNEL)
20868         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20869      else
20870         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20871   }
20872   [(set_attr "type" "multi")])
20873
20874 (define_expand "stack_protect_test"
20875   [(match_operand 0 "memory_operand" "")
20876    (match_operand 1 "memory_operand" "")
20877    (match_operand 2 "" "")]
20878   ""
20879 {
20880   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20881   ix86_compare_op0 = operands[0];
20882   ix86_compare_op1 = operands[1];
20883   ix86_compare_emitted = flags;
20884
20885 #ifdef TARGET_THREAD_SSP_OFFSET
20886   if (TARGET_64BIT)
20887     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20888                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20889   else
20890     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20891                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20892 #else
20893   if (TARGET_64BIT)
20894     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20895   else
20896     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20897 #endif
20898   emit_jump_insn (gen_beq (operands[2]));
20899   DONE;
20900 })
20901
20902 (define_insn "stack_protect_test_si"
20903   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20904         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20905                      (match_operand:SI 2 "memory_operand" "m")]
20906                     UNSPEC_SP_TEST))
20907    (clobber (match_scratch:SI 3 "=&r"))]
20908   ""
20909   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20910   [(set_attr "type" "multi")])
20911
20912 (define_insn "stack_protect_test_di"
20913   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20914         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20915                      (match_operand:DI 2 "memory_operand" "m")]
20916                     UNSPEC_SP_TEST))
20917    (clobber (match_scratch:DI 3 "=&r"))]
20918   "TARGET_64BIT"
20919   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20920   [(set_attr "type" "multi")])
20921
20922 (define_insn "stack_tls_protect_test_si"
20923   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20924         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20925                      (match_operand:SI 2 "const_int_operand" "i")]
20926                     UNSPEC_SP_TLS_TEST))
20927    (clobber (match_scratch:SI 3 "=r"))]
20928   ""
20929   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20930   [(set_attr "type" "multi")])
20931
20932 (define_insn "stack_tls_protect_test_di"
20933   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20934         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20935                      (match_operand:DI 2 "const_int_operand" "i")]
20936                     UNSPEC_SP_TLS_TEST))
20937    (clobber (match_scratch:DI 3 "=r"))]
20938   "TARGET_64BIT"
20939   {
20940      /* The kernel uses a different segment register for performance reasons; a
20941         system call would not have to trash the userspace segment register,
20942         which would be expensive */
20943      if (ix86_cmodel != CM_KERNEL)
20944         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20945      else
20946         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20947   }
20948   [(set_attr "type" "multi")])
20949
20950 (include "sse.md")
20951 (include "mmx.md")
20952 (include "sync.md")